I have a code for a band pass filter process:
clc;
f=2075; % Input frequency
Fs=4*f; % Sampling Frequency
t=0:(1:100)/Fs:0.01;
s=sin(2*pi*f*t);
subplot(2,3,1)
plot(t,s)
grid on;
xlabel('time')
ylabel('magnitude')
fp1=2070; % Low Cut
fp2=2080; % High Cut
w1=(fp1)/(Fs); % normalization
w2=(fp2)/(Fs); % normalization
%Bandpass Filter Function
[b,a] = butter(8, w1, 'low'); % lowpass filter
y1 = filtfilt(b, a, s);
[b,a] = butter(8, w2, 'high'); % highpass filter
y2 = filtfilt(b, a, y1);
subplot (2,3,2);
plot(y2);
grid on;
xlabel('time')
ylabel('magnitude')
% Input Frequency Spectrum
S1=fft(s,512);
w=(0:255)/256*(Fs/2);
subplot(2,3,4)
plot(w,abs(S1(1:256)))
grid on;
xlabel('frequency')
ylabel('magnitude')
% Out of Band pass filter spectrum
S2=fft(y2,512);
w=(0:255)/256*(Fs/2);
subplot(2,3,5)
plot(w,abs(S2(1:256)))
grid on;
xlabel('frequency')
ylabel('magnitude') `
Here are my questions:
Is the code of the program that I created is correct
What command line should I add to look for the maximum frequency of the bandpass filter spectrum results
I thank you for your help!
Best Regards
Related
I have a respiration (breathing) signal and a sampling frequency of 25 Hz and need to detect where is the lowest breathing frequency on a time scale, which should tell me actually when the person became sleepy. Fourier transforms in its classical form doesn't give me much useful information. So, to clarify: the time of measurement should be on the x-axis and the breathing frequency should be on the y-axis. Then, I suppose, lower amplitudes of the signal will show the slower breathing. What should be done with the signal to plot it the way I need?
All credits for this code go to Star Strider.
D = load('respiratory.txt');
Fs = 25; % Sampling Frequency (Hz)
Fn = Fs/2; % Nyquist Frequency
Ts = 1/Fs; % Sampling Time (sec)
L = numel(D);
t = linspace(0, L, L)*Ts; % Time Vector (sec)
figure(1)
plot(t, D)
grid
% axis([0 60 -850 -750])
axis([xlim -850 -750])
xlabel('Time')
ylabel('Amplitude')
FTD = fft(D-mean(D))/L; % Fourier Transform
Fv = linspace(0, 1, fix(L/2)+1)*Fn; % Frequency Vector
Iv = 1:numel(Fv); % Index Vector
figure(2)
plot(Fv, abs(FTD(Iv))*2)
grid
axis([0 2.5 ylim])
xlabel('Frequency (Hz)')
ylabel('Amplitude')
Wp = [0.35 0.65]/Fn; % Passband Frequency (Normalised)
Ws = [0.30 0.75]/Fn; % Stopband Frequency (Normalised)
Rp = 1; % Passband Ripple (dB)
Rs = 50; % Stopband Ripple (dB)
[n,Ws] = cheb2ord(Wp,Ws,Rp,Rs); % Filter Order
[z,p,k] = cheby2(n,Rs,Ws); % Filter Design, Sepcify Bandpass
[sos,g] = zp2sos(z,p,k); % Convert To Second-Order-Section For Stability
figure(3)
freqz(sos, 2^16, Fs) % Filter Bode Plot
D_filtered = filtfilt(sos, g, D); % Filter Signal
[pks,locs] = findpeaks(D_filtered, 'MinPeakDist',40);
figure(4)
plot(t, D_filtered)
hold on
plot(t(locs), pks, '^r')
hold off
grid
% axis([0 60 ylim])
axis([0 60 -15 15])
xlabel('Time')
ylabel('Amplitude')
tdif = diff([0 t(locs)]); % Time Difference Between Peaks (sec)
Dfrq = 60./tdif; % Frequency (Respirations/Minute)
figure(5)
plot(t(locs), Dfrq)
grid
axis([xlim 10 40])
xlabel('Time (sec)')
ylabel('Frequency (minute^{-1})')
When the FFT is performed on a function of time u in Matlab, a complex spectrum uf is returned. To plot the spectral amplitude abs(uf) against its frequency content, a frequency grid can be made to accommodate uf. I can associate a wavelength grid with the frequency grid, and plot uf against that also. The spacing between each element in the frequency array is constant, but since wavelength ~ 1/frequency, the spacing between each point in the wavelength array varies over the array index. I am curious if there is a way to take the FFT of a function of time to yield a spectrum in wavelength that has constant spacing. Here is my code in Matlab:
clc;
close all;
clear all;
lam = 800e-9; % Wavelength (m)
c = 3e8; % Light speed (m/s)
nt = 8192; % Temporal grid resolution
T = 400*1e-15; % Temporal grid size (s)
dt = T/nt; % Temporal pixel spacing
df = 1/(nt*dt); % Frequency pixel spacing
ff = [(0:nt/2-1) (-nt/2:-1)]*df; % Frequency grid
ff = fftshift(ff);
wav = c./ff; % Wavelength array (spacing is not constant between each element)
for k = 1:nt
tt(k) = (-nt/2+k-1)*dt; % Time array
u(k) = cos(2*pi*c/lam*tt(k)); % Function of time
end
%Now I can take FFT:
uf = fftshift(fft(u)); % The spectrum of my function. The FFT has yielded a spectrum associated with a frequency array of linearly spaced elements (ff).
Both plots of spectral amplitude vs. wavelength and vs. frequency yield good results.
figure(1)
plot(ff,abs(uf))
title('Spectral amplitude vs frequency')
xlabel('Frequency (Hz)')
ylabel('Spectral amplitude')
figure(2)
plot(wav,abs(uf))
title('Spectral amplitude vs wavelength')
xlabel('Wavelength (m)')
ylabel('Spectral amplitude');
But my wavelength array does not have constant spacing:
figure(3)
plot(ff)
title('Frequency array')
ylabel('Frequency (Hz)')
xlabel('Index')
figure(4)
plot(wav)
xlim([(nt/2 +1) (nt/2 + 100)])
title('Wavelength array')
ylabel('Wavelength (m)')
xlabel('Index')
You should make a linearly spaced wavelength array and interpolate your data to find the linearly spaced y values.
In this code f1 and f2 are the Fourier Transform of Gate and Train of Impulse..
I need the plot of convolution between these two spectrums
I am expecting train of sinc function since convolution of a signal with train of impulse gives train of that func..
but using direct conv() I am getting a positive sine pulse...
fSampling = 10000; %Sampling Frequency
tSampling = 1/fSampling; %Sampling Time
L = 10000; %Length of Signal
to = (0:L-1)*tSampling; %Time Vector
F = 100;
% message signal
t = -5:0.01:5;
w=1;
a= rectpuls(t,2);
subplot(2,4,1);
plot(t,a);
xlabel('Time');
ylabel('Amplitude');
title('Message signal');
grid on;
% Fourier transform of sine wave
subplot(2,4,2)
NFFT = 2^nextpow2(L);
Xsig = fft(a,NFFT)/L;
f1 = fSampling/2*(linspace(0,1,NFFT/2+1));
plot(f1,2*abs(Xsig(1:NFFT/2+1)),'r');
grid on;
axis([-50 500 1.0000e-005 1])
title('\itSignle-Sided Amplitude Sepectrum of xsig(t)');
xlabel('\itFrequency(Hz) \rightarrow');
ylabel('|Xsig(f)| \rightarrow');
% train of impulse
n= -5:1:5;
l =length(n);
for i= 1:l
x(i)=1;
end;
subplot(2,4,3);
stem(n,x);
xlabel('Time');
ylabel('Amplitude');
title('Train of Impulses');
grid on;
% Fourier Transform of Train of Impulse
subplot(2,4,4)
NFFT = 2^nextpow2(L);
Xsig = fft(x,NFFT)/L;
f2 = fSampling/2*(linspace(0,1,NFFT/2+1));
stem(f2,2*abs(Xsig(1:NFFT/2+1)),'r');
grid on;
axis([-50 500 1.0000e-005 1])
title('\itSignle-Sided Amplitude Sepectrum of xsig(t)');
xlabel('\itFrequency(Hz) \rightarrow');
ylabel('|Xsig(f)| \rightarrow');
% multiplication of signals
T = -5:0.01:5;
b = a.*x(i);
subplot(2,4,5);
stem(T,b);
xlabel('Time');
ylabel('Amplitude');
title('Sampled signal');
grid on;
% Fourier transform of Sampled Signal
subplot(2,4,6)
NFFT = 2^nextpow2(L);
Xsig = fft(x,NFFT)/L;
f3 = fSampling/2*(linspace(0,1,NFFT/2+1));
plot(f3,2*abs(Xsig(1:NFFT/2+1)),'r');
grid on;
axis([-50 500 1.0000e-005 1])
title('\itSignle-Sided Amplitude Sepectrum of xsig(t)');
xlabel('\itFrequency(Hz) \rightarrow');
ylabel('|Xsig(f)| \rightarrow');
%Convolution of
c= conv(f1,f2)
subplot(2,4,7);
plot(c);
grid on;
I'm new to Matlab for LTI signal processing and wondering if anyone can help with something that I'm sure is meant to be basic. I've spent hours and hours researching and obtaining background information and still cannot obtain a clear path to tackle these problems. So far, from scratch, I have generated a signal required and managed to use the fft function to produce the signal's DFT:
function x = fourier_rikki(A,t,O)
Fs = 1000;
t = 0:(1/Fs):1;
A = [0.5,0,0.5];
N = (length(A) - 1)/2;
x = zeros(size(t));
f1 = 85;
O1 = 2*pi*f1;
for k = 1:length(A)
x1 = x + A(k)*exp(1i*O1*t*(k-N-1));
end
f2 = 150;
O2 = 2*pi*f2;
for k = 1:length(A);
x2 = x + A(k)*exp(1i*O2*t*(k-N-1));
end
f3 = 330;
O3 = 2*pi*f3;
for k = 1:length(A);
x3 = x + A(k)*exp(1i*O3*t*(k-N-1));
end
signal = x1 + x2 + x3;
figure(1);
subplot(3,1,1);
plot(t, signal);
title('Signal x(t) in the Time Domain');
xlabel('Time (Seconds)');
ylabel('x(t)');
X = fft(signal); %DFT of the signal
subplot(3,1,2);
plot(t, X);
title('Power Spectrum of Discrete Fourier Transform of x(t)');
xlabel('Time (Seconds)');
ylabel('Power');
f = linspace(0, 1000, length(X)); %?
subplot(3,1,3);
plot(f, abs(X)); %Only want the positive values
title('Spectral Frequency');
xlabel('Frequency (Hz)'); ylabel('Power');
end
At this stage, I'm assuming this is correct for:
"Generate a signal with frequencies 85,150,330Hz using a sampling frequency of 1000Hz - plot 1seconds worth of the signal and its Discrete Fourier Transform."
The next step is to "Find the frequency response of an LTI system that filters out the higher and lower frequencies using the Fourier Transform". I'm stuck trying to create an LTI system that does that! I have to be left with the 150Hz signal, and I'm guessing I perform the filtering on the FFT, perhaps using conv.
My course is not a programming course - we are not assessed on our programming skills and I have minimal Matlab experience - basically we have been left to our own devices to struggle through, so any help would be greatly appreciated! I am sifting through tonnes of different examples and searching Matlab functions using 'help' etc, but since each one is different and does not have a break down of the variables used, explaining why certain parameters/values are chosen etc. it is just adding to the confusion.
Among many (many) others I have looked at:
http://www.ee.columbia.edu/~ronw/adst-spring2010/lectures/matlab/lecture1.html
http://gribblelab.org/scicomp/09_Signals_and_sampling.html section 10.4 especially.
As well as Matlab Geeks examples and Mathworks Matlab function explanations.
I guess the worst that can happen is that nobody answers and I continue burning my eyeballs out until I manage to come up with something :) Thanks in advance.
I found this bandpass filter code as a Mathworks example, which is exactly what needs to be applied to my fft signal, but I don't understand the attenuation values Ast or the amount of ripple Ap.
n = 0:159;
x = cos(pi/8*n)+cos(pi/2*n)+sin(3*pi/4*n);
d = fdesign.bandpass('Fst1,Fp1,Fp2,Fst2,Ast1,Ap,Ast2',1/4,3/8,5/8,6/8,60,1,60);
Hd = design(d,'equiripple');
y = filter(Hd,x);
freq = 0:(2*pi)/length(x):pi;
xdft = fft(x);
ydft = fft(y);
plot(freq,abs(xdft(1:length(x)/2+1)));
hold on;
plot(freq,abs(ydft(1:length(x)/2+1)),'r','linewidth',2);
legend('Original Signal','Bandpass Signal');
Here is something you can use as a reference. I think I got the gist of what you were trying to do. Let me know if you have any questions.
clear all
close all
Fs = 1000;
t = 0:(1/Fs):1;
N = length(t);
% 85, 150, and 330 Hz converted to radian frequency
w1 = 2*pi*85;
w2 = 2*pi*150;
w3 = 2*pi*330;
% amplitudes
a1 = 1;
a2 = 1.5;
a3 = .75;
% construct time-domain signals
x1 = a1*cos(w1*t);
x2 = a2*cos(w2*t);
x3 = a3*cos(w3*t);
% superposition of 85, 150, and 330 Hz component signals
x = x1 + x2 + x3;
figure
plot(t(1:100), x(1:100));
title('unfiltered time-domain signal, amplitude vs. time');
ylabel('amplitude');
xlabel('time (seconds)');
% compute discrete Fourier transform of time-domain signal
X = fft(x);
Xmag = 20*log10(abs(X)); % magnitude spectrum
Xphase = 180*unwrap(angle(X))./pi; % phase spectrum (degrees)
w = 2*pi*(0:N-1)./N; % normalized radian frequency
f = w./(2*pi)*Fs; % radian frequency to Hz
k = 1:N; % bin indices
% plot magnitude spectrum
figure
plot(f, Xmag)
title('frequency-domain signal, magnitude vs. frequency');
xlabel('frequency (Hz)');
ylabel('magnitude (dB)');
% frequency vector of the filter. attenuates undesired frequency components
% and keeps desired components.
H = 1e-3*ones(1, length(k));
H(97:223) = 1;
H((end-223):(end-97)) = 1;
% plot magnitude spectrum of signal and filter
figure
plot(k, Xmag)
hold on
plot(k, 20*log10(H), 'r')
title('frequency-domain signal (blue) and filter (red), magnitude vs. bin index');
xlabel('bin index');
ylabel('magnitude (dB)');
% filtering in frequency domain is just multiplication
Y = X.*H;
% plot magnitude spectrum of filtered signal
figure
plot(f, 20*log10(abs(Y)))
title('filtered frequency-domain signal, magnitude vs. frequency');
xlabel('frequency (Hz)');
ylabel('magnitude (dB)');
% use inverse discrete Fourier transform to obtain the filtered time-domain
% signal. This signal is complex due to imperfect symmetry in the
% frequency-domain, however the imaginary components are nearly zero.
y = ifft(Y);
% plot overlay of filtered signal and desired signal
figure
plot(t(1:100), x(1:100), 'r')
hold on
plot(t(1:100), x2(1:100), 'linewidth', 2)
plot(t(1:100), real(y(1:100)), 'g')
title('input signal (red), desired signal (blue), signal extracted via filtering (green)');
ylabel('amplitude');
xlabel('time (seconds)');
Here is the end result...
Hi I'm trying to calculate mfcc for which i'm windowing. I have seen this one post I'm getting error in fftOneSide.
my code is
waveFile='test_preEmphasis.wav';
[y, fs]=wavread(waveFile);
n=512;
t=(1:n)'/fs;
startIndex=30418;
endIndex=startIndex+n-1;
original=y(startIndex:endIndex);
windowed=original.*hamming(n);
[mag1, phase1, freq1]=fftOneSide(original, fs);
[mag2, phase2, freq2]=fftOneSide(windowed, fs);
subplot(3,2,1); plot(original); grid on; axis([-inf inf -1 1]);
title('Original signal');
subplot(3,2,2); plot(windowed); grid on; axis([-inf inf -1 1]);
title('Windowedsignal');
subplot(3,2,3); plot(freq1, mag1); grid on;
title('Energy spectrum (linear scale)');
subplot(3,2,4); plot(freq2, mag2); grid on;
title('Energy spectrum (linear scale)');
subplot(3,2,5); plot(freq1, 20*log(mag1)); grid on;
axis([-inf inf -80 120]); title('Energy spectrum (db)');
subplot(3,2,6); plot(freq2, 20*log(mag2)); grid on; axis([-inf inf -80 120]);
title('Energy spectrum (db)');
the error i'm getting is
??? Undefined function or method 'fftOneSide' for input arguments of type 'double'.
any help is appreciated
thanks
This is a really old post, it'd be neat if someone still cared. I just provided what I believe to be the answer in the recent post below, which I arrived at after a fair bit of frustration: Undefined function 'fftOneSide' for input arguments of type 'double'.
It should be noted here there's a call to a file, which I'm not sure if the author had originally or not. I suspect all the problems are related to a similarly named file in the sourcecode.
If you look at my discussion in the other post, within the function definition there is a call to a method demo with a file - which isn't present if you just have the function definition, not the original file. Calling [mag1, phase1, freq1]=fftOneSide(original, fs,1), after you comment out the first line if nargin <1... and the demo routine worked fine on my machine with the code which I'll show below. Having the third argument equal to 1 guarantees that the code will run the print routines, which is important.
In case the other thread is closed, I just want to show the output, when the input is manually defined, and I call [mag1, phase1, freq1]=fftOneSide(original, fs,1) on the properly edited method, with the inputs as in the original post shown below (notice the call is to original in fftOneSide..in the other post it was like this as well.. I believe the call was was meant to be instead for windowed, but I don't have the signals toolbox with hamming anyways):
fs=8000;
t=(1:512)'/fs; %'// <-- prevents string markdown
f=306.396;
original=sin(2*pi*f*t)+0.2*randn(length(t),1);
% windowed=original.*hamming(length(t)); % defined in other post
[mag1,phase1,freq1]=fftOneSide(original,fs); % I call fftOneSide(original,fs,1);
The output is as follows (source code below!)
Anyways, here's the source code in case anyone wants to use this function
function [magSpec, phaseSpec, freq, powerSpecInDb]=fftOneSide(signal, fs, plotOpt)
% fftOneSide: One-sided FFT for real signals
% Usage: [magSpec, phaseSpec, freq, powerSpecInDb]=fftOneSide(signal, fs)
%
% For example:
% [y, fs]=wavread('welcome.wav');
% frameSize=512;
% startIndex=2047;
% signal=y(startIndex:startIndex+frameSize+1);
% signal=signal.*hamming(length(signal));
% plotOpt=1;
% [magSpec, phaseSpec, freq, powerSpecInDb]=fftOneSide(signal, fs, plotOpt);
% Roger Jang, 20060411, 20070506
if nargin<1, selfdemo; return; end %=== (MathBio: Comment this out!)
if nargin<2, fs=1; end
if nargin<3, plotOpt=0; end
N = length(signal); % Signal length
freqStep = fs/N; % Frequency resolution
time = (0:N-1)/fs; % Time vector
z = fft(signal); % Spectrum
freq = freqStep*(0:N/2); % Frequency vector
z = z(1:length(freq)); % One side
z(2:end-1)=2*z(2:end-1); % Assuming N is even, symmetric data is multiplied by 2
magSpec=abs(z); % Magnitude spectrum
phaseSpec=unwrap(angle(z)); % Phase spectrum
powerSpecInDb=20*log(magSpec+realmin); % Power in db
if plotOpt
% ====== Plot time-domain signals
subplot(3,1,1);
plot(time, signal, '.-');
title(sprintf('Input signals (fs=%d)', fs));
xlabel('Time (seconds)'); ylabel('Amplitude'); axis tight
% ====== Plot spectral power
subplot(3,1,2);
plot(freq, powerSpecInDb, '.-'); grid on
title('Power spectrum');
xlabel('Frequency (Hz)'); ylabel('Power (db)'); axis tight
% ====== Plot phase
subplot(3,1,3);
plot(freq, phaseSpec, '.-'); grid on
title('Phase');
xlabel('Frequency (Hz)'); ylabel('Phase (Radian)'); axis tight
end
% ====== Self demo (MathBio: Comment all of this out! )
function selfdemo
[y, fs]=wavread('welcome.wav');
frameSize=512;
startIndex=2047;
signal=y(startIndex:startIndex+frameSize+1);
signal=signal.*hamming(length(signal));
[magSpec, phaseSpec, freq, powerSpecInDb]=feval(mfilename, signal, fs, 1);