# How can create a .wav bar based spectrogram on matlab?

How can I create a bar based spectrogram that updates as a .wav file is playing. This is commonly found in music players. Here is an example below:

I am able to display a amplitude/frequency graph that updates as the .wav file is being played using this code below:

function syncPlayerDemo()
%some example music
%set up audio player
player = audioplayer(y, Fs);
[samples,channels]=size(y);
%calculate timeline
t=linspace(0,1/Fs*(samples-1),samples);
%initialize full plot, update will only move the visible area using xlim
h=plot(t,y);
%set up callback to update every <TimerPeriod> s
player.TimerFcn=@timerFcn;
player.TimerPeriod=0.1;
player.playblocking()
end
function timerFcn(source,data)
%an area of length <area> s will be visible
area=1;
position=(source.CurrentSample-1)/source.SampleRate;
%move visible area, current position is in the center
set(gca,'XLim',[position-area/2,position+area/2]);
%used a waitbar for testing, might be commented in
%waitbar(source.CurrentSample/source.TotalSamples);
end


Which results in an updating graph:

How can I get the bars like above, any suggestions?

• Your "amplitude/frequency graph" is actually amplitude vs time. To get amplitude vs frequency you need to do an FFT on each chunk and then probably bin it on a log frequency scale. – endolith Nov 24 '15 at 14:43
• that's not a spectrogram, that is a frequency analysis over the whole time. Break down your signal in segments of equal length, and do this for each of them. See specgram for something that already does this. – Marcus Müller Aug 20 '16 at 17:31
• dsp.stackexchange.com/a/2427/29 – endolith May 8 at 17:14

• This is only half of the solution. Using bar() instead of plot() will change how the data is plotted. However, @Techno04335 asked for a spectrogram. The nomenclature does not quite match the plot he's showing. I assume the goal is a plot of some sort of power spectral density (PSD) estimate and - most preferrably - a conversion to logarithmic dB scale. Something like y = 20 * log10(abs(FFT(y))) should do the trick in this case. Furthermore, it will not be possible to shift the visible region when displaying the PSD. Better compute the PSD for each block and plot it indvidually. – applesoup Feb 23 '16 at 23:41