0
0

I’ve a routine that decompress mp3 into pcm using callbacks to fill the input/output buffer… and then I want to send this decoded pcm to pcmreadcallback(…).

Now I ask:

-How do I know how many bytes of mp3 it’s needed to be decompressed to fit a pcm buffer of 16384(int datalen)? (Is it possible to change datalen value?)

-In general, how do I synchronize the mp3 decode output buffer(already in pcm), with the pcmreadcallback(…)? Furthermore, it’s also needed to know the # of samples, channels, etc. How do I get this info from a buffer of mp3 data??

Give me some pseudo-code example, it’s ok. Thanks

  • You must to post comments
0
0

Have you considered using a filesystem callback and encoding the memory location in a fake ‘filename’?

  • You must to post comments
0
0

[quote="Janus":1bd2wfh6]Have you considered using a filesystem callback and encoding the memory location in a fake ‘filename’?[/quote:1bd2wfh6]

Like I said, Janus, I want to use the HDD only for reading. But what you mean by “encoding the memory location in a fake ‘filename'”?

  • You must to post comments
0
0

[quote="brett":b41q7c04]you’re probably going to all this trouble when all you want to do is play an mp3 from a zip file.[/quote:b41q7c04]

Well, everyone has their own purposes.

[quote="brett":b41q7c04]All you would have to do is override fmod’s filesystem so it reads from the zip file.[/quote:b41q7c04]

You mean override the System::setFileSystem function?

  • You must to post comments
0
0

[quote="brett":172695cg][quote="LÔPÂN":172695cg]I’ve a routine that decompress mp3 into pcm using callbacks to fill the input/output buffer… and then I want to send this decoded pcm to pcmreadcallback(…).

Now I ask:

-How do I know how many bytes of mp3 it’s needed to be decompressed to fit a pcm buffer of 16384(int datalen)? (Is it possible to change datalen value?)
[quote:172695cg]

How are you decompressing the mp3? If you were using Sound::readData you would just use readData(buffer, 16384, 0);
If you’re not, then just make sure you buffer your data so that you give fmod 16384 as it ask for.

[quote:172695cg]
-In general, how do I synchronize the mp3 decode output buffer(already in pcm), with the pcmreadcallback(…)? Furthermore, it’s also needed to know the # of samples, channels, etc. How do I get this info from a buffer of mp3 data??

Give me some pseudo-code example, it’s ok. Thanks[/quote:172695cg]

There is no synchronization needed because you should be using a non-realtime mp3 decompression routine, not some sort of routine where you are trying to capture the output of another buffer and put it into fmod’s as it plays or something.
If you are then you have to buffer the data yourself. You have given no details on the actual mp3 decode side of things.[/quote:172695cg]
[/quote:172695cg][/quote:172695cg]

Hi, Brett.

Let me explain: I have a 60MB mp3 file inside a .zip, rather than seizeing 60MB of memory at once, I want to unzip the mp3 inside the zip into pieces (2MB-buffer), then decompress the mp3 data in this buffer and send it as pcm data to fmod for instant playing.

Can this Sound::readData decompress mp3 into pcm as I mentioned? Because I’m using the high-level api of the [url=http://www.underbit.com/products/mad:172695cg]MAD library[/url:172695cg] to do that. BTW, can you give me some directions on using MAD with FMOD? (If it really is necessary to use MAD).

regards,
LÔPÂN

  • You must to post comments
0
0

[quote="LÔPÂN":1l0vsn4j][quote="Janus":1l0vsn4j]Have you considered using a filesystem callback and encoding the memory location in a fake ‘filename’?[/quote:1l0vsn4j]

Like I said, Janus, I want to use the HDD only for reading. But what you mean by “encoding the memory location in a fake ‘filename'”?[/quote:1l0vsn4j]If you set up a filesystem callback FMOD uses your callback to load files instead of using the HDD, so your callbacks could read audio directly from memory like you want. I’m pretty sure the docs explain this.

You could store the memory location in a fake filename by converting the location to a string and passing that in as the filename. An easy way to do that would be to use sprintf() to generate a filename string and atoi() to convert it back to a numeric address.

  • You must to post comments
0
0

[quote="LÔPÂN":101ic9ox]Let me explain: I have a 60MB mp3 file inside a .zip, rather than seizeing 60MB of memory at once, I want to unzip the mp3 inside the zip into pieces (2MB-buffer), then decompress the mp3 data in this buffer and send it as pcm data to fmod for instant playing.[/quote:101ic9ox]Why not install a custom filesystem handler for FMod and just use a regular MP3 stream? Then you can take advantage of FMod’s streamer and not need to waste extra memory by buffering and decoding the MP3 yourself.

[quote="LÔPÂN":101ic9ox]Can this Sound::readData decompress mp3 into pcm as I mentioned?[/quote:101ic9ox]My understanding of the Sound::readData api makes me think that it can definitely do what you’re after.

  • You must to post comments
0
0

Thanks, I’m gonna sit back a while and try as you suggested some time soon.

  • You must to post comments
0
0

[quote:e33ra94i]Why not install a custom filesystem handler for FMod and just use a regular MP3 stream? Then you can take advantage of FMod’s streamer and not need to waste extra memory by buffering and decoding the MP3 yourself.[/quote:e33ra94i]

But If I use a filesystem handler, then I wouldn’t be able to passa the first argument as a pointer to a memory location, it’s mandatory to be a file path, as the documentation states:

Remark from System::setFileSystem
[quote:e33ra94i]This has no affect on sounds loaded with FMOD_OPENMEMORY or FMOD_CREATEUSER.[/quote:e33ra94i]

[quote:e33ra94i]ystem->createStream([b:e33ra94i]”../media/wave.mp3″[/b:e33ra94i], FMOD_HARDWARE | FMOD_LOOP_NORMAL | FMOD_2D, 0, &sound);[/quote:e33ra94i]

Is there a way or workaround to use System::setFileSystem with memory location, any suggestion?

I don’t want to extract any single byte of the zip file to the HDD, I want to work only with the memory and buffers.

  • You must to post comments
0
0

[quote="brett":4pp4osq6]Anyway, forget the filecallbacks they dont matter. If you’ve loaded the data into memory from your zip, then you pass it to System::createSound what’s the problem? Just call readData like we said. You dont -need- the filesystem at this point, it is all in memory.[/quote:4pp4osq6]

I don’t know how to proceed, brett. I still need a callback function because I’m unzipping the mp3 into a buffer, one after another, not all at once. I don’t know whether I should use either FMOD_OPENMEMORY or FMOD_OPENUSER modes when creating the sound. If I user OPENMEMORY it doesn’t allow the pcmreadcallback, right?

But if I use OPENUSER, then I can’t use the Sound::readData in my callback because a “0” is mandatory to be passed as the first argument of System::createSound, and thus no data is associated with the Sound::readData.

[quote:4pp4osq6]Good to see i can’t spell (affect vs effect), thanks for quoting it i’ve just updated the docs for setFileSystem now [/quote:4pp4osq6]

OK… I’ll warn you if I see anymore typos 😉

  • You must to post comments
0
0

[quote="brett":2hchb76u]i dont know why you’ve got a new problem.

All i said to do was, with your original code add FMOD_OPENONLY.
Then you read the pcm data yourself with Sound::readData. It is simple as that.
You dont have to use FMOD_OPENMEMORY if you dont want to, but you can if you want to. What do you want? If you dont use FMOD_OPENMEMORY then it will just use the filesystem callbacks if you’ve set one.[/quote:2hchb76u]

My code wasn’t functional. I don’t know how I am supposed to use Sound::readData if my Sound object hasn’t got any real sound data in it, since it was created with a 0, because it was a FMOD_OPENUSER. Here is the code:

[code:2hchb76u]
FMOD::Sound *mp3_sound;

void PlayMP3(FMOD::System *system, FMOD_RESULT result)
{

FMOD::Channel *channel = 0;
FMOD_CREATESOUNDEXINFO createsoundexinfo;
memset(&createsoundexinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
createsoundexinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
createsoundexinfo.length = 364032;
createsoundexinfo.decodebuffersize = 44100;
createsoundexinfo.numchannels = 1;
createsoundexinfo.defaultfrequency = 11025;
createsoundexinfo.format = FMOD_SOUND_FORMAT_PCM16;
createsoundexinfo.pcmreadcallback = mp3readcallback;

system->createSound( 0, FMOD_2D | FMOD_OPENUSER | FMOD_OPENONLY | FMOD_HARDWARE | FMOD_CREATESTREAM, &createsoundexinfo, &mp3_sound);

result = system->playSound(FMOD_CHANNEL_FREE, mp3_sound, 0, &channel);

}

//CALLBACK:

FMOD_RESULT F_CALLBACK mp3readcallback(FMOD_SOUND *sound, void *data, unsigned int datalen)
{

if (count == 1){
unsigned int *data_read = 0;
unsigned char my_data[50000];
UnzipItem( hz, a, my_data, 50000 ); //Unzip first 50k bytes to my_data

result = mp3_sound->readData( data, datalen, data_read ); /*Error here... "Invalid file handle", of course, the mp3_sound object hasn't got any sound data associated, and I don't know how to do that. I'd need maybe a mp3_sound->setData(my_data); /*
if (result == FMOD_OK)
    printf("Success: This is the MP3 Callback");
else
    printf("Error : %s", FMOD_ErrorString(result));
count++;
}



return FMOD_OK;

}
[/code:2hchb76u]

  • You must to post comments
0
0

[quote="brett":3l8f9xci]you’re supposed to use 2 sounds.

1 is the user created sound, 2 is the mp3 which you call readdata on.[/quote:3l8f9xci]

OK… Now I’m getting the sound played all messed up.

My [b:3l8f9xci]Sound::readData[/b:3l8f9xci] is returning [b:3l8f9xci]FMOD_OK[/b:3l8f9xci] but the [b:3l8f9xci]unsigned int * read[/b:3l8f9xci] parameter always [b:3l8f9xci]0[/b:3l8f9xci]. But in fact, it is reading data, because I can hear. Is this normal?

  • You must to post comments
0
0

[quote="brett":ozihmm4o]maybe you’re calling readData on the wrong sound (ie the user one) instead of the mp3 one, and maybe you didnt use OPENONLY like i said. It would return 0 if it loaded the whole thing and had nothing left to read.[/quote:ozihmm4o]

No… I’m calling the right one and using FMOD_OPENONLY, take a look:

[code:ozihmm4o]
FMOD::Sound *mp3_sound; //user sound
FMOD::Sound *my_sound; //readData sound
int count = 1;

void PlayMP3(FMOD::System *system)
{
FMOD_RESULT result = FMOD_OK;
FMOD::Channel *channel = 0;
FMOD_CREATESOUNDEXINFO createsoundexinfo;
memset(&createsoundexinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
createsoundexinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
createsoundexinfo.length = 584762;
createsoundexinfo.decodebuffersize = 44100;
createsoundexinfo.numchannels = 1;
createsoundexinfo.defaultfrequency = 11025;
createsoundexinfo.format = FMOD_SOUND_FORMAT_PCM16;
createsoundexinfo.pcmreadcallback = mp3readcallback;

result = system->createSound( 0, FMOD_2D | FMOD_OPENUSER | FMOD_HARDWARE | FMOD_CREATESTREAM, &createsoundexinfo, &mp3_sound);

result = system->playSound(FMOD_CHANNEL_FREE, mp3_sound, 0, &channel);

}
[/code:ozihmm4o]

//CALLBACK:
[code:ozihmm4o]

FMOD_RESULT F_CALLBACK mp3readcallback(FMOD_SOUND *sound, void *data, unsigned int datalen)
{
FMOD_RESULT result = FMOD_OK;
FMOD_CREATESOUNDEXINFO createsoundexinfo2;

unsigned int *data_read = 0;

if (count == 1) //IF first time callback is called
{

my_data = new char[16384];
UnzipItem( hz, a, my_data, 16384 );

memset(&createsoundexinfo2, 0, sizeof(FMOD_CREATESOUNDEXINFO));
createsoundexinfo2.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
createsoundexinfo2.length = 584762;
createsoundexinfo2.decodebuffersize = 44100;
createsoundexinfo2.numchannels = 1;
createsoundexinfo2.defaultfrequency = 11025; createsoundexinfo2.format = FMOD_SOUND_FORMAT_PCM16;

//system_alias = system

result = system_alias->createSound( my_data, FMOD_OPENMEMORY | FMOD_OPENONLY | FMOD_CREATESTREAM, &createsoundexinfo2, &my_sound);
} //count == 1 END

//count > 1
if (count > 1) UnzipItem( hz, a, my_data, 16384 );

result = my_sound->readData( data, datalen, data_read );

if (result == FMOD_OK)
printf("SUCCESS: This is the MP3 Callback, Bytes read: %d", data_read);
else
printf("ERROR: %s\n", FMOD_ErrorString(result));

count++;

return FMOD_OK;

}//END CALLBACK
[/code:ozihmm4o]

The sound plays OK in the first seconds, but then it crashes. And Sound::readData is returning FMOD_OK and data_read always zero…

If I want exactly 16384 bytes decoded from a mp3, using readData, how much mp3 bytes do I’ve to feed to readData?

  • You must to post comments
0
0

[quote="brett":1i3x5fdm]you cant just provide a part of the sound, the whole mp3 should be in memory[/quote:1i3x5fdm]

How sad. That’s why I was using the MAD engine for doing the mp3 decompressing process. If I have a 100MB-mp3 inside the zip I can’t load it into memory all at once.

I’m going to have kind of a hard time synchronizing FMOD and MAD. But thanks anyway, Brett.

  • You must to post comments
Showing 13 results
Your Answer

Please first to submit.