Plotting spectrograms for multiple files

조회 수: 32 (최근 30일)
Louise Wilson
Louise Wilson 2021년 10월 6일
댓글: Bjorn Gustavsson 2021년 10월 8일
I have multiple acoustic files for which I would like to plot a spectrogram on a single plot.
I know how to plot one spectrogram:
[xbit,fs]=audioread(fullfname, [nlo nup]); %read in wav
xbit=detrend(xbit); %remove DC offset
calxbit=xbit*cal; %apply calibration
%Perform FFT and plot:
[S,F,T,P] = spectrogram(calxbit,window,overlap,nfft,fs,'yaxis');
figure(2);
h = pcolor(T,F,10*log10(P));
set(h,'EdgeColor','none');
This provides one figure with time on the x axis and frequency on the y-axis, and colourplot for intensity.
However, I would like to plot multiple spectrograms and so the x-axis represents multiple files which were collected over time e.g. every 5 minutes.
I considered that I could read in the acoustic data for multiple files and concatenate it, but this would not preserve any gaps in time between the subsequent files (which may or may not be negligible). I'd like to have the x tick marks represent the start time of each separate file perhaps.

답변 (1개)

Bjorn Gustavsson
Bjorn Gustavsson 2021년 10월 6일
Wouldn't you achieve the desired output by putting the different spectrograms in consecutive subplots?
Something like this perhaps:
nFiles = numel(fullfnames);
for iFile = 1:nFiles
fullfname = fullfnames{iFile};
t0 = Tstart(iFile);
[xbit,fs]=audioread(fullfname, [nlo nup]); %read in wav
xbit=detrend(xbit); %remove DC offset
calxbit=xbit*cal; %apply calibration
%Perform FFT and plot:
[S,F,T,P] = spectrogram(calxbit,window,overlap,nfft,fs,'yaxis');
sph(iFile) = subplot(1,nFiles,iFile);
h = pcolor(T,F,10*log10(P)); % Here you might want to add the start-time, t0, to T
% with proper conversion of time-format...
set(h,'EdgeColor','none');
end
Then you can adjust the spacing of the sub-plot-panels using sph (also consider using tile-nexttile)
HTH
  댓글 수: 8
Louise Wilson
Louise Wilson 2021년 10월 7일
This works, but when I try to expand the limits of the plot to see both spectrograms (when doing 2 files only) the plot goes blank.
directory={'X:\SoundTrap\Boats\wav\Noises\LTSA test\LTSA test batch'}; %folder where wav files are
folder=char(directory);
fullfnames=dir(fullfile(folder,'*.wav')); %list all .wavs in folder
nFiles=numel(fullfnames);
%get fs of first (i.e. all) files in folder
firstfile=fullfile(folder,char(fullfnames(1,1).name));
[xbit,fs]=audioread(firstfile,[1 2]);
tlo=1.0;
thi=114.0;
nlo=fs*tlo; %multiply fs by tlo to get starting point
nup=fs*thi; %do the same for end point
nfft=16384;
window=16384;
overlap=window/2; %50% overlap
cal=176.4;
cal=power(10,cal/20); %calculate calibration value
t0=0;
dt=1;
for iFile = 1:2%nFiles
fullfname = fullfnames(iFile).name;
%format is xxxx.yyMMddHHmmss.cut.wav
% you'll have to set/get/extract start-time for each spectrogram
fname=strsplit(fullfname,{'.'});
fname_st=fname(2);
fname_st=datenum(fname_st,'yyMMddHHmmss');
tStartstrings{iFile} = fname_st;% you'll have to set/get/extract start-time for each spectrogram
[xbit,fs]=audioread(fullfile(folder,fullfname), [nlo nup]); %read in wav
xbit=detrend(xbit); %remove DC offset
calxbit=xbit*cal; %apply calibration
%Perform FFT and plot:
[S,F,T,P] = spectrogram(calxbit,window,overlap,nfft,fs,'yaxis');
T=fname_st+datenum(seconds(T)); %start time of .wav file + seconds of each chunk
%to produce informative x-axis
h = pcolor(T,F,10*log10(P)); % Here you might want to add the start-time, t0, to T
% with proper conversion of time-format...
hold on
set(h,'EdgeColor','none');
end
Bjorn Gustavsson
Bjorn Gustavsson 2021년 10월 8일
That might be because you now add the ID-time of each file to the start-time, which meand that if you have large gaps (you mentioned something like 5 minutes appart, and then each of those files were for a couple of seconds worth of data) between the spectrograms. The idea I proposed was to plot the first spectrogram at times between
0 and "10 s" the next spectrogram between "10 s"+dt and "20 s"+dt, the third spectrogram between "20 s"+2*dt and "30 s"+2*dt and so on. The next step is then to se the tick-marks to:
xTickTimes = 0:("10 s"+dt):(N*("10 s"+dt));
set(gca,'Xtick',xTickTimes)
Which should give you tickmarks at the start of each spectra, next you'll have to set the Xticklabel. For that you should have made a cell-array of the fname_st-contents, lets say you call that variable t_filestarts_all, then this should be:
set(gca,'XtickLabel',t_filestarts_all)
This way you will have an uneven time-axis, one scale for the file-start-times and between those the time-scales of the spectrograms.
HTH

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Time-Frequency Analysis에 대해 자세히 알아보기

제품


릴리스

R2020a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by