
Originally Posted by
MikeDB
BTW, you mention having so calculate cos() and sin() values slowing you down. These are normally pre-calculated in an array as you need the same values time and time again if the Fourier transforms are all the same size. Or am I missing something about your algorithm ? I haven't looked at the library you mentioned yet.
In this algorithm you are not using the same values over and over again so they can't be precomputed like for wave synthesis. You are taking the input complex phasor and multiplying in by another phase-shifed phasor where the argument of this complex sinusoid is a function of the current phase, the frequency and the scaling factor.
Code:
void AudioEffectPitchShift::m_ocean(float *inputFreq, float *outputFreq, float frameIndex, float pitchScale)
{
// zero the output buffer
for (unsigned i=0; i<(2*SYNTHESIS_SIZE); i++) {
outputFreq[i] = 0.0f;
}
float phaseAdjustFactor = -((2.0f*((float)(M_PI))*frameIndex)
/ (OVERLAP_FACTOR_F * FFT_OVERSAMPLE_FACTOR_F * SYNTHESIS_SIZE_F));
for (unsigned k=1; k < SYNTHESIS_SIZE/2; k++) {
float a = (float)k;
// b = mka + 0.5
// where m is the FFT oversample factor, k is the pitch scaling, a
// is the original bin number
float b = std::roundf( (FFT_OVERSAMPLE_FACTOR_F * pitchScale * a));
unsigned b_int = (unsigned)(b);
if (b_int < SYNTHESIS_SIZE/2) {
// phaseAdjust = (b-ma) * phaseAdjustFactor
float phaseAdjust = (b - (FFT_OVERSAMPLE_FACTOR_F * a)) * phaseAdjustFactor;
float a_real = inputFreq[2*k];
float a_imag = inputFreq[2*k+1];
outputFreq[2*b_int] = (a_real * arm_cos_f32(phaseAdjust)) - (a_imag * arm_sin_f32(phaseAdjust));
outputFreq[2*b_int+1] = (a_real * arm_sin_f32(phaseAdjust)) + (a_imag * arm_cos_f32(phaseAdjust));
}
}
}