My project has interleaved timeline-data streams. Some are audio, but some are animation, subtitles, etc. I would like to use createStream to play the audio blocks, so I must provide my own file system callbacks to FMOD.
However, in a starvation condition, it seems I must thread-block within FMOD_FILE_READCALLBACK until the data becomes available. This is awkward for my project, our file system only provides data asynchronously. I don’t particularly relish the notion of introducing mutexes in our system, with all the hard-to-debug edge case testing it implies (what if the sound is cancelled while thread is blocked? what if multiple FMOD streams are waiting for the same batch of data from the file system? etc).
Ideally, I would like a thread-less push model for providing data to my FMOD stream. Once a frame, I would query the buffer emptiness, and react by pushing some more data if available or muting if no data is ready yet (starvation). FMOD’s mixing thread, which consumes the buffer data, would simply update its fullness indicator as it goes.
[code:18mwfwq4]n = stream->BytesWanted();
if (n >= nAvailable)
stream->PushBytes (src, nAvailable);
else if (stream->IsStarving())
I’ve even considered creating a static looping buffer and filling it myself exactly as shown above with the help of Sound::lock/unlock and Channel::getPosition, with a separate Sound::readData to handle decompression. While that’s not particularly appealing, it’s pretty much what we had in the last iteration of our project, before deciding to evaulate FMOD. I’d be concerned about performance on PS3/SPE though.
One compromise might be if FMOD_FILE_READCALLBACK were permitted to obtain less than the sizebytes requested. Perhaps an "ERR" value of "STARVING" may be returned to indicate the condition that data is not available now, please ask again later. In addition there would need to be either a "retry timeout" value set somewhere, or a "try again now" function to call.
- sgugler asked 10 years ago
- You must login to post comments