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
Bump, bump, help? ;D
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;
}
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!!!!
You're welcome :)
I've never used FMOD, but this article (http://www.gamedev.net/reference/articles/article2098.asp) is rather informative and helpful.
I just wanted to inform you, that my program does what it should!
Thanks!
bye Isegrim