In my game, I want to play an audio stream that I receive over the network in an FMOD event. I’m using a custom DSP to provide the PCM data. The setup looks like this (C#, but not Unity):
eventInstance.getChannelGroup(out eventChannelGroup);
FMOD.DSP_DESCRIPTION description = new() {
numinputbuffers = 1,
numoutputbuffers = 1,
read = dspCallback,
userdata = /* ... */
};
AudioEngine.Instance.coreSystem.createDSP(ref description, out streamDSP);
eventChannelGroup.addDSP(FMOD.CHANNELCONTROL_DSP_INDEX.TAIL, streamDSP);
The callback is essentially just copying the PCM data from a ringbuffer to the DSP’s outbuffer:
private static readonly FMOD.DSP_READ_CALLBACK dspCallback = DSPCallback;
static FMOD.RESULT DSPCallback(ref FMOD.DSP_STATE dsp_state, IntPtr inbuffer, IntPtr outbuffer, uint length, int inchannels, ref int outchannels) {
/* ... */
Marshal.Copy(myRingBuffer, offset, outbuffer, (int)length);
return FMOD.RESULT.OK;
}
So far, this works fine.
I’m constantly measuring the delay between the time when I receive network packets and the time when I play back samples. I want to use a dynamic jitter buffer, so I have to adjust that latency dynamically. To do so, I need to increase or slow down the playback rate slightly when the latency gets to large or to small (similar to the “Record” scripting example at https://www.fmod.com/docs/2.03/unity/examples-record.html).
How would I do that? I tried setting the pitch to 0.5
with eventInstance.setPitch
or eventChannelGroup.setPitch
just to understand what happens, but both parameters don’t seem to have an effect in my setup. I would expect that either my DSPCallback
is called less frequently if I reduce the playback speed, or the length
parameter is shorter, but everything is constant, so my DSPCallback
“consumes” PCM data with a constant speed.
What’s the right approach here?