comparison dsp/keydetection/GetKeyMode.cpp @ 499:af5b7ef02aa7

Style fixes: avoid unsigned, fix formatting
author Chris Cannam <cannam@all-day-breakfast.com>
date Mon, 03 Jun 2019 14:20:39 +0100
parents c92718cc6ef1
children 3f0a96460c33
comparison
equal deleted inserted replaced
498:8b92623e81c9 499:af5b7ef02aa7
29 // Chords profile 29 // Chords profile
30 static double MajProfile[kBinsPerOctave] = { 30 static double MajProfile[kBinsPerOctave] = {
31 0.0384, 0.0629, 0.0258, 0.0121, 0.0146, 0.0106, 0.0364, 0.0610, 0.0267, 31 0.0384, 0.0629, 0.0258, 0.0121, 0.0146, 0.0106, 0.0364, 0.0610, 0.0267,
32 0.0126, 0.0121, 0.0086, 0.0364, 0.0623, 0.0279, 0.0275, 0.0414, 0.0186, 32 0.0126, 0.0121, 0.0086, 0.0364, 0.0623, 0.0279, 0.0275, 0.0414, 0.0186,
33 0.0173, 0.0248, 0.0145, 0.0364, 0.0631, 0.0262, 0.0129, 0.0150, 0.0098, 33 0.0173, 0.0248, 0.0145, 0.0364, 0.0631, 0.0262, 0.0129, 0.0150, 0.0098,
34 0.0312, 0.0521, 0.0235, 0.0129, 0.0142, 0.0095, 0.0289, 0.0478, 0.0239}; 34 0.0312, 0.0521, 0.0235, 0.0129, 0.0142, 0.0095, 0.0289, 0.0478, 0.0239
35 };
35 36
36 static double MinProfile[kBinsPerOctave] = { 37 static double MinProfile[kBinsPerOctave] = {
37 0.0375, 0.0682, 0.0299, 0.0119, 0.0138, 0.0093, 0.0296, 0.0543, 0.0257, 38 0.0375, 0.0682, 0.0299, 0.0119, 0.0138, 0.0093, 0.0296, 0.0543, 0.0257,
38 0.0292, 0.0519, 0.0246, 0.0159, 0.0234, 0.0135, 0.0291, 0.0544, 0.0248, 39 0.0292, 0.0519, 0.0246, 0.0159, 0.0234, 0.0135, 0.0291, 0.0544, 0.0248,
39 0.0137, 0.0176, 0.0104, 0.0352, 0.0670, 0.0302, 0.0222, 0.0349, 0.0164, 40 0.0137, 0.0176, 0.0104, 0.0352, 0.0670, 0.0302, 0.0222, 0.0349, 0.0164,
40 0.0174, 0.0297, 0.0166, 0.0222, 0.0401, 0.0202, 0.0175, 0.0270, 0.0146}; 41 0.0174, 0.0297, 0.0166, 0.0222, 0.0401, 0.0202, 0.0175, 0.0270, 0.0146
42 };
41 // 43 //
42 44
43 45
44 ////////////////////////////////////////////////////////////////////// 46 //////////////////////////////////////////////////////////////////////
45 // Construction/Destruction 47 // Construction/Destruction
47 49
48 GetKeyMode::GetKeyMode( int sampleRate, float tuningFrequency, 50 GetKeyMode::GetKeyMode( int sampleRate, float tuningFrequency,
49 double hpcpAverage, double medianAverage ) : 51 double hpcpAverage, double medianAverage ) :
50 m_hpcpAverage( hpcpAverage ), 52 m_hpcpAverage( hpcpAverage ),
51 m_medianAverage( medianAverage ), 53 m_medianAverage( medianAverage ),
52 m_ChrPointer(0), 54 m_chrPointer(0),
53 m_DecimatedBuffer(0), 55 m_decimatedBuffer(0),
54 m_ChromaBuffer(0), 56 m_chromaBuffer(0),
55 m_MeanHPCP(0), 57 m_meanHPCP(0),
56 m_MajCorr(0), 58 m_majCorr(0),
57 m_MinCorr(0), 59 m_minCorr(0),
58 m_MedianFilterBuffer(0), 60 m_medianFilterBuffer(0),
59 m_SortedBuffer(0), 61 m_sortedBuffer(0),
60 m_keyStrengths(0) 62 m_keyStrengths(0)
61 { 63 {
62 m_DecimationFactor = 8; 64 m_decimationFactor = 8;
63 65
64 // Chromagram configuration parameters 66 // Chromagram configuration parameters
65 m_ChromaConfig.normalise = MathUtilities::NormaliseUnitMax; 67 m_chromaConfig.normalise = MathUtilities::NormaliseUnitMax;
66 m_ChromaConfig.FS = sampleRate/(double)m_DecimationFactor; 68 m_chromaConfig.FS = sampleRate / (double)m_decimationFactor;
67 if (m_ChromaConfig.FS < 1) { 69 if (m_chromaConfig.FS < 1) {
68 m_ChromaConfig.FS = 1; 70 m_chromaConfig.FS = 1;
69 } 71 }
70 72
71 // Set C3 (= MIDI #48) as our base: 73 // Set C3 (= MIDI #48) as our base:
72 // This implies that key = 1 => Cmaj, key = 12 => Bmaj, key = 13 => Cmin, etc. 74 // This implies that key = 1 => Cmaj, key = 12 => Bmaj, key = 13 => Cmin, etc.
73 m_ChromaConfig.min = Pitch::getFrequencyForPitch( 48, 0, tuningFrequency ); 75 m_chromaConfig.min = Pitch::getFrequencyForPitch( 48, 0, tuningFrequency );
74 m_ChromaConfig.max = Pitch::getFrequencyForPitch( 96, 0, tuningFrequency ); 76 m_chromaConfig.max = Pitch::getFrequencyForPitch( 96, 0, tuningFrequency );
75 77
76 m_ChromaConfig.BPO = kBinsPerOctave; 78 m_chromaConfig.BPO = kBinsPerOctave;
77 m_ChromaConfig.CQThresh = 0.0054; 79 m_chromaConfig.CQThresh = 0.0054;
78 80
79 // Chromagram inst. 81 // Chromagram inst.
80 m_Chroma = new Chromagram( m_ChromaConfig ); 82 m_chroma = new Chromagram( m_chromaConfig );
81 83
82 // Get calculated parameters from chroma object 84 // Get calculated parameters from chroma object
83 m_ChromaFrameSize = m_Chroma->getFrameSize(); 85 m_chromaFrameSize = m_chroma->getFrameSize();
84 // override hopsize for this application 86 // override hopsize for this application
85 m_ChromaHopSize = m_ChromaFrameSize; 87 m_chromaHopSize = m_chromaFrameSize;
86 88
87 // std::cerr << "chroma frame size = " << m_ChromaFrameSize << ", decimation factor = " << m_DecimationFactor << " therefore block size = " << getBlockSize() << std::endl; 89 // std::cerr << "chroma frame size = " << m_ChromaFrameSize << ", decimation factor = " << m_DecimationFactor << " therefore block size = " << getBlockSize() << std::endl;
88 90
89 // Chromagram average and estimated key median filter lengths 91 // Chromagram average and estimated key median filter lengths
90 m_ChromaBuffersize = (int)ceil( m_hpcpAverage * m_ChromaConfig.FS/m_ChromaFrameSize ); 92 m_chromaBufferSize = (int)ceil
91 m_MedianWinsize = (int)ceil( m_medianAverage * m_ChromaConfig.FS/m_ChromaFrameSize ); 93 (m_hpcpAverage * m_chromaConfig.FS / m_chromaFrameSize);
94 m_medianWinSize = (int)ceil
95 (m_medianAverage * m_chromaConfig.FS / m_chromaFrameSize);
92 96
93 // Reset counters 97 // Reset counters
94 m_bufferindex = 0; 98 m_bufferIndex = 0;
95 m_ChromaBufferFilling = 0; 99 m_chromaBufferFilling = 0;
96 m_MedianBufferFilling = 0; 100 m_medianBufferFilling = 0;
97 101
98 // Spawn objectc/arrays 102 // Spawn objectc/arrays
99 m_DecimatedBuffer = new double[m_ChromaFrameSize]; 103 m_decimatedBuffer = new double[m_chromaFrameSize];
100 104 m_chromaBuffer = new double[kBinsPerOctave * m_chromaBufferSize];
101 m_ChromaBuffer = new double[kBinsPerOctave * m_ChromaBuffersize]; 105
102 memset( m_ChromaBuffer, 0, sizeof(double) * kBinsPerOctave * m_ChromaBuffersize); 106 memset(m_chromaBuffer, 0,
103 107 sizeof(double) * kBinsPerOctave * m_chromaBufferSize);
104 m_MeanHPCP = new double[kBinsPerOctave]; 108
105 109 m_meanHPCP = new double[kBinsPerOctave];
106 m_MajCorr = new double[kBinsPerOctave]; 110
107 m_MinCorr = new double[kBinsPerOctave]; 111 m_majCorr = new double[kBinsPerOctave];
108 112 m_minCorr = new double[kBinsPerOctave];
109 m_MajProfileNorm = new double[kBinsPerOctave]; 113
110 m_MinProfileNorm = new double[kBinsPerOctave]; 114 m_majProfileNorm = new double[kBinsPerOctave];
115 m_minProfileNorm = new double[kBinsPerOctave];
111 116
112 double mMaj = MathUtilities::mean( MajProfile, kBinsPerOctave ); 117 double mMaj = MathUtilities::mean( MajProfile, kBinsPerOctave );
113 double mMin = MathUtilities::mean( MinProfile, kBinsPerOctave ); 118 double mMin = MathUtilities::mean( MinProfile, kBinsPerOctave );
114 119
115 for( unsigned int i = 0; i < kBinsPerOctave; i++ ) { 120 for (int i = 0; i < kBinsPerOctave; i++) {
116 m_MajProfileNorm[i] = MajProfile[i] - mMaj; 121 m_majProfileNorm[i] = MajProfile[i] - mMaj;
117 m_MinProfileNorm[i] = MinProfile[i] - mMin; 122 m_minProfileNorm[i] = MinProfile[i] - mMin;
118 } 123 }
119 124
120 m_MedianFilterBuffer = new int[ m_MedianWinsize ]; 125 m_medianFilterBuffer = new int[ m_medianWinSize ];
121 memset( m_MedianFilterBuffer, 0, sizeof(int)*m_MedianWinsize); 126 memset( m_medianFilterBuffer, 0, sizeof(int)*m_medianWinSize);
122 127
123 m_SortedBuffer = new int[ m_MedianWinsize ]; 128 m_sortedBuffer = new int[ m_medianWinSize ];
124 memset( m_SortedBuffer, 0, sizeof(int)*m_MedianWinsize); 129 memset( m_sortedBuffer, 0, sizeof(int)*m_medianWinSize);
125 130
126 m_Decimator = new Decimator( m_ChromaFrameSize*m_DecimationFactor, m_DecimationFactor ); 131 m_decimator = new Decimator( m_chromaFrameSize * m_decimationFactor,
132 m_decimationFactor );
127 133
128 m_keyStrengths = new double[24]; 134 m_keyStrengths = new double[24];
129 } 135 }
130 136
131 GetKeyMode::~GetKeyMode() 137 GetKeyMode::~GetKeyMode()
132 { 138 {
133 delete m_Chroma; 139 delete m_chroma;
134 delete m_Decimator; 140 delete m_decimator;
135 141
136 delete [] m_DecimatedBuffer; 142 delete [] m_decimatedBuffer;
137 delete [] m_ChromaBuffer; 143 delete [] m_chromaBuffer;
138 delete [] m_MeanHPCP; 144 delete [] m_meanHPCP;
139 delete [] m_MajCorr; 145 delete [] m_majCorr;
140 delete [] m_MinCorr; 146 delete [] m_minCorr;
141 delete [] m_MajProfileNorm; 147 delete [] m_majProfileNorm;
142 delete [] m_MinProfileNorm; 148 delete [] m_minProfileNorm;
143 delete [] m_MedianFilterBuffer; 149 delete [] m_medianFilterBuffer;
144 delete [] m_SortedBuffer; 150 delete [] m_sortedBuffer;
145 delete [] m_keyStrengths; 151 delete [] m_keyStrengths;
146 } 152 }
147 153
148 double GetKeyMode::krumCorr( const double *pDataNorm, const double *pProfileNorm, 154 double GetKeyMode::krumCorr( const double *pDataNorm, const double *pProfileNorm,
149 int shiftProfile, unsigned int length) 155 int shiftProfile, int length)
150 { 156 {
151 double retVal= 0.0; 157 double retVal= 0.0;
152 158
153 double num = 0; 159 double num = 0;
154 double den = 0; 160 double den = 0;
155 double sum1 = 0; 161 double sum1 = 0;
156 double sum2 = 0; 162 double sum2 = 0;
157 163
158 for( unsigned int i = 0; i <length; i++ ) { 164 for (int i = 0; i < length; i++) {
159 165
160 int k = (i - shiftProfile + length) % length; 166 int k = (i - shiftProfile + length) % length;
161 167
162 num += pDataNorm[i] * pProfileNorm[k]; 168 num += pDataNorm[i] * pProfileNorm[k];
163 169
164 sum1 += ( pDataNorm[i] * pDataNorm[i] ); 170 sum1 += (pDataNorm[i] * pDataNorm[i]);
165 sum2 += ( pProfileNorm[k] * pProfileNorm[k] ); 171 sum2 += (pProfileNorm[k] * pProfileNorm[k]);
166 } 172 }
167 173
168 den = sqrt(sum1 * sum2); 174 den = sqrt(sum1 * sum2);
169 175
170 if( den>0 ) { 176 if (den > 0) {
171 retVal = num/den; 177 retVal = num/den;
172 } else { 178 } else {
173 retVal = 0; 179 retVal = 0;
174 } 180 }
175 181
176 return retVal; 182 return retVal;
177 } 183 }
178 184
179 int GetKeyMode::process(double *PCMData) 185 int GetKeyMode::process(double *pcmData)
180 { 186 {
181 int key; 187 int key;
182 unsigned int j,k; 188 int j, k;
183 189
184 m_Decimator->process( PCMData, m_DecimatedBuffer); 190 m_decimator->process(pcmData, m_decimatedBuffer);
185 191
186 m_ChrPointer = m_Chroma->process( m_DecimatedBuffer ); 192 m_chrPointer = m_chroma->process(m_decimatedBuffer);
187 193
188 // populate hpcp values; 194 // populate hpcp values
189 int cbidx; 195 int cbidx;
190 for( j = 0; j < kBinsPerOctave; j++ ) { 196 for (j = 0;j < kBinsPerOctave;j++ ) {
191 cbidx = (m_bufferindex * kBinsPerOctave) + j; 197 cbidx = (m_bufferIndex * kBinsPerOctave) + j;
192 m_ChromaBuffer[ cbidx ] = m_ChrPointer[j]; 198 m_chromaBuffer[ cbidx ] = m_chrPointer[j];
193 } 199 }
194 200
195 //keep track of input buffers; 201 // keep track of input buffers
196 if( m_bufferindex++ >= m_ChromaBuffersize - 1) { 202 if (m_bufferIndex++ >= m_chromaBufferSize - 1) {
197 m_bufferindex = 0; 203 m_bufferIndex = 0;
198 } 204 }
199 205
200 // track filling of chroma matrix 206 // track filling of chroma matrix
201 if( m_ChromaBufferFilling++ >= m_ChromaBuffersize) { 207 if (m_chromaBufferFilling++ >= m_chromaBufferSize) {
202 m_ChromaBufferFilling = m_ChromaBuffersize; 208 m_chromaBufferFilling = m_chromaBufferSize;
203 } 209 }
204 210
205 //calculate mean 211 // calculate mean
206 for( k = 0; k < kBinsPerOctave; k++ ) { 212 for (k = 0; k < kBinsPerOctave; k++) {
207 double mnVal = 0.0; 213 double mnVal = 0.0;
208 for( j = 0; j < m_ChromaBufferFilling; j++ ) { 214 for (j = 0; j < m_chromaBufferFilling; j++) {
209 mnVal += m_ChromaBuffer[ k + (j*kBinsPerOctave) ]; 215 mnVal += m_chromaBuffer[ k + (j * kBinsPerOctave) ];
210 } 216 }
211 217
212 m_MeanHPCP[k] = mnVal/(double)m_ChromaBufferFilling; 218 m_meanHPCP[k] = mnVal / (double)m_chromaBufferFilling;
213 } 219 }
214 220
215 // Normalize for zero average 221 // Normalize for zero average
216 double mHPCP = MathUtilities::mean( m_MeanHPCP, kBinsPerOctave ); 222 double mHPCP = MathUtilities::mean(m_meanHPCP, kBinsPerOctave);
217 for( k = 0; k < kBinsPerOctave; k++ ) { 223 for (k = 0; k < kBinsPerOctave; k++) {
218 m_MeanHPCP[k] -= mHPCP; 224 m_meanHPCP[k] -= mHPCP;
219 } 225 }
220 226
221 for( k = 0; k < kBinsPerOctave; k++ ) { 227 for (k = 0; k < kBinsPerOctave; k++) {
222 // The Chromagram has the center of C at bin 0, while the major 228 // The Chromagram has the center of C at bin 0, while the major
223 // and minor profiles have the center of C at 1. We want to have 229 // and minor profiles have the center of C at 1. We want to have
224 // the correlation for C result also at 1. 230 // the correlation for C result also at 1.
225 // To achieve this we have to shift two times: 231 // To achieve this we have to shift two times:
226 m_MajCorr[k] = krumCorr( m_MeanHPCP, m_MajProfileNorm, (int)k - 2, kBinsPerOctave ); 232 m_majCorr[k] = krumCorr
227 m_MinCorr[k] = krumCorr( m_MeanHPCP, m_MinProfileNorm, (int)k - 2, kBinsPerOctave ); 233 (m_meanHPCP, m_majProfileNorm, k - 2, kBinsPerOctave);
234 m_minCorr[k] = krumCorr
235 (m_meanHPCP, m_minProfileNorm, k - 2, kBinsPerOctave);
228 } 236 }
229 237
230 // m_MajCorr[1] is C center 1 / 3 + 1 = 1 238 // m_MajCorr[1] is C center 1 / 3 + 1 = 1
231 // m_MajCorr[4] is D center 4 / 3 + 1 = 2 239 // m_MajCorr[4] is D center 4 / 3 + 1 = 2
232 // '+ 1' because we number keys 1-24, not 0-23. 240 // '+ 1' because we number keys 1-24, not 0-23.
233 double maxMaj; 241 double maxMaj;
234 int maxMajBin = MathUtilities::getMax( m_MajCorr, kBinsPerOctave, &maxMaj ); 242 int maxMajBin = MathUtilities::getMax(m_majCorr, kBinsPerOctave, &maxMaj);
235 double maxMin; 243 double maxMin;
236 int maxMinBin = MathUtilities::getMax( m_MinCorr, kBinsPerOctave, &maxMin ); 244 int maxMinBin = MathUtilities::getMax(m_minCorr, kBinsPerOctave, &maxMin);
237 int maxBin = (maxMaj > maxMin) ? maxMajBin : (maxMinBin + kBinsPerOctave); 245 int maxBin = (maxMaj > maxMin) ? maxMajBin : (maxMinBin + kBinsPerOctave);
238 key = maxBin / 3 + 1; 246 key = maxBin / 3 + 1;
239 247
240 //Median filtering 248 // Median filtering
241 249
242 // track Median buffer initial filling 250 // track Median buffer initial filling
243 if( m_MedianBufferFilling++ >= m_MedianWinsize) { 251 if (m_medianBufferFilling++ >= m_medianWinSize) {
244 m_MedianBufferFilling = m_MedianWinsize; 252 m_medianBufferFilling = m_medianWinSize;
245 } 253 }
246 254
247 //shift median buffer 255 // shift median buffer
248 for( k = 1; k < m_MedianWinsize; k++ ) { 256 for (k = 1; k < m_medianWinSize; k++ ) {
249 m_MedianFilterBuffer[ k - 1 ] = m_MedianFilterBuffer[ k ]; 257 m_medianFilterBuffer[ k - 1 ] = m_medianFilterBuffer[ k ];
250 } 258 }
251 259
252 //write new key value into median buffer 260 // write new key value into median buffer
253 m_MedianFilterBuffer[ m_MedianWinsize - 1 ] = key; 261 m_medianFilterBuffer[ m_medianWinSize - 1 ] = key;
254 262
255 263 // copy median into sorting buffer, reversed
256 //Copy median into sorting buffer, reversed 264 int ijx = 0;
257 unsigned int ijx = 0; 265 for (k = 0; k < m_medianWinSize; k++) {
258 for( k = 0; k < m_MedianWinsize; k++ ) { 266 m_sortedBuffer[k] = m_medianFilterBuffer[m_medianWinSize - 1 - ijx];
259 m_SortedBuffer[k] = m_MedianFilterBuffer[m_MedianWinsize-1-ijx];
260 ijx++; 267 ijx++;
261 } 268 }
262 269
263 qsort(m_SortedBuffer, m_MedianBufferFilling, sizeof(unsigned int), 270 qsort(m_sortedBuffer, m_medianBufferFilling, sizeof(int),
264 MathUtilities::compareInt); 271 MathUtilities::compareInt);
265 272
266 int sortlength = m_MedianBufferFilling; 273 int sortlength = m_medianBufferFilling;
267 int midpoint = (int)ceil((double)sortlength/2); 274 int midpoint = (int)ceil((double)sortlength / 2);
268 275
269 if( midpoint <= 0 ) { 276 if (midpoint <= 0) {
270 midpoint = 1; 277 midpoint = 1;
271 } 278 }
272 279
273 key = m_SortedBuffer[midpoint-1]; 280 key = m_sortedBuffer[midpoint-1];
274 281
275 return key; 282 return key;
276 } 283 }
277 284
278 285
279 bool GetKeyMode::isModeMinor( int key ) 286 bool GetKeyMode::isModeMinor( int key )
280 { 287 {
281 return (key > 12); 288 return (key > 12);
282 } 289 }
283 290
284 unsigned int getChromaSize() 291 int GetKeyMode::getChromaSize()
285 { 292 {
286 return kBinsPerOctave; 293 return kBinsPerOctave;
287 } 294 }
288 295
289 double* GetKeyMode::getKeyStrengths() { 296 double* GetKeyMode::getKeyStrengths() {
290 unsigned int k; 297 int k;
291 298
292 for (k = 0; k < 24; ++k) { 299 for (k = 0; k < 24; ++k) {
293 m_keyStrengths[k] = 0; 300 m_keyStrengths[k] = 0;
294 } 301 }
295 302
296 for( k = 0; k < kBinsPerOctave; k++ ) { 303 for (k = 0; k < kBinsPerOctave; k++) {
297 int idx = k / (kBinsPerOctave/12); 304 int idx = k / (kBinsPerOctave/12);
298 int rem = k % (kBinsPerOctave/12); 305 int rem = k % (kBinsPerOctave/12);
299 if (rem == 0 || m_MajCorr[k] > m_keyStrengths[idx]) { 306 if (rem == 0 || m_majCorr[k] > m_keyStrengths[idx]) {
300 m_keyStrengths[idx] = m_MajCorr[k]; 307 m_keyStrengths[idx] = m_majCorr[k];
301 } 308 }
302 } 309 }
303 310
304 for( k = 0; k < kBinsPerOctave; k++ ) { 311 for (k = 0; k < kBinsPerOctave; k++) {
305 int idx = (k + kBinsPerOctave) / (kBinsPerOctave/12); 312 int idx = (k + kBinsPerOctave) / (kBinsPerOctave/12);
306 int rem = k % (kBinsPerOctave/12); 313 int rem = k % (kBinsPerOctave/12);
307 if (rem == 0 || m_MinCorr[k] > m_keyStrengths[idx]) { 314 if (rem == 0 || m_minCorr[k] > m_keyStrengths[idx]) {
308 m_keyStrengths[idx] = m_MinCorr[k]; 315 m_keyStrengths[idx] = m_minCorr[k];
309 } 316 }
310 } 317 }
311 318
312 return m_keyStrengths; 319 return m_keyStrengths;
313 } 320 }