Mercurial > hg > vamp-simple-cepstrum
comparison SimpleCepstrum.cpp @ 3:a6f9ece68482
Add choice of cepstrum transform method
author | Chris Cannam |
---|---|
date | Fri, 22 Jun 2012 23:01:00 +0100 |
parents | e6faf01e25d8 |
children | 3467d995ea2b |
comparison
equal
deleted
inserted
replaced
2:e6faf01e25d8 | 3:a6f9ece68482 |
---|---|
15 m_channels(0), | 15 m_channels(0), |
16 m_stepSize(256), | 16 m_stepSize(256), |
17 m_blockSize(1024), | 17 m_blockSize(1024), |
18 m_fmin(50), | 18 m_fmin(50), |
19 m_fmax(1000), | 19 m_fmax(1000), |
20 m_clamp(false) | 20 m_clamp(false), |
21 m_method(InverseSymmetric) | |
21 { | 22 { |
22 } | 23 } |
23 | 24 |
24 SimpleCepstrum::~SimpleCepstrum() | 25 SimpleCepstrum::~SimpleCepstrum() |
25 { | 26 { |
123 d.maxValue = m_inputSampleRate / 2; | 124 d.maxValue = m_inputSampleRate / 2; |
124 d.defaultValue = 1000; | 125 d.defaultValue = 1000; |
125 d.isQuantized = false; | 126 d.isQuantized = false; |
126 list.push_back(d); | 127 list.push_back(d); |
127 | 128 |
129 d.identifier = "method"; | |
130 d.name = "Cepstrum transform method"; | |
131 d.unit = ""; | |
132 d.minValue = 0; | |
133 d.maxValue = 3; | |
134 d.defaultValue = 0; | |
135 d.isQuantized = true; | |
136 d.quantizeStep = 1; | |
137 d.valueNames.push_back("Inverse symmetric"); | |
138 d.valueNames.push_back("Inverse asymmetric"); | |
139 d.valueNames.push_back("Forward magnitude"); | |
140 d.valueNames.push_back("Forward difference"); | |
141 list.push_back(d); | |
142 | |
128 d.identifier = "clamp"; | 143 d.identifier = "clamp"; |
129 d.name = "Clamp negative values in cepstrum at zero"; | 144 d.name = "Clamp negative values in cepstrum at zero"; |
130 d.unit = ""; | 145 d.unit = ""; |
131 d.minValue = 0; | 146 d.minValue = 0; |
132 d.maxValue = 1; | 147 d.maxValue = 1; |
133 d.defaultValue = 0; | 148 d.defaultValue = 0; |
134 d.isQuantized = true; | 149 d.isQuantized = true; |
135 d.quantizeStep = 1; | 150 d.quantizeStep = 1; |
151 d.valueNames.clear(); | |
136 list.push_back(d); | 152 list.push_back(d); |
137 | 153 |
138 return list; | 154 return list; |
139 } | 155 } |
140 | 156 |
142 SimpleCepstrum::getParameter(string identifier) const | 158 SimpleCepstrum::getParameter(string identifier) const |
143 { | 159 { |
144 if (identifier == "fmin") return m_fmin; | 160 if (identifier == "fmin") return m_fmin; |
145 else if (identifier == "fmax") return m_fmax; | 161 else if (identifier == "fmax") return m_fmax; |
146 else if (identifier == "clamp") return (m_clamp ? 1 : 0); | 162 else if (identifier == "clamp") return (m_clamp ? 1 : 0); |
163 else if (identifier == "method") return (int)m_method; | |
147 else return 0.f; | 164 else return 0.f; |
148 } | 165 } |
149 | 166 |
150 void | 167 void |
151 SimpleCepstrum::setParameter(string identifier, float value) | 168 SimpleCepstrum::setParameter(string identifier, float value) |
152 { | 169 { |
153 if (identifier == "fmin") m_fmin = value; | 170 if (identifier == "fmin") m_fmin = value; |
154 else if (identifier == "fmax") m_fmax = value; | 171 else if (identifier == "fmax") m_fmax = value; |
155 else if (identifier == "clamp") m_clamp = (value > 0.5); | 172 else if (identifier == "clamp") m_clamp = (value > 0.5); |
173 else if (identifier == "method") m_method = Method(int(value + 0.5)); | |
156 } | 174 } |
157 | 175 |
158 SimpleCepstrum::ProgramList | 176 SimpleCepstrum::ProgramList |
159 SimpleCepstrum::getPrograms() const | 177 SimpleCepstrum::getPrograms() const |
160 { | 178 { |
307 | 325 |
308 int bs = m_blockSize; | 326 int bs = m_blockSize; |
309 int hs = m_blockSize/2 + 1; | 327 int hs = m_blockSize/2 + 1; |
310 | 328 |
311 double *logmag = new double[bs]; | 329 double *logmag = new double[bs]; |
330 | |
312 for (int i = 0; i < hs; ++i) { | 331 for (int i = 0; i < hs; ++i) { |
332 | |
313 double mag = sqrt(inputBuffers[0][i*2 ] * inputBuffers[0][i*2 ] + | 333 double mag = sqrt(inputBuffers[0][i*2 ] * inputBuffers[0][i*2 ] + |
314 inputBuffers[0][i*2+1] * inputBuffers[0][i*2+1]); | 334 inputBuffers[0][i*2+1] * inputBuffers[0][i*2+1]); |
315 logmag[i] = log(mag + 0.00000001); | 335 double lm = log(mag + 0.00000001); |
316 if (i > 0) { | 336 |
317 logmag[bs - i] = logmag[i]; | 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; | |
318 } | 353 } |
319 } | 354 } |
320 | 355 |
321 double *cep = new double[bs]; | 356 double *cep = new double[bs]; |
322 double *discard = new double[bs]; | 357 double *io = new double[bs]; |
323 fft(bs, true, logmag, 0, cep, discard); | 358 |
359 if (m_method == InverseSymmetric || | |
360 m_method == InverseAsymmetric) { | |
361 | |
362 fft(bs, true, logmag, 0, cep, io); | |
363 | |
364 } else { | |
365 | |
366 fft(bs, false, logmag, 0, cep, io); | |
367 | |
368 if (m_method == ForwardDifference) { | |
369 for (int i = 0; i < hs; ++i) { | |
370 cep[i] = fabs(io[i]) - fabs(cep[i]); | |
371 } | |
372 } else { | |
373 for (int i = 0; i < hs; ++i) { | |
374 cep[i] = sqrt(cep[i]*cep[i] + io[i]*io[i]); | |
375 } | |
376 } | |
377 } | |
324 | 378 |
325 if (m_clamp) { | 379 if (m_clamp) { |
326 for (int i = 0; i < bs; ++i) { | 380 for (int i = 0; i < bs; ++i) { |
327 if (cep[i] < 0) cep[i] = 0; | 381 if (cep[i] < 0) cep[i] = 0; |
328 } | 382 } |
399 cep[i] /= bs; | 453 cep[i] /= bs; |
400 } | 454 } |
401 for (int i = from; i < bs; ++i) { | 455 for (int i = from; i < bs; ++i) { |
402 cep[i] = 0; | 456 cep[i] = 0; |
403 } | 457 } |
404 fft(bs, false, cep, 0, logmag, discard); | 458 fft(bs, false, cep, 0, logmag, io); |
405 for (int i = 0; i < hs; ++i) { | 459 for (int i = 0; i < hs; ++i) { |
406 logmag[i] = exp(logmag[i]); | 460 logmag[i] = exp(logmag[i]); |
407 } | 461 } |
408 Feature env; | 462 Feature env; |
409 for (int i = 0; i < hs; ++i) { | 463 for (int i = 0; i < hs; ++i) { |
418 double mag = sqrt(re*re + im*im); | 472 double mag = sqrt(re*re + im*im); |
419 es.values.push_back(mag); | 473 es.values.push_back(mag); |
420 } | 474 } |
421 fs[m_esOutput].push_back(es); | 475 fs[m_esOutput].push_back(es); |
422 | 476 |
423 delete[] discard; | 477 delete[] io; |
424 delete[] logmag; | 478 delete[] logmag; |
425 delete[] cep; | 479 delete[] cep; |
426 | 480 |
427 return fs; | 481 return fs; |
428 } | 482 } |