I know when N is even, fft(x,N) corresponds to frequencies 0,df,…,N/2*df,-(N/2-2)*df,…,-df.
What about if N is odd?
fftfrequencyspectrum
clc%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% load signal
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% data
data = importdata('SFC5S_nov25_ST_1_1.txt');dt = 1e-6; % 1 micro seconds
signal = data(:,1);samples = length(signal);Fs = 1/dt; % sampling frequency (Hz)
%% decimate (if needed)
% NB : decim = 1 will do nothing (output = input)
decim = 1;if decim>1 signal = decimate(signal,decim); Fs = Fs/decim;end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FFT parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%NFFT = 512; %
OVERLAP = 0.95;% spectrogram dB scale
spectrogram_dB_scale = 80; % dB range scale (means , the lowest displayed level is XX dB below the max level)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% options
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if you are dealing with acoustics, you may wish to have A weighted
% spectrums
% option_w = 0 : linear spectrum (no weighting dB (L) )
% option_w = 1 : A weighted spectrum (dB (A) )
option_w = 0;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% display 1 : averaged FFT spectrum
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%[freq, sensor_spectrum] = myfft_peak(signal,Fs,NFFT,OVERLAP);% convert to dB scale (ref = 1)
sensor_spectrum_dB = 20*log10(sensor_spectrum);% apply A weigthing if needed
if option_w == 1 pondA_dB = pondA_function(freq); sensor_spectrum_dB = sensor_spectrum_dB+pondA_dB; my_ylabel = ('Amplitude (dB (A))');else my_ylabel = ('Amplitude (dB (L))');endfigure(1),plot(freq,sensor_spectrum_dB,'b');gridtitle(['Averaged FFT Spectrum / Fs = ' num2str(Fs) ' Hz / Delta f = ' num2str(freq(2)-freq(1)) ' Hz ']);xlabel('Frequency (Hz)');ylabel(my_ylabel);%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% display 2 : time / frequency analysis : spectrogram demo
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%[sg,fsg,tsg] = specgram(signal,NFFT,Fs,hanning(NFFT),floor(NFFT*OVERLAP)); % FFT normalisation and conversion amplitude from linear to dB (peak)
sg_dBpeak = 20*log10(abs(sg))+20*log10(2/length(fsg)); % NB : X=fft(x.*hanning(N))*4/N; % hanning only
% apply A weigthing if neededif option_w == 1 pondA_dB = pondA_function(fsg); sg_dBpeak = sg_dBpeak+(pondA_dB*ones(1,size(sg_dBpeak,2))); my_title = ('Spectrogram (dB (A))');else my_title = ('Spectrogram (dB (L))');end% saturation of the dB range :
% saturation_dB = 60; % dB range scale (means , the lowest displayed level is XX dB below the max level)
min_disp_dB = round(max(max(sg_dBpeak))) - spectrogram_dB_scale;sg_dBpeak(sg_dBpeak<min_disp_dB) = min_disp_dB;% plots spectrogram
figure(2);imagesc(tsg,fsg,sg_dBpeak);colormap('jet');axis('xy');colorbar('vert');gridtitle([my_title ' / Fs = ' num2str(Fs) ' Hz / Delta f = ' num2str(fsg(2)-fsg(1)) ' Hz ']);xlabel('Time (s)');ylabel('Frequency (Hz)');function pondA_dB = pondA_function(f) % dB (A) weighting curve
n = ((12200^2*f.^4)./((f.^2+20.6^2).*(f.^2+12200^2).*sqrt(f.^2+107.7^2).*sqrt(f.^2+737.9^2))); r = ((12200^2*1000.^4)./((1000.^2+20.6^2).*(1000.^2+12200^2).*sqrt(1000.^2+107.7^2).*sqrt(1000.^2+737.9^2))) * ones(size(f)); pondA = n./r; pondA_dB = 20*log10(pondA(:));endfunction [freq_vector,fft_spectrum] = myfft_peak(signal, Fs, nfft, Overlap)% FFT peak spectrum of signal (example sinus amplitude 1 = 0 dB after fft).
% Linear averaging
% signal - input signal,
% Fs - Sampling frequency (Hz).
% nfft - FFT window size
% Overlap - buffer overlap % (between 0 and 0.95)
signal = signal(:);samples = length(signal);% fill signal with zeros if its length is lower than nfft
if samples<nfft s_tmp = zeros(nfft,1); s_tmp((1:samples)) = signal; signal = s_tmp; samples = nfft;end% window : hanning
window = hanning(nfft);window = window(:);% compute fft with overlap
offset = fix((1-Overlap)*nfft); spectnum = 1+ fix((samples-nfft)/offset); % Number of windows
% % for info is equivalent to :
% noverlap = Overlap*nfft;
% spectnum = fix((samples-noverlap)/(nfft-noverlap)); % Number of windows
% main loop
fft_spectrum = 0; for i=1:spectnum start = (i-1)*offset; sw = signal((1+start):(start+nfft)).*window; fft_spectrum = fft_spectrum + (abs(fft(sw))*4/nfft); % X=fft(x.*hanning(N))*4/N; % hanning only
end fft_spectrum = fft_spectrum/spectnum; % to do linear averaging scaling
% one sidded fft spectrum % Select first half
if rem(nfft,2) % nfft odd
select = (1:(nfft+1)/2)'; else select = (1:nfft/2+1)'; endfft_spectrum = fft_spectrum(select);freq_vector = (select - 1)*Fs/nfft;end
close all,clear all, clc, plt = 0; N = 48 T = 3*pi dt = T/N t = dt*(0:N-1); Fs = 1/dt df = Fs/N f = df*(0:N-1); A =4 y = A * sin(f .* t); plt=plt+1,figure(plt) hold on plot( t, y, 'LineWidth', 2) plot( t, zeros(1,N), 'k--', 'LineWidth', 2 ) xlabel('Time (seconds)') ylabel('y(t)') title( 'SWEPT FREQUENCY TIME SIGNAL' ) Y = fftshift(fft(y))/N; fb = f-Fs/2; realY = real(Y); imagY = imag(Y); absY = abs(Y); phaseY = angle(Y); plt=plt+1,figure(plt) subplot(2,2,1) hold on plot( fb, realY, 'LineWidth', 2 ) plot( fb, zeros(1,N), 'k--', 'LineWidth', 2 ) xlim( [ -Fs/2 Fs/2 ] ) ylabel( ' REAL(Y) ' ) title([ blanks(85) , ' SPECTRUM OF SWEPT FREQUENCY SIGNAL ' ] ) subplot(2,2,2) hold on plot( fb, imagY, 'LineWidth', 2 ) plot( fb, zeros(1,N), 'k--', 'LineWidth', 2 ) xlim( [ -Fs/2 Fs/2 ] ) ylabel( ' IMAG(Y) ' ) subplot(2,2,3) hold on plot( fb, absY, 'LineWidth', 2) xlim( [ -Fs/2 Fs/2 ] ) ylabel( ' AMPLITUDE(Y) ' ) xlabel( ' FREQUENCY(HZ) ' ) ; subplot(2,2,4) hold on plot(fb,phaseY, 'LineWidth', 2) plot( fb, zeros(1,N), 'k--', 'LineWidth', 2 ) xlim( [ -Fs/2 Fs/2 ] ) ylabel( ' PHASE(Y) ' ) xlabel( ' FREQUENCY(HZ) ' ) ;
Best Answer