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