summaryrefslogtreecommitdiff
path: root/libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.cpp
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2008-01-29 14:53:08 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2008-01-29 14:53:08 +0000
commit3b0e89d43c6e261b7a9c50b07f714f8130bef325 (patch)
treef1dc775a3f6c32741a0e910a18bb52a6d62a7495 /libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.cpp
parent301009848c756dc25130f936978bb83663951b6d (diff)
merge to 2967 in vamp vendor branch
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2975 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.cpp')
-rw-r--r--libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.cpp145
1 files changed, 118 insertions, 27 deletions
diff --git a/libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.cpp b/libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.cpp
index d664486557..e706414ae2 100644
--- a/libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.cpp
+++ b/libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.cpp
@@ -38,6 +38,28 @@
#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.
+ *
+ * Remember that FFTW is licensed under the GPL (unlike this SDK, which
+ * is licensed liberally in order to permit closed-source usage), so
+ * you should not define this symbol unless your code is also under the
+ * GPL. Also, parties redistributing this SDK for use in other
+ * programs should be careful _not_ to define this symbol in order not
+ * to affect the stated license of this SDK.
+ *
+ * Note: This code uses FFTW_MEASURE, and 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
+
+
namespace Vamp {
namespace HostExt {
@@ -58,15 +80,22 @@ public:
protected:
Plugin *m_plugin;
float m_inputSampleRate;
- size_t m_channels;
- size_t m_blockSize;
+ int m_channels;
+ int m_blockSize;
float **m_freqbuf;
+
double *m_ri;
+ double *m_window;
+
+#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
size_t makeBlockSizeAcceptable(size_t) const;
};
@@ -117,7 +146,16 @@ PluginInputDomainAdapter::Impl::Impl(Plugin *plugin, float inputSampleRate) :
m_inputSampleRate(inputSampleRate),
m_channels(0),
m_blockSize(0),
- m_freqbuf(0)
+ m_freqbuf(0),
+ m_ri(0),
+ m_window(0),
+#ifdef HAVE_FFTW3
+ m_plan(0),
+ m_cbuf(0)
+#else
+ m_ro(0),
+ m_io(0)
+#endif
{
}
@@ -126,23 +164,38 @@ PluginInputDomainAdapter::Impl::~Impl()
// the adapter will delete the plugin
if (m_channels > 0) {
- for (size_t c = 0; c < m_channels; ++c) {
+ 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.14159265358979232846
+#endif
bool
PluginInputDomainAdapter::Impl::initialise(size_t channels, size_t stepSize, size_t blockSize)
{
if (m_plugin->getInputDomain() == TimeDomain) {
- m_blockSize = blockSize;
- m_channels = channels;
+ m_blockSize = int(blockSize);
+ m_channels = int(channels);
return m_plugin->initialise(channels, stepSize, blockSize);
}
@@ -158,25 +211,48 @@ PluginInputDomainAdapter::Impl::initialise(size_t channels, size_t stepSize, siz
}
if (m_channels > 0) {
- for (size_t c = 0; c < m_channels; ++c) {
+ 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_blockSize = blockSize;
- m_channels = channels;
+ m_blockSize = int(blockSize);
+ m_channels = int(channels);
m_freqbuf = new float *[m_channels];
- for (size_t c = 0; c < m_channels; ++c) {
+ 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
return m_plugin->initialise(channels, stepSize, blockSize);
}
@@ -220,7 +296,11 @@ PluginInputDomainAdapter::Impl::makeBlockSizeAcceptable(size_t blockSize) const
} else if (blockSize & (blockSize-1)) {
- // not a power of two, can't handle that with our current fft
+#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;
@@ -241,16 +321,13 @@ PluginInputDomainAdapter::Impl::makeBlockSizeAcceptable(size_t blockSize) const
std::cerr << "WARNING: Vamp::HostExt::PluginInputDomainAdapter::Impl::initialise: non-power-of-two\nblocksize " << blockSize << " not supported, using blocksize " << nearest << " instead" << std::endl;
blockSize = nearest;
+
+#endif
}
return blockSize;
}
-// for some visual studii apparently
-#ifndef M_PI
-#define M_PI 3.14159265358979232846
-#endif
-
Plugin::FeatureSet
PluginInputDomainAdapter::Impl::process(const float *const *inputBuffers,
RealTime timestamp)
@@ -308,33 +385,45 @@ PluginInputDomainAdapter::Impl::process(const float *const *inputBuffers,
// std::cerr << " to " << timestamp << std::endl;
- for (size_t c = 0; c < m_channels; ++c) {
+ for (int c = 0; c < m_channels; ++c) {
- for (size_t i = 0; i < m_blockSize; ++i) {
- // Hanning window
- m_ri[i] = double(inputBuffers[c][i])
- * (0.50 - 0.50 * cos((2 * M_PI * i)
- / m_blockSize));
+ for (int i = 0; i < m_blockSize; ++i) {
+ m_ri[i] = double(inputBuffers[c][i]) * m_window[i];
}
- for (size_t i = 0; i < m_blockSize/2; ++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 (size_t i = 0; i <= m_blockSize/2; ++i) {
- m_freqbuf[c][i * 2] = m_ro[i];
- m_freqbuf[c][i * 2 + 1] = m_io[i];
+ 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);
}
+#ifndef HAVE_FFTW3
+
void
PluginInputDomainAdapter::Impl::fft(unsigned int n, bool inverse,
double *ri, double *ii, double *ro, double *io)
@@ -452,6 +541,8 @@ PluginInputDomainAdapter::Impl::fft(unsigned int n, bool inverse,
}
}
+#endif
+
}
}