comparison dsp/keydetection/GetKeyMode.cpp @ 240:1a406914b3a9

Change GetKeyMode to number bins with 1 = C, and shift chroma so that notes are centred correctly.
author chriss <devnull@localhost>
date Wed, 21 Nov 2007 16:53:51 +0000
parents ac95b396c8c3
children 2e3f5d2d62c1
comparison
equal deleted inserted replaced
239:135f16b49065 240:1a406914b3a9
9 #include <iostream> 9 #include <iostream>
10 10
11 // Chords profile 11 // Chords profile
12 static double MajProfile[36] = 12 static double MajProfile[36] =
13 { 0.0384, 0.0629, 0.0258, 0.0121, 0.0146, 0.0106, 0.0364, 0.0610, 0.0267, 13 { 0.0384, 0.0629, 0.0258, 0.0121, 0.0146, 0.0106, 0.0364, 0.0610, 0.0267,
14 0.0126, 0.0121, 0.0086, 0.0364, 0.0623, 0.0279, 0.0275, 0.0414, 0.0186, 14 0.0126, 0.0121, 0.0086, 0.0364, 0.0623, 0.0279, 0.0275, 0.0414, 0.0186,
15 0.0173, 0.0248, 0.0145, 0.0364, 0.0631, 0.0262, 0.0129, 0.0150, 0.0098, 15 0.0173, 0.0248, 0.0145, 0.0364, 0.0631, 0.0262, 0.0129, 0.0150, 0.0098,
16 0.0312, 0.0521, 0.0235, 0.0129, 0.0142, 0.0095, 0.0289, 0.0478, 0.0239}; 16 0.0312, 0.0521, 0.0235, 0.0129, 0.0142, 0.0095, 0.0289, 0.0478, 0.0239};
17 17
18 static double MinProfile[36] = 18 static double MinProfile[36] =
19 { 0.0375, 0.0682, 0.0299, 0.0119, 0.0138, 0.0093, 0.0296, 0.0543, 0.0257, 19 { 0.0375, 0.0682, 0.0299, 0.0119, 0.0138, 0.0093, 0.0296, 0.0543, 0.0257,
48 m_ChromaConfig.FS = lrint(sampleRate/(double)m_DecimationFactor); 48 m_ChromaConfig.FS = lrint(sampleRate/(double)m_DecimationFactor);
49 49
50 // m_ChromaConfig.min = 111.0641; 50 // m_ChromaConfig.min = 111.0641;
51 // m_ChromaConfig.max = 1.7770e+003; 51 // m_ChromaConfig.max = 1.7770e+003;
52 52
53 // m_ChromaConfig.min = Pitch::getFrequencyForPitch 53 // Set C (= MIDI #12) as our base :
54 // (12, 0, tuningFrequency); 54 // This implies that key = 1 => Cmaj, key = 12 => Bmaj, key = 13 => Cmin, etc.
55 // m_ChromaConfig.max = Pitch::getFrequencyForPitch 55 m_ChromaConfig.min = Pitch::getFrequencyForPitch
56 // (96, 0, tuningFrequency); 56 (12, 0, tuningFrequency);
57 m_ChromaConfig.max = Pitch::getFrequencyForPitch
58 (96, 0, tuningFrequency);
57 59
58 // The chromagram minimum pitch is 1/6 of a tone above A, two 60 // The chromagram minimum pitch is 1/6 of a tone above A, two
59 // octaves below middle C (for a 36-bin chromagram). The 61 // octaves below middle C (for a 36-bin chromagram). The
60 // maximum pitch is four octaves higher. 62 // maximum pitch is four octaves higher.
61 63 /* m_ChromaConfig.min = Pitch::getFrequencyForPitch
62 m_ChromaConfig.min = Pitch::getFrequencyForPitch
63 (45, 1.f / 3.f, tuningFrequency); 64 (45, 1.f / 3.f, tuningFrequency);
64 65
65 m_ChromaConfig.max = m_ChromaConfig.min * 2; 66 m_ChromaConfig.max = m_ChromaConfig.min * 2;
66 m_ChromaConfig.max = m_ChromaConfig.max * 2; 67 m_ChromaConfig.max = m_ChromaConfig.max * 2;
67 m_ChromaConfig.max = m_ChromaConfig.max * 2; 68 m_ChromaConfig.max = m_ChromaConfig.max * 2;
68 m_ChromaConfig.max = m_ChromaConfig.max * 2; 69 m_ChromaConfig.max = m_ChromaConfig.max * 2;
69 70 */
70 std::cerr << "Chromagram range: " << m_ChromaConfig.min << " -> " << m_ChromaConfig.max << std::endl; 71 std::cerr << "Chromagram range: " << m_ChromaConfig.min << " -> " << m_ChromaConfig.max << std::endl;
71 72
72 m_ChromaConfig.BPO = 36; 73 m_ChromaConfig.BPO = 36;
73 m_ChromaConfig.CQThresh = 0.0054; 74 m_ChromaConfig.CQThresh = 0.0054;
74 75
168 ////////////////////////////////////////////// 169 //////////////////////////////////////////////
169 m_Decimator->process( PCMData, m_DecimatedBuffer); 170 m_Decimator->process( PCMData, m_DecimatedBuffer);
170 171
171 m_ChrPointer = m_Chroma->process( m_DecimatedBuffer ); 172 m_ChrPointer = m_Chroma->process( m_DecimatedBuffer );
172 173
174
175 // Move bins such that the centre of the base note is in the middle of its three bins :
176 // Added 21.11.07 by Chris Sutton based on debugging with Katy Noland + comparison with Matlab equivalent.
177 MathUtilities::circShift( m_ChrPointer, m_BPO, 1);
178
173 std::cout << "raw chroma: "; 179 std::cout << "raw chroma: ";
174 for (int ii = 0; ii < m_BPO; ++ii) { 180 for (int ii = 0; ii < m_BPO; ++ii) {
175 std::cout << m_ChrPointer[ii] << " "; 181 std::cout << m_ChrPointer[ii] << " ";
176 } 182 }
177 std::cout << std::endl; 183 std::cout << std::endl;
211 m_MinCorr[k] = krumCorr( m_MeanHPCP, MinProfile, m_BPO ); 217 m_MinCorr[k] = krumCorr( m_MeanHPCP, MinProfile, m_BPO );
212 218
213 MathUtilities::circShift( MajProfile, m_BPO, 1 ); 219 MathUtilities::circShift( MajProfile, m_BPO, 1 );
214 MathUtilities::circShift( MinProfile, m_BPO, 1 ); 220 MathUtilities::circShift( MinProfile, m_BPO, 1 );
215 } 221 }
216 222
217 for( k = 0; k < m_BPO; k++ ) 223 for( k = 0; k < m_BPO; k++ )
218 { 224 {
219 m_Keys[k] = m_MajCorr[k]; 225 m_Keys[k] = m_MajCorr[k];
220 m_Keys[k+m_BPO] = m_MinCorr[k]; 226 m_Keys[k+m_BPO] = m_MinCorr[k];
221 } 227 }
222 /* 228
229
223 std::cout << "raw keys: "; 230 std::cout << "raw keys: ";
224 for (int ii = 0; ii < 2*m_BPO; ++ii) { 231 for (int ii = 0; ii < 2*m_BPO; ++ii) {
225 std::cout << m_Keys[ii] << " "; 232 std::cout << m_Keys[ii] << " ";
226 } 233 }
227 std::cout << std::endl; 234 std::cout << std::endl;
228 */ 235
229 double dummy; 236 double dummy;
230 key = /*1 +*/ (int)ceil( (double)MathUtilities::getMax( m_Keys, 2* m_BPO, &dummy )/3 ); 237 // '1 +' because we number keys 1-24, not 0-23.
231 238 key = 1 + (int)ceil( (double)MathUtilities::getMax( m_Keys, 2* m_BPO, &dummy )/3 );
232 // std::cout << "key pre-sorting: " << key << std::endl; 239
240 std::cout << "key pre-sorting: " << key << std::endl;
233 241
234 242
235 //Median filtering 243 //Median filtering
236 244
237 // track Median buffer initial filling 245 // track Median buffer initial filling
257 } 265 }
258 266
259 267
260 //quicksort 268 //quicksort
261 qsort(m_SortedBuffer, m_MedianBufferFilling, sizeof(unsigned int), MathUtilities::compareInt); 269 qsort(m_SortedBuffer, m_MedianBufferFilling, sizeof(unsigned int), MathUtilities::compareInt);
262 /* 270
263 std::cout << "sorted: "; 271 std::cout << "sorted: ";
264 for (int ii = 0; ii < m_MedianBufferFilling; ++ii) { 272 for (int ii = 0; ii < m_MedianBufferFilling; ++ii) {
265 std::cout << m_SortedBuffer[ii] << " "; 273 std::cout << m_SortedBuffer[ii] << " ";
266 } 274 }
267 std::cout << std::endl; 275 std::cout << std::endl;
268 */ 276
269 int sortlength = m_MedianBufferFilling; 277 int sortlength = m_MedianBufferFilling;
270 int midpoint = (int)ceil((double)sortlength/2); 278 int midpoint = (int)ceil((double)sortlength/2);
271 279
272 if( midpoint <= 0 ) 280 if( midpoint <= 0 )
273 midpoint = 1; 281 midpoint = 1;