comparison dsp/keydetection/GetKeyMode.cpp @ 458:e7e36ecd7ad2

make m_BPO const and rename to kBinsPerOctave
author Daniel Schürmann <daschuer@mixxx.org>
date Fri, 24 May 2019 20:31:32 +0200
parents 8a8cf7296e58
children b7e10277a84c
comparison
equal deleted inserted replaced
457:8a8cf7296e58 458:e7e36ecd7ad2
20 #include <iostream> 20 #include <iostream>
21 21
22 #include <cstring> 22 #include <cstring>
23 #include <cstdlib> 23 #include <cstdlib>
24 24
25 static const int kBinsPerOctave = 36;
26
25 // Chords profile 27 // Chords profile
26 static double MajProfile[36] = { 28 static double MajProfile[kBinsPerOctave] = {
27 0.0384, 0.0629, 0.0258, 0.0121, 0.0146, 0.0106, 0.0364, 0.0610, 0.0267, 29 0.0384, 0.0629, 0.0258, 0.0121, 0.0146, 0.0106, 0.0364, 0.0610, 0.0267,
28 0.0126, 0.0121, 0.0086, 0.0364, 0.0623, 0.0279, 0.0275, 0.0414, 0.0186, 30 0.0126, 0.0121, 0.0086, 0.0364, 0.0623, 0.0279, 0.0275, 0.0414, 0.0186,
29 0.0173, 0.0248, 0.0145, 0.0364, 0.0631, 0.0262, 0.0129, 0.0150, 0.0098, 31 0.0173, 0.0248, 0.0145, 0.0364, 0.0631, 0.0262, 0.0129, 0.0150, 0.0098,
30 0.0312, 0.0521, 0.0235, 0.0129, 0.0142, 0.0095, 0.0289, 0.0478, 0.0239}; 32 0.0312, 0.0521, 0.0235, 0.0129, 0.0142, 0.0095, 0.0289, 0.0478, 0.0239};
31 33
32 static double MinProfile[36] = { 34 static double MinProfile[kBinsPerOctave] = {
33 0.0375, 0.0682, 0.0299, 0.0119, 0.0138, 0.0093, 0.0296, 0.0543, 0.0257, 35 0.0375, 0.0682, 0.0299, 0.0119, 0.0138, 0.0093, 0.0296, 0.0543, 0.0257,
34 0.0292, 0.0519, 0.0246, 0.0159, 0.0234, 0.0135, 0.0291, 0.0544, 0.0248, 36 0.0292, 0.0519, 0.0246, 0.0159, 0.0234, 0.0135, 0.0291, 0.0544, 0.0248,
35 0.0137, 0.0176, 0.0104, 0.0352, 0.0670, 0.0302, 0.0222, 0.0349, 0.0164, 37 0.0137, 0.0176, 0.0104, 0.0352, 0.0670, 0.0302, 0.0222, 0.0349, 0.0164,
36 0.0174, 0.0297, 0.0166, 0.0222, 0.0401, 0.0202, 0.0175, 0.0270, 0.0146}; 38 0.0174, 0.0297, 0.0166, 0.0222, 0.0401, 0.0202, 0.0175, 0.0270, 0.0146};
37 // 39 //
68 // Set C (= MIDI #12) as our base : 70 // Set C (= MIDI #12) as our base :
69 // This implies that key = 1 => Cmaj, key = 12 => Bmaj, key = 13 => Cmin, etc. 71 // This implies that key = 1 => Cmaj, key = 12 => Bmaj, key = 13 => Cmin, etc.
70 m_ChromaConfig.min = Pitch::getFrequencyForPitch( 48, 0, tuningFrequency ); 72 m_ChromaConfig.min = Pitch::getFrequencyForPitch( 48, 0, tuningFrequency );
71 m_ChromaConfig.max = Pitch::getFrequencyForPitch( 96, 0, tuningFrequency ); 73 m_ChromaConfig.max = Pitch::getFrequencyForPitch( 96, 0, tuningFrequency );
72 74
73 m_ChromaConfig.BPO = 36; 75 m_ChromaConfig.BPO = kBinsPerOctave;
74 m_ChromaConfig.CQThresh = 0.0054; 76 m_ChromaConfig.CQThresh = 0.0054;
75 77
76 // Chromagram inst. 78 // Chromagram inst.
77 m_Chroma = new Chromagram( m_ChromaConfig ); 79 m_Chroma = new Chromagram( m_ChromaConfig );
78 80
79 // Get calculated parameters from chroma object 81 // Get calculated parameters from chroma object
80 m_ChromaFrameSize = m_Chroma->getFrameSize(); 82 m_ChromaFrameSize = m_Chroma->getFrameSize();
81 // override hopsize for this application 83 // override hopsize for this application
82 m_ChromaHopSize = m_ChromaFrameSize; 84 m_ChromaHopSize = m_ChromaFrameSize;
83 m_BPO = m_ChromaConfig.BPO;
84 85
85 // std::cerr << "chroma frame size = " << m_ChromaFrameSize << ", decimation factor = " << m_DecimationFactor << " therefore block size = " << getBlockSize() << std::endl; 86 // std::cerr << "chroma frame size = " << m_ChromaFrameSize << ", decimation factor = " << m_DecimationFactor << " therefore block size = " << getBlockSize() << std::endl;
86 87
87 // Chromagram average and estimated key median filter lengths 88 // Chromagram average and estimated key median filter lengths
88 m_ChromaBuffersize = (int)ceil( m_hpcpAverage * m_ChromaConfig.FS/m_ChromaFrameSize ); 89 m_ChromaBuffersize = (int)ceil( m_hpcpAverage * m_ChromaConfig.FS/m_ChromaFrameSize );
94 m_MedianBufferFilling = 0; 95 m_MedianBufferFilling = 0;
95 96
96 // Spawn objectc/arrays 97 // Spawn objectc/arrays
97 m_DecimatedBuffer = new double[m_ChromaFrameSize]; 98 m_DecimatedBuffer = new double[m_ChromaFrameSize];
98 99
99 m_ChromaBuffer = new double[m_BPO * m_ChromaBuffersize]; 100 m_ChromaBuffer = new double[kBinsPerOctave * m_ChromaBuffersize];
100 memset( m_ChromaBuffer, 0, sizeof(double) * m_BPO * m_ChromaBuffersize); 101 memset( m_ChromaBuffer, 0, sizeof(double) * kBinsPerOctave * m_ChromaBuffersize);
101 102
102 m_MeanHPCP = new double[m_BPO]; 103 m_MeanHPCP = new double[kBinsPerOctave];
103 104
104 m_MajCorr = new double[m_BPO]; 105 m_MajCorr = new double[kBinsPerOctave];
105 m_MinCorr = new double[m_BPO]; 106 m_MinCorr = new double[kBinsPerOctave];
106 m_Keys = new double[2*m_BPO]; 107 m_Keys = new double[2*kBinsPerOctave];
107 108
108 m_MedianFilterBuffer = new int[ m_MedianWinsize ]; 109 m_MedianFilterBuffer = new int[ m_MedianWinsize ];
109 memset( m_MedianFilterBuffer, 0, sizeof(int)*m_MedianWinsize); 110 memset( m_MedianFilterBuffer, 0, sizeof(int)*m_MedianWinsize);
110 111
111 m_SortedBuffer = new int[ m_MedianWinsize ]; 112 m_SortedBuffer = new int[ m_MedianWinsize ];
175 176
176 // The Cromagram has the center of C at bin 0, while the major 177 // The Cromagram has the center of C at bin 0, while the major
177 // and minor profiles have the center of C at 1. We want to have 178 // and minor profiles have the center of C at 1. We want to have
178 // the correlation for C result also at 1. 179 // the correlation for C result also at 1.
179 // To achieve this we have to shift two times: 180 // To achieve this we have to shift two times:
180 MathUtilities::circShift( m_ChrPointer, m_BPO, 2); 181 MathUtilities::circShift( m_ChrPointer, kBinsPerOctave, 2);
181 /* 182 /*
182 std::cout << "raw chroma: "; 183 std::cout << "raw chroma: ";
183 for (int ii = 0; ii < m_BPO; ++ii) { 184 for (int ii = 0; ii < kBinsPerOctave; ++ii) {
184 if (ii % (m_BPO/12) == 0) std::cout << "\n"; 185 if (ii % (kBinsPerOctave/12) == 0) std::cout << "\n";
185 std::cout << m_ChrPointer[ii] << " "; 186 std::cout << m_ChrPointer[ii] << " ";
186 } 187 }
187 std::cout << std::endl; 188 std::cout << std::endl;
188 */ 189 */
189 // populate hpcp values; 190 // populate hpcp values;
190 int cbidx; 191 int cbidx;
191 for( j = 0; j < m_BPO; j++ ) { 192 for( j = 0; j < kBinsPerOctave; j++ ) {
192 cbidx = (m_bufferindex * m_BPO) + j; 193 cbidx = (m_bufferindex * kBinsPerOctave) + j;
193 m_ChromaBuffer[ cbidx ] = m_ChrPointer[j]; 194 m_ChromaBuffer[ cbidx ] = m_ChrPointer[j];
194 } 195 }
195 196
196 //keep track of input buffers; 197 //keep track of input buffers;
197 if( m_bufferindex++ >= m_ChromaBuffersize - 1) { 198 if( m_bufferindex++ >= m_ChromaBuffersize - 1) {
202 if( m_ChromaBufferFilling++ >= m_ChromaBuffersize) { 203 if( m_ChromaBufferFilling++ >= m_ChromaBuffersize) {
203 m_ChromaBufferFilling = m_ChromaBuffersize; 204 m_ChromaBufferFilling = m_ChromaBuffersize;
204 } 205 }
205 206
206 //calculate mean 207 //calculate mean
207 for( k = 0; k < m_BPO; k++ ) { 208 for( k = 0; k < kBinsPerOctave; k++ ) {
208 double mnVal = 0.0; 209 double mnVal = 0.0;
209 for( j = 0; j < m_ChromaBufferFilling; j++ ) { 210 for( j = 0; j < m_ChromaBufferFilling; j++ ) {
210 mnVal += m_ChromaBuffer[ k + (j*m_BPO) ]; 211 mnVal += m_ChromaBuffer[ k + (j*kBinsPerOctave) ];
211 } 212 }
212 213
213 m_MeanHPCP[k] = mnVal/(double)m_ChromaBufferFilling; 214 m_MeanHPCP[k] = mnVal/(double)m_ChromaBufferFilling;
214 } 215 }
215 216
216 217
217 for( k = 0; k < m_BPO; k++ ) { 218 for( k = 0; k < kBinsPerOctave; k++ ) {
218 m_MajCorr[k] = krumCorr( m_MeanHPCP, MajProfile, m_BPO ); 219 m_MajCorr[k] = krumCorr( m_MeanHPCP, MajProfile, kBinsPerOctave );
219 m_MinCorr[k] = krumCorr( m_MeanHPCP, MinProfile, m_BPO ); 220 m_MinCorr[k] = krumCorr( m_MeanHPCP, MinProfile, kBinsPerOctave );
220 221
221 MathUtilities::circShift( MajProfile, m_BPO, 1 ); 222 MathUtilities::circShift( MajProfile, kBinsPerOctave, 1 );
222 MathUtilities::circShift( MinProfile, m_BPO, 1 ); 223 MathUtilities::circShift( MinProfile, kBinsPerOctave, 1 );
223 } 224 }
224 225
225 for( k = 0; k < m_BPO; k++ ) { 226 for( k = 0; k < kBinsPerOctave; k++ ) {
226 m_Keys[k] = m_MajCorr[k]; 227 m_Keys[k] = m_MajCorr[k];
227 m_Keys[k+m_BPO] = m_MinCorr[k]; 228 m_Keys[k+kBinsPerOctave] = m_MinCorr[k];
228 } 229 }
229 230
230 for (k = 0; k < 24; ++k) { 231 for (k = 0; k < 24; ++k) {
231 m_keyStrengths[k] = 0; 232 m_keyStrengths[k] = 0;
232 } 233 }
233 234
234 for( k = 0; k < m_BPO*2; k++ ) { 235 for( k = 0; k < kBinsPerOctave*2; k++ ) {
235 int idx = k / (m_BPO/12); 236 int idx = k / (kBinsPerOctave/12);
236 int rem = k % (m_BPO/12); 237 int rem = k % (kBinsPerOctave/12);
237 if (rem == 0 || m_Keys[k] > m_keyStrengths[idx]) { 238 if (rem == 0 || m_Keys[k] > m_keyStrengths[idx]) {
238 m_keyStrengths[idx] = m_Keys[k]; 239 m_keyStrengths[idx] = m_Keys[k];
239 } 240 }
240 241
241 // m_keyStrengths[k/(m_BPO/12)] += m_Keys[k]; 242 // m_keyStrengths[k/(kBinsPerOctave/12)] += m_Keys[k];
242 } 243 }
243 244
244 /* 245 /*
245 std::cout << "raw keys: "; 246 std::cout << "raw keys: ";
246 for (int ii = 0; ii < 2*m_BPO; ++ii) { 247 for (int ii = 0; ii < 2*kBinsPerOctave; ++ii) {
247 if (ii % (m_BPO/12) == 0) std::cout << "\n"; 248 if (ii % (kBinsPerOctave/12) == 0) std::cout << "\n";
248 std::cout << m_Keys[ii] << " "; 249 std::cout << m_Keys[ii] << " ";
249 } 250 }
250 std::cout << std::endl; 251 std::cout << std::endl;
251 252
252 std::cout << "key strengths: "; 253 std::cout << "key strengths: ";
258 */ 259 */
259 double dummy; 260 double dummy;
260 // m_Keys[1] is C center 1 / 3 + 1 = 1 261 // m_Keys[1] is C center 1 / 3 + 1 = 1
261 // m_Keys[4] is D center 4 / 3 + 1 = 2 262 // m_Keys[4] is D center 4 / 3 + 1 = 2
262 // '+ 1' because we number keys 1-24, not 0-23. 263 // '+ 1' because we number keys 1-24, not 0-23.
263 key = MathUtilities::getMax( m_Keys, 2* m_BPO, &dummy ) / 3 + 1; 264 key = MathUtilities::getMax( m_Keys, 2* kBinsPerOctave, &dummy ) / 3 + 1;
264 265
265 // std::cout << "key pre-sorting: " << key << std::endl; 266 // std::cout << "key pre-sorting: " << key << std::endl;
266 267
267 268
268 //Median filtering 269 //Median filtering
316 317
317 bool GetKeyMode::isModeMinor( int key ) 318 bool GetKeyMode::isModeMinor( int key )
318 { 319 {
319 return (key > 12); 320 return (key > 12);
320 } 321 }
322
323 unsigned int getChromaSize()
324 {
325 return kBinsPerOctave;
326 }