MATLAB: I wish to get the spectrum (Magnitude vs Frequency(Hz)) of a pure tone(1 kHz). However, the piece of code I’m employing to do so isn’t working. What am I doing wrong

fftfftshift

%fft of puretone
%the cell puretone{1,1} contains the puretone
fft_puretone{1,1} = abs(fftshift(fft(puretone{1,1})));
plot(x_axis,fft_puretone{1,1})
However, I am getting this plot:
whereas I should get a peak at 1kHz. I think there is some problem in using fftshift() and fft() but I can't figure out what. There maybe some problem with setting up the axis which I've taken as
x_bins = [-N/2:N/2-1] %where N is the number of samples in the sound
x_axis = x_bins*fs/N;

Best Answer

Hello Komal,
The whole point of using fftshift is to put zero frequency at the center of the resulting frequency array. If you zero-pad fft_puretone on one side only, it messes up that symmetry. So fft_puretone needs to be zero-padded equally on each side.
An an N-point fft with time array spacing of delt and frequency array spacing of delf always obeys delt*delf = 1/N. That remains true after subsequent zero-padding.
For the correct frequency domain amplitude, you need to multiply the fft by a factor of 1/N.
You did not specify what puretone looks like in the time domain, but I am speculating that the time record was 5 seconds, and the amplitude of the wave = 1/sqrt(2) (peak), = 1/2 (rms).
Here is an example of how this would work. The resulting arrays have 1105920 elements and show a peak at 1kHz and another at -1kHz. After ffting a real function, people often double the positive frequency peak and ignore the negative frequency peak, which is all right as long as you keep in mind what the fft is actually doing.
hmax = 1105920
fs = 44100
% 1k puretone in time domain
delt = 1/fs;
f0 = 1000;
T = 5; % time record (sec)
N = T*44100;
t = (0:N-1)*delt;
puretone = (1/sqrt(2))*sin(2*pi*f0*t);
% back to fft code
fft_puretone = abs(fftshift(fft(puretone)/N));
Npad = hmax-N;
fft_puretone = [zeros(1,Npad/2) fft_puretone zeros(1,Npad/2)];
delf = 1/(N*delt); % fundamental rule for fft
freq = (-hmax/2:hmax/2-1)*delf;
figure(1)
plot(freq,fft_puretone)