Mercurial > hg > vamp-simple-cepstrum
changeset 2:e6faf01e25d8
Remove optimistic f0 output (not implemented); add a couple of envelope-related features
author | Chris Cannam |
---|---|
date | Fri, 22 Jun 2012 17:50:03 +0100 |
parents | ce41d2d066a1 |
children | a6f9ece68482 |
files | SimpleCepstrum.cpp SimpleCepstrum.h |
diffstat | 2 files changed, 65 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/SimpleCepstrum.cpp Fri Jun 22 16:58:55 2012 +0100 +++ b/SimpleCepstrum.cpp Fri Jun 22 17:50:03 2012 +0100 @@ -40,7 +40,7 @@ string SimpleCepstrum::getDescription() const { - return "Return simple cepstral data from DFT bins"; + return "Return simple cepstral data from DFT bins. This plugin is intended for casual inspection of cepstral data. It returns a lot of different sorts of data and is quite slow; it's not a good way to extract a single feature rapidly."; } string @@ -181,6 +181,7 @@ int n = 0; OutputDescriptor d; + d.identifier = "f0"; d.name = "Estimated fundamental frequency"; d.description = ""; @@ -193,11 +194,14 @@ d.isQuantized = false; d.sampleType = OutputDescriptor::OneSamplePerStep; d.hasDuration = false; +/* m_f0Output = n++; outputs.push_back(d); +*/ d.identifier = "raw_cepstral_peak"; d.name = "Frequency corresponding to raw cepstral peak"; + d.description = "Return the frequency whose period corresponds to the quefrency with the maximum value within the specified range of the cepstrum"; d.unit = "Hz"; m_rawOutput = n++; outputs.push_back(d); @@ -205,24 +209,28 @@ d.identifier = "variance"; d.name = "Variance of cepstral bins in range"; d.unit = ""; + d.description = "Return the variance of bin values within the specified range of the cepstrum"; m_varOutput = n++; outputs.push_back(d); d.identifier = "peak"; d.name = "Peak value"; d.unit = ""; + d.description = "Return the value found in the maximum-valued bin within the specified range of the cepstrum"; m_pvOutput = n++; outputs.push_back(d); d.identifier = "peak_to_mean"; d.name = "Peak-to-mean distance"; d.unit = ""; + d.description = "Return the difference between maximum and mean bin values within the specified range of the cepstrum"; m_p2mOutput = n++; outputs.push_back(d); d.identifier = "cepstrum"; d.name = "Cepstrum"; d.unit = ""; + d.description = "The unprocessed cepstrum bins within the specified range"; int from = int(m_inputSampleRate / m_fmax); int to = int(m_inputSampleRate / m_fmin); @@ -233,7 +241,7 @@ for (int i = from; i <= to; ++i) { float freq = m_inputSampleRate / i; char buffer[10]; - sprintf(buffer, "%.2f", freq); + sprintf(buffer, "%.2f Hz", freq); d.binNames.push_back(buffer); } @@ -243,9 +251,30 @@ d.identifier = "am"; d.name = "Cepstrum bins relative to mean"; + d.description = "The cepstrum bins within the specified range, expressed as a value relative to the mean bin value in the range, with values below the mean clamped to zero"; m_amOutput = n++; outputs.push_back(d); + d.identifier = "env"; + d.name = "Spectral envelope"; + d.description = "Envelope calculated from the cepstral values below the specified minimum"; + d.binCount = m_blockSize/2 + 1; + d.binNames.clear(); + for (int i = 0; i < d.binCount; ++i) { + float freq = (m_inputSampleRate / m_blockSize) * i; + char buffer[10]; + sprintf(buffer, "%.2f Hz", freq); + d.binNames.push_back(buffer); + } + m_envOutput = n++; + outputs.push_back(d); + + d.identifier = "es"; + d.name = "Spectrum without envelope"; + d.description = "Magnitude of spectrum values divided by calculated envelope values, to deconvolve the envelope"; + m_esOutput = n++; + outputs.push_back(d); + return outputs; } @@ -283,7 +312,7 @@ for (int i = 0; i < hs; ++i) { double mag = sqrt(inputBuffers[0][i*2 ] * inputBuffers[0][i*2 ] + inputBuffers[0][i*2+1] * inputBuffers[0][i*2+1]); - logmag[i] = log(mag + 0.000001); + logmag[i] = log(mag + 0.00000001); if (i > 0) { logmag[bs - i] = logmag[i]; } @@ -292,7 +321,6 @@ double *cep = new double[bs]; double *discard = new double[bs]; fft(bs, true, logmag, 0, cep, discard); - delete[] discard; if (m_clamp) { for (int i = 0; i < bs; ++i) { @@ -363,6 +391,36 @@ } fs[m_amOutput].push_back(am); + // destructively wipe the higher cepstral bins in order to + // calculate the envelope + cep[0] /= 2; + cep[from-1] /= 2; + for (int i = 0; i < from; ++i) { + cep[i] /= bs; + } + for (int i = from; i < bs; ++i) { + cep[i] = 0; + } + fft(bs, false, cep, 0, logmag, discard); + for (int i = 0; i < hs; ++i) { + logmag[i] = exp(logmag[i]); + } + Feature env; + for (int i = 0; i < hs; ++i) { + env.values.push_back(logmag[i]); + } + fs[m_envOutput].push_back(env); + + Feature es; + for (int i = 0; i < hs; ++i) { + double re = inputBuffers[0][i*2 ] / logmag[i]; + double im = inputBuffers[0][i*2+1] / logmag[i]; + double mag = sqrt(re*re + im*im); + es.values.push_back(mag); + } + fs[m_esOutput].push_back(es); + + delete[] discard; delete[] logmag; delete[] cep;
--- a/SimpleCepstrum.h Fri Jun 22 16:58:55 2012 +0100 +++ b/SimpleCepstrum.h Fri Jun 22 17:50:03 2012 +0100 @@ -50,13 +50,15 @@ float m_fmax; bool m_clamp; - mutable int m_f0Output; +// mutable int m_f0Output; mutable int m_rawOutput; mutable int m_varOutput; mutable int m_p2mOutput; mutable int m_cepOutput; mutable int m_pvOutput; mutable int m_amOutput; + mutable int m_envOutput; + mutable int m_esOutput; void fft(unsigned int n, bool inverse, double *ri, double *ii, double *ro, double *io);