comparison SimpleCepstrum.cpp @ 4:3467d995ea2b

Attempt a complex inverse transform -- doesn't seem to work well?
author Chris Cannam
date Fri, 22 Jun 2012 23:56:37 +0100
parents a6f9ece68482
children 05c558f1a23b
comparison
equal deleted inserted replaced
3:a6f9ece68482 4:3467d995ea2b
5 #include <vector> 5 #include <vector>
6 #include <algorithm> 6 #include <algorithm>
7 7
8 #include <cstdio> 8 #include <cstdio>
9 #include <cmath> 9 #include <cmath>
10 #include <complex>
10 11
11 using std::string; 12 using std::string;
12 13
13 SimpleCepstrum::SimpleCepstrum(float inputSampleRate) : 14 SimpleCepstrum::SimpleCepstrum(float inputSampleRate) :
14 Plugin(inputSampleRate), 15 Plugin(inputSampleRate),
128 129
129 d.identifier = "method"; 130 d.identifier = "method";
130 d.name = "Cepstrum transform method"; 131 d.name = "Cepstrum transform method";
131 d.unit = ""; 132 d.unit = "";
132 d.minValue = 0; 133 d.minValue = 0;
133 d.maxValue = 3; 134 d.maxValue = 5;
134 d.defaultValue = 0; 135 d.defaultValue = 0;
135 d.isQuantized = true; 136 d.isQuantized = true;
136 d.quantizeStep = 1; 137 d.quantizeStep = 1;
137 d.valueNames.push_back("Inverse symmetric"); 138 d.valueNames.push_back("Inverse symmetric");
138 d.valueNames.push_back("Inverse asymmetric"); 139 d.valueNames.push_back("Inverse asymmetric");
140 d.valueNames.push_back("Inverse complex");
141 d.valueNames.push_back("Forward power");
139 d.valueNames.push_back("Forward magnitude"); 142 d.valueNames.push_back("Forward magnitude");
140 d.valueNames.push_back("Forward difference"); 143 d.valueNames.push_back("Forward difference");
141 list.push_back(d); 144 list.push_back(d);
142 145
143 d.identifier = "clamp"; 146 d.identifier = "clamp";
324 FeatureSet fs; 327 FeatureSet fs;
325 328
326 int bs = m_blockSize; 329 int bs = m_blockSize;
327 int hs = m_blockSize/2 + 1; 330 int hs = m_blockSize/2 + 1;
328 331
329 double *logmag = new double[bs];
330
331 for (int i = 0; i < hs; ++i) {
332
333 double mag = sqrt(inputBuffers[0][i*2 ] * inputBuffers[0][i*2 ] +
334 inputBuffers[0][i*2+1] * inputBuffers[0][i*2+1]);
335 double lm = log(mag + 0.00000001);
336
337 switch (m_method) {
338 case InverseSymmetric:
339 logmag[i] = lm;
340 if (i > 0) logmag[bs - i] = lm;
341 break;
342 case InverseAsymmetric:
343 logmag[i] = lm;
344 if (i > 0) logmag[bs - i] = 0;
345 break;
346 case ForwardMagnitude:
347 case ForwardDifference:
348 logmag[bs/2 + i - 1] = lm;
349 if (i < hs-1) {
350 logmag[bs/2 - i - 1] = lm;
351 }
352 break;
353 }
354 }
355
356 double *cep = new double[bs]; 332 double *cep = new double[bs];
357 double *io = new double[bs]; 333 double *io = new double[bs];
358 334
359 if (m_method == InverseSymmetric || 335 if (m_method != InverseComplex) {
360 m_method == InverseAsymmetric) { 336
361 337 double *logmag = new double[bs];
362 fft(bs, true, logmag, 0, cep, io); 338
363 339 for (int i = 0; i < hs; ++i) {
364 } else { 340
365 341 double power =
366 fft(bs, false, logmag, 0, cep, io); 342 inputBuffers[0][i*2 ] * inputBuffers[0][i*2 ] +
367 343 inputBuffers[0][i*2+1] * inputBuffers[0][i*2+1];
368 if (m_method == ForwardDifference) { 344
369 for (int i = 0; i < hs; ++i) { 345 double lm;
370 cep[i] = fabs(io[i]) - fabs(cep[i]); 346
347 if (m_method == ForwardPower) {
348 lm = log(power + 0.00000001);
349 } else {
350 double mag = sqrt(power);
351 lm = log(mag + 0.00000001);
371 } 352 }
372 } else { 353
373 for (int i = 0; i < hs; ++i) { 354 switch (m_method) {
374 cep[i] = sqrt(cep[i]*cep[i] + io[i]*io[i]); 355 case InverseSymmetric:
356 logmag[i] = lm;
357 if (i > 0) logmag[bs - i] = lm;
358 break;
359 case InverseAsymmetric:
360 logmag[i] = lm;
361 if (i > 0) logmag[bs - i] = 0;
362 break;
363 default:
364 logmag[bs/2 + i - 1] = lm;
365 if (i < hs-1) {
366 logmag[bs/2 - i - 1] = lm;
367 }
368 break;
375 } 369 }
376 } 370 }
371
372 if (m_method == InverseSymmetric ||
373 m_method == InverseAsymmetric) {
374
375 fft(bs, true, logmag, 0, cep, io);
376
377 } else {
378
379 fft(bs, false, logmag, 0, cep, io);
380
381 if (m_method == ForwardDifference) {
382 for (int i = 0; i < hs; ++i) {
383 cep[i] = fabs(io[i]) - fabs(cep[i]);
384 }
385 } else {
386 for (int i = 0; i < hs; ++i) {
387 cep[i] = sqrt(cep[i]*cep[i] + io[i]*io[i]);
388 }
389 }
390 }
391
392 delete[] logmag;
393
394 } else { // InverseComplex
395
396 double *ri = new double[bs];
397 double *ii = new double[bs];
398
399 for (int i = 0; i < hs; ++i) {
400 double re = inputBuffers[0][i*2];
401 double im = inputBuffers[0][i*2+1];
402 std::complex<double> c(re, im);
403 std::complex<double> clog = std::log(c);
404 ri[i] = clog.real();
405 ii[i] = clog.imag();
406 if (i > 0) {
407 ri[bs - i] = ri[i];
408 ii[bs - i] = -ii[i];
409 }
410 }
411
412 fft(bs, true, ri, ii, cep, io);
413
414 delete[] ri;
415 delete[] ii;
377 } 416 }
378 417
379 if (m_clamp) { 418 if (m_clamp) {
380 for (int i = 0; i < bs; ++i) { 419 for (int i = 0; i < bs; ++i) {
381 if (cep[i] < 0) cep[i] = 0; 420 if (cep[i] < 0) cep[i] = 0;
445 } 484 }
446 fs[m_amOutput].push_back(am); 485 fs[m_amOutput].push_back(am);
447 486
448 // destructively wipe the higher cepstral bins in order to 487 // destructively wipe the higher cepstral bins in order to
449 // calculate the envelope 488 // calculate the envelope
489 double *env = new double[bs];
450 cep[0] /= 2; 490 cep[0] /= 2;
451 cep[from-1] /= 2; 491 cep[from-1] /= 2;
452 for (int i = 0; i < from; ++i) { 492 for (int i = 0; i < from; ++i) {
453 cep[i] /= bs; 493 cep[i] /= bs;
454 } 494 }
455 for (int i = from; i < bs; ++i) { 495 for (int i = from; i < bs; ++i) {
456 cep[i] = 0; 496 cep[i] = 0;
457 } 497 }
458 fft(bs, false, cep, 0, logmag, io); 498 fft(bs, false, cep, 0, env, io);
459 for (int i = 0; i < hs; ++i) { 499 for (int i = 0; i < hs; ++i) {
460 logmag[i] = exp(logmag[i]); 500 env[i] = exp(env[i]);
461 } 501 }
462 Feature env; 502 Feature envf;
463 for (int i = 0; i < hs; ++i) { 503 for (int i = 0; i < hs; ++i) {
464 env.values.push_back(logmag[i]); 504 envf.values.push_back(env[i]);
465 } 505 }
466 fs[m_envOutput].push_back(env); 506 fs[m_envOutput].push_back(envf);
467 507
468 Feature es; 508 Feature es;
469 for (int i = 0; i < hs; ++i) { 509 for (int i = 0; i < hs; ++i) {
470 double re = inputBuffers[0][i*2 ] / logmag[i]; 510 double re = inputBuffers[0][i*2 ] / env[i];
471 double im = inputBuffers[0][i*2+1] / logmag[i]; 511 double im = inputBuffers[0][i*2+1] / env[i];
472 double mag = sqrt(re*re + im*im); 512 double mag = sqrt(re*re + im*im);
473 es.values.push_back(mag); 513 es.values.push_back(mag);
474 } 514 }
475 fs[m_esOutput].push_back(es); 515 fs[m_esOutput].push_back(es);
476 516
517 delete[] env;
477 delete[] io; 518 delete[] io;
478 delete[] logmag;
479 delete[] cep; 519 delete[] cep;
480 520
481 return fs; 521 return fs;
482 } 522 }
483 523