diff options
Diffstat (limited to 'libs/vamp-sdk/src/vamp-hostsdk/PluginInputDomainAdapter.cpp')
-rw-r--r-- | libs/vamp-sdk/src/vamp-hostsdk/PluginInputDomainAdapter.cpp | 673 |
1 files changed, 0 insertions, 673 deletions
diff --git a/libs/vamp-sdk/src/vamp-hostsdk/PluginInputDomainAdapter.cpp b/libs/vamp-sdk/src/vamp-hostsdk/PluginInputDomainAdapter.cpp deleted file mode 100644 index c2d2add53b..0000000000 --- a/libs/vamp-sdk/src/vamp-hostsdk/PluginInputDomainAdapter.cpp +++ /dev/null @@ -1,673 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Vamp - - An API for audio analysis and feature extraction plugins. - - Centre for Digital Music, Queen Mary, University of London. - Copyright 2006-2009 Chris Cannam and QMUL. - - This file is based in part on Don Cross's public domain FFT - implementation. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR - ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the names of the Centre for - Digital Music; Queen Mary, University of London; and Chris Cannam - shall not be used in advertising or otherwise to promote the sale, - use or other dealings in this Software without prior written - authorization. -*/ - -#include "vamp-hostsdk/PluginInputDomainAdapter.h" - -#include <cmath> - - -/** - * If you want to compile using FFTW instead of the built-in FFT - * implementation for the PluginInputDomainAdapter, define HAVE_FFTW3 - * in the Makefile. - * - * Be aware that FFTW is licensed under the GPL -- unlike this SDK, - * which is provided under a more liberal BSD license in order to - * permit use in closed source applications. The use of FFTW would - * mean that your code would need to be licensed under the GPL as - * well. Do not define this symbol unless you understand and accept - * the implications of this. - * - * Parties such as Linux distribution packagers who redistribute this - * SDK for use in other programs should _not_ define this symbol, as - * it would change the effective licensing terms under which the SDK - * was available to third party developers. - * - * The default is not to use FFTW, and to use the built-in FFT instead. - * - * Note: The FFTW code uses FFTW_MEASURE, and so will perform badly on - * its first invocation unless the host has saved and restored FFTW - * wisdom (see the FFTW documentation). - */ -#ifdef HAVE_FFTW3 -#include <fftw3.h> -#endif - - -_VAMP_SDK_HOSTSPACE_BEGIN(PluginInputDomainAdapter.cpp) - -namespace Vamp { - -namespace HostExt { - -class PluginInputDomainAdapter::Impl -{ -public: - Impl(Plugin *plugin, float inputSampleRate); - ~Impl(); - - bool initialise(size_t channels, size_t stepSize, size_t blockSize); - void reset(); - - size_t getPreferredStepSize() const; - size_t getPreferredBlockSize() const; - - FeatureSet process(const float *const *inputBuffers, RealTime timestamp); - - void setProcessTimestampMethod(ProcessTimestampMethod m); - ProcessTimestampMethod getProcessTimestampMethod() const; - - RealTime getTimestampAdjustment() const; - -protected: - Plugin *m_plugin; - float m_inputSampleRate; - int m_channels; - int m_stepSize; - int m_blockSize; - float **m_freqbuf; - - double *m_ri; - double *m_window; - - ProcessTimestampMethod m_method; - int m_processCount; - float **m_shiftBuffers; - -#ifdef HAVE_FFTW3 - fftw_plan m_plan; - fftw_complex *m_cbuf; -#else - double *m_ro; - double *m_io; - void fft(unsigned int n, bool inverse, - double *ri, double *ii, double *ro, double *io); -#endif - - FeatureSet processShiftingTimestamp(const float *const *inputBuffers, RealTime timestamp); - FeatureSet processShiftingData(const float *const *inputBuffers, RealTime timestamp); - - size_t makeBlockSizeAcceptable(size_t) const; -}; - -PluginInputDomainAdapter::PluginInputDomainAdapter(Plugin *plugin) : - PluginWrapper(plugin) -{ - m_impl = new Impl(plugin, m_inputSampleRate); -} - -PluginInputDomainAdapter::~PluginInputDomainAdapter() -{ - delete m_impl; -} - -bool -PluginInputDomainAdapter::initialise(size_t channels, size_t stepSize, size_t blockSize) -{ - return m_impl->initialise(channels, stepSize, blockSize); -} - -void -PluginInputDomainAdapter::reset() -{ - m_impl->reset(); -} - -Plugin::InputDomain -PluginInputDomainAdapter::getInputDomain() const -{ - return TimeDomain; -} - -size_t -PluginInputDomainAdapter::getPreferredStepSize() const -{ - return m_impl->getPreferredStepSize(); -} - -size_t -PluginInputDomainAdapter::getPreferredBlockSize() const -{ - return m_impl->getPreferredBlockSize(); -} - -Plugin::FeatureSet -PluginInputDomainAdapter::process(const float *const *inputBuffers, RealTime timestamp) -{ - return m_impl->process(inputBuffers, timestamp); -} - -void -PluginInputDomainAdapter::setProcessTimestampMethod(ProcessTimestampMethod m) -{ - m_impl->setProcessTimestampMethod(m); -} - -PluginInputDomainAdapter::ProcessTimestampMethod -PluginInputDomainAdapter::getProcessTimestampMethod() const -{ - return m_impl->getProcessTimestampMethod(); -} - -RealTime -PluginInputDomainAdapter::getTimestampAdjustment() const -{ - return m_impl->getTimestampAdjustment(); -} - - -PluginInputDomainAdapter::Impl::Impl(Plugin *plugin, float inputSampleRate) : - m_plugin(plugin), - m_inputSampleRate(inputSampleRate), - m_channels(0), - m_stepSize(0), - m_blockSize(0), - m_freqbuf(0), - m_ri(0), - m_window(0), - m_method(ShiftTimestamp), - m_processCount(0), - m_shiftBuffers(0), -#ifdef HAVE_FFTW3 - m_plan(0), - m_cbuf(0) -#else - m_ro(0), - m_io(0) -#endif -{ -} - -PluginInputDomainAdapter::Impl::~Impl() -{ - // the adapter will delete the plugin - - if (m_shiftBuffers) { - for (int c = 0; c < m_channels; ++c) { - delete[] m_shiftBuffers[c]; - } - delete[] m_shiftBuffers; - } - - if (m_channels > 0) { - for (int c = 0; c < m_channels; ++c) { - delete[] m_freqbuf[c]; - } - delete[] m_freqbuf; -#ifdef HAVE_FFTW3 - if (m_plan) { - fftw_destroy_plan(m_plan); - fftw_free(m_ri); - fftw_free(m_cbuf); - m_plan = 0; - } -#else - delete[] m_ri; - delete[] m_ro; - delete[] m_io; -#endif - delete[] m_window; - } -} - -// for some visual studii apparently -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -bool -PluginInputDomainAdapter::Impl::initialise(size_t channels, size_t stepSize, size_t blockSize) -{ - if (m_plugin->getInputDomain() == TimeDomain) { - - m_stepSize = int(stepSize); - m_blockSize = int(blockSize); - m_channels = int(channels); - - return m_plugin->initialise(channels, stepSize, blockSize); - } - - if (blockSize < 2) { - std::cerr << "ERROR: PluginInputDomainAdapter::initialise: blocksize < 2 not supported" << std::endl; - return false; - } - - if (blockSize & (blockSize-1)) { - std::cerr << "ERROR: PluginInputDomainAdapter::initialise: non-power-of-two\nblocksize " << blockSize << " not supported" << std::endl; - return false; - } - - if (m_channels > 0) { - for (int c = 0; c < m_channels; ++c) { - delete[] m_freqbuf[c]; - } - delete[] m_freqbuf; -#ifdef HAVE_FFTW3 - if (m_plan) { - fftw_destroy_plan(m_plan); - fftw_free(m_ri); - fftw_free(m_cbuf); - m_plan = 0; - } -#else - delete[] m_ri; - delete[] m_ro; - delete[] m_io; -#endif - delete[] m_window; - } - - m_stepSize = int(stepSize); - m_blockSize = int(blockSize); - m_channels = int(channels); - - m_freqbuf = new float *[m_channels]; - for (int c = 0; c < m_channels; ++c) { - m_freqbuf[c] = new float[m_blockSize + 2]; - } - m_window = new double[m_blockSize]; - - for (int i = 0; i < m_blockSize; ++i) { - // Hanning window - m_window[i] = (0.50 - 0.50 * cos((2.0 * M_PI * i) / m_blockSize)); - } - -#ifdef HAVE_FFTW3 - m_ri = (double *)fftw_malloc(blockSize * sizeof(double)); - m_cbuf = (fftw_complex *)fftw_malloc((blockSize/2 + 1) * sizeof(fftw_complex)); - m_plan = fftw_plan_dft_r2c_1d(blockSize, m_ri, m_cbuf, FFTW_MEASURE); -#else - m_ri = new double[m_blockSize]; - m_ro = new double[m_blockSize]; - m_io = new double[m_blockSize]; -#endif - - m_processCount = 0; - - return m_plugin->initialise(channels, stepSize, blockSize); -} - -void -PluginInputDomainAdapter::Impl::reset() -{ - m_processCount = 0; - m_plugin->reset(); -} - -size_t -PluginInputDomainAdapter::Impl::getPreferredStepSize() const -{ - size_t step = m_plugin->getPreferredStepSize(); - - if (step == 0 && (m_plugin->getInputDomain() == FrequencyDomain)) { - step = getPreferredBlockSize() / 2; - } - - return step; -} - -size_t -PluginInputDomainAdapter::Impl::getPreferredBlockSize() const -{ - size_t block = m_plugin->getPreferredBlockSize(); - - if (m_plugin->getInputDomain() == FrequencyDomain) { - if (block == 0) { - block = 1024; - } else { - block = makeBlockSizeAcceptable(block); - } - } - - return block; -} - -size_t -PluginInputDomainAdapter::Impl::makeBlockSizeAcceptable(size_t blockSize) const -{ - if (blockSize < 2) { - - std::cerr << "WARNING: PluginInputDomainAdapter::initialise: blocksize < 2 not" << std::endl - << "supported, increasing from " << blockSize << " to 2" << std::endl; - blockSize = 2; - - } else if (blockSize & (blockSize-1)) { - -#ifdef HAVE_FFTW3 - // not an issue with FFTW -#else - - // not a power of two, can't handle that with our built-in FFT - // implementation - - size_t nearest = blockSize; - size_t power = 0; - while (nearest > 1) { - nearest >>= 1; - ++power; - } - nearest = 1; - while (power) { - nearest <<= 1; - --power; - } - - if (blockSize - nearest > (nearest*2) - blockSize) { - nearest = nearest*2; - } - - std::cerr << "WARNING: PluginInputDomainAdapter::initialise: non-power-of-two\nblocksize " << blockSize << " not supported, using blocksize " << nearest << " instead" << std::endl; - blockSize = nearest; - -#endif - } - - return blockSize; -} - -RealTime -PluginInputDomainAdapter::Impl::getTimestampAdjustment() const -{ - if (m_plugin->getInputDomain() == TimeDomain) { - return RealTime::zeroTime; - } else if (m_method == ShiftData || m_method == NoShift) { - return RealTime::zeroTime; - } else { - return RealTime::frame2RealTime - (m_blockSize/2, int(m_inputSampleRate + 0.5)); - } -} - -void -PluginInputDomainAdapter::Impl::setProcessTimestampMethod(ProcessTimestampMethod m) -{ - m_method = m; -} - -PluginInputDomainAdapter::ProcessTimestampMethod -PluginInputDomainAdapter::Impl::getProcessTimestampMethod() const -{ - return m_method; -} - -Plugin::FeatureSet -PluginInputDomainAdapter::Impl::process(const float *const *inputBuffers, - RealTime timestamp) -{ - if (m_plugin->getInputDomain() == TimeDomain) { - return m_plugin->process(inputBuffers, timestamp); - } - - if (m_method == ShiftTimestamp || m_method == NoShift) { - return processShiftingTimestamp(inputBuffers, timestamp); - } else { - return processShiftingData(inputBuffers, timestamp); - } -} - -Plugin::FeatureSet -PluginInputDomainAdapter::Impl::processShiftingTimestamp(const float *const *inputBuffers, - RealTime timestamp) -{ - if (m_method == ShiftTimestamp) { - timestamp = timestamp + getTimestampAdjustment(); - } - - for (int c = 0; c < m_channels; ++c) { - - for (int i = 0; i < m_blockSize; ++i) { - m_ri[i] = double(inputBuffers[c][i]) * m_window[i]; - } - - for (int i = 0; i < m_blockSize/2; ++i) { - // FFT shift - double value = m_ri[i]; - m_ri[i] = m_ri[i + m_blockSize/2]; - m_ri[i + m_blockSize/2] = value; - } - -#ifdef HAVE_FFTW3 - fftw_execute(m_plan); - - for (int i = 0; i <= m_blockSize/2; ++i) { - m_freqbuf[c][i * 2] = float(m_cbuf[i][0]); - m_freqbuf[c][i * 2 + 1] = float(m_cbuf[i][1]); - } -#else - fft(m_blockSize, false, m_ri, 0, m_ro, m_io); - - for (int i = 0; i <= m_blockSize/2; ++i) { - m_freqbuf[c][i * 2] = float(m_ro[i]); - m_freqbuf[c][i * 2 + 1] = float(m_io[i]); - } -#endif - } - - return m_plugin->process(m_freqbuf, timestamp); -} - -Plugin::FeatureSet -PluginInputDomainAdapter::Impl::processShiftingData(const float *const *inputBuffers, - RealTime timestamp) -{ - if (m_processCount == 0) { - if (!m_shiftBuffers) { - m_shiftBuffers = new float *[m_channels]; - for (int c = 0; c < m_channels; ++c) { - m_shiftBuffers[c] = new float[m_blockSize + m_blockSize/2]; - } - } - for (int c = 0; c < m_channels; ++c) { - for (int i = 0; i < m_blockSize + m_blockSize/2; ++i) { - m_shiftBuffers[c][i] = 0.f; - } - } - } - - for (int c = 0; c < m_channels; ++c) { - for (int i = m_stepSize; i < m_blockSize + m_blockSize/2; ++i) { - m_shiftBuffers[c][i - m_stepSize] = m_shiftBuffers[c][i]; - } - for (int i = 0; i < m_blockSize; ++i) { - m_shiftBuffers[c][i + m_blockSize/2] = inputBuffers[c][i]; - } - } - - for (int c = 0; c < m_channels; ++c) { - - for (int i = 0; i < m_blockSize; ++i) { - m_ri[i] = double(m_shiftBuffers[c][i]) * m_window[i]; - } - - for (int i = 0; i < m_blockSize/2; ++i) { - // FFT shift - double value = m_ri[i]; - m_ri[i] = m_ri[i + m_blockSize/2]; - m_ri[i + m_blockSize/2] = value; - } - -#ifdef HAVE_FFTW3 - fftw_execute(m_plan); - - for (int i = 0; i <= m_blockSize/2; ++i) { - m_freqbuf[c][i * 2] = float(m_cbuf[i][0]); - m_freqbuf[c][i * 2 + 1] = float(m_cbuf[i][1]); - } -#else - fft(m_blockSize, false, m_ri, 0, m_ro, m_io); - - for (int i = 0; i <= m_blockSize/2; ++i) { - m_freqbuf[c][i * 2] = float(m_ro[i]); - m_freqbuf[c][i * 2 + 1] = float(m_io[i]); - } -#endif - } - - ++m_processCount; - - return m_plugin->process(m_freqbuf, timestamp); -} - -#ifndef HAVE_FFTW3 - -void -PluginInputDomainAdapter::Impl::fft(unsigned int n, bool inverse, - double *ri, double *ii, double *ro, double *io) -{ - if (!ri || !ro || !io) return; - - unsigned int bits; - unsigned int i, j, k, m; - unsigned int blockSize, blockEnd; - - double tr, ti; - - if (n < 2) return; - if (n & (n-1)) return; - - double angle = 2.0 * M_PI; - if (inverse) angle = -angle; - - for (i = 0; ; ++i) { - if (n & (1 << i)) { - bits = i; - break; - } - } - - static unsigned int tableSize = 0; - static int *table = 0; - - if (tableSize != n) { - - delete[] table; - - table = new int[n]; - - for (i = 0; i < n; ++i) { - - m = i; - - for (j = k = 0; j < bits; ++j) { - k = (k << 1) | (m & 1); - m >>= 1; - } - - table[i] = k; - } - - tableSize = n; - } - - if (ii) { - for (i = 0; i < n; ++i) { - ro[table[i]] = ri[i]; - io[table[i]] = ii[i]; - } - } else { - for (i = 0; i < n; ++i) { - ro[table[i]] = ri[i]; - io[table[i]] = 0.0; - } - } - - blockEnd = 1; - - for (blockSize = 2; blockSize <= n; blockSize <<= 1) { - - double delta = angle / (double)blockSize; - double sm2 = -sin(-2 * delta); - double sm1 = -sin(-delta); - double cm2 = cos(-2 * delta); - double cm1 = cos(-delta); - double w = 2 * cm1; - double ar[3], ai[3]; - - for (i = 0; i < n; i += blockSize) { - - ar[2] = cm2; - ar[1] = cm1; - - ai[2] = sm2; - ai[1] = sm1; - - for (j = i, m = 0; m < blockEnd; j++, m++) { - - ar[0] = w * ar[1] - ar[2]; - ar[2] = ar[1]; - ar[1] = ar[0]; - - ai[0] = w * ai[1] - ai[2]; - ai[2] = ai[1]; - ai[1] = ai[0]; - - k = j + blockEnd; - tr = ar[0] * ro[k] - ai[0] * io[k]; - ti = ar[0] * io[k] + ai[0] * ro[k]; - - ro[k] = ro[j] - tr; - io[k] = io[j] - ti; - - ro[j] += tr; - io[j] += ti; - } - } - - blockEnd = blockSize; - } - - if (inverse) { - - double denom = (double)n; - - for (i = 0; i < n; i++) { - ro[i] /= denom; - io[i] /= denom; - } - } -} - -#endif - -} - -} - -_VAMP_SDK_HOSTSPACE_END(PluginInputDomainAdapter.cpp) - |