summaryrefslogtreecommitdiff
path: root/libs/vamp-sdk/src/vamp-hostsdk/PluginInputDomainAdapter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/vamp-sdk/src/vamp-hostsdk/PluginInputDomainAdapter.cpp')
-rw-r--r--libs/vamp-sdk/src/vamp-hostsdk/PluginInputDomainAdapter.cpp673
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)
-