FMOD streaming audio data consumption problem

We’re using FMOD to output two different “sounds” to two different output devices. These sounds are user audio streams we fill with data using the pcmreadcallback.

The sound is created as followed:

exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);                 
exinfo.numchannels = inchannels;                                                      
exinfo.defaultfrequency = insamplerate;  
exinfo.decodebuffersize = decodebuffersize;  
exinfo.length = exinfo.defaultfrequency * exinfo.numchannels * sizeof(float);    
exinfo.format = FMOD_SOUND_FORMAT_PCMFLOAT;                                  
exinfo.pcmreadcallback = pcmreadcallback;                  
exinfo.pcmsetposcallback = pcmsetposcallback;               
exinfo.userdata = (void*)this;
result = system->createSound(0, mode, &exinfo, sound);

The problem is that the rate the callback consumes data on average is 48KHZ samples per second but at some point drops below this value. Sometimes it does recover after a couple of seconds but sometimes it stays on the lower rate for minutes. This can be 47.7KHZ but I’ve seen moments of 46KHZ

This is a problem because our audio data source comes in at a steady 48KHZ and if it’s not consumed at the same rate the data is kept in a buffer until finally requested/read by fmod. Effectively causing a delay between our audio source data and sound being outputted by fmod.

Is there something we can do to improve the data consumption of the callback/fmod or setup the streaming audio in a way we can rely on a steady data consumption? Or is there a different solution to this problem?

So a few minutes of losing 300 samples a second would add up to a couple of seconds of delay, and that would only get worse as time goes on. Are these the kinds of delays you are hearing?
For a producer producing faster than a consumer can consume, the only solutions really would be to slow down the producer or speed up the consumer. You can increase the input to the pcmreadcallback by increasing the exinfo’s defaultfrequency value to be slightly faster than the sample rate to compensate- that’s admittedly not a very robust solution and I’m apprehensive to call that a reccomendation.
A better solution would be to adjust the channel’s frequency at runtime with Channel::setFrequency to compensate for any drift as required. We have an example of how to achieve this in the Core API record example.

It’s not a constant rate of losing samples. It’s periodically starts and stops. Even worse it’s not all systems a problem.

We already set the defaultfrequency (exinfo.defaultfrequency = insamplerate;) to the source sample rate.

By setting the frequency dynamically on the channel would that still cause frequency distortions in the audio? At the moment we use a work around where we periodically throw away a sample if the buffer grows to large but it does influence the audio.

True, though periodic sample rate deviations of ±400 samples would be imperceptible to most people for most natural audio sources. Playing back a sine wave you might be able to hear differences, and regular, high-frequency sample rate oscillations of 400 samples would give you a slight tape fluttering effect. It sounds like the frequency of the dropouts wouldn’t nearly be high enough to create fluttering though, and I think this would be a better option than needing to drop samples.