Several frame delay when playing "some" sounds

Some sounds (not all) experience a 2 or 3 frame delay before they are played. I am using FMOD_System_SetFileSystem to load data. I under the impression that when using this the data is streamed. I don’t know if it is the load times causing the issue since some large sounds don’t cause a delay but small ones do. It’s perplexing.

I can’t just load the events because I rarely have knowledge of the sounds that will be played at any given time, and it would be a huge burden on memory to load hundreds of anticipated events.

I’m hoping there is something I am doing wrong.

My game is all in cpp and I don’t use Unity Unreal of any other game engine.

1 Like

I haven’t been able to reproduce any noticable delays with various sounds in the asyncio example, what version of FMOD are you using?
You can ensure sounds are being streamed in by creating offending sounds with System::createStream instead of createSound. Otherwise, you should be getting “Loading delay exceeded” warnings when running FMOD in logging mode, which might provide some more useufl information.
To run FMOD in logging will need to call Debug_Initialize and link to the logging versions of the libs.

I finally got the debug libs installed on the Switch. There is a 6 second delay is starting a sound. That makes little sense. I see this all over the game, this is just an easy one to make happen. It’s not feasible to “preload” sounds. The game has hundreds and hundreds of sounds and based on game play and can’t be predicted. This isn’t a game with levels that can be loaded. I sometimes see 1 or 2 frame delays on the PC, but never 6 seconds like on the Switch.

The event has 3 tracks, each with a 8 sound Multi Instrument. The sounds last 1/10 of a second, so these aren’t large sounds.

[WRN] EventInstance::update                    : Event {b33005ad-c309-4d10-968a-8e27a118a4fe} waited 6616 milliseconds for sample data to load.  Preload sample data to avoid this delay.
NX Memory Use: 552.6M / 4758.0M heap | 1.5M / 32.0M graphics firmware | 59.1M program bytes | 2.0M stack bytes

Here is the log when it inits

[LOG] System::create                           : Header version = 2.02.06. Current version = 2.02.06.
[LOG] Manager::init                            : maxchannels = 64 studioflags = 00000000 flags 00000000 extradriverdata 0.
[LOG] SystemI::init                            : Initialize version=20206 (124257), maxchannels=64, flags=0x00020000
[LOG] SystemI::setOutputInternal               : Setting output to 'FMOD nn::audio Output'
[LOG] Thread::initThread                       : Init FMOD stream thread. Affinity: 0x4000000000000003, Priority: 0xFFFF7FFB, Stack Size: 98304, Semaphore: No, Sleep Time: 10, Looping: Yes.
[LOG] Thread::initThread                       : Init FMOD mixer thread. Affinity: 0x4000000000000001, Priority: 0xFFFF7FFA, Stack Size: 81920, Semaphore: No, Sleep Time: 0, Looping: Yes.
[LOG] AsyncManager::init                       : manager 0x2090e73008 isAsync 1 updatePeriod 0.02
[LOG] Thread::initThread                       : Init FMOD Studio update thread. Affinity: 0x4000000000000002, Priority: 0xFFFF7FFD, Stack Size: 98304, Semaphore: No, Sleep Time: 1, Looping: No.
[LOG] AsyncManager::init                       : done
[LOG] PlaybackSystem::init                     : 
[LOG] Thread::initThread                       : Init FMOD Studio sample load thread. Affinity: 0x4000000000000003, Priority: 0xFFFF7FFD, Stack Size: 98304, Semaphore: No, Sleep Time: 1, Looping: No.
[LOG] PlaybackSystem::init                     : done
[LOG] Thread::initThread                       : Init FMOD Studio bank load thread. Affinity: 0x4000000000000003, Priority: 0xFFFF7FFD, Stack Size: 98304, Semaphore: No, Sleep Time: 1, Looping: No.
[LOG] Manager::init                            : done.

I have noticed that if we wait a while before starting to play much of the delay goes away. It seems that FMOD might be sill getting everything loaded (strings). If this is the case, can we just wait for all that to be done?

The log is filled with these:

[LOG] SystemI::createSoundInternal             : Sample 0/1: name='amb_cave_drip_flooded_09', format=2, channels=2, frequency=48000, lengthbytes=151776, lengthpcm=138752, pcmblocksize=256, loopstart=0, loopend=0, mode=0x00000000, channelmask=0x00000000, channelorder=0, peakvolume=0.581861.
[LOG] SystemI::createSoundInternal             : Create name='', mode=0x02000202
[LOG] SystemI::createSoundInternal             : exinfo->cbsize             = 224
[LOG] SystemI::createSoundInternal             : exinfo->length             = 1407156736
[LOG] SystemI::createSoundInternal             : exinfo->fileoffset         = 466176
[LOG] SystemI::createSoundInternal             : exinfo->numsubsounds       = 1
[LOG] SystemI::createSoundInternal             : exinfo->inclusionlist      = 0x107c22086c
[LOG] SystemI::createSoundInternal             : exinfo->inclusionlistnum   = 1
[LOG] SystemI::createSoundInternal             : exinfo->encryptionkey      = skkpycwtxzxnbozd0hb1ial0hxnrbuo0
[LOG] SystemI::createSoundInternal             : exinfo->suggestedsoundtype = 5
[LOG] SystemI::createSoundInternal             : exinfo->useropen           = 0x8480bb0
[LOG] SystemI::createSoundInternal             : exinfo->userclose          = 0x8480c80
[LOG] SystemI::createSoundInternal             : exinfo->userread           = 0x8480cc0
[LOG] SystemI::createSoundInternal             : exinfo->userseek           = 0x8480d90
[LOG] SystemI::createSoundInternal             : exinfo->fileuserdata       = 0x2096c5a6c8
[LOG] SystemI::createSoundInternal             : exinfo->initialseekpostype = 1
[LOG] SystemI::DSPCodecPoolRegister            : register codec pool for pool type 7

These happen when the bank is loaded (FMOD_Studio_System_LoadBankFile). I’m not playing any of these sounds. Is there a way to wait until this is over, or am I initing the banks wrong?

I am using FMOD_Studio_EventInstance_Start to start events, is there a way to make them streaming by default?

Thank you for the additional information. 6 seconfs is a significantly long time for such a short sound to load. If you are able to share your Master.bank file and the bank file that this event is contained in I can try reproducing this issue and see what’s going wrong?

Loading a bank alone shouldn’t result in all of these sounds being created. A call to FMOD_Studio_EventDescription_CreateInstance will cause sample data to be loaded, otherwise are you calling FMOD_Studio_Bank_LoadSampleData anywhere to load all of the sample data in a bank, or FMOD_Studio_EventDescription_LoadSampleData to load the sample data for individual events?

In FMOD Studio you can set inidividual assets to be streamed in by setting its Loading Mode in the Audio Bin, or you can set the loading mode for everything for a Platform by going to Edit>Preferences…>Build>{Platform name}>Advanced Loading Mode.
For the offending sounds in this case, if they are encoded as an MP3, Vorbis or FADPCM then you will be able to take advantage of the Compressed Sample loading mode which will load faster than the default Sample (Decompressed Sample) loading mode. Stream is usually best suited for larger sounds and you should aim to limit the amount of them you have playing at any one time.

I have some more information about what appears to be happening. All the ambient sounds for the entire game are in one event (made from 100’s of wav files) and I use a param to jump around based on the location. When I first start the ambience I get the stream of SystemI::createSoundInternal calls and while this is happening (in the background) all new events seem to be blocked.

Setting up the ambience like that was probably not a good idea, but it’s too late to change. Is there a API call I can do to know if new events are going to be blocked?

The only platform where this is causing issues is the Switch.

Thank you for the additional information, I will see if I can setup a similarly large event and reproduce this problem on Switch.

Perhaps you can try polling the sample loading state of that event using EventDescription::getSampleLoadingState.
While that reports FMOD_STUDIO_LOADING_STATE_LOADING you will know that any subsequent events will not be able to load as that thread is occupied, and once it returns FMOD_STUDIO_LOADING_STATE_LOADED you can move on to loading other events. Alternatively, you can call Studio::System::flushSampleLoading immediately after beginning to load that event’s sample data. This will block the calling thread until all sample loading and unloading has completed, and then you can try playing/loading any other events after that.