Just checking back in on this issue, since another Dissonance user seems to have encountered the problem.
There seems to be two theories that have been discussed: sample rates and virtualisation.
Has the default sample rate been changed in the FMOD Settings
Dissonance gets the rate with RuntimeManager.CoreSystem.getSoftwareFormat(out _sampleRate, out _, out _);. Give that, shouldn’t it work correctly no matter what rate has been set?
Virtualisation
There was some talk about virtualisation, and ensuring Dissonance playback never gets virtualised. This shouldn’t be necessary because Dissonance handles virtual channels.
We subscribe to channel event callbacks to monitor for the channel becoming virtual with code like this;
private static RESULT ChannelEventCallback(IntPtr channelcontrol, CHANNELCONTROL_TYPE controltype, CHANNELCONTROL_CALLBACK_TYPE callbacktype, IntPtr commanddata1, IntPtr commanddata2)
{
// Check this is a virtualisation event
if (controltype != CHANNELCONTROL_TYPE.CHANNEL)
return RESULT.OK;
if (callbacktype != CHANNELCONTROL_CALLBACK_TYPE.VIRTUALVOICE)
return RESULT.OK;
/* snipped some error handling and sanity checking here */
var isVirtual = commanddata1.ToInt32() != 0;
SetChannelVirtual(isVirtual);
Then this other method is called in FixedUpdate on the “audio generator” - this is the object the channel pulls from in ReadDSP:
public void PumpVirtualised(float deltaTime, int sampleRate)
{
if (!_isVirtual)
return;
lock (_pumpLock)
{
if (!_isVirtual)
return;
// Accumulate time elapsed since this audio generator was made virtual
_virtualisedTimeAccumulator += deltaTime;
// Take as many complete integer samples as possible
var samples = (uint)Math.Floor(_virtualisedTimeAccumulator * sampleRate);
// Decrease the timer by however much time that many samples is
_virtualisedTimeAccumulator -= (float)samples / sampleRate;
// Pump for that much audio, passing a null pointer because we don't
// actually care about the result
GetAudio(IntPtr.Zero, samples, 1);
}
}
The idea here is when FMOD virtualises the channel we take over pumping audio out of the generator at the correct rate.
I think that addresses both of the working theories. Does this code all look like the correct way to handle things from an FMOD perspective?