Mercurial > hg > sonic-visualiser
comparison audioio/PhaseVocoderTimeStretcher.cpp @ 32:e3b32dc5180b
* Make resampler quality configurable
* Fall back to linear resampling when playing very fast
* Switch off transient detection in time stretcher when playing very very fast
author | Chris Cannam |
---|---|
date | Thu, 21 Sep 2006 11:17:19 +0000 |
parents | 37af203dbd15 |
children | 76cc2c424268 |
comparison
equal
deleted
inserted
replaced
31:37af203dbd15 | 32:e3b32dc5180b |
---|---|
36 m_transientCount(0), | 36 m_transientCount(0), |
37 m_n2sum(0), | 37 m_n2sum(0), |
38 m_mutex(new QMutex()) | 38 m_mutex(new QMutex()) |
39 { | 39 { |
40 initialise(); | 40 initialise(); |
41 | |
42 } | 41 } |
43 | 42 |
44 PhaseVocoderTimeStretcher::~PhaseVocoderTimeStretcher() | 43 PhaseVocoderTimeStretcher::~PhaseVocoderTimeStretcher() |
45 { | 44 { |
46 std::cerr << "PhaseVocoderTimeStretcher::~PhaseVocoderTimeStretcher" << std::endl; | 45 std::cerr << "PhaseVocoderTimeStretcher::~PhaseVocoderTimeStretcher" << std::endl; |
142 } else if (m_ratio < 0.8) { | 141 } else if (m_ratio < 0.8) { |
143 m_n1 = 512; | 142 m_n1 = 512; |
144 } else { | 143 } else { |
145 m_n1 = 256; | 144 m_n1 = 256; |
146 } | 145 } |
147 if (m_sharpen) { | 146 if (shouldSharpen()) { |
148 m_wlen = 2048; | 147 m_wlen = 2048; |
149 } | 148 } |
150 m_n2 = lrintf(m_n1 * m_ratio); | 149 m_n2 = lrintf(m_n1 * m_ratio); |
151 } else { | 150 } else { |
152 if (m_ratio > 2) { | 151 if (m_ratio > 2) { |
156 m_n2 = 384; | 155 m_n2 = 384; |
157 m_wlen = 2048; | 156 m_wlen = 2048; |
158 } else { | 157 } else { |
159 m_n2 = 256; | 158 m_n2 = 256; |
160 } | 159 } |
161 if (m_sharpen) { | 160 if (shouldSharpen()) { |
162 if (m_wlen < 2048) m_wlen = 2048; | 161 if (m_wlen < 2048) m_wlen = 2048; |
163 } | 162 } |
164 m_n1 = lrintf(m_n2 / m_ratio); | 163 m_n1 = lrintf(m_n2 / m_ratio); |
165 } | 164 } |
166 | 165 |
316 | 315 |
317 size_t writable = m_inbuf[0]->getWriteSpace(); | 316 size_t writable = m_inbuf[0]->getWriteSpace(); |
318 writable = std::min(writable, samples - consumed); | 317 writable = std::min(writable, samples - consumed); |
319 | 318 |
320 if (writable == 0) { | 319 if (writable == 0) { |
321 //!!! then what? I don't think this should happen, but | 320 #ifdef DEBUG_PHASE_VOCODER_TIME_STRETCHER |
322 std::cerr << "WARNING: PhaseVocoderTimeStretcher::putInput: writable == 0 (inbuf has " << m_inbuf[0]->getReadSpace() << " samples available for reading, space for " << m_inbuf[0]->getWriteSpace() << " more)" << std::endl; | 321 std::cerr << "WARNING: PhaseVocoderTimeStretcher::putInput: writable == 0 (inbuf has " << m_inbuf[0]->getReadSpace() << " samples available for reading, space for " << m_inbuf[0]->getWriteSpace() << " more)" << std::endl; |
322 #endif | |
323 if (m_inbuf[0]->getReadSpace() < m_wlen || | 323 if (m_inbuf[0]->getReadSpace() < m_wlen || |
324 m_outbuf[0]->getWriteSpace() < m_n2) { | 324 m_outbuf[0]->getWriteSpace() < m_n2) { |
325 std::cerr << "Outbuf has space for " << m_outbuf[0]->getWriteSpace() << " (n2 = " << m_n2 << "), won't be able to process" << std::endl; | 325 std::cerr << "WARNING: PhaseVocoderTimeStretcher::putInput: Inbuf has " << m_inbuf[0]->getReadSpace() << ", outbuf has space for " << m_outbuf[0]->getWriteSpace() << " (n2 = " << m_n2 << ", wlen = " << m_wlen << "), won't be able to process" << std::endl; |
326 break; | 326 break; |
327 } | 327 } |
328 } else { | 328 } else { |
329 | 329 |
330 #ifdef DEBUG_PHASE_VOCODER_TIME_STRETCHER | 330 #ifdef DEBUG_PHASE_VOCODER_TIME_STRETCHER |
352 | 352 |
353 analyseBlock(c, m_tempbuf); | 353 analyseBlock(c, m_tempbuf); |
354 } | 354 } |
355 | 355 |
356 bool transient = false; | 356 bool transient = false; |
357 if (m_sharpen) transient = isTransient(); | 357 if (shouldSharpen()) transient = isTransient(); |
358 | 358 |
359 size_t n2 = m_n2; | 359 size_t n2 = m_n2; |
360 | 360 |
361 if (transient) { | 361 if (transient) { |
362 n2 = m_n1; | 362 n2 = m_n1; |
378 | 378 |
379 int squashyCount = m_totalCount - m_transientCount; | 379 int squashyCount = m_totalCount - m_transientCount; |
380 | 380 |
381 n2 = lrintf(idealSquashy / squashyCount); | 381 n2 = lrintf(idealSquashy / squashyCount); |
382 | 382 |
383 #ifdef DEBUG_PHASE_VOCODER_TIME_STRETCHER | |
383 if (n2 != m_n2) { | 384 if (n2 != m_n2) { |
384 std::cerr << m_n2 << " -> " << n2 << std::endl; | 385 std::cerr << m_n2 << " -> " << n2 << std::endl; |
385 } | 386 } |
387 #endif | |
386 } | 388 } |
387 | 389 |
388 for (size_t c = 0; c < m_channels; ++c) { | 390 for (size_t c = 0; c < m_channels; ++c) { |
389 | 391 |
390 synthesiseBlock(c, m_mashbuf[c], | 392 synthesiseBlock(c, m_mashbuf[c], |