comparison audioio/PhaseVocoderTimeStretcher.cpp @ 19:f17798a555df

...
author Chris Cannam
date Thu, 14 Sep 2006 11:20:09 +0000
parents c1aee08c60b1
children e125f0dde7a3
comparison
equal deleted inserted replaced
18:c1aee08c60b1 19:f17798a555df
69 else m_prevMag = 0; 69 else m_prevMag = 0;
70 m_prevPercussiveCount = new int[m_channels]; 70 m_prevPercussiveCount = new int[m_channels];
71 m_prevPercussive = false; 71 m_prevPercussive = false;
72 72
73 m_dbuf = (float *)fftwf_malloc(sizeof(float) * m_wlen); 73 m_dbuf = (float *)fftwf_malloc(sizeof(float) * m_wlen);
74 m_time = (fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex) * m_wlen); 74 m_time = (float *)fftwf_malloc(sizeof(float) * m_wlen);
75 m_freq = (fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex) * m_wlen); 75 m_freq = (fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex) * m_wlen);
76 76
77 m_plan = fftwf_plan_dft_1d(m_wlen, m_time, m_freq, FFTW_FORWARD, FFTW_ESTIMATE); 77 m_plan = fftwf_plan_dft_r2c_1d(m_wlen, m_time, m_freq, FFTW_ESTIMATE);
78 m_iplan = fftwf_plan_dft_c2r_1d(m_wlen, m_freq, m_dbuf, FFTW_ESTIMATE); 78 m_iplan = fftwf_plan_dft_c2r_1d(m_wlen, m_freq, m_time, FFTW_ESTIMATE);
79 79
80 m_inbuf = new RingBuffer<float> *[m_channels]; 80 m_inbuf = new RingBuffer<float> *[m_channels];
81 m_outbuf = new RingBuffer<float> *[m_channels]; 81 m_outbuf = new RingBuffer<float> *[m_channels];
82 m_mashbuf = new float *[m_channels]; 82 m_mashbuf = new float *[m_channels];
83 83
339 for (i = 0; i < m_wlen/2; ++i) { 339 for (i = 0; i < m_wlen/2; ++i) {
340 float temp = buf[i]; 340 float temp = buf[i];
341 buf[i] = buf[i + m_wlen/2]; 341 buf[i] = buf[i + m_wlen/2];
342 buf[i + m_wlen/2] = temp; 342 buf[i + m_wlen/2] = temp;
343 } 343 }
344 344
345 for (i = 0; i < m_wlen; ++i) { 345 for (i = 0; i < m_wlen; ++i) {
346 m_time[i][0] = buf[i]; 346 m_time[i] = buf[i];
347 m_time[i][1] = 0.0;
348 } 347 }
349 348
350 fftwf_execute(m_plan); // m_time -> m_freq 349 fftwf_execute(m_plan); // m_time -> m_freq
351 350
352 if (m_sharpen && c == 0) { //!!! 351 if (m_sharpen && c == 0) { //!!!
373 } 372 }
374 373
375 m_prevPercussiveCount[c] = count; 374 m_prevPercussiveCount[c] = count;
376 } 375 }
377 376
378 for (i = 0; i < m_wlen; ++i) { 377 for (i = 0; i < m_wlen; ++i) { //!!! /2
379 378
380 float mag; 379 float mag;
381 380
382 if (m_sharpen && c == 0) { 381 if (m_sharpen && c == 0) {
383 mag = m_prevMag[c][i]; // can reuse this 382 mag = m_prevMag[c][i]; // can reuse this
392 391
393 float expectedPhase = m_prevPhase[c][i] + omega; 392 float expectedPhase = m_prevPhase[c][i] + omega;
394 393
395 float phaseError = princargf(phase - expectedPhase); 394 float phaseError = princargf(phase - expectedPhase);
396 395
397 float phaseIncrement = (omega + phaseError) / m_n1; 396 float adjustedPhase = phase;
398 397
399 float adjustedPhase = m_prevAdjustedPhase[c][i] + 398 if (!isPercussive) {
400 lastStep * phaseIncrement; 399 // if (fabsf(phaseError) < (1.1f * (lastStep * M_PI) / m_wlen)) {
401 400
402 if (isPercussive) adjustedPhase = phase; 401 float phaseIncrement = (omega + phaseError) / m_n1;
402
403 adjustedPhase = m_prevAdjustedPhase[c][i] +
404 lastStep * phaseIncrement;
405 // }
406 }
407
408 // if (isPercussive) adjustedPhase = phase;
403 409
404 float real = mag * cosf(adjustedPhase); 410 float real = mag * cosf(adjustedPhase);
405 float imag = mag * sinf(adjustedPhase); 411 float imag = mag * sinf(adjustedPhase);
406 m_freq[i][0] = real; 412 m_freq[i][0] = real;
407 m_freq[i][1] = imag; 413 m_freq[i][1] = imag;
408 414
409 m_prevPhase[c][i] = phase; 415 m_prevPhase[c][i] = phase;
410 m_prevAdjustedPhase[c][i] = adjustedPhase; 416 m_prevAdjustedPhase[c][i] = adjustedPhase;
411 } 417 }
412 418
413 fftwf_execute(m_iplan); // m_freq -> in, inverse fft 419 fftwf_execute(m_iplan); // m_freq -> m_time, inverse fft
414 420
415 for (i = 0; i < m_wlen/2; ++i) { 421 for (i = 0; i < m_wlen/2; ++i) {
416 float temp = buf[i] / m_wlen; 422 float temp = m_time[i];
417 buf[i] = buf[i + m_wlen/2] / m_wlen; 423 m_time[i] = m_time[i + m_wlen/2];
418 buf[i + m_wlen/2] = temp; 424 m_time[i + m_wlen/2] = temp;
419 } 425 }
420
421 m_window->cut(buf);
422 426
423 for (i = 0; i < m_wlen; ++i) { 427 for (i = 0; i < m_wlen; ++i) {
424 out[i] += buf[i]; 428 m_time[i] = m_time[i] / m_wlen;
429 }
430
431 m_window->cut(m_time);
432
433 for (i = 0; i < m_wlen; ++i) {
434 out[i] += m_time[i];
425 } 435 }
426 436
427 if (modulation) { 437 if (modulation) {
428 438
429 float area = m_window->getArea(); 439 float area = m_window->getArea();