How do I freqency shift a signal by a fractional amount using IFFT and FFT?
이전 댓글 표시
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
답변 (2개)
Matt J
2013년 6월 11일
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
This is equivalent to shifting a sinc-interpolated version of y. Unless you really can't live with linear interpolation, though, directly shifting/resampling in the original domain, without FFTs is going to be more efficient. Compare:
SHIFT=0.3;
y=rand(1,1e7);
N=length(y);
ax=(0:N-1);
tic
mult = exp(-1i*2*pi/N*(0:N-1)*SHIFT);
w=ifft((fft(y).*mult ),'symmetric');
toc;
%Elapsed time is 1.242511 seconds.
tic;
w= interp1(y,ax+SHIFT,'linear');
toc
%Elapsed time is 0.512226 seconds.
F=griddedInterpolant(y,'linear');
tic
w=F(ax+SHIFT);
toc
%Elapsed time is 0.312686 seconds.
Matt J
2013년 6월 12일
Victoria commented:
Thanks. That did the trick.
Matt J
2013년 6월 12일
You're welcome. If this resolves your question, the normal thing for you to do now would be to Accept-click my Answer.
rashi
2020년 8월 3일
but the output for w,w1 and w2 are different, will those be not same?
Matt J
2020년 8월 3일
No, the first version does not use linear interpolation and so will be different from the others.
Duncan Carlsmith
2025년 6월 21일
1 개 추천
analytic_segment = hilbert(segment); % Complex analytic signal
shifted_segment = real(analytic_segment .* exp(1j*2*pi*f_shift*t));
댓글 수: 2
Paul
2025년 6월 22일
Hi Duncan,
Can you illustrate this approach with a concrete example?
Duncan Carlsmith
2025년 6월 22일
이동: Matt J
2025년 6월 23일
%% 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]);
카테고리
도움말 센터 및 File Exchange에서 Vibration Analysis에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!