Need advanced C++ programming help... DONE!

Started by Isegrim, Wed 16/06/2004 13:39:56

Previous topic - Next topic

Isegrim

Hey there!

I know that there are some advanced C++ Programmers out there, so I thought maybe one of you could help me with a little programming problem:
I have to do a team project "MP3 over Profibus" (Profibus is an industrial fieldbus system), which means that I have an MP3-Player application that decodes the MP3 into data that can be sent over Profibus to a microcontroller, which does the sound output over DAC.
I already have a Player that works over FMOD.dll coded in C++.

My idea is now, that I'd first try to write the uncompressed music data to a file, so that I have somthing to talk about with my team partner who is programming the microcontroller.
Now there's the problem: I'm rather new to C++ and it's quite hard for me to understand all the sample programs. I've already tried a few things but have failed so far...
Is there anyone out there who is familiar with FMOD and C++?

I've already posted this question on the FMOD-Forum, but that is little visited and so I thought it can't hurt to post it here either...

A big thanks to all of you who have even read so far ;) (and a bigger even to those who will reply)

Isegrim
This post was generated automatically and therefore bears no signature.

Isegrim

This post was generated automatically and therefore bears no signature.

Scorpiorus

I haven't ever used FMOD but I looked through examples provided along with the library and a "cddarip" sample is very close to what you are after. It reads a stream from a CD and writes it to a file. I changed it a bit and added some comments. I'm not sure if the following code will definately work (I hadn't a chance to test it but there are no header files included etc) but I hope it shows the basic idea. It's basically a rip from the "cddarip" but I removed several lines to point out the main framework, so see a "cddarip" sample for the full working source:

Btw, most of the examples provided along with FMOD are in an ANSI C style with the "main" function as an entry point etc. so I left it as is:

// a file to write into:
FILE *fp;

// a global var to indicate that a stream has been read:
signed char stream_ended = FALSE;

// how many bytes written:
unsigned int byteswritten = 0;

// An event function that will be called by FMOD when a stream has ended:

signed char F_CALLBACKAPI endcallback(FSOUND_STREAM *stream, void *buff, int len, void *param)
{
Ã,  Ã,  stream_ended = TRUE;
Ã,  Ã,  return TRUE;
}

// An event function that will be called by FMOD when there is a next portion of data
// awating to be processed by us. We just write that data into a file:

void * F_CALLBACKAPI DSP_RawWriteCallback(void *originalbuffer, void *newbuffer, int length, void *param)
{
Ã,  Ã,  if (fp && !stream_ended) // fp (filepointer) is ok and stream hasn't ended:
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  fwrite(newbuffer, 1, length << 2, fp); // write a potion of data into file;
Ã,  Ã,  Ã,  Ã,  byteswritten += (length << 2); // just a count of how many bytes has been already written;
Ã,  Ã,  }

Ã,  Ã,  return newbuffer; // we must return a pointer to buffer so FMOD can use it to continue his own processing;
}



// an entry point:
int main(int argc, char *argv[])
{
Ã,  Ã,  unsigned char key;   // holds a key we pressed (used during the main update loop);
Ã,  Ã,  char inputFilename[32] = "input.wav"; // a file we read from;
Ã,  Ã,  char outputFilename[32] = "output.wav"; // a file we write to;

Ã,  Ã,  FSOUND_STREAM *stream;Ã,  // a stream;
Ã,  Ã,  FSOUND_DSPUNIT *rawwrite_dsp; // a dsp unit we use to access stream's data;


// Initialization:

// We want to use a SOFTWARE mixer:
Ã,  Ã,  FSOUND_SetOutput(FSOUND_OUTPUT_NOSOUND_NONREALTIME);

Ã,  Ã,  if (!FSOUND_Init(44100, 32, 0))
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  printf("Error!\n");
Ã,  Ã,  Ã,  Ã,  printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));
Ã,  Ã,  Ã,  Ã,  FSOUND_Close();
Ã,  Ã,  Ã,  Ã,  return 1;
Ã,  Ã,  }

// Prepeare a file write into:
Ã,  Ã,  fp = fopen(outputFilename, "wb");
Ã,  Ã,  if (!fp)
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  printf("ERROR: Couldn't open %s for writing\n", outputFilename);
Ã,  Ã,  Ã,  Ã,  FSOUND_Close();
Ã,  Ã,  Ã,  Ã,  return 1;
Ã,  Ã,  }


// move for some number of bytes forward (so we can add a WAV header at the beginning later);
// We can't do it right now because we haven't read a stream yet and hence don't know
// all the info required (such as the size of a chunk):
Ã,  Ã,  fseek(fp, sizeof(WavHeader) + sizeof(FmtChunk) + sizeof(DataChunk), SEEK_SET);


// Create a DSP callback which will capture the mixed data and write it to disk:
Ã, 
Ã,  Ã,  rawwrite_dsp = FSOUND_DSP_Create(&DSP_RawWriteCallback, FSOUND_DSP_DEFAULTPRIORITY_USER, 0);
Ã,  Ã,  FSOUND_DSP_SetActive(rawwrite_dsp, TRUE);

// Setting buffer size:
Ã,  Ã,  FSOUND_Stream_SetBufferSize(2000);


// Now open a stream:
Ã,  Ã,  stream = FSOUND_Stream_Open(drive_letter, FSOUND_NORMAL, 0, 0);
Ã,  Ã,  if (!stream)
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  printf("ERROR: Couldn't create CDDA stream\n");
Ã,  Ã,  Ã,  Ã,  FSOUND_DSP_SetActive(rawwrite_dsp, FALSE);
Ã,  Ã,  Ã,  Ã,  FSOUND_DSP_Free(rawwrite_dsp);
Ã,  Ã,  Ã,  Ã,  FSOUND_Close();
Ã,  Ã,  Ã,  Ã,  return 1;
Ã,  Ã,  }


// Inform FMOD that we want it to call our "endcallback" we declared before
// when a stream has ended:
Ã,  Ã,  FSOUND_Stream_SetEndCallback(stream, endcallback, 0);


Ã,  Ã,  FSOUND_Stream_SetSubStream(stream, 0);

// Finally, start playing a stream:
Ã,  Ã,  FSOUND_Stream_Play(FSOUND_FREE, stream);


// Main loop: process stream date until ESC pressed or a stream has ended:
Ã,  Ã,  key = 0;
Ã,  Ã,  do
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  if (kbhit()) key = getch();

Ã,  Ã,  Ã,  Ã,  Ã, FSOUND_Update(); // update FMOD (ex: a software mixer which we use btw)
Ã,  Ã, 
Ã,  Ã,  } while ((key != 27) && !stream_ended);


// Now close a stream:
Ã,  Ã,  FSOUND_Stream_Close(stream);

// Turning off a DSP unit we have used:
Ã,  Ã,  FSOUND_DSP_SetActive(rawwrite_dsp, FALSE);

// And free it and remove it from the chain:
Ã,  Ã,  FSOUND_DSP_Free(rawwrite_dsp);


// After a stream has been read we have all info required to add a WAV header
// at the very top of a .wav file:
Ã,  Ã,  WavHeader.chunk.size = sizeof(FmtChunk) + sizeof(RiffChunk) + byteswritten;
Ã,  Ã,  DataChunk.chunk.size = byteswritten;

Ã,  Ã,  fseek(fp, 0, SEEK_SET);
Ã,  Ã,  fwrite(&WavHeader, sizeof(WavHeader), 1, fp);
Ã,  Ã,  fwrite(&FmtChunk, sizeof(FmtChunk), 1, fp);
Ã,  Ã,  fwrite(&DataChunk, sizeof(DataChunk), 1, fp);

// Close file:
Ã,  Ã,  fclose(fp);

// Shut down the while FMOD sound system:
Ã,  Ã,  FSOUND_Close();

Ã,  Ã,  return 0;
}

Isegrim

Man, you are a livesaving GOD!!!
*bows to Scorpiorus*

That was exactly what I needed and exactly where I had never looked myself  ;)
I had the idea to do it in a quite similar way, but I couldn't figure the other examples out (which I thought more appropriate)...

Thank you!!!!
This post was generated automatically and therefore bears no signature.

Scorpiorus


Migs

I've never used FMOD, but this article is rather informative and helpful.
This signature intentionally left blank.

Isegrim

I just wanted to inform you, that my program does what it should!
Thanks!

bye Isegrim
This post was generated automatically and therefore bears no signature.

SMF spam blocked by CleanTalk