Playback latency

I’m new to FMOD and currently implementing basic playback in my custom C# engine. Following the quick-start tutorial here, I’ve exported my banks and successfully loaded and played a sound effect in-game (played on key press). The issue is that, no matter what I try, I seem to be stuck with roughly 150-250 ms latency.

There are many existing posts on this forum related to event latency. Unfortunately, none of the proposed solutions have worked for me so far. Here’s what I’ve already tried/verified:

  1. Sample data is loaded in advance (using Studio::EventDescription::loadSampleData). I’ve verified that the data is loaded (using Studio::EventDescription::getSampleLoadingState) prior to creating an event instance.
  2. The asset in FMOD Studio is not marked as streaming.
  3. There’s no blank space at the beginning of each asset. In other words, latency is not present in FMOD Studio (or when playing assets through a separate player).
  4. I’ve called System::setDSPBufferSize with varying values (to no effect).
  5. All relevant objects are valid (verified using the isValid() function on each object).
  6. No FMOD errors are detected (the FMOD_RESULT from each relevant call is always OK).
  7. I’ve tried pausing the instance immediately after creation (using Studio::EventInstance::setPaused), then unpausing later (no change).
  8. The system itself is updated frequently (currently 60 FPS). I’ve also tried calling Studio::System::update as quickly as the thread can run, with no change. In other words, there are no other slow or blocking parts of my engine currently affecting FMOD.

As a last-ditch effort, I even precisely timed the delay between starting an instance (using Studio::EventDescription::createInstance, then Studio::EventInstance::start on the returned instance) and that instance being confirmed as playing (using Studio::EventInstance::getPlaybackState). Over many instances, the average delay between creation and playback was roughly 10 ms. I’ve further experimented with additional assets and events, and changed platform encoding settings (no luck).

Given all this, I’m at a loss for why I’m still experiencing latency during playback. Hoping someone can provide some direction. Thank you!

Sounds like you’ve eliminated all of the usual suspects. Are you using any Convolution Reverb plugins in any of your events/buses? That’s another common source of additional latency.
Just to verify your system settings, can you please run this basic debug code inside your game engine and tell me what the results for blocksize, buffersize and latency are reported as?

var result = system.getDSPBufferSize(out uint blocksize, out int numblocks);
result = system.getSoftwareFormat(out int frequency, out _, out _);

float ms = (float)blocksize * 1000.0f / (float)frequency;

Console.WriteLine("Mixer blocksize        = {0:N2} ms", ms);
Console.WriteLine("Mixer Total buffersize = {0:N2} ms", ms * numblocks);
Console.WriteLine("Mixer Average Latency  = {0:N2} ms", ms * ((float)numblocks - 1.5f));
1 Like

Thank you for the reply! I’m not using any convolution reverb plugins currently, no.

Here are my current settings:

  • blocksize: 1024
  • numBlocks: 4
  • frequency: 48,000

And the console output:

  • Mixer blocksize = 21.33 ms
  • Mixer Total buffersize = 85.33 ms
  • Mixer Average Latency = 53.33 ms

In grabbing these values, I also realized an important mistake I made: the reason that calling setDSPBufferSize had no effect is that I had been calling it after initializing the FMOD.Studio.System. When calling it prior to initialization, I am finally hearing reduced latency (I’ve tried bufferlength values of 512 and 256, and unsurprisingly, 256 gives the lowest latency).

The documentation for setDSPBufferSize mentions that bufferlength is best left alone. Changing numbuffers does have a small effect, but not nearly as impactful as lowering bufferlength. Are there recommended values generally used for video games (besides the defaults)?

Thank you for the additional information, glad to hear the latency has improved.
The required bufferlength should always be a factor of 2, but other than that there are no definite rules. Just low enough that you don’t notice latency, and high enough that it isn’t flogging the cpu and creating other issues like clicks and pops.
There are platform considerations when setting the bufferlength which you can read about in the Latency section of each respective platform.

1 Like

I’ll keep that in mind. Thanks so much Jeff!

As mentioned in my post above, the fix here was to call setDSPBufferSize prior to FMOD.Studio.System initialization, where I had been calling it after (which, per documentation and debugging, has no effect). I’ll mark this answer as the solution for clarity.

2 Likes