This is kind of a weird one--I'm a little stuck.
I'm making a sampler, and I have implemented pitch shifting of samples similarly to how Jules did in the source. Everything was working fine--pitch shifting up as well as down resulted in no artifacts. Now, what I'm trying to do is calculate the FFT and IFFT in the rendering callback so I can do some custom filtering, etc.
In the SampleVoice::renderNextBlock function I calculate the FFT (using FFTW3), then the IFFT, which results in the exact same input (as long as you divide the unnormalized output by the numSamples parameter); however, when pitch shifting samples after this conversion, I'm getting artifacts only ABOVE the root note and not below. This is very puzzling to me.
I'm using the same linear interpolation used in the source code:
const int pos = (int) samplePosition;
float alpha = (float) (samplePosition - pos);
float invAlpha = 1.0f - alpha;
//outFL holds the unnormalized IFFT (i.e. the original input) of the Left channel.
//outFR holds the unnormalized IFFT (i.e. the original input) of the Right channel.
float l = ((outFL [pos-start]/numSamples) * invAlpha + (outFL[pos-start + 1]/numSamples) * alpha);
float r = inR != nullptr ? (outFR[pos-start]/numSamples) * invAlpha + (outFR[pos-start + 1]/numSamples * alpha) : l;
*outL += l*attack_multiplier*release_multiplier;
*outR += r*attack_multiplier*release_multiplier;
samplePosition += pitchRatio;
I'm not sure why the artifacts would happen only ABOVE the root note and not below, when the same interpolation algorithm works fine on the original input that was not transformed via FFT and then IFFT. Any ideas what's going on?