Frequency Shifting with FFT

4.9k views Asked by At

I've been experimenting with a few different techniques that I can find for a freq shifting (specifically I want to shift high freq signals to a lower freq). At the moment I'm trying to use this technique -

take the original signal, x(t), multiply it by: cos(2 PI dF t), sin(2 PI dF t) R(t) = x(t) cos(2 PI dF t) I(t) = x(t) sin(2 PI dF t) where dF is the delta frequency to be shifted. Now you have two time series signals: R(t) and I(t). Conduct complex Fourier transform using R(t) as real and I(t) as imaginary parts. The results will be frequency shifted spectrum.

I have interpreted this into the following code -

for(j=0;j<(BUFFERSIZE/2);j++)
{
Partfunc = (((double)j)/2048);

PreFFTShift[j+x] = PingData[j]*(cos(2*M_PI*Shift*(Partfunc)));
PreFFTShift[j+1+x] = PingData[j]*(sin(2*M_PI*Shift*(Partfunc)));
x++;
}

//INITIALIZE FFT
status = arm_cfft_radix4_init_f32(&S, fftSize, ifftFlag, doBitReverse); 

//FFT on FFTData
arm_cfft_radix4_f32(&S, PreFFTShift); 

This builds me an array with interleaved real and imag data and then FFT. I then inverse the FFT, but the output im getting is pretty garbled. Results seem huge in comparison to what I think they should be, and although there are a few traces of a freq shifted signal, its hard to tell as the result seems mostly pretty noisy.

I've also attempted simply revolving the array values of a standard FFT of my original signal to get a freq shift, but to no avail. Is there a better method for doing this?

2

There are 2 answers

0
hotpaw2 On

If you want the frequency shift to sound more "natural", you will have to maintain the ratios between all the initial frequency bins, where the amount of shift will depend on the FFT bin, thus requiring lots of interpolation. The Phase Vocoder algorithm will use multiple FFTs to reduce phase distortion in the result.

2
ederwander On

have you tried something like:

  • Use a Hanning window for each framed data

  • Once you have your windowed frame of audio data, you do an FFT on it

  • Do some kind of transformation in the frequency domain (you can use Flanagan - phase vocoder)

  • Now you need to go back to the time domain with an IFFT

  • Apply Hanning window in the IFFT data

  • Use overlap-add at each new frame of time-domain data into the output stream

My results:

I created two concatenated sinusoids (250Hz and 400Hz) and move one octave UP!

enter image description here

Blue waveform is the original and red was changed, you can see one fadeIN-fadeOut caused by overlap add and hann window !