Mercurial > hg > constant-q-cpp
comparison yeti/cqtkernel.yeti @ 23:4f2f28d5df58
Fix frequency calculation in cpp, and some diagnostics
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Fri, 01 Nov 2013 17:58:39 +0000 |
parents | b54bd1d0dc1e |
children | 5ca24ff67566 |
comparison
equal
deleted
inserted
replaced
22:701900c371b0 | 23:4f2f28d5df58 |
---|---|
45 // parts separately as real = cos(2*pi*x), imag = sin(2*pi*x). | 45 // parts separately as real = cos(2*pi*x), imag = sin(2*pi*x). |
46 | 46 |
47 kernels = map do k: | 47 kernels = map do k: |
48 | 48 |
49 nk = round(bigQ * sampleRate / (minFreq * (pow 2 ((k-1)/binsPerOctave)))); | 49 nk = round(bigQ * sampleRate / (minFreq * (pow 2 ((k-1)/binsPerOctave)))); |
50 | 50 |
51 // the cq MATLAB toolbox uses a symmetric window for | 51 // the cq MATLAB toolbox uses a symmetric window for |
52 // blackmanharris -- which is odd because it uses a periodic one | 52 // blackmanharris -- which is odd because it uses a periodic one |
53 // for other types. Oh well | 53 // for other types. Oh well |
54 win = bf.divideBy nk | 54 win = bf.divideBy nk |
55 (bf.sqrt | 55 (bf.sqrt |
56 (window.windowFunction (BlackmanHarris ()) [Symmetric true] nk)); | 56 (window.windowFunction (BlackmanHarris ()) [Symmetric true] nk)); |
57 | 57 |
58 fk = minFreq * (pow 2 ((k-1)/binsPerOctave)); | 58 fk = minFreq * (pow 2 ((k-1)/binsPerOctave)); |
59 | 59 |
60 genKernel f = bf.multiply win | 60 genKernel f = bf.multiply win |
61 (vec.fromList | 61 (vec.fromList |
62 (map do i: f (2 * pi * fk * i / sampleRate) done [0..nk-1])); | 62 (map do i: f (2 * pi * fk * i / sampleRate) done [0..nk-1])); |
63 | 63 |
64 reals = genKernel cos; | 64 reals = genKernel cos; |
72 | 72 |
73 specKernel = fftFunc | 73 specKernel = fftFunc |
74 (complex.complexArray | 74 (complex.complexArray |
75 (vec.concat [shift, reals]) | 75 (vec.concat [shift, reals]) |
76 (vec.concat [shift, imags])); | 76 (vec.concat [shift, imags])); |
77 | 77 |
78 map do c: | 78 map do c: |
79 if complex.magnitude c <= thresh then complex.zero else c fi | 79 if complex.magnitude c <= thresh then complex.zero else c fi |
80 done specKernel; | 80 done specKernel; |
81 | 81 |
82 done [1..winNr]; | 82 done [1..winNr]; |
83 | 83 |
84 done [1..binsPerOctave]; | 84 done [1..binsPerOctave]; |
85 | 85 |
86 kmat = cm.toSparse | 86 kmat = cm.toSparse |
87 (cm.scaled (1/fftSize) | 87 (cm.scaled (1/fftSize) |
88 (cm.newComplexMatrix (RowMajor()) (concat kernels))); | 88 (cm.newComplexMatrix (RowMajor()) (concat kernels))); |
89 | 89 |
90 eprintln "density = \(cm.density kmat)"; | 90 eprintln "density = \(cm.density kmat) (\(cm.nonZeroValues kmat) of \(cm.width kmat * cm.height kmat))"; |
91 | 91 |
92 // Normalisation | 92 // Normalisation |
93 | 93 |
94 wx1 = bf.maxindex (complex.magnitudes (cm.getRow 0 kmat)); | 94 wx1 = bf.maxindex (complex.magnitudes (cm.getRow 0 kmat)); |
95 wx2 = bf.maxindex (complex.magnitudes (cm.getRow (cm.height kmat - 1) kmat)); | 95 wx2 = bf.maxindex (complex.magnitudes (cm.getRow (cm.height kmat - 1) kmat)); |
100 wK = vec.slice diag (round(1/q)) (vec.length diag - round(1/q) - 2); | 100 wK = vec.slice diag (round(1/q)) (vec.length diag - round(1/q) - 2); |
101 | 101 |
102 weight = (fftHop / fftSize) / (bf.mean (bf.abs wK)); | 102 weight = (fftHop / fftSize) / (bf.mean (bf.abs wK)); |
103 weight = sqrt(weight); | 103 weight = sqrt(weight); |
104 | 104 |
105 eprintln "weight = \(weight)"; | |
106 | |
105 { | 107 { |
106 kernel = cm.scaled weight kmat, | 108 kernel = cm.scaled weight kmat, |
107 fftSize, | 109 fftSize, |
108 fftHop, | 110 fftHop, |
109 binsPerOctave, | 111 binsPerOctave, |