Mercurial > hg > pyin
changeset 137:109c3a2ad930 vamp-fft-revision
Make use of new Vamp FFT interface. This reduces the runtime of the regression test from 5.7 to 2.2 seconds on this machine, but it does need the right version of the SDK, which is currently only available in the vampipe branch.
author | Chris Cannam |
---|---|
date | Fri, 19 Aug 2016 13:26:40 +0100 |
parents | 7cbf40306c10 |
children | d71170f5ba76 |
files | YinUtil.cpp |
diffstat | 1 files changed, 29 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/YinUtil.cpp Fri Aug 19 12:00:13 2016 +0100 +++ b/YinUtil.cpp Fri Aug 19 13:26:40 2016 +0100 @@ -38,7 +38,7 @@ double delta ; int startPoint = 0; int endPoint = 0; - for (int i = 1; i < m_yinBufferSize; ++i) { + for (int i = 1; i < int(m_yinBufferSize); ++i) { yinBuffer[i] = 0; startPoint = m_yinBufferSize/2 - i/2; endPoint = startPoint + m_yinBufferSize; @@ -52,21 +52,18 @@ void YinUtil::fastDifference(const double *in, double *yinBuffer) { - // DECLARE AND INITIALISE // initialisation of most of the arrays here was done in a separate function, // with all the arrays as members of the class... moved them back here. size_t frameSize = 2 * m_yinBufferSize; - - double *audioTransformedReal = new double[frameSize]; - double *audioTransformedImag = new double[frameSize]; - double *nullImag = new double[frameSize]; + size_t halfSize = m_yinBufferSize; + + double *audioTransformedComplex = new double[frameSize + 2]; + double *audioOutReal = new double[frameSize]; double *kernel = new double[frameSize]; - double *kernelTransformedReal = new double[frameSize]; - double *kernelTransformedImag = new double[frameSize]; - double *yinStyleACFReal = new double[frameSize]; - double *yinStyleACFImag = new double[frameSize]; + double *kernelTransformedComplex = new double[frameSize + 2]; + double *yinStyleACFComplex = new double[frameSize + 2]; double *powerTerms = new double[m_yinBufferSize]; for (size_t j = 0; j < m_yinBufferSize; ++j) @@ -77,14 +74,7 @@ for (size_t j = 0; j < frameSize; ++j) { - nullImag[j] = 0.; - audioTransformedReal[j] = 0.; - audioTransformedImag[j] = 0.; kernel[j] = 0.; - kernelTransformedReal[j] = 0.; - kernelTransformedImag[j] = 0.; - yinStyleACFReal[j] = 0.; - yinStyleACFImag[j] = 0.; } // POWER TERM CALCULATION @@ -96,43 +86,48 @@ // now iteratively calculate all others (saves a few multiplications) for (size_t tau = 1; tau < m_yinBufferSize; ++tau) { - powerTerms[tau] = powerTerms[tau-1] - in[tau-1] * in[tau-1] + in[tau+m_yinBufferSize] * in[tau+m_yinBufferSize]; + powerTerms[tau] = powerTerms[tau-1] - + in[tau-1] * in[tau-1] + + in[tau+m_yinBufferSize] * in[tau+m_yinBufferSize]; } // YIN-STYLE AUTOCORRELATION via FFT // 1. data - Vamp::FFT::forward(frameSize, in, nullImag, audioTransformedReal, audioTransformedImag); + m_fft.forward(in, audioTransformedComplex); // 2. half of the data, disguised as a convolution kernel for (size_t j = 0; j < m_yinBufferSize; ++j) { kernel[j] = in[m_yinBufferSize-1-j]; } - Vamp::FFT::forward(frameSize, kernel, nullImag, kernelTransformedReal, kernelTransformedImag); + m_fft.forward(kernel, kernelTransformedComplex); // 3. convolution via complex multiplication -- written into - for (size_t j = 0; j < frameSize; ++j) { - yinStyleACFReal[j] = audioTransformedReal[j]*kernelTransformedReal[j] - audioTransformedImag[j]*kernelTransformedImag[j]; // real - yinStyleACFImag[j] = audioTransformedReal[j]*kernelTransformedImag[j] + audioTransformedImag[j]*kernelTransformedReal[j]; // imaginary + for (size_t j = 0; j <= halfSize; ++j) { + yinStyleACFComplex[j*2] = // real + audioTransformedComplex[j*2] * kernelTransformedComplex[j*2] - + audioTransformedComplex[j*2+1] * kernelTransformedComplex[j*2+1]; + yinStyleACFComplex[j*2+1] = // imaginary + audioTransformedComplex[j*2] * kernelTransformedComplex[j*2+1] + + audioTransformedComplex[j*2+1] * kernelTransformedComplex[j*2]; } - Vamp::FFT::inverse(frameSize, yinStyleACFReal, yinStyleACFImag, audioTransformedReal, audioTransformedImag); + + m_fft.inverse(yinStyleACFComplex, audioOutReal); // CALCULATION OF difference function // ... according to (7) in the Yin paper. for (size_t j = 0; j < m_yinBufferSize; ++j) { - // taking only the real part - yinBuffer[j] = powerTerms[0] + powerTerms[j] - 2 * audioTransformedReal[j+m_yinBufferSize-1]; + yinBuffer[j] = powerTerms[0] + powerTerms[j] - 2 * + audioOutReal[j+m_yinBufferSize-1]; } - delete [] audioTransformedReal; - delete [] audioTransformedImag; - delete [] nullImag; + delete [] audioTransformedComplex; + delete [] audioOutReal; delete [] kernel; - delete [] kernelTransformedReal; - delete [] kernelTransformedImag; - delete [] yinStyleACFReal; - delete [] yinStyleACFImag; + delete [] kernelTransformedComplex; + delete [] yinStyleACFComplex; delete [] powerTerms; } + void YinUtil::cumulativeDifference(double *yinBuffer) { @@ -298,7 +293,7 @@ minInd = tau; } currThreshInd = nThresholdInt-1; - while (thresholds[currThreshInd] > yinBuffer[tau] && currThreshInd > -1) { + while (currThreshInd > -1 && thresholds[currThreshInd] > yinBuffer[tau]) { // std::cerr << distribution[currThreshInd] << std::endl; peakProb[tau] += distribution[currThreshInd]; currThreshInd--;