Inverse FFT for Signal Components

4 views (last 30 days)
Sam Hurrell
Sam Hurrell on 11 Nov 2022
Commented: Star Strider on 15 Nov 2022
I have a signal with 2 known frequencies present and I wish to extract and graph each frequency as its own signal. I have put the data through an FFT and have tried to create manual bandpasses to gate the FFT and take the real components of the IFFT of each gate as their individual components of the signals. I have gotten some odd results when putting the "new" data through an IFFT and I don't know how else to finish this script for the most accurate results?
% origin = Signal Data, Data(:,1) = Time
[j,~] = size(origin); NFFT = 2^nextpow2(j);
Fs = 1/(data(2,1)-data(1,1)); Fn = Fs/2;
FTD = fft(origin - mean(origin),NFFT)/j;
Fv(:,1) = linspace(0, 1, NFFT/2-1)*Fn;
Iv(:,1) = 1:numel(Fv); Y = abs(FTD(Iv))*2;
% For f1 = 1.2MHz, f2 = 2.4MHz
H = 3.2; [~,c] = min(abs(Fv(:,1)-(H)));
d = 1.7; [~,b] = min(abs(Fv(:,1)-(d)));
L = 0.5; [~,a] = min(abs(Fv(:,1)-(L)));
BP1 = zeros(length(Fv),1); BP1(b:c,1) = 1; new1 = Y.*BP1;
BP2 = zeros(length(Fv),1); BP2(a:b,1) = 1; new2 = Y.*BP2;

Answers (1)

Star Strider
Star Strider on 11 Nov 2022
If you just want to filter two frequencies from your signal, either use two bandpass calls (for best results, use the 'ImpulseResponse','iir' name-value pair) or (if the signal is long enough) fir1 to design a FIR filter that will filter both at the same time (however the result will be a signal with those two frequencies, not the individual frequencies). You can use a FIR filter with the fftfilt function, however the two separate (parallel) bandpass calls are likely to give the result you want.
Star Strider
Star Strider on 15 Nov 2022
It will be necessary to change the code, especially if the code you’re using isn’t doing what you want it to do.
If you want to do basic frequency domain filtering (that I do not recommend), try something like this —
Fs = 500;
Fn = Fs/2;
L = 9001;
s = randn(1, L);
t = linspace(0, L-1, L)/Fs;
FTs = fft(s)/L;
FTss = fftshift(FTs);
Fv = linspace(-1, 1, L)*Fn;
plot(Fv, abs(FTs))
FilterFreq = (Fv <= -99) & (Fv >= -100) | (Fv >= 99) & (Fv <= 100); % Symmetrical Passbands
FTss_filtered = FTss; % Create Filtered Frequency Vector
FTss_filtered(~FilterFreq) = 0; % Set Frequency Components Outside Of The Passband To Zero
plot(Fv, abs(FTss_filtered))
title('Filtered Signal')
FTss_filtered = ifftshift(FTss_filtered);
s_filtered = ifft(FTss_filtered);
plot(t, s_filtered)
peridx = islocalmax(s_filtered);
t_peak = t(peridx);
s_filt_freq = 1/mean(diff(t_peak))
s_filt_freq = 99.4331
plot(t, s_filtered)
xlim([1.9 2.1])
Filtering in the time domain is much more straightforward in concept and simply easier in practise.

Sign in to comment.




Community Treasure Hunt

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

Start Hunting!

Translated by