spectrogram code error shows up
10 views (last 30 days)
Show older comments
i have this code for spectrogram there is an error occured in 57 line
figure(1);subplot(3,1,3);plot(fVec,20*log10(spectrogram(:,j)));axis([0 fs maxAxisFreq-50 maxAxisFreq]);
says that vector length must match
how can i fix that
clear all
close all
fileToRead = 'twoToneSequence1.wav';
%fileToRead = 'twoToneSequence2.wav';
%fileToRead = 'ground_8K.wav';
%fileToRead = 'pureMelody.wav';
%fileToRead = 'sax-phrase-8K.wav';
%fileToRead = 'piano-8K.wav';
%fileToRead = 'vocals_8K.wav';
[x,fs]=audioread(fileToRead);
%length returns the number of samples
N=length(x);
%uncomment the below if you want to listen to the wav file
p = audioplayer(x,fs);
play(p)
windowSize = 300; %contains the number of samples in the spectrogram analysis window
windowStep = windowSize/2; %number of samples to jump
%define below the samples of the window
window = [ones(1,windowSize),zeros(1,1000)]';
%pre-allocate memory for spectrogram matrix
spectrogram = zeros(length(window),floor((N-length(window)+1)/windowStep)-1);
timeIndx = zeros(1 ,floor((N-length(window)+1)/windowStep)-1); %this vector will store the time indexes for each entry in the spectrogram
%fVec is a vector that will store the frequencies of the DTFT being sampled during the DFT/FFT
%TIP: for the spectrogram, you take the FFT of windowSize samples at various points of the signal
fVec = fs*[0:(N-1)]/N ; %<-------------- FOR STUDENT TO COMPLETE;
i=1;
j=1;
while (i+length(window)-1 <= N)
xw = x(i:i+length(window)-1).*window; %<--------------- FOR STUDENT TO COMPLETE
spectrogram(:,j)= fft(xw); %<--------------- FOR STUDENT TO COMPLETE
timeIndx(j) = i;
i=i+windowStep;
j=j+1;
end
maxAxisFreq = max(max(20*log10(spectrogram)));
%make the below "if (0)" to turn off visualization
if (1)
i=1;
j=1;
while (i+length(window)-1 <= N)
xw = x(i:i+length(window)-1).*window; %<--------------- FOR STUDENT TO COMPLETE
figure(1);subplot(3,1,1);plot(1:N,x,'b',i:i+windowSize-1,x(i:i+windowSize-1),'r');;axis([0 N -0.3 +0.3]);
xlabel('n');
ylabel('x[n]')
figure(1);subplot(3,1,2);plot(i:i+length(window)-1,xw,'r');axis([i i+length(window) -0.3 +0.3]);
xlabel('n');
ylabel('xw[n]')
figure(1);subplot(3,1,3);plot(fVec,20*log10(spectrogram(:,j)));axis([0 fs maxAxisFreq-50 maxAxisFreq]);
xlabel('Hz');
ylabel('|Xw[k]| (dB)')
pause(0.1); %pause between steps
if mod(j,1)==0 %replace 0 for -1 to avoid stopping
keyboard;
end
i=i+windowStep;
j=j+1;
end
end
%the 2 lines below are just to remove -Inf entries that occur when computing 20*log10(0))
entriesWithTooLowValues = (20*log10(spectrogram)<(max(max(20*log10(spectrogram)))-100));
spectrogram(entriesWithTooLowValues) = 10^((max(max(20*log10(spectrogram)))-100)/20);
figure(2);imagesc(timeIndx,fVec,20*log10(spectrogram));colorbar
xlabel('n (time)');
ylabel('Hz');
thresholdSpectrogram = maxAxisFreq-10;
%figure(3);imagesc(timeIndx,fVec,(20*log10(spectrogram)>thresholdSpectrogram));colormap gray; colorbar
0 Comments
Answers (1)
Walter Roberson
on 25 Feb 2019
In your code, window is length 300+1000 = 1300
In your while loop, i:i+length(window)-1 would be length(window) = 1300 long, so xw will be 1300 entries, so spectrogram(:,j) would end up with 1300 rows (same as you initialize it to be.)
In your code, N = length(x) which would typically be the number of samples, but could be the number of channels instead of the number of samples was fewer than the number of channels (it could happen.)
fVec is created from 0:N-1 so fVec is N long -- number of samples.
You plot(Fvec, 20*log10(spectrogram(:,j)) . We demonstrated above that Fvec is the full number of samples in the sound. But spectrogram(:,j) we demonstrated with be the size of the window, 1300. That is a mismatch unless the sound just happens to be exactly 1300 samples long.
Perhaps your Fvec should be created based upon the window size.
0 Comments
See Also
Categories
Find more on Time-Frequency Analysis in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!