Has anyone run into this, or can any of the support ninjas for FMOD give me any advice on how to resolve the following issue? It’s PS3 specific as I’ve managed to solve it on the Xbox 360… but the fact that my fix doesn’t translate across to the other platform is scary…

I’ve encountered a problem recently when running FMOD on a PS3 or Xbox 360, what I found is that in certain steps without precautions a streaming sound would find itself starving and then continiously loop a portion of its buffer until it gets regenerated.

And no I can’t increase the stream buffer size… That has been discussed, and not even a heart-felt poem could give me a couple of hundred extra KB of main memory.

The reason behind all this is a simple game pause, pausing the game for a prolonged period of time and having all the stream sounds work as they should when the game is resumed. As this may include streaming sounds that accompany cutscene animations, it’s important to ensure that the game is paused if the streams can’t play properly due to the disk being idle until those streaming sounds can once again play.

Simple steps below:

  1. Create a non-blocking streaming sound
  2. Pause the sound or a parent channel group long enough for the disc in the console to go idle as it no longer has any file accesses hitting it
  3. Resume the sound to find that it will loop its buffer numerous times because the stream is starving while the disc spins up, allowing the audio streams to once again get their data as per normal, and continue as desired.

Attempted solution:
1. Flush the buffer, using:
// Code to flush a channel

// Input arguments
Channel *channel;

// Code

// Get current position
unsigned int lastPosition;
FMOD_RESULT result = channel->getPosition(&lastPosition);
if( result != FMOD_OK ) ERROR();

// Make the sound position invalid
result = channel->setPosition( 0 );
if( result != FMOD_OK ) ERROR();

// Make the sound position valid once more
result = channel->setPosition( lastPosition );
if( result != FMOD_OK ) ERROR();

( possible that the setPosition(0) is unnecessary for flushing but I’m doing it to be sure because the documentation says "may" cause a seek )

  1. In the update loop: Test for starving streams and stall the game until those streams are functioning correctly.

And this solution worked perfectly on the Xbox 360

Xbox 360 Result:

  • Game Unpaused, Remained paused for a small time, streams and game continued fine.

however when trying this on the PS3 I had mixed results…

PS3 Results:

  1. Audio looped as though the fix was not existant (64kb buffer)
  2. Game unpaused, game and audio played for a small time and then game and audio paused. (96 kb buffer – too much, must go back down to 64kb)
  3. Audio functioned correctly (128kb buffer — too much, must go back down )

So the apparrent result on the PS3 appears to be that the stream doesn’t get flushed.

Finally I get around to asking my question:

Why doesn’t it:
– flush?
– force the stream to be ‘starved’; thus allowing me to stall for an appropriate time until the stream is no longer starving?

  • You must to post comments

I would get the position and stop the channel and free the sound.
create a new sound, wait for the OK and start a new channel with it, then set the position.

  • You must to post comments

Just in case anyone has visited here to see this one, here’s the general solution without having to destroy/re-create the sound:


// Input arguments: FMOD::Channel *channel

unsigned int soundLength;
unsigned int soundPosition;

// Get the sound
FMOD::Sound *sound;
result = channel->getCurrentSound( &sound );
//CHECK( result == FMOD_OK, ERROR MSG );

// Get the sound length
result = sound->getLength( &soundLength, FMOD_TIMEUNIT_PCM );
//CHECK( result == FMOD_OK, ERROR MSG );

// Get channel position
result = channel->getPosition( &soundPosition, FMOD_TIMEUNIT_PCM );
//CHECK( result == FMOD_OK, ERROR MSG );

// Seek the channel to 0
result = sound->seekData( 0 );
//CHECK( result == FMOD_OK, ERROR MSG );

// Seek the channel to end – 1 PCM
result = sound->seekData( soundLength – 1 );
//CHECK( result == FMOD_OK, ERROR MSG );

// Set position back to play position
result = channel->setPosition( soundPosition, FMOD_TIMEUNIT_PCM );
//CHECK( result == FMOD_OK, ERROR MSG );


From preliminary testing only FMOD_TIMEUNIT_PCM will work as that is the required measurement for Sound::seekData

Unforetuantely this fix does not have the added benefit of ‘working’ without issues when the disc IS spinning in the drive and we don’t want to possibly stall the game to ensure that streams are valid once more… Next up disc status checking.

And if you need to do this without stalling the main thread it will have to be done in a new thread.

  • You must to post comments
Showing 2 results
Your Answer

Please first to submit.