1

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?

ederwander
  • 3,410
  • 1
  • 18
  • 23
user2675197
  • 11
  • 1
  • 2
  • You'll probably find that there is a scaling factor of N (where N = FFT size) in your forward FFT, so you'll want to divide by N after doing FFT and IFFT to get back to the original signal level. You probably also want to look at overlap-add/overlap-save methods if you're applying this to successive buffers. – Paul R Aug 12 '13 at 14:24
  • Thanks for the reply. Yes i'm aware of the scaling factor - however this is rescaled by the IFFT (proven by the fact I have it workign for simply FFT of my orignal signal and then IFFT with no processing) I'm assuming that it's my maths that is incorrect, but I really dont't have a clue where it's going wrong – user2675197 Aug 12 '13 at 14:46
  • Try starting with a simple sinusoid input - then look at the frequency domain representation before/after your frequency shift processing (plot log magnitude versus frequency) - you should see a peak at the original frequency in the "before" case and at the new frequency in the "after" case. – Paul R Aug 12 '13 at 14:50

2 Answers2

2

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 !

ederwander
  • 3,410
  • 1
  • 18
  • 23
  • Thanks for the reply. Am I right in thinking that this technique limits my frequency shift to an integer number corresponding to the bins? I was hoping to use a technique to avoid this problem, do you think that is possible? – user2675197 Aug 13 '13 at 07:30
  • yes you are right! Shift=0.5; for L=0:length(Fourrier)-1 bins = round(L*Shift) + 1; end I always round the bin corresponding ! I honestly do not know if it will be possible to do the way you want ... – ederwander Aug 13 '13 at 14:42
1

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.

hotpaw2
  • 70,107
  • 14
  • 90
  • 153