Adjust event playback speed with custom DSP

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?

I think I figured it out. The Sound instance in the “Record” scripting example is not just a special ring buffer that the system can record into, it’s also what makes a channel’s pitch property work in the first place.

Instead of a custom DSP with a read callback I’m now using a Sound and write directly into its buffer which I access with Sound.lock. When I change the associated channel’s pitch, the playback speed is adjusted as expected.

Happy to hear you found a solution!