Mercurial > hg > emotion-detection-top-level
comparison Code/Descriptors/Matlab/MPEG7/FromWeb/h_specgram2.m @ 4:92ca03a8fa99 tip
Update to ICASSP 2013 benchmark
| author | Dawn Black |
|---|---|
| date | Wed, 13 Feb 2013 11:02:39 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 3:e1cfa7765647 | 4:92ca03a8fa99 |
|---|---|
| 1 function [yo,fo,to] = h_specgram2(varargin) | |
| 2 %SPECGRAM Calculate spectrogram from signal. | |
| 3 % B = SPECGRAM(A,NFFT,Fs,WINDOW,SHIFT) calculates the spectrogram for | |
| 4 % the signal in vector A. SPECGRAM splits the signal into overlapping | |
| 5 % segments, windows each with the WINDOW vector and forms the columns of | |
| 6 % B with their zero-padded, length NFFT discrete Fourier transforms. Thus | |
| 7 % each column of B contains an estimate of the short-term, time-localized | |
| 8 % frequency content of the signal A. Time increases linearly across the | |
| 9 % columns of B, from left to right. Frequency increases linearly down | |
| 10 % the rows, starting at 0. If A is a length NX complex signal, B is a | |
| 11 % complex matrix with NFFT rows and | |
| 12 % k = fix((NX-NOVERLAP)/(length(WINDOW)-NOVERLAP)) | |
| 13 % columns, where NOVERLAP = length(WINDOW)-mean(SHIFT) | |
| 14 % If A is real, B still has k columns but the higher frequency | |
| 15 % components are truncated (because they are redundant); in that case, | |
| 16 % SPECGRAM returns B with NFFT/2+1 rows for NFFT even and (NFFT+1)/2 rows | |
| 17 % for NFFT odd. If you specify a scalar for WINDOW, SPECGRAM uses a | |
| 18 % Hanning window of that length. WINDOW must have length smaller than | |
| 19 % or equal to NFFT and greater than NOVERLAP. NOVERLAP is the number of | |
| 20 % samples the sections of A overlap. Fs is the sampling frequency | |
| 21 % which does not effect the spectrogram but is used for scaling plots. | |
| 22 % | |
| 23 % [B,F,T] = SPECGRAM(A,NFFT,Fs,WINDOW,NOVERLAP) returns a column of | |
| 24 % frequencies F and one of times T at which the spectrogram is computed. | |
| 25 % F has length equal to the number of rows of B, T has length k. If you | |
| 26 % leave Fs unspecified, SPECGRAM assumes a default of 2 Hz. | |
| 27 % | |
| 28 % B = SPECGRAM(A) produces the spectrogram of the signal A using default | |
| 29 % settings; the defaults are NFFT = minimum of 256 and the length of A, a | |
| 30 % Hanning window of length NFFT, and NOVERLAP = length(WINDOW)/2. You | |
| 31 % can tell SPECGRAM to use the default for any parameter by leaving it | |
| 32 % off or using [] for that parameter, e.g. SPECGRAM(A,[],1000) | |
| 33 % | |
| 34 % See also PWELCH, CSD, COHERE and TFE. | |
| 35 | |
| 36 % Author(s): L. Shure, 1-1-91 | |
| 37 % T. Krauss, 4-2-93, updated | |
| 38 % Copyright 1988-2000 The MathWorks, Inc. | |
| 39 % $Revision: 1.6 $ $Date: 2000/06/09 22:07:35 $ | |
| 40 | |
| 41 error(nargchk(1,5,nargin)) | |
| 42 [msg,x,nfft,Fs,window,shift]=specgramchk(varargin); | |
| 43 error(msg) | |
| 44 | |
| 45 nx = length(x); | |
| 46 nwind = length(window); | |
| 47 if nx < nwind % zero-pad x if it has length less than the window length | |
| 48 x(nwind)=0; nx=nwind; | |
| 49 end | |
| 50 x = x(:); % make a column vector for ease later | |
| 51 window = window(:); % be consistent with data set | |
| 52 noverlap = nwind - mean(shift); | |
| 53 ncol = fix((nx-noverlap)/(nwind-noverlap)); | |
| 54 | |
| 55 totalshift = sum(shift); | |
| 56 numshift = length(shift); | |
| 57 progshift = (cumsum(shift)-shift(1))'; | |
| 58 overshift = 1:totalshift:nx; | |
| 59 shifts = progshift(:,ones(1,length(overshift)))+overshift(ones(length(progshift),1),:); | |
| 60 colindex = reshape(shifts,1,prod(size(shifts))); | |
| 61 colindex = colindex(1:ncol); | |
| 62 %colindex = 1 + (0:(ncol-1))*(nwind-noverlap); | |
| 63 rowindex = (1:nwind)'; | |
| 64 if length(x)<(nwind+colindex(ncol)-1) | |
| 65 x(nwind+colindex(ncol)-1) = 0; % zero-pad x | |
| 66 end | |
| 67 | |
| 68 y = zeros(nwind,ncol); | |
| 69 | |
| 70 % put x into columns of y with the proper offset | |
| 71 % should be able to do this with fancy indexing! | |
| 72 y(:) = x(rowindex(:,ones(1,ncol))+colindex(ones(nwind,1),:)-1); | |
| 73 | |
| 74 % Apply the window to the array of offset signal segments. | |
| 75 y = window(:,ones(1,ncol)).*y; | |
| 76 | |
| 77 % now fft y which does the columns | |
| 78 y = fft(y,nfft); | |
| 79 if ~any(any(imag(x))) % x purely real | |
| 80 if rem(nfft,2), % nfft odd | |
| 81 select = [1:(nfft+1)/2]; | |
| 82 else | |
| 83 select = [1:nfft/2+1]; | |
| 84 end | |
| 85 y = y(select,:); | |
| 86 else | |
| 87 select = 1:nfft; | |
| 88 end | |
| 89 f = (select - 1)'*Fs/nfft; | |
| 90 | |
| 91 t = (colindex-1)'/Fs; | |
| 92 | |
| 93 % take abs, and use image to display results | |
| 94 if nargout == 0 | |
| 95 % newplot; | |
| 96 % if length(t)==1 | |
| 97 % imagesc([0 1/f(2)],f,20*log10(abs(y)+eps));axis xy; colormap(jet) | |
| 98 % else | |
| 99 % imagesc(t,f,20*log10(abs(y)+eps));axis xy; colormap(jet) | |
| 100 % end | |
| 101 % xlabel('Time') | |
| 102 % ylabel('Frequency') | |
| 103 elseif nargout == 1, | |
| 104 yo = y; | |
| 105 elseif nargout == 2, | |
| 106 yo = y; | |
| 107 fo = f; | |
| 108 elseif nargout == 3, | |
| 109 yo = y; | |
| 110 fo = f; | |
| 111 to = t; | |
| 112 end | |
| 113 | |
| 114 function [msg,x,nfft,Fs,window,shift] = specgramchk(P) | |
| 115 %SPECGRAMCHK Helper function for SPECGRAM. | |
| 116 % SPECGRAMCHK(P) takes the cell array P and uses each cell as | |
| 117 % an input argument. Assumes P has between 1 and 5 elements. | |
| 118 | |
| 119 msg = []; | |
| 120 | |
| 121 x = P{1}; | |
| 122 if (length(P) > 1) & ~isempty(P{2}) | |
| 123 nfft = P{2}; | |
| 124 else | |
| 125 nfft = min(length(x),256); | |
| 126 end | |
| 127 if (length(P) > 2) & ~isempty(P{3}) | |
| 128 Fs = P{3}; | |
| 129 else | |
| 130 Fs = 2; | |
| 131 end | |
| 132 if length(P) > 3 & ~isempty(P{4}) | |
| 133 window = P{4}; | |
| 134 else | |
| 135 if length(nfft) == 1 | |
| 136 window = hanning(nfft); | |
| 137 else | |
| 138 msg = 'You must specify a window function.'; | |
| 139 end | |
| 140 end | |
| 141 if length(window) == 1, window = hanning(window); end | |
| 142 if (length(P) > 4) & ~isempty(P{5}) | |
| 143 shift = P{5}; | |
| 144 else | |
| 145 shift = ceil(length(window)/2); | |
| 146 end | |
| 147 | |
| 148 % NOW do error checking | |
| 149 if (length(nfft)==1) & (nfft<length(window)), | |
| 150 msg = 'Requires window''s length to be no greater than the FFT length.'; | |
| 151 end | |
| 152 if (min(shift) <= 0), | |
| 153 msg = 'Requires SHIFT to be strictly positive.'; | |
| 154 end | |
| 155 if (length(nfft)==1) & (nfft ~= abs(round(nfft))) | |
| 156 msg = 'Requires positive integer values for NFFT.'; | |
| 157 end | |
| 158 if sum(shift ~= abs(round(shift))), | |
| 159 msg = 'Requires positive integer value for NOVERLAP.'; | |
| 160 end | |
| 161 if min(size(x))~=1, | |
| 162 msg = 'Requires vector (either row or column) input.'; | |
| 163 end |
