Changing Pitch with Pitch Canvas and What Limits It
I compared a 200 ms sweep from 11 kHz to 50 Hz in Phase Plant and Surge XT. Here's how buffer size and pitch bend update rates affect the sound, and what I'm trying in REAPER.
As I kept developing Pitch Canvas and using it myself, I noticed something odd. By ear, the pitch sounded more or less right. When I slowed down playback and looked at the spectrogram, though, the pitch didn’t always follow the curve I’d drawn.
I found a few things while looking into this, so I thought I’d write them down here.
Pitch Canvas converts the curve you draw into pitch bend data and sends it through the DAW to the synth. Two things limit how closely the sound can follow the curve:
- How often pitch bend data is updated
- The DAW’s buffer size and how the synth processes the data
1. How often pitch bend data is updated
The first limit is the timing resolution of the pitch bend data.
When Pitch Canvas converts a curve into pitch bend data, it has to decide how often to send an updated value.
If it sends a value every 100 ms, for example, there’s no information about how the pitch changes between those updates. Unless the synth interpolates between values, the pitch changes in steps every 100 ms.
Pitch Canvas is also meant for sounds like kicks, where you sweep the pitch of a sine wave along a steep curve. Those steps are a real problem when the pitch changes a lot in a short time.
When I increased the update rate too far to smooth things out, some DAWs didn’t pass the pitch bend data through as expected, and the pitch barely changed.
When I tested a higher update rate, I sometimes got a different, much slower curve where I’d expected a fast change. I addressed that issue, but in my tests the highest update rate that played back reliably varied by DAW.
I had to test each DAW and keep the update rate within a range it could handle reliably.
2. The DAW’s buffer size and how the synth processes the data
Suppose the DAW can handle the pitch bend update rate. The next question is how the synth receives that data and applies it to the sound.
A DAW processes audio in groups of samples called blocks. The audio device’s buffer size affects the processing block size during normal playback. At 48 kHz, a block of 1,024 samples contains about 21.3 ms of audio.
The effect of block size depends on how the synth processes the data.
In the worst case, several pitch bend values may fall within a block, but only the last value affects the sound. With a 1,024-sample block, only one value per 1,024 samples gets used, no matter how often Pitch Canvas sends updates. Interpolation in the synth can make the pitch move smoothly, but the resulting curve may still differ from the one I drew.
VST3 and CLAP can pass parameter changes along with their sample positions within a block. Depending on the implementation, a synth can use that information to apply pitch changes at the intended samples. How and when the synth applies those changes is up to its implementation, which may not be public.
For example, in 2022 JUCE’s VST3 implementation used only the last value in a block when reconstructing MIDI events such as pitch bend from parameter changes. The fix went into JUCE’s development branch in September 2022. In synths built with the earlier implementation, the pitch curve can still vary with block size unless the developer addressed it separately.
That part depends on the synth developer. The tool generating the MIDI data has no control over how the synth applies it.
How different does it sound?
I drew a curve in Pitch Canvas that drops from 11 kHz to 50 Hz over 200 ms and compared how it sounded at different buffer sizes.
I tested both Phase Plant and Surge XT at 48 kHz using Pitch Canvas’s Live output. I changed the buffer size in this order:
32 → 64 → 128 → 256 → 512 → 1,024 → 2,048 samples
With Phase Plant, the pitch sweep gets less smooth as the buffer size increases. By the end, it sounds pretty rough.
With Surge XT, the pitch sweep was just as smooth at 1,024 samples as it was at 32 samples.
The comparison shows that even at the same buffer size, how closely the pitch follows the curve depends on the synth.
Pitch Canvas’s control ends at the MIDI output. The synth determines how that data turns into sound.
For steep curves that need to play back accurately, try a synth that handles closely spaced pitch bend updates or lower the buffer size, then listen to the result.
What I’m trying in REAPER
In many DAWs, working around this means switching synths or lowering the buffer size for a render. REAPER lets you set the processing block size for offline rendering separately from the audio device buffer size. I added an option in Pitch Canvas for REAPER’s stereo Apply Take FX action. It temporarily sets the block size to four samples and restores the previous setting after rendering. The issue can still occur during normal playback.
I’m also developing a REAPER extension called Adaptive Precision to tackle the problem at the point where REAPER passes audio processing to the synth.
It intercepts the processing blocks that REAPER sends to a VST3 synth and splits them according to how much the incoming parameters change. For example, where the pitch barely moves, the synth processes the full block. Where it changes quickly, the extension splits the block into chunks of 64 samples or fewer. It can go down to a single sample if needed.
The same synth instance processes the smaller blocks in sequence, so its oscillators, envelopes, and other internal state carry over between blocks. This could make pitch changes more accurate even with a synth that uses only the last pitch bend value in each block.
The adaptive block splitting itself is working. It’s still an experimental way to intervene in VST3 processing, and there’s more to test, including compatibility with different synths and CPU usage. The extension leaves the synth’s internal control rate and smoothing up to the synth, so the improvement may vary between instruments.
I don’t know yet whether it’ll be practical to use, but I’d like to get the sound as close as possible to the curve drawn in Pitch Canvas, even when the synth has these limitations.
I’d like to release it once it’s ready for real use.
