Matlab not plotting the exact fourier signal - matlab

I'm trying to plot a simple signal in fourier domain using Matlab. It's not plotting the correct signal. Here is my code:
clc;
clear all;
close all;
x=1:0.001:10;
f1=sin(2*pi*10*x);
f2=sin(2*pi*15*x);
f3=sin(2*pi*30*x);
f=f1+f2+f3;
plot(2*pi*x,fft(f1));
figure
plot(x,fft(f1));
I've expected a peak at 10 since the frequency is 10. But it is giving a peak at some other point
Here are the two plot images:
This is the image for plot(x,fft(f1))
This is the image for plot(2*pi*x,fft(f1))
It is not showing the peak at 10.I even tried using abs(fft(f1)). No luck :/
Isn't it the correct way to plot signal in fourier domain?

The fft function assumes unit time step. In order to correct for non unit time step you need to define the frequency component based on the nyquist rate. The following code plots the magnitude of the fft with the correct frequency axis.
clc;
clear all;
close all;
x=1:0.001:10;
% ^ this is your sampling time step
f1=sin(2*pi*10*x);
f2=sin(2*pi*15*x);
f3=sin(2*pi*30*x);
% bounds of fourier transform based on sampling rate
Fs = 1/0.001;
ff = linspace(-Fs/2,Fs/2,numel(x));
F1 = fftshift(fft(f1)/numel(x));
F2 = fftshift(fft(f2)/numel(x));
F3 = fftshift(fft(f3)/numel(x));
figure();
plot(ff,abs(F1),'-r'); hold on;
plot(ff,abs(F2),'-b');
plot(ff,abs(F3),'-k');
Edit: To answer OPs question in the comment.
Speaking in normalized frequency units (assuming sampling rate of 1). The fft function returns the frequency response from 0 to 2*pi radians, but due to some signal processing properties and the way that discrete signals are interpreted when performing an FFT, the signal is actually periodic so the pi to 2*pi section is identical to the -pi to 0 section. To display the plot with the DC component (0 frequency) in the center we use fftshift which does a circular shift equal to 1/2 the length of the signal on the data returned by fft. Before you take the ifft make sure you use ifftshift to put it back in the right place.
Edit2: The normalization term (/numel(x)) is necessary to estimate the continuous time fourier transform using the discrete fourier transform. I don't remember the precise mathematical reason off the top of my head but the examples in the MATLAB documentation also imply the necessity of this normalization.
Edit 3: The original link that I had is down. I may come back to add a more detailed answer but in the mean time I definitely recommend that anyone interested in understanding the relationship between the fundamentals of the FS, FT, DTFT, and DFT watch Professor Oppenheim's hilariously old, but amazingly informative and straightforward lectures on MIT OpenCourseWare.

Related

3-D Plot in MATLAB Containing: Time, Frequency and Power Spectral Density

I am currently working on a project for my Speech Processing course and have just finished making a time waveform plot as well as both wide/narrow band spectrograms for a spoken word in Spanish (aire).
The next part of the project is as follows:
Make a 3-D plot of each word signal, as a function of time, frequency and power spectral density. The analysis time step should be 20ms, and power density should be computed using a 75%-overlapped Hamming window and the FFT. Choose a viewing angle that best highlights the signal features as they change in time and frequency.
I was hoping that someone can offer me some guidance as to how to begin doing this part. I have started by looking here under the Spectrogram and Instantaneous Frequency heading but was unsure of how to add PSD to the script.
Thanks
I am going to give you an example.
I am going to generate a linear chirp signal.
Fs = 1000;
t = 0:1/Fs:2;
y = chirp(t,100,2,300,'linear');
And then, I am going to define number of fft and hamming window.
nfft=128;
win=hamming(nfft);
And then I am going to define length of overlap, 75% of nfft.
nOvl=nfft*0.75;
And then, I am performing STFT by using spectrogram function.
[s,f,t,pxx] = spectrogram(y,win,nOvl,nfft,Fs,'psd');
'y' is time signal, 'win' is defined hamming window, 'nOvl' is number of overlap, 'nfft' is number of fft, 'Fs' is sampling frequency, and 'psd' makes the result,pxx, as power spectral density.
Finally, I am going to plot the 'pxx' by using waterfall graph.
waterfall(f,t,pxx')
xlabel('frequency(Hz)')
ylabel('time(sec)')
zlabel('PSD')
The length of FFT, corresponding to 20ms, depends on sampling frequency of your signal.
EDIT : In plotting waterfall graph, I transposed pxx to change t and f axis.

Matlab fft on one period of sinewave returns phase of -pi/2. Why?

While trying to understand Fast Fourier Transform I encountered a problem with the phase. I have broken it down to the simple code below. Calculating one period of a 50Hz sinewave, and applying an fft algorithm:
fs = 1600;
dt = 1/fs;
L = 32;
t=(0:L-1)*dt;
signal = sin(t/0.02*2*pi);
Y = fft(signal);
myAmplitude = abs(Y)/L *2 ;
myAngle = angle(Y);
Amplitude_at_50Hz = myAmplitude(2);
Phase_at_50Hz = myAngle(2);
While the amplitude is ok, I don't understand the phase result. Why do I get -pi/2 ? As there is only one pure sinewave, I expected the phase to be 0. Either my math is wrong, or my use of Matlab, or both of them... (A homemade fft gives me the same result. So I guess I am stumbling over my math.)
There is a similar post here: MATLAB FFT Phase plot. However, the suggested 'unwrap' command doesn't solve my problem.
Thanks and best regards,
DanK
The default waveform for an FFT phase angle of zero is a cosine wave which starts and ends in the FFT window at 1.0 (not a sinewave which starts and ends in the FFT window at 0.0, or at its zero crossings.) This is because the common nomenclature is to call the cosine function components of the FFT basis vectors (the complex exponentials) the "real" components. The sine function basis components are called "imaginary", and thus infer a non-zero complex phase.
That is what it should be. If you used cosine, you would have found a phase of zero.
Ignoring numerical Fourier transforms for a moment and taking a good old Fourier transform of sin(x), which I am too lazy to walk through, we get a pair of purely imaginary deltas.
As for an intuitive reason, recall that a discrete Fourier transform is averaging a bunch of points along a curve in the complex plane while turning at the angular frequency of the bin you're computing and using the amplitude corresponding to the sample. If you sample a sine curve while turning at its own frequency, the shape you get is a circle centered on the imaginary axis (see below). The average of that is of course going to be right on the imaginary axis.
Plot made with wolfram alpha.
Fourier transform of a sine function such as A*sin((2*pi*f)*t) where f is the frequency will yield 2 impulses of magnitude A/2 in the frequency domain at +f and -f where the associated phases are -pi/2 and pi/2 respectively.
You can take a look at its proof here:
http://mathworld.wolfram.com/FourierTransformSine.html
So the code is working fine.

How does this logic produce high and low pass filters?

I was studying for a signals & systems project and I have come across this code on high and low pass filters for an audio signal on the internet. Now I have tested this code and it works but I really don't understand how it is doing the low/high pass action.
The logic is that a sound is read into MATLAB by using the audioread or wavread function and the audio is stored as an nx2 matrix. The n depends on the sampling rate and the 2 columns are due to the 2 sterio channels.
Now here is the code for the low pass;
[hootie,fs]=wavread('hootie.wav'); % loads Hootie
out=hootie;
for n=2:length(hootie)
out(n,1)=.9*out(n-1,1)+hootie(n,1); % left
out(n,2)=.9*out(n-1,2)+hootie(n,2); % right
end
And this is for the high pass;
out=hootie;
for n=2:length(hootie)
out(n,1)=hootie(n,1)-hootie(n-1,1); % left
out(n,2)=hootie(n,2)-hootie(n-1,2); % right
end
I would really like to know how this produces the filtering effect since this is making no sense to me yet it works. Also shouldn't there be any cutoff points in these filters ?
The frequency response for a filter can be roughly estimated using a pole-zero plot. How this works can be found on the internet, for example in this link. The filter can be for example be a so called Finite Impulse Response (FIR) filter, or an Infinite Impulse Response (IIR) filter. The FIR-filters properties is determined only from the input signal (no feedback, open loop), while the IIR-filter uses the previous signal output to control the current signal output (feedback loop or closed loop). The general equation can be written like,
a_0*y(n)+a_1*y(n-1)+... = b_0*x(n)+ b_1*x(n-1)+...
Applying the discrete fourier transform you may define a filter H(z) = X(z)/Y(Z) using the fact that it is possible to define a filter H(z) so that Y(Z)=H(Z)*X(Z). Note that I skip a lot of steps here to cut down this text to proper length.
The point of the discussion is that these discrete poles can be mapped in a pole-zero plot. The pole-zero plot for digital filters plots the poles and zeros in a diagram where the normalized frequencies, relative to the sampling frequencies are illustrated by the unit circle, where fs/2 is located at 180 degrees( eg. a frequency fs/8 will be defined as the polar coordinate (r, phi)=(1,pi/4) ). The "zeros" are then the nominator polynom A(z) and the poles are defined by the denominator polynom B(z). A frequency close to a zero will have an attenuation at that frequency. A frequency close to a pole will instead have a high amplifictation at that frequency instead. Further, frequencies far from a pole is attenuated and frequencies far from a zero is amplified.
For your highpass filter you have a polynom,
y(n)=x(n)-x(n-1),
for each channel. This is transformed and it is possble to create a filter,
H(z) = 1 - z^(-1)
For your lowpass filter the equation instead looks like this,
y(n) - y(n-1) = x(n),
which becomes the filter
H(z) = 1/( 1-0.9*z^(-1) ).
Placing these filters in the pole-zero plot you will have the zero in the highpass filter on the positive x-axis. This means that you will have high attenuation for low frequencies and high amplification for high frequencies. The pole in the lowpass filter will also be loccated on the positive x-axis and will thus amplify low frequencies and attenuate high frequencies.
This description is best illustrated with images, which is why I recommend you to follow my links. Good luck and please comment ask if anything is unclear.

How to produce a log scale FFT with MatLab

It's my first time performing an FFT within MatLab by experimenting with some example code from the MathWorks website. I was wondering if it was possible to take the code I have and transform the x axis to a log-scale representation rather than linear. I understand most of the code, but it is the x axis line of code that I'm still not 100% sure exactly what it is doing apart from the +1 at the end of the line, which is that fact that MatLab's indexing structure doesn't start on 0.
My code so far is:
[y,fs] = wavread('Wav/800Hz_2sec.wav');
NFFT = 4096;
Y = fft(y,NFFT)/length(y);
f = fs/2*linspace(0,1,NFFT/2+1);
plot(f,2*abs(Y(1:NFFT/2+1))
frequency usually comes out in linear scale from Discrete Fourier Transform. if you want, you can make a new frequency vector in log scale and interpolate the results you already have
fnew=fs/2.*logspace(log10(fs/length(y)),0,npts);
Ynew= interp1(f,Y(1:NFFT/2+1),fnew);
where npts is the length of your new frequency vector. for just plotting
loglog(f,2*abs(Y(1:NFFT/2+1));
honestly IMO, the interpolation thing doesn't work very well because FFT of real signals produces strong peaks and troughs in spectra, so unless you smooth your spectrum first, the interpolated spectrum won't look as nice

Confusion in figuring out the relation between actual frequency values and FFT plot indexes in MATLAB

I know that there are a lot of similar questions to this, I am still unable to figure out the answer.
Let's say we have time signal in MATLAB:
t=0:1/44100:1
and a cosine signal with frequency 500Hz:
x=cos(2*pi*500*t);
Now, I am trying to plot the magnitude spectrum obtained using the fft command on signal x
FFT=abs(fft(x))
plot(FFT)
According to the theory, we should get two peaks in the plot, one at -500 Hz and the other at 500Hz.
What I don't understand is that I do get two peaks but I can't figure out at what frequencies these peaks are. I know there is a way to figure out the frequency using the FFT index, length of the input signal and the sampling frequency but I still can't calculate the frequency.
I know that there are methods to align the FFT plots so that the peaks lie at the index number of the frequency they represent by using the fftshift function, but what I want is to figure out the frequency using the the plot resulting from simply calling this function:
FFT=fft(x)
In this case, I already know that signal contains a cosine of 500Hz, but what if the signal that we want to get the FFT of is not known before time. How can we get the frequency values of the peaks in that sample using the output from the fft function?
You need to generate the frequency array yourself and plot your FFT result against it.
Like this:
function [Ycomp, fHz] = getFFT(data, Fs)
len = length(data);
NFFT = 2^nextpow2(len);
Ydouble = fft(data, NFFT)/len; % Double-sided FFT
Ycomp = Ydouble(1:NFFT/2+1); % Single-sided FFT, complex
fHz = Fs/2*linspace(0,1,NFFT/2+1); % Frequency array in Hertz.
semilogx(fHz, abs(Ycomp))
end
You will see peaks at 500 Hz and Fs - 500 Hz (i.e. 44100 - 500 = 43600 Hz in your particular case).
This is because the real-to-complex FFT output is complex conjugate symmetric - the top half of the spectrum is a "mirror image" of the bottom half when you are just looking at the magnitude and is therefore redundant.
Note that of plotting power spectra you can usually save yourself a lot of work by using MATLAB's periodogram function rather than dealing directly with all the details of FFT, window functions, plotting, etc.