samer@33: function [edges,map]=cqmap(parms,range,res) samer@33: % cqmap - Audio Spectrum linear to log frequency map samer@32: % samer@32: % Converts a constant-Q filterbank specification into a sparse matrix samer@32: % which can be multiplied by a STFT power spectrogram to get a samer@32: % constant-Q spectrogram. Note that though the logarithmic frequency samer@32: % sampling grid has an adjustable spacing (the resolution parameter), samer@32: % its origin is FIXED at 1kHz. samer@32: % samer@33: % cqmap :: samer@32: % struct { samer@32: % fs:real ~ 'sampling rate', samer@32: % FFTsize:natural ~ 'FFT frame size to be used to get STFT' samer@32: % } ~'framing parameter structure (see h_fparms)', samer@32: % [[2]] ~ 'requested lower and upper cut-off frequencies', samer@32: % real|nan ~ 'resolution in octaves, or return one band if nan' samer@32: % -> samer@32: % [[L-1]] ~ 'frequency bin edges, excluding 0 and fs/2', samer@32: % [[L,M]] ~ 'L by M sparse array'. samer@32: samer@32: % If resolution is nan, we just use the two edges unmodified samer@32: % as per MPEG-7 spec (except we're using nan instead of the samer@32: % magic '8'). Obviously, we can't even quantise the band edges samer@32: % without a valid resolution. samer@32: if isnan(res), samer@32: edges=min(range/parms.fs,0.5); samer@32: else samer@32: F0=1000; % MAGIC number - origin of frequnecy grid is 1kHz samer@33: edges=cqedges(parms.fs,range,res,F0); samer@32: samer@32: % remove edges from bottom end until each band can be resolved samer@32: e = 0.5+edges*parms.FFTsize; % band edges relative to FT bin edges samer@32: k = find(diff(e)<1); % find bands narrower than one bin samer@32: k = k(ceil(e(k))==1+floor(e(k+1))); % filter out bands spanning >1 bin samer@32: % if any bands remaining, then remove these from main edges list samer@32: if ~isempty(k), edges=edges(1+max(k):end); end samer@32: end samer@32: samer@32: % build sparse matrix of standard size if requested samer@32: if nargout>1, samer@32: map = specbasis(parms.FFTsize*edges,dftbins(parms.FFTsize)); samer@32: end