How do I freqency shift a signal by a fractional amount using IFFT and FFT?

24 vues (au cours des 30 derniers jours)
Victoria
Victoria le 11 Juin 2013
Déplacé(e) : Matt J le 23 Juin 2025
Let me preface this with: I am an extreme novice when it comes to FFTs.
I have a signal vector x of length 1200. To shift the frequency of the signal I am doing the following:
y=IFFT(x);
SHIFT=1;
t=[1:1200]*2*pi/1200;
for j=1:1200
mult(j)=exp(-i*SHIFT*t(j));
z=mult.*y;
end
w=real(fft(z));
When SHIFT is an integer I get what I am looking for in w, which is the signal x shifted by the value of SHIFT. However, when SHIFT is fractional the vector w looks like some combination between a shifted x and its derivative.
My question is: what do I do to shift x by a fractional amount using FFTs and IFFTs?
Thanks,
Victoria

Réponses (2)

Matt J
Matt J le 11 Juin 2013
You would do something like this
N=length(y);
mult = exp(-1i*2*pi/N*(0:N-1)*SHIFT);
w=ifft((fft(y).*mult ),'symmetric')
  5 commentaires
rashi
rashi le 3 Août 2020
but the output for w,w1 and w2 are different, will those be not same?
Matt J
Matt J le 3 Août 2020
No, the first version does not use linear interpolation and so will be different from the others.

Connectez-vous pour commenter.


Duncan Carlsmith
Duncan Carlsmith le 21 Juin 2025
analytic_segment = hilbert(segment); % Complex analytic signal
shifted_segment = real(analytic_segment .* exp(1j*2*pi*f_shift*t));
  2 commentaires
Paul
Paul le 22 Juin 2025
Hi Duncan,
Can you illustrate this approach with a concrete example?
Duncan Carlsmith
Duncan Carlsmith le 22 Juin 2025
Déplacé(e) : Matt J le 23 Juin 2025
%% Frequency-Shift Demo with Synthetic Audio
% This script creates a 1-s synthetic audio signal consisting of four
% sinusoids (1, 2, 3, 4 kHz) of decreasing amplitude plus Gaussian noise,
% shifts it up by 500 Hz, and compares the spectra and waveforms.
% -------------------------------------------------------------------------
% Parameters
% -------------------------------------------------------------------------
fs = 44100; % Sampling rate (Hz)
duration = 1.0; % Signal length (s)
f_shift = 500; % Desired frequency up-shift (Hz)
% -------------------------------------------------------------------------
% Construct synthetic signal (column vector)
% -------------------------------------------------------------------------
t = (0:1/fs:duration-1/fs).'; % Time axis
amp = [1.0 0.8 0.6 0.4]; % Amplitudes
freqs = [1000 2000 3000 4000]; % Frequencies (Hz)
segment = zeros(size(t));
for k = 1:numel(freqs)
segment = segment + amp(k)*sin(2*pi*freqs(k)*t);
end
segment = segment + 0.2*randn(size(t)); % Additive white Gaussian noise
% -------------------------------------------------------------------------
% Play original audio
% -------------------------------------------------------------------------
soundsc(segment,fs);
pause(2); % Brief pause
% -------------------------------------------------------------------------
% Frequency-shift via analytic signal
% -------------------------------------------------------------------------
analytic_segment = hilbert(segment); % Analytic (complex) signal
shifted_segment = real(analytic_segment ...
.* exp(1j*2*pi*f_shift*t));
% -------------------------------------------------------------------------
% Play shifted audio
% -------------------------------------------------------------------------
soundsc(shifted_segment,fs);
pause(2);
% -------------------------------------------------------------------------
% Power spectra (overlaid)
% -------------------------------------------------------------------------
% 1 Hz frequency resolution for clear peak separation
[P_orig,F] = pspectrum(segment, fs,'FrequencyResolution',3);
[P_shift,~] = pspectrum(shifted_segment,fs,'FrequencyResolution',3);
figure;
plot(F,10*log10(P_orig),'b','LineWidth',1.2,'DisplayName','Original');
hold on;
plot(F,10*log10(P_shift),'r','LineWidth',1.2,'DisplayName','Shifted');
xlim([0 6000]);
xlabel('Frequency (Hz)');
ylabel('Power/Frequency (dB/Hz)');
title('Power Spectrum: Original vs. Frequency-Shifted');
legend('Location','best');
grid on;
ylim([-60,0])
% -------------------------------------------------------------------------
% Time-domain waveforms (overlaid)
% -------------------------------------------------------------------------
figure;
plot(t,segment, 'b','DisplayName','Original'); hold on;
plot(t,shifted_segment,'r','DisplayName','Shifted');
xlabel('Time (s)');
ylabel('Amplitude');
title('Waveforms: Original vs. Frequency-Shifted');
legend('Location','best');
grid on;
% Uncomment the next line to zoom into the first 10 ms:
xlim([0 0.01]);

Connectez-vous pour commenter.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by