Mercurial > hg > sonic-visualiser
comparison audioio/PhaseVocoderTimeStretcher.cpp @ 17:67d54627efd3
* Fix phase calculation for percussive frames, and some tweaks -- we can do
better fairly easily though
author | Chris Cannam |
---|---|
date | Wed, 13 Sep 2006 18:58:17 +0000 |
parents | 3715efc38f95 |
children | c1aee08c60b1 |
comparison
equal
deleted
inserted
replaced
16:3715efc38f95 | 17:67d54627efd3 |
---|---|
38 m_n1 = 512; | 38 m_n1 = 512; |
39 } else { | 39 } else { |
40 m_n1 = 256; | 40 m_n1 = 256; |
41 } | 41 } |
42 if (m_sharpen) { | 42 if (m_sharpen) { |
43 m_n1 /= 2; | 43 // m_n1 /= 2; |
44 m_wlen = 2048; | 44 m_wlen = 2048; |
45 } | 45 } |
46 m_n2 = m_n1 * ratio; | 46 m_n2 = m_n1 * ratio; |
47 } else { | 47 } else { |
48 if (ratio > 2) { | 48 if (ratio > 2) { |
53 m_wlen = 2048; | 53 m_wlen = 2048; |
54 } else { | 54 } else { |
55 m_n2 = 256; | 55 m_n2 = 256; |
56 } | 56 } |
57 if (m_sharpen) { | 57 if (m_sharpen) { |
58 m_n2 /= 2; | 58 // m_n2 /= 2; |
59 if (m_wlen < 2048) m_wlen = 2048; | 59 if (m_wlen < 2048) m_wlen = 2048; |
60 } | 60 } |
61 m_n1 = m_n2 / ratio; | 61 m_n1 = m_n2 / ratio; |
62 } | 62 } |
63 | 63 |
66 m_prevPhase = new float *[m_channels]; | 66 m_prevPhase = new float *[m_channels]; |
67 m_prevAdjustedPhase = new float *[m_channels]; | 67 m_prevAdjustedPhase = new float *[m_channels]; |
68 if (m_sharpen) m_prevMag = new float *[m_channels]; | 68 if (m_sharpen) m_prevMag = new float *[m_channels]; |
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 | 72 |
72 m_dbuf = (float *)fftwf_malloc(sizeof(float) * m_wlen); | 73 m_dbuf = (float *)fftwf_malloc(sizeof(float) * m_wlen); |
73 m_time = (fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex) * m_wlen); | 74 m_time = (fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex) * m_wlen); |
74 m_freq = (fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex) * m_wlen); | 75 m_freq = (fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex) * m_wlen); |
75 | 76 |
229 assert(got == m_wlen); | 230 assert(got == m_wlen); |
230 | 231 |
231 bool thisChannelPercussive = | 232 bool thisChannelPercussive = |
232 processBlock(c, m_dbuf, m_mashbuf[c], | 233 processBlock(c, m_dbuf, m_mashbuf[c], |
233 c == 0 ? m_modulationbuf : 0, | 234 c == 0 ? m_modulationbuf : 0, |
234 isPercussive); | 235 m_prevPercussive); |
235 | 236 |
236 if (thisChannelPercussive && c == 0) { | 237 if (thisChannelPercussive && c == 0) { |
237 isPercussive = true; | 238 isPercussive = true; |
238 } | 239 } |
239 | 240 |
260 | 261 |
261 for (size_t i = m_wlen - n2; i < m_wlen; ++i) { | 262 for (size_t i = m_wlen - n2; i < m_wlen; ++i) { |
262 m_mashbuf[c][i] = 0.0f; | 263 m_mashbuf[c][i] = 0.0f; |
263 } | 264 } |
264 } | 265 } |
266 | |
267 m_prevPercussive = isPercussive; | |
265 | 268 |
266 for (size_t i = 0; i < m_wlen - n2; ++i) { | 269 for (size_t i = 0; i < m_wlen - n2; ++i) { |
267 m_modulationbuf[i] = m_modulationbuf[i + n2]; | 270 m_modulationbuf[i] = m_modulationbuf[i + n2]; |
268 } | 271 } |
269 | 272 |
317 | 320 |
318 bool | 321 bool |
319 PhaseVocoderTimeStretcher::processBlock(size_t c, | 322 PhaseVocoderTimeStretcher::processBlock(size_t c, |
320 float *buf, float *out, | 323 float *buf, float *out, |
321 float *modulation, | 324 float *modulation, |
322 bool knownPercussive) | 325 bool lastPercussive) |
323 { | 326 { |
324 size_t i; | 327 size_t i; |
325 bool isPercussive = knownPercussive; | 328 bool isPercussive = false; |
326 | 329 |
327 // buf contains m_wlen samples; out contains enough space for | 330 // buf contains m_wlen samples; out contains enough space for |
328 // m_wlen * ratio samples (we mix into out, rather than replacing) | 331 // m_wlen * ratio samples (we mix into out, rather than replacing) |
329 | 332 |
330 #ifdef DEBUG_PHASE_VOCODER_TIME_STRETCHER | 333 #ifdef DEBUG_PHASE_VOCODER_TIME_STRETCHER |
361 } | 364 } |
362 | 365 |
363 m_prevMag[c][i] = mag; | 366 m_prevMag[c][i] = mag; |
364 } | 367 } |
365 | 368 |
366 if (count > m_wlen / 6 && | 369 if (count > m_wlen / 4 && //!!! |
367 count > m_prevPercussiveCount[c] * 1.2) { | 370 count > m_prevPercussiveCount[c] * 1.2) { |
368 isPercussive = true; | 371 isPercussive = true; |
369 std::cerr << "isPercussive (count = " << count << ", prev = " << m_prevPercussiveCount[c] << ")" << std::endl; | 372 std::cerr << "isPercussive (count = " << count << ", prev = " << m_prevPercussiveCount[c] << ")" << std::endl; |
370 } | 373 } |
371 | 374 |
372 m_prevPercussiveCount[c] = count; | 375 m_prevPercussiveCount[c] = count; |
373 } | 376 } |
374 | 377 |
375 size_t n2 = m_n2; | 378 size_t n2 = m_n2; |
376 if (isPercussive) n2 = m_n1; | 379 if (lastPercussive) n2 = m_n1; |
377 | 380 |
378 for (i = 0; i < m_wlen; ++i) { | 381 for (i = 0; i < m_wlen; ++i) { |
379 | 382 |
380 float mag; | 383 float mag; |
381 | 384 |