I am trying my luck with Interpolators but can’t seem to nail it (I’m a noob, I know).
I want to do a very simple pitch shift process resampling the sound, and no matter what I try, I always get constant pops.
In short, I copy my buffer to a tmp, and then I process a Linear interpolator using a ratio. If I use a 1.0 ratio, all is well, but if I move (above or below) I can hear the pitch changing, but completely surrounded by pops.
If your ratio is > 1.0, then you’ll raise the pitch of the input, but have silence in the output buffer when it ran out of input = pops (when the block size is small enough, if you had a large enough block size you’d notice this more as glitching instead of popping).
If your ratio is < 1.0, then you’ll fill the output buffer before using all the input for that block, then next block will have a discontinuity in the wave = pops.
a linear interpolation pitchshifter will definitely sound very grainy, unless you’re on a very high samplerate. if those pops are regular you are either making a mistake about the block processing or it’s just the pitchshifter’s architecture itself. is this running in realtime?
then it is the clear. as you already noticed it would make sense to have a different number of samples in the output. but that is not possible in realtime. input buffer is output buffer. so shift your thought away from that and instead ask yourself how to make a resampler that stays inside numSamples, but still fills up a grain in its total size everytime. you can do that with a ring buffer. you’ll still get pops then, but for a different reason. it will be about making sure the grain always loops in a smooth way.
more infos on ring buffers in my delay video:
and i released an open source pitch shifter just yesterday which you could check out:
sry if my pitchshifter looks a bit complicated. it’s just that i added some unique features like the feedback parameter. and you can also ignore this whole multiple-voices-stuff and all the parameter-smoothing things to make it easier
An Interpolator / Resampler is not sufficient for pitch shifting.
While it changes the pitch, it also changes the number of samples, i.e. the duration. In a streaming plugin that VST3 and AUs etc. are, you have to deliver the same amount of samples as you received.
@asimilon described in his first answer what happens: on each block you are either discarding additional samples creating a discontinuity in the signal, or you are zero-padding (if you are lucky, or leaving garbage from the input signal if you are unlucky), which is also creating the noise you are hearing.
A real pitch shifter like the one @Mrugalla posted needs to fill the gaps or smoothen the discontinuities using fragemnts (grains) of the signal which they duplicate and arrange as needed.
Depending on the strategy of restoring the continuous signal from the fragments the result will sound better or artificial.
To pitch shift, as others have said, you’ll need to make sure you output the same number of samples as is the buffer size (input size).
Generally, you want to find the base frequency, then duplicate or reduce the waves at that frequency. It can be a little complicated to get right, I think. You can to smooth the edges of the redundancy, like using a Hanning window or similar.
I found it to be an interesting article and website in general. The article is well written, there’s a good discussion in the comments and source code is included too. As far as I can see it’s quite instructive.
Could you explain which concepts discussed in the article have become outdated and which are the “big steps” which science and technology have made since? Could you provide an up-to-date example?