Starvation in WASAPI buffer + questions on a better fix

(Using Unity 2021.3.8f1 and FMOD Studio 2.02.27. The project I’m referring to is uploaded in my profile)

Hello, I’ve been working on a project for the last month that is of a bigger scope than other projects I’ve worked on with FMOD. Everything went quite alright as I had good programmers in my team who helped me with some of the implementations.

The only major issues that I encountered that led me to spend quite some time on these forums looking for answers were errors regarding buffer size. These are some examples of the errors I had:

[FMOD] AsyncCommandBuffer::growBuffer : Growing command buffer to 65536 bytes. Initial command buffer size can be tuned to avoid dynamic growth using Studio::System::setAdvancedSettings()

[FMOD] OutputWASAPI::mixerThread : Starvation detected in WASAPI output buffer!

These errors would lead to sounds not being played or to overall freezing of the game in the editor. The Profiler helped me see that almost all of the instances (like 120) were active at the same time.

To fix these I resorted to limiting the amount of Max instances for specific sounds and using Stealing. The problem with this is that, for example, limiting the max instances of the torches in the level and using Furthest for Stealing would cause some of them to not be played at all (which I wrongfully believed it would be updated every frame). Even after adding more sounds for the later parts of the game I had to limit the max instances in the mixer since it was causing the same buffer errors.

So, all of this makes me wonder, how do games with a greater scope deal with this? Our game consists of a single level and a gameplay time of around 20 minutes. How come a game of this scope is reaching it’s limits sound-wise? What am I doing wrong?

I couldn’t find information in the documentation that would tell me how to, for example, disable instances through distance from the listener or even update the “Furthest” Stealing to make it so that the player would never run into a torch without sound. Maybe I haven’t looked hard enough or missed it.

I’ve uploaded the project to my profile so it’s easily accessible alongside the FMOD project. I can point to any specific script where FMOD is being used if need be.

I would love to know how to be able to have all the sounds I’d like without depleting the buffer. I’ve been loving FMOD so far and would like to keep learning on how to tackle these sort of things.

Thanks to anyone who may help.

Sorry for the delayed response,

For some context, the AsyncCommandBuffer::growBuffer warning means that the Studio system is receiving more commands than it can currently keep track of, and as a result needs to expand its command buffer - this isn’t necessarily an issue, unless you want to avoid dynamic growth, or are running into memory constraints. The Starvation detected in WASAPI output buffer! warning indicates that the mixer was too slow to output a sound due to some kind of processing constraint, i.e. too much CPU overhead. These issues together lead me to think you’re creating too many event instances and/or calling functions on them really frequently.

And as expected, when looking at your profiler sessions in FMOD Studio, I can see that a number of your events, specifically the Gate and Door events, are being created with an extremely high frequency. You can examine this yourself by clicking on the “Lifespans” section at the top of the Profiler window, which will show you the creation and destruction of every event instance in the recorded session. In your DoorAudio.cs script, you’re creating an event instance every single update - though this code has been commented out in favor of TriggerSounds.cs from what I can tell, I believe this was likely the cause of your problem when you initially recorded your profiler sessions.

If I remove all instance limits that you’ve set in Studio, and test the game running with the current method you’re using to play door sounds (TriggerSounds.cs), I don’t seem to be running into any issues. Please try doing the same and seeing whether the problem is resolved on your end.

Also, though it’s unrelated and mostly benign: you seem to be attempting to set the “Speed” parameter for your Footstep event in FMODStudioFirstPersonFootsteps.cs when it doesn’t actually have that parameter.

Hi Louis,

Thank you very much for the detailed response! I’m happy to see how deep you went looking through the project.

As you correctly noted, I chose to switch from the DoorAudio script to the TriggerSounds script with positive results.

I will try what you suggested and play without any instance limits.

This leads to another question: Despite having limited instances, I would notice that sometimes when playtesting (in editor and build), certain sounds (like torches or sewer sounds, i.e sounds that are looped) would stop playing altogether and maybe resume play after a few seconds. Is that something that happens because of the amount of sounds being played at the same time and thus a limit of resources?

Thanks again for your help!

I would still recommend setting instances limits appropriately, but removing instance limits will allow you to see whether the issue is resolved.

It’s likely that your problem with looped sounds cutting out is an issue with having too many streams playing at the same time. From what I can see, a lot of your ambience events have audio assets set to stream. As streaming assets are continuously loaded piece by piece into memory, each instance if a streaming asset requires a constant file I/O in order to function. Typically this wouldn’t be an issue for ambiences - in fact, we recommend using streaming for audio like ambiences and music - but because the torch event’s audio asset is set to stream and you have multiple torches, every single playing torch is simultaneously streaming data from storage into memory. As the torch event has a transition region for your loop, this gets doubled for the length of the region as FMOD continues streaming the existing asset while streaming the asset at the start of the loop, and that’s on top of all other streams you have playing. Try setting the torch audio asset to not stream, and see if that resolves the problem.

Thank you Louis!

I had no idea about streaming assets.

I am now reading more about it in the documentation

Is there any other source you could point me to to read more about it besides the documentation link I provided?

After trying out your suggestions, things seem to be working fine except for a particular object. But I will have to test further to see if it’s an issue coming from someplace else.
While doing this, I was using a Profiler window to keep track of things while some warnings and errors popped up:

[FMOD] Monitoring::Module::addData : Not enough bandwidth to send monitoring data, discarding 487 commands (2101522 bytes worth) due to backlog!!

Coming from RuntimeManager.cs:81 which it seems to be a Profiler thing

But then these new errors appeared, haven’t seen them before

[FMOD] FMOD_OS_Net_Write : send failed 10004

UnityEngine.Debug:LogError (object)
FMODUnity.RuntimeUtils:DebugLogError (string) (at Assets/Plugins/FMOD/src/RuntimeUtils.cs:574)
FMODUnity.RuntimeManager:DEBUG_CALLBACK (FMOD.DEBUG_FLAGS,intptr,int,intptr,intptr) (at Assets/Plugins/FMOD/src/RuntimeManager.cs:77)

and

[FMOD] ProfileClient::sendThreadLoopFunction : Send thread loop returned 43

UnityEngine.Debug:LogError (object)
FMODUnity.RuntimeUtils:DebugLogError (string) (at Assets/Plugins/FMOD/src/RuntimeUtils.cs:574)
FMODUnity.RuntimeManager:DEBUG_CALLBACK (FMOD.DEBUG_FLAGS,intptr,int,intptr,intptr) (at Assets/Plugins/FMOD/src/RuntimeManager.cs:77)

Could you please help me pinpoint the source of these?

Besides this, I was wondering if there is a way to update Stealing so that the torches that are further away change depending on the characters location, instead of having it be set at the start of the game (if I’m understanding it correctly)

Thanks again for your help, is much appreciated!

The Studio API Glossary topic on Streams contains some more info about streams, as well as issues that you may run into when using them. A lot of the API functions that are noted in those docs are things you likely won’t need to interact with, but the information is still relevant.

The profiler receives network packets from your project in order to log what’s happening - this message indicates that there wasn’t enough bandwidth to send all the of the various occurrences in your project since the last update. Typically this won’t occur unless some combination of the following occurs:

  • You’re running the game and the profiler on separate networks or machines, and thus limiting the bandwidth
  • You’re consuming a disproportionate amount of network bandwidth with other processes, also limiting the bandwidth
  • You’re making large amount of changes/updates to the FMOD Studio system extremely frequently in your game, and thus consuming too much bandwidth - i.e. rapidly setting a ton of parameters and/or 3D attributes, or creating an extremely large amount of event instances, etc.

When profiling your game on my machine I wasn’t running into this issue, so it’s likely that you’ve made a change that is causing one or more of the above to occur. If you’re unable to diagnose it, feel free to let me know of any changes you’ve made so I can help. Uploading a profiler session where you run into the issue would also be helpful.

I’m not entirely sure what you mean by “change” - do you want to completely stop the existing event instances that are furthest away? Or have them virtualize, and then become real when they’re more audible? My recommendation for them would be to use the “Virtualize” stealing mode, so that the least audible instances (functionally the furthest away, in the case of the torches) are virtualized, but I’m not sure if that’s what you mean. In general though, for more info you should take a look at the Studio docs on Stealing and Virtualization.

Hi Louis,

Thank you for all the information, helps a tonne.

What you say about using Virtualize is exactly what I was referring - I was using them before with the project but with all the errors I was afraid this was one of the reasons why, therefore I sort of blocked Virtualize out of my head and forgot about it. I will return to use them.

You’ve given me enough help and I believe I can continue. I don’t want to derail this QA Post too much so other people could find the main issue useful. I’ll tag your solution and move on.

Thanks again and wish you the best!

1 Like

No problem, and likewise all the best with your project, it looks really interesting! If you run into any more issues, feel free to create another post.