Search code examples
matlabaudiofftoctavespectrum

How to plot a one-sided spectrum from a two-sided spectrum?


I have a wav file in my code. I used the FFT on my audio signal to do a STFT. Basically what I am doing is a "real-time spectral analysis". What I get from my signal is a two-sided spectrum.

The code here provided, helps you to understand, what I mean. I advise you to try it out. Just take any wav file and put it in your Matlab/Octave directory. The variable Yres contains the the two-sided spectrum.

Any Idea, how to make it one-sided? I am sure it is something simple I am missing.

[y,fs]=wavread('UnchainMyHeart.wav');
t=linspace(0,length(y)/fs,length(y));
plot(t,y)

%Plotting my signal in the time domain
fftlen = 4096; 
segl =floor(0.05*fs); 
windowshift=segl/2; 
window=hann(segl); 
window=window.'; 

si=1; 
ei=segl; 
AOS= length(y)/windowshift - 1;
f1=figure;
f=0:1:fftlen-1;
f=f/(fftlen-1)*fs;

Ya=zeros(1,fftlen);
plot(f,Ya),axis([0 fs -90 20])
grid on 

n=0;
for m = 1:1:AOS
  y_a = y(si:ei);
  y_a= y_a.*window;
  Ya=fft(y_a, fftlen);
  n=n+1;
  if n==1
    Yres=abs(Ya);
  else
    Yres=Yres+abs(Ya);
  end

  if n=10
    Yres=Yres/10;
    n=0;
    drawnow; 
    figure(f1);
    plot(f, 20*log10(abs(Yres)));
    ylim([-90 20]);
    title("Spectrum of a audio signal");
    xlabel("f(Hz)");
    ylabel("dB");
    grid on;
  end

  si=si+windowshift;   
  ei=ei+windowshift; 
end     

Solution

  • you can just plot half of the spectrum you already have:

    plot(f(1:end/2), 20*log10(abs(Yres(1:end/2))));
    

    Or alternativly you can the full one but centered:

    plot(fftshift(f), 20*log10(abs(fftshift(Yres))));