comparison SimpleCepstrum.cpp @ 6:ffed34f519db

Add total and peak-proportion outputs
author Chris Cannam
date Mon, 25 Jun 2012 13:39:46 +0100
parents 05c558f1a23b
children 47355877a58d
comparison
equal deleted inserted replaced
5:05c558f1a23b 6:ffed34f519db
227 OutputDescriptor d; 227 OutputDescriptor d;
228 228
229 d.identifier = "f0"; 229 d.identifier = "f0";
230 d.name = "Estimated fundamental frequency"; 230 d.name = "Estimated fundamental frequency";
231 d.description = ""; 231 d.description = "";
232 d.unit = ""; 232 d.unit = "Hz";
233 d.hasFixedBinCount = true; 233 d.hasFixedBinCount = true;
234 d.binCount = 1; 234 d.binCount = 1;
235 d.hasKnownExtents = true; 235 d.hasKnownExtents = true;
236 d.minValue = m_fmin; 236 d.minValue = m_fmin;
237 d.maxValue = m_fmax; 237 d.maxValue = m_fmax;
252 252
253 d.identifier = "variance"; 253 d.identifier = "variance";
254 d.name = "Variance of cepstral bins in range"; 254 d.name = "Variance of cepstral bins in range";
255 d.unit = ""; 255 d.unit = "";
256 d.description = "Return the variance of bin values within the specified range of the cepstrum"; 256 d.description = "Return the variance of bin values within the specified range of the cepstrum";
257 d.hasKnownExtents = false;
257 m_varOutput = n++; 258 m_varOutput = n++;
258 outputs.push_back(d); 259 outputs.push_back(d);
259 260
260 d.identifier = "peak"; 261 d.identifier = "peak";
261 d.name = "Peak value"; 262 d.name = "Peak value";
274 d.identifier = "peak_to_rms"; 275 d.identifier = "peak_to_rms";
275 d.name = "Peak-to-RMS distance"; 276 d.name = "Peak-to-RMS distance";
276 d.unit = ""; 277 d.unit = "";
277 d.description = "Return the difference between maximum and root mean square bin values within the specified range of the cepstrum"; 278 d.description = "Return the difference between maximum and root mean square bin values within the specified range of the cepstrum";
278 m_p2rOutput = n++; 279 m_p2rOutput = n++;
280 outputs.push_back(d);
281
282 d.identifier = "peak_proportion";
283 d.name = "Peak proportion";
284 d.unit = "";
285 d.description = "Return the proportion of total energy found in the bins around the peak bin of the cepstrum (as far as the nearest local minima)";
286 m_ppOutput = n++;
287 outputs.push_back(d);
288
289 d.identifier = "total";
290 d.name = "Total energy";
291 d.unit = "";
292 d.description = "Return the total energy found in all cepstrum bins within range";
293 m_totOutput = n++;
279 outputs.push_back(d); 294 outputs.push_back(d);
280 295
281 d.identifier = "cepstrum"; 296 d.identifier = "cepstrum";
282 d.name = "Cepstrum"; 297 d.name = "Cepstrum";
283 d.unit = ""; 298 d.unit = "";
404 void 419 void
405 SimpleCepstrum::addStatisticalOutputs(FeatureSet &fs, const double *data) 420 SimpleCepstrum::addStatisticalOutputs(FeatureSet &fs, const double *data)
406 { 421 {
407 int n = m_bins; 422 int n = m_bins;
408 423
409 double maxval = 0.f; 424 double maxval = 0.0;
410 int maxbin = 0; 425 int maxbin = 0;
411 426
412 for (int i = 0; i < n; ++i) { 427 for (int i = 0; i < n; ++i) {
413 if (data[i] > maxval) { 428 if (data[i] > maxval) {
414 maxval = data[i]; 429 maxval = data[i];
415 maxbin = i + m_binFrom; 430 maxbin = i;
416 } 431 }
417 } 432 }
418 433
419 Feature rf; 434 Feature rf;
420 if (maxbin > 0) { 435 if (maxval > 0.0) {
421 rf.values.push_back(m_inputSampleRate / maxbin); 436 rf.values.push_back(m_inputSampleRate / (maxbin + m_binFrom));
422 } else { 437 } else {
423 rf.values.push_back(0); 438 rf.values.push_back(0);
424 } 439 }
425 fs[m_pkOutput].push_back(rf); 440 fs[m_pkOutput].push_back(rf);
426 441
427 double mean = 0; 442 double total = 0;
428 for (int i = 0; i < n; ++i) { 443 for (int i = 0; i < n; ++i) {
429 mean += data[i]; 444 total += data[i];
430 } 445 }
431 mean /= n; 446
432 447 Feature tot;
433 double rms = 0; 448 tot.values.push_back(total);
449 fs[m_totOutput].push_back(tot);
450
451 double mean = total / n;
452
453 double totsqr = 0;
434 for (int i = 0; i < n; ++i) { 454 for (int i = 0; i < n; ++i) {
435 rms += data[i] * data[i]; 455 totsqr += data[i] * data[i];
436 } 456 }
437 rms = sqrt(rms / n); 457 double rms = sqrt(totsqr / n);
438 458
439 double variance = 0; 459 double variance = 0;
440 for (int i = 0; i < n; ++i) { 460 for (int i = 0; i < n; ++i) {
441 double dev = fabs(data[i] - mean); 461 double dev = fabs(data[i] - mean);
442 variance += dev * dev; 462 variance += dev * dev;
443 } 463 }
444 variance /= n; 464 variance /= n;
465
466 double aroundPeak = 0.0;
467 double peakProportion = 0.0;
468 if (maxval > 0.0) {
469 aroundPeak += maxval * maxval;
470 int i = maxbin - 1;
471 while (i > 0 && data[i] <= data[i+1]) {
472 aroundPeak += data[i] * data[i];
473 --i;
474 }
475 i = maxbin + 1;
476 while (i < n && data[i] <= data[i-1]) {
477 aroundPeak += data[i] * data[i];
478 ++i;
479 }
480 }
481 peakProportion = sqrt(aroundPeak) / sqrt(totsqr);
482 Feature pp;
483 pp.values.push_back(peakProportion);
484 fs[m_ppOutput].push_back(pp);
445 485
446 Feature vf; 486 Feature vf;
447 vf.values.push_back(variance); 487 vf.values.push_back(variance);
448 fs[m_varOutput].push_back(vf); 488 fs[m_varOutput].push_back(vf);
449 489