comparison SimpleCepstrum.cpp @ 23:1ae8041ae31b

Merge from branch "track"
author Chris Cannam
date Thu, 05 Jul 2012 08:29:20 +0100
parents 7786d595d2f2
children 0a3c1ecff644
comparison
equal deleted inserted replaced
7:47355877a58d 23:1ae8041ae31b
36 m_channels(0), 36 m_channels(0),
37 m_stepSize(256), 37 m_stepSize(256),
38 m_blockSize(1024), 38 m_blockSize(1024),
39 m_fmin(50), 39 m_fmin(50),
40 m_fmax(1000), 40 m_fmax(1000),
41 m_histlen(3), 41 m_histlen(1),
42 m_vflen(1),
42 m_clamp(false), 43 m_clamp(false),
43 m_method(InverseSymmetric), 44 m_method(InverseSymmetric),
44 m_binFrom(0), 45 m_binFrom(0),
45 m_binTo(0), 46 m_binTo(0),
46 m_bins(0), 47 m_bins(0),
157 d.name = "Mean filter history length"; 158 d.name = "Mean filter history length";
158 d.description = ""; 159 d.description = "";
159 d.unit = ""; 160 d.unit = "";
160 d.minValue = 1; 161 d.minValue = 1;
161 d.maxValue = 10; 162 d.maxValue = 10;
162 d.defaultValue = 3; 163 d.defaultValue = 1;
163 d.isQuantized = true; 164 d.isQuantized = true;
164 d.quantizeStep = 1; 165 d.quantizeStep = 1;
166 list.push_back(d);
167
168 d.identifier = "vflen";
169 d.name = "Vertical filter length";
170 d.description = "";
171 d.unit = "";
172 d.minValue = 1;
173 d.maxValue = 11;
174 d.defaultValue = 1;
175 d.isQuantized = true;
176 d.quantizeStep = 2;
165 list.push_back(d); 177 list.push_back(d);
166 178
167 d.identifier = "method"; 179 d.identifier = "method";
168 d.name = "Cepstrum transform method"; 180 d.name = "Cepstrum transform method";
169 d.unit = ""; 181 d.unit = "";
197 SimpleCepstrum::getParameter(string identifier) const 209 SimpleCepstrum::getParameter(string identifier) const
198 { 210 {
199 if (identifier == "fmin") return m_fmin; 211 if (identifier == "fmin") return m_fmin;
200 else if (identifier == "fmax") return m_fmax; 212 else if (identifier == "fmax") return m_fmax;
201 else if (identifier == "histlen") return m_histlen; 213 else if (identifier == "histlen") return m_histlen;
214 else if (identifier == "vflen") return m_vflen;
202 else if (identifier == "clamp") return (m_clamp ? 1 : 0); 215 else if (identifier == "clamp") return (m_clamp ? 1 : 0);
203 else if (identifier == "method") return (int)m_method; 216 else if (identifier == "method") return (int)m_method;
204 else return 0.f; 217 else return 0.f;
205 } 218 }
206 219
208 SimpleCepstrum::setParameter(string identifier, float value) 221 SimpleCepstrum::setParameter(string identifier, float value)
209 { 222 {
210 if (identifier == "fmin") m_fmin = value; 223 if (identifier == "fmin") m_fmin = value;
211 else if (identifier == "fmax") m_fmax = value; 224 else if (identifier == "fmax") m_fmax = value;
212 else if (identifier == "histlen") m_histlen = value; 225 else if (identifier == "histlen") m_histlen = value;
226 else if (identifier == "vflen") m_vflen = value;
213 else if (identifier == "clamp") m_clamp = (value > 0.5); 227 else if (identifier == "clamp") m_clamp = (value > 0.5);
214 else if (identifier == "method") m_method = Method(int(value + 0.5)); 228 else if (identifier == "method") m_method = Method(int(value + 0.5));
215 } 229 }
216 230
217 SimpleCepstrum::ProgramList 231 SimpleCepstrum::ProgramList
263 d.hasKnownExtents = false; 277 d.hasKnownExtents = false;
264 m_varOutput = n++; 278 m_varOutput = n++;
265 outputs.push_back(d); 279 outputs.push_back(d);
266 280
267 d.identifier = "peak"; 281 d.identifier = "peak";
268 d.name = "Peak value"; 282 d.name = "Value at peak";
269 d.unit = ""; 283 d.unit = "";
270 d.description = "Return the value found in the maximum-valued bin within the specified range of the cepstrum"; 284 d.description = "Return the value found in the maximum-valued bin within the specified range of the cepstrum";
271 m_pvOutput = n++; 285 m_pvOutput = n++;
272 outputs.push_back(d); 286 outputs.push_back(d);
273 287
281 d.identifier = "peak_proportion"; 295 d.identifier = "peak_proportion";
282 d.name = "Energy around peak"; 296 d.name = "Energy around peak";
283 d.unit = ""; 297 d.unit = "";
284 d.description = "Return the proportion of total energy that is found in the bins around the peak bin (as far as the nearest local minima), within the specified range of the cepstrum"; 298 d.description = "Return the proportion of total energy that is found in the bins around the peak bin (as far as the nearest local minima), within the specified range of the cepstrum";
285 m_ppOutput = n++; 299 m_ppOutput = n++;
300 outputs.push_back(d);
301
302 d.identifier = "peak_to_second_peak";
303 d.name = "Peak to second-peak ratio";
304 d.unit = "";
305 d.description = "Return the ratio of the value found in the peak bin within the specified range of the cepstrum, to the value found in the next highest peak";
306 m_pkoOutput = n++;
286 outputs.push_back(d); 307 outputs.push_back(d);
287 308
288 d.identifier = "total"; 309 d.identifier = "total";
289 d.name = "Total energy"; 310 d.name = "Total energy";
290 d.unit = ""; 311 d.unit = "";
400 // and stick this back in the newest spot, to recycle 421 // and stick this back in the newest spot, to recycle
401 m_history[hix] = oldest; 422 m_history[hix] = oldest;
402 } 423 }
403 424
404 for (int i = 0; i < m_bins; ++i) { 425 for (int i = 0; i < m_bins; ++i) {
405 m_history[hix][i] = cep[i + m_binFrom]; 426 double v = 0;
427 int n = 0;
428 // average according to the vertical filter length
429 for (int j = -m_vflen/2; j <= m_vflen/2; ++j) {
430 int ix = i + m_binFrom + j;
431 if (ix >= 0 && ix < m_blockSize) {
432 v += cep[ix];
433 ++n;
434 }
435 }
436 m_history[hix][i] = v / n;
406 } 437 }
407 438
408 for (int i = 0; i < m_bins; ++i) { 439 for (int i = 0; i < m_bins; ++i) {
409 double mean = 0.0; 440 double mean = 0.0;
410 for (int j = 0; j < m_histlen; ++j) { 441 for (int j = 0; j < m_histlen; ++j) {
425 456
426 for (int i = 0; i < n; ++i) { 457 for (int i = 0; i < n; ++i) {
427 if (data[i] > maxval) { 458 if (data[i] > maxval) {
428 maxval = data[i]; 459 maxval = data[i];
429 maxbin = i; 460 maxbin = i;
461 }
462 }
463
464 double nextPeakVal = 0.0;
465
466 for (int i = 1; i+1 < n; ++i) {
467 if (data[i] > data[i-1] &&
468 data[i] > data[i+1] &&
469 i != maxbin &&
470 data[i] > nextPeakVal) {
471 nextPeakVal = data[i];
430 } 472 }
431 } 473 }
432 474
433 Feature rf; 475 Feature rf;
434 if (maxval > 0.0) { 476 if (maxval > 0.0) {
448 fs[m_totOutput].push_back(tot); 490 fs[m_totOutput].push_back(tot);
449 491
450 double mean = total / n; 492 double mean = total / n;
451 493
452 double totsqr = 0; 494 double totsqr = 0;
495 double abstot = 0;
453 for (int i = 0; i < n; ++i) { 496 for (int i = 0; i < n; ++i) {
454 totsqr += data[i] * data[i]; 497 totsqr += data[i] * data[i];
498 abstot += fabs(data[i]);
455 } 499 }
456 double rms = sqrt(totsqr / n); 500 double rms = sqrt(totsqr / n);
457 501
458 double variance = 0; 502 double variance = 0;
459 for (int i = 0; i < n; ++i) { 503 for (int i = 0; i < n; ++i) {
475 while (i < n && data[i] <= data[i-1]) { 519 while (i < n && data[i] <= data[i-1]) {
476 aroundPeak += fabs(data[i]); 520 aroundPeak += fabs(data[i]);
477 ++i; 521 ++i;
478 } 522 }
479 } 523 }
480 peakProportion = aroundPeak / sqrt(totsqr); 524 peakProportion = aroundPeak / abstot;
481 Feature pp; 525 Feature pp;
482 pp.values.push_back(peakProportion); 526 pp.values.push_back(peakProportion);
483 fs[m_ppOutput].push_back(pp); 527 fs[m_ppOutput].push_back(pp);
484 528
485 Feature vf; 529 Feature vf;
491 fs[m_p2rOutput].push_back(pr); 535 fs[m_p2rOutput].push_back(pr);
492 536
493 Feature pv; 537 Feature pv;
494 pv.values.push_back(maxval); 538 pv.values.push_back(maxval);
495 fs[m_pvOutput].push_back(pv); 539 fs[m_pvOutput].push_back(pv);
540
541 Feature pko;
542 if (nextPeakVal != 0.0) {
543 pko.values.push_back(maxval / nextPeakVal);
544 } else {
545 pko.values.push_back(0.0);
546 }
547 fs[m_pkoOutput].push_back(pko);
496 548
497 Feature am; 549 Feature am;
498 for (int i = 0; i < n; ++i) { 550 for (int i = 0; i < n; ++i) {
499 if (data[i] < rms) am.values.push_back(0); 551 if (data[i] < rms) am.values.push_back(0);
500 else am.values.push_back(data[i] - rms); 552 else am.values.push_back(data[i] - rms);