summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2011-03-02 12:38:17 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2011-03-02 12:38:17 +0000
commit730cdb38bcefc6dd2af7bd62b3be42f0d4c57000 (patch)
tree66fa2e380b5037d6dd2877c2f59c5195b4c1e43b
parent3deba1921bcf5bddd8bea9846a203c92b6c9239d (diff)
upgrade VAMP SDK to latest (or newer) version
git-svn-id: svn://localhost/ardour2/branches/3.0@9030 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--libs/vamp-sdk/src/vamp-hostsdk/PluginBufferingAdapter.cpp17
-rw-r--r--libs/vamp-sdk/src/vamp-hostsdk/PluginChannelAdapter.cpp2
-rw-r--r--libs/vamp-sdk/src/vamp-hostsdk/PluginHostAdapter.cpp4
-rw-r--r--libs/vamp-sdk/src/vamp-hostsdk/PluginInputDomainAdapter.cpp201
-rw-r--r--libs/vamp-sdk/src/vamp-hostsdk/PluginLoader.cpp77
-rw-r--r--libs/vamp-sdk/src/vamp-hostsdk/PluginSummarisingAdapter.cpp2
-rw-r--r--libs/vamp-sdk/src/vamp-hostsdk/PluginWrapper.cpp2
-rw-r--r--libs/vamp-sdk/src/vamp-sdk/PluginAdapter.cpp11
-rw-r--r--libs/vamp-sdk/vamp-hostsdk/PluginBufferingAdapter.h2
-rw-r--r--libs/vamp-sdk/vamp-hostsdk/PluginChannelAdapter.h2
-rw-r--r--libs/vamp-sdk/vamp-hostsdk/PluginInputDomainAdapter.h70
-rw-r--r--libs/vamp-sdk/vamp-hostsdk/PluginLoader.h2
-rw-r--r--libs/vamp-sdk/vamp-hostsdk/PluginSummarisingAdapter.h4
-rw-r--r--libs/vamp-sdk/vamp-hostsdk/PluginWrapper.h2
-rw-r--r--libs/vamp-sdk/vamp-sdk/Plugin.h17
-rw-r--r--libs/vamp-sdk/vamp-sdk/PluginBase.h4
16 files changed, 329 insertions, 90 deletions
diff --git a/libs/vamp-sdk/src/vamp-hostsdk/PluginBufferingAdapter.cpp b/libs/vamp-sdk/src/vamp-hostsdk/PluginBufferingAdapter.cpp
index 797173d7f8..a14fe44086 100644
--- a/libs/vamp-sdk/src/vamp-hostsdk/PluginBufferingAdapter.cpp
+++ b/libs/vamp-sdk/src/vamp-hostsdk/PluginBufferingAdapter.cpp
@@ -6,8 +6,8 @@
An API for audio analysis and feature extraction plugins.
Centre for Digital Music, Queen Mary, University of London.
- Copyright 2006-2007 Chris Cannam and QMUL.
- This file by Mark Levy and Chris Cannam, Copyright 2007-2008 QMUL.
+ Copyright 2006-2009 Chris Cannam and QMUL.
+ This file by Mark Levy and Chris Cannam, Copyright 2007-2009 QMUL.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -39,6 +39,7 @@
#include <map>
#include "vamp-hostsdk/PluginBufferingAdapter.h"
+#include "vamp-hostsdk/PluginInputDomainAdapter.h"
using std::vector;
using std::map;
@@ -652,6 +653,14 @@ PluginBufferingAdapter::Impl::processBlock(FeatureSet& allFeatureSets)
FeatureSet featureSet = m_plugin->process(m_buffers, timestamp);
+ PluginWrapper *wrapper = dynamic_cast<PluginWrapper *>(m_plugin);
+ RealTime adjustment;
+ if (wrapper) {
+ PluginInputDomainAdapter *ida =
+ wrapper->getWrapper<PluginInputDomainAdapter>();
+ if (ida) adjustment = ida->getTimestampAdjustment();
+ }
+
for (FeatureSet::iterator iter = featureSet.begin();
iter != featureSet.end(); ++iter) {
@@ -667,14 +676,14 @@ PluginBufferingAdapter::Impl::processBlock(FeatureSet& allFeatureSets)
case OutputDescriptor::OneSamplePerStep:
// use our internal timestamp, always
- featureList[i].timestamp = timestamp;
+ featureList[i].timestamp = timestamp + adjustment;
featureList[i].hasTimestamp = true;
break;
case OutputDescriptor::FixedSampleRate:
// use our internal timestamp if feature lacks one
if (!featureList[i].hasTimestamp) {
- featureList[i].timestamp = timestamp;
+ featureList[i].timestamp = timestamp + adjustment;
featureList[i].hasTimestamp = true;
}
break;
diff --git a/libs/vamp-sdk/src/vamp-hostsdk/PluginChannelAdapter.cpp b/libs/vamp-sdk/src/vamp-hostsdk/PluginChannelAdapter.cpp
index 9a5abf5463..d259a259a6 100644
--- a/libs/vamp-sdk/src/vamp-hostsdk/PluginChannelAdapter.cpp
+++ b/libs/vamp-sdk/src/vamp-hostsdk/PluginChannelAdapter.cpp
@@ -6,7 +6,7 @@
An API for audio analysis and feature extraction plugins.
Centre for Digital Music, Queen Mary, University of London.
- Copyright 2006-2007 Chris Cannam and QMUL.
+ Copyright 2006-2009 Chris Cannam and QMUL.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
diff --git a/libs/vamp-sdk/src/vamp-hostsdk/PluginHostAdapter.cpp b/libs/vamp-sdk/src/vamp-hostsdk/PluginHostAdapter.cpp
index 051a9bb905..c30c98724e 100644
--- a/libs/vamp-sdk/src/vamp-hostsdk/PluginHostAdapter.cpp
+++ b/libs/vamp-sdk/src/vamp-hostsdk/PluginHostAdapter.cpp
@@ -37,8 +37,8 @@
#include "vamp-hostsdk/PluginHostAdapter.h"
#include <cstdlib>
-#if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 0 )
-#error Incorrect Vamp SDK header included (not the expected 2.0 SDK)
+#if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 2 )
+#error Unexpected version of Vamp SDK header included
#endif
_VAMP_SDK_HOSTSPACE_BEGIN(PluginHostAdapter.cpp)
diff --git a/libs/vamp-sdk/src/vamp-hostsdk/PluginInputDomainAdapter.cpp b/libs/vamp-sdk/src/vamp-hostsdk/PluginInputDomainAdapter.cpp
index e5b37b56ab..f1391b5bbd 100644
--- a/libs/vamp-sdk/src/vamp-hostsdk/PluginInputDomainAdapter.cpp
+++ b/libs/vamp-sdk/src/vamp-hostsdk/PluginInputDomainAdapter.cpp
@@ -6,7 +6,7 @@
An API for audio analysis and feature extraction plugins.
Centre for Digital Music, Queen Mary, University of London.
- Copyright 2006-2007 Chris Cannam and QMUL.
+ Copyright 2006-2009 Chris Cannam and QMUL.
This file is based in part on Don Cross's public domain FFT
implementation.
@@ -83,11 +83,15 @@ public:
~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;
@@ -95,12 +99,17 @@ 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;
@@ -111,6 +120,9 @@ protected:
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;
};
@@ -131,6 +143,12 @@ PluginInputDomainAdapter::initialise(size_t channels, size_t stepSize, size_t bl
return m_impl->initialise(channels, stepSize, blockSize);
}
+void
+PluginInputDomainAdapter::reset()
+{
+ m_impl->reset();
+}
+
Plugin::InputDomain
PluginInputDomainAdapter::getInputDomain() const
{
@@ -155,6 +173,18 @@ PluginInputDomainAdapter::process(const float *const *inputBuffers, RealTime tim
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
{
@@ -166,10 +196,14 @@ 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)
@@ -184,6 +218,13 @@ 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];
@@ -215,6 +256,7 @@ PluginInputDomainAdapter::Impl::initialise(size_t channels, size_t stepSize, siz
{
if (m_plugin->getInputDomain() == TimeDomain) {
+ m_stepSize = int(stepSize);
m_blockSize = int(blockSize);
m_channels = int(channels);
@@ -222,12 +264,12 @@ PluginInputDomainAdapter::Impl::initialise(size_t channels, size_t stepSize, siz
}
if (blockSize < 2) {
- std::cerr << "ERROR: Vamp::HostExt::PluginInputDomainAdapter::Impl::initialise: blocksize < 2 not supported" << std::endl;
+ std::cerr << "ERROR: PluginInputDomainAdapter::initialise: blocksize < 2 not supported" << std::endl;
return false;
}
if (blockSize & (blockSize-1)) {
- std::cerr << "ERROR: Vamp::HostExt::PluginInputDomainAdapter::Impl::initialise: non-power-of-two\nblocksize " << blockSize << " not supported" << std::endl;
+ std::cerr << "ERROR: PluginInputDomainAdapter::initialise: non-power-of-two\nblocksize " << blockSize << " not supported" << std::endl;
return false;
}
@@ -251,6 +293,7 @@ PluginInputDomainAdapter::Impl::initialise(size_t channels, size_t stepSize, siz
delete[] m_window;
}
+ m_stepSize = int(stepSize);
m_blockSize = int(blockSize);
m_channels = int(channels);
@@ -275,9 +318,18 @@ PluginInputDomainAdapter::Impl::initialise(size_t channels, size_t stepSize, siz
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
{
@@ -311,7 +363,7 @@ PluginInputDomainAdapter::Impl::makeBlockSizeAcceptable(size_t blockSize) const
{
if (blockSize < 2) {
- std::cerr << "WARNING: Vamp::HostExt::PluginInputDomainAdapter::Impl::initialise: blocksize < 2 not" << std::endl
+ std::cerr << "WARNING: PluginInputDomainAdapter::initialise: blocksize < 2 not" << std::endl
<< "supported, increasing from " << blockSize << " to 2" << std::endl;
blockSize = 2;
@@ -340,7 +392,7 @@ PluginInputDomainAdapter::Impl::makeBlockSizeAcceptable(size_t blockSize) const
nearest = nearest*2;
}
- std::cerr << "WARNING: Vamp::HostExt::PluginInputDomainAdapter::Impl::initialise: non-power-of-two\nblocksize " << blockSize << " not supported, using blocksize " << nearest << " instead" << std::endl;
+ std::cerr << "WARNING: PluginInputDomainAdapter::initialise: non-power-of-two\nblocksize " << blockSize << " not supported, using blocksize " << nearest << " instead" << std::endl;
blockSize = nearest;
#endif
@@ -354,12 +406,26 @@ 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)
@@ -368,53 +434,20 @@ PluginInputDomainAdapter::Impl::process(const float *const *inputBuffers,
return m_plugin->process(inputBuffers, timestamp);
}
- // The timestamp supplied should be (according to the Vamp::Plugin
- // spec) the time of the start of the time-domain input block.
- // However, we want to pass to the plugin an FFT output calculated
- // from the block of samples _centred_ on that timestamp.
- //
- // We have two options:
- //
- // 1. Buffer the input, calculating the fft of the values at the
- // passed-in block minus blockSize/2 rather than starting at the
- // passed-in block. So each time we call process on the plugin,
- // we are passing in the same timestamp as was passed to our own
- // process plugin, but not (the frequency domain representation
- // of) the same set of samples. Advantages: avoids confusion in
- // the host by ensuring the returned values have timestamps
- // comparable with that passed in to this function (in fact this
- // is pretty much essential for one-value-per-block outputs);
- // consistent with hosts such as SV that deal with the
- // frequency-domain transform themselves. Disadvantages: means
- // making the not necessarily correct assumption that the samples
- // preceding the first official block are all zero (or some other
- // known value).
- //
- // 2. Increase the passed-in timestamps by half the blocksize. So
- // when we call process, we are passing in the frequency domain
- // representation of the same set of samples as passed to us, but
- // with a different timestamp. Advantages: simplicity; avoids
- // iffy assumption mentioned above. Disadvantages: inconsistency
- // with SV in cases where stepSize != blockSize/2; potential
- // confusion arising from returned timestamps being calculated
- // from the adjusted input timestamps rather than the original
- // ones (and inaccuracy where the returned timestamp is implied,
- // as in one-value-per-block).
- //
- // Neither way is ideal, but I don't think either is strictly
- // incorrect either. I think this is just a case where the same
- // plugin can legitimately produce differing results from the same
- // input data, depending on how that data is packaged.
- //
- // We'll go for option 2, adjusting the timestamps. Note in
- // particular that this means some results can differ from those
- // produced by SV.
-
-// std::cerr << "PluginInputDomainAdapter: sampleRate " << m_inputSampleRate << ", blocksize " << m_blockSize << ", adjusting time from " << timestamp;
-
- timestamp = timestamp + getTimestampAdjustment();
-
-// std::cerr << " to " << timestamp << std::endl;
+ 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) {
@@ -430,26 +463,84 @@ PluginInputDomainAdapter::Impl::process(const float *const *inputBuffers,
}
#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);
}
diff --git a/libs/vamp-sdk/src/vamp-hostsdk/PluginLoader.cpp b/libs/vamp-sdk/src/vamp-hostsdk/PluginLoader.cpp
index 686a77c36c..83e9d45ef9 100644
--- a/libs/vamp-sdk/src/vamp-hostsdk/PluginLoader.cpp
+++ b/libs/vamp-sdk/src/vamp-hostsdk/PluginLoader.cpp
@@ -6,7 +6,7 @@
An API for audio analysis and feature extraction plugins.
Centre for Digital Music, Queen Mary, University of London.
- Copyright 2006-2007 Chris Cannam and QMUL.
+ Copyright 2006-2009 Chris Cannam and QMUL.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -270,25 +270,38 @@ PluginLoader::Impl::enumeratePlugins(PluginKey forPlugin)
(handle, "vampGetPluginDescriptor");
if (!fn) {
+ if (forPlugin != "") {
+ cerr << "Vamp::HostExt::PluginLoader: No vampGetPluginDescriptor function found in library \""
+ << fullPath << "\"" << endl;
+ }
unloadLibrary(handle);
continue;
}
int index = 0;
const VampPluginDescriptor *descriptor = 0;
+ bool found = false;
while ((descriptor = fn(VAMP_API_VERSION, index))) {
++index;
if (identifier != "") {
if (descriptor->identifier != identifier) continue;
}
+
+ found = true;
PluginKey key = composePluginKey(*fi, descriptor->identifier);
-// std::cerr << "enumerate: " << key << " (path: " << fullPath << ")" << std::endl;
+
if (m_pluginLibraryNameMap.find(key) ==
m_pluginLibraryNameMap.end()) {
m_pluginLibraryNameMap[key] = fullPath;
}
}
+
+ if (!found && forPlugin != "") {
+ cerr << "Vamp::HostExt::PluginLoader: Plugin \""
+ << identifier << "\" not found in library \""
+ << fullPath << "\"" << endl;
+ }
unloadLibrary(handle);
}
@@ -345,9 +358,11 @@ PluginLoader::Impl::getLibraryPathForPlugin(PluginKey plugin)
{
if (m_pluginLibraryNameMap.find(plugin) == m_pluginLibraryNameMap.end()) {
if (m_allPluginsEnumerated) return "";
+ cerr << "plug not found enumerate" << endl;
enumeratePlugins(plugin);
}
if (m_pluginLibraryNameMap.find(plugin) == m_pluginLibraryNameMap.end()) {
+ cerr << "plug not found enumerate" << endl;
return "";
}
return m_pluginLibraryNameMap[plugin];
@@ -365,7 +380,10 @@ PluginLoader::Impl::loadPlugin(PluginKey key,
}
string fullPath = getLibraryPathForPlugin(key);
- if (fullPath == "") return 0;
+ if (fullPath == "") {
+ std::cerr << "Vamp::HostExt::PluginLoader: No library found in Vamp path for plugin \"" << key << "\"" << std::endl;
+ return 0;
+ }
void *handle = loadLibrary(fullPath);
if (!handle) return 0;
@@ -375,6 +393,8 @@ PluginLoader::Impl::loadPlugin(PluginKey key,
(handle, "vampGetPluginDescriptor");
if (!fn) {
+ cerr << "Vamp::HostExt::PluginLoader: No vampGetPluginDescriptor function found in library \""
+ << fullPath << "\"" << endl;
unloadLibrary(handle);
return 0;
}
@@ -513,7 +533,21 @@ PluginLoader::Impl::loadLibrary(string path)
{
void *handle = 0;
#ifdef _WIN32
+#ifdef UNICODE
+ int len = path.length(); // cannot be more wchars than length in bytes of utf8 string
+ wchar_t *buffer = new wchar_t[len];
+ int rv = MultiByteToWideChar(CP_UTF8, 0, path.c_str(), len, buffer, len);
+ if (rv <= 0) {
+ cerr << "Vamp::HostExt::PluginLoader: Unable to convert library path \""
+ << path << "\" to wide characters " << endl;
+ delete[] buffer;
+ return handle;
+ }
+ handle = LoadLibrary(buffer);
+ delete[] buffer;
+#else
handle = LoadLibrary(path.c_str());
+#endif
if (!handle) {
cerr << "Vamp::HostExt::PluginLoader: Unable to load library \""
<< path << "\"" << endl;
@@ -564,8 +598,41 @@ PluginLoader::Impl::listFiles(string dir, string extension)
vector<string> files;
#ifdef _WIN32
-
string expression = dir + "\\*." + extension;
+#ifdef UNICODE
+ int len = expression.length(); // cannot be more wchars than length in bytes of utf8 string
+ wchar_t *buffer = new wchar_t[len];
+ int rv = MultiByteToWideChar(CP_UTF8, 0, expression.c_str(), len, buffer, len);
+ if (rv <= 0) {
+ cerr << "Vamp::HostExt::PluginLoader: Unable to convert wildcard path \""
+ << expression << "\" to wide characters" << endl;
+ delete[] buffer;
+ return files;
+ }
+ WIN32_FIND_DATA data;
+ HANDLE fh = FindFirstFile(buffer, &data);
+ if (fh == INVALID_HANDLE_VALUE) {
+ delete[] buffer;
+ return files;
+ }
+
+ bool ok = true;
+ while (ok) {
+ wchar_t *fn = data.cFileName;
+ int wlen = wcslen(fn);
+ int maxlen = wlen * 6;
+ char *conv = new char[maxlen];
+ int rv = WideCharToMultiByte(CP_UTF8, 0, fn, wlen, conv, maxlen, 0, 0);
+ if (rv > 0) {
+ files.push_back(conv);
+ }
+ delete[] conv;
+ ok = FindNextFile(fh, &data);
+ }
+
+ FindClose(fh);
+ delete[] buffer;
+#else
WIN32_FIND_DATA data;
HANDLE fh = FindFirstFile(expression.c_str(), &data);
if (fh == INVALID_HANDLE_VALUE) return files;
@@ -577,7 +644,7 @@ PluginLoader::Impl::listFiles(string dir, string extension)
}
FindClose(fh);
-
+#endif
#else
size_t extlen = extension.length();
diff --git a/libs/vamp-sdk/src/vamp-hostsdk/PluginSummarisingAdapter.cpp b/libs/vamp-sdk/src/vamp-hostsdk/PluginSummarisingAdapter.cpp
index 4a1a63da73..e3547a3daa 100644
--- a/libs/vamp-sdk/src/vamp-hostsdk/PluginSummarisingAdapter.cpp
+++ b/libs/vamp-sdk/src/vamp-hostsdk/PluginSummarisingAdapter.cpp
@@ -6,7 +6,7 @@
An API for audio analysis and feature extraction plugins.
Centre for Digital Music, Queen Mary, University of London.
- Copyright 2006-2008 Chris Cannam and QMUL.
+ Copyright 2006-2009 Chris Cannam and QMUL.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
diff --git a/libs/vamp-sdk/src/vamp-hostsdk/PluginWrapper.cpp b/libs/vamp-sdk/src/vamp-hostsdk/PluginWrapper.cpp
index dc076f8b53..9defb8cf36 100644
--- a/libs/vamp-sdk/src/vamp-hostsdk/PluginWrapper.cpp
+++ b/libs/vamp-sdk/src/vamp-hostsdk/PluginWrapper.cpp
@@ -6,7 +6,7 @@
An API for audio analysis and feature extraction plugins.
Centre for Digital Music, Queen Mary, University of London.
- Copyright 2006-2007 Chris Cannam and QMUL.
+ Copyright 2006-2009 Chris Cannam and QMUL.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
diff --git a/libs/vamp-sdk/src/vamp-sdk/PluginAdapter.cpp b/libs/vamp-sdk/src/vamp-sdk/PluginAdapter.cpp
index f8d4bf2d28..5a4593dde8 100644
--- a/libs/vamp-sdk/src/vamp-sdk/PluginAdapter.cpp
+++ b/libs/vamp-sdk/src/vamp-sdk/PluginAdapter.cpp
@@ -39,8 +39,8 @@
#include <cstring>
#include <cstdlib>
-#if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 0 )
-#error Incorrect Vamp SDK header included (not the expected 2.0 SDK)
+#if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 2 )
+#error Unexpected version of Vamp SDK header included
#endif
@@ -168,6 +168,11 @@ PluginAdapterBase::Impl::getDescriptor()
if (m_populated) return &m_descriptor;
Plugin *plugin = m_base->createPlugin(48000);
+
+ if (!plugin) {
+ std::cerr << "PluginAdapterBase::Impl::getDescriptor: Failed to create plugin" << std::endl;
+ return 0;
+ }
if (plugin->getVampApiVersion() != VAMP_API_VERSION) {
std::cerr << "Vamp::PluginAdapterBase::Impl::getDescriptor: ERROR: "
@@ -583,7 +588,7 @@ PluginAdapterBase::Impl::vampGetRemainingFeatures(VampPluginHandle handle)
}
void
-PluginAdapterBase::Impl::vampReleaseFeatureSet(VampFeatureList */*fs*/)
+PluginAdapterBase::Impl::vampReleaseFeatureSet(VampFeatureList *fs)
{
#ifdef DEBUG_PLUGIN_ADAPTER
std::cerr << "PluginAdapterBase::Impl::vampReleaseFeatureSet" << std::endl;
diff --git a/libs/vamp-sdk/vamp-hostsdk/PluginBufferingAdapter.h b/libs/vamp-sdk/vamp-hostsdk/PluginBufferingAdapter.h
index 21c2b36d74..0236a7ad9b 100644
--- a/libs/vamp-sdk/vamp-hostsdk/PluginBufferingAdapter.h
+++ b/libs/vamp-sdk/vamp-hostsdk/PluginBufferingAdapter.h
@@ -6,7 +6,7 @@
An API for audio analysis and feature extraction plugins.
Centre for Digital Music, Queen Mary, University of London.
- Copyright 2006-2007 Chris Cannam and QMUL.
+ Copyright 2006-2009 Chris Cannam and QMUL.
This file by Mark Levy and Chris Cannam, Copyright 2007-2008 QMUL.
Permission is hereby granted, free of charge, to any person
diff --git a/libs/vamp-sdk/vamp-hostsdk/PluginChannelAdapter.h b/libs/vamp-sdk/vamp-hostsdk/PluginChannelAdapter.h
index 28ee82ae7d..a0c2333d3f 100644
--- a/libs/vamp-sdk/vamp-hostsdk/PluginChannelAdapter.h
+++ b/libs/vamp-sdk/vamp-hostsdk/PluginChannelAdapter.h
@@ -6,7 +6,7 @@
An API for audio analysis and feature extraction plugins.
Centre for Digital Music, Queen Mary, University of London.
- Copyright 2006-2007 Chris Cannam and QMUL.
+ Copyright 2006-2009 Chris Cannam and QMUL.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
diff --git a/libs/vamp-sdk/vamp-hostsdk/PluginInputDomainAdapter.h b/libs/vamp-sdk/vamp-hostsdk/PluginInputDomainAdapter.h
index 7f7c11c3be..f0fe7da5c4 100644
--- a/libs/vamp-sdk/vamp-hostsdk/PluginInputDomainAdapter.h
+++ b/libs/vamp-sdk/vamp-hostsdk/PluginInputDomainAdapter.h
@@ -6,7 +6,7 @@
An API for audio analysis and feature extraction plugins.
Centre for Digital Music, Queen Mary, University of London.
- Copyright 2006-2007 Chris Cannam and QMUL.
+ Copyright 2006-2009 Chris Cannam and QMUL.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -91,6 +91,7 @@ public:
virtual ~PluginInputDomainAdapter();
bool initialise(size_t channels, size_t stepSize, size_t blockSize);
+ void reset();
InputDomain getInputDomain() const;
@@ -100,6 +101,63 @@ public:
FeatureSet process(const float *const *inputBuffers, RealTime timestamp);
/**
+ * ProcessTimestampMethod determines how the
+ * PluginInputDomainAdapter handles timestamps for the data passed
+ * to the process() function of the plugin it wraps, in the case
+ * where the plugin is expecting frequency-domain data.
+ *
+ * The Vamp specification requires that the timestamp passed to
+ * the plugin for frequency-domain input should be that of the
+ * centre of the processing block, rather than the start as is the
+ * case for time-domain input.
+ *
+ * Since PluginInputDomainAdapter aims to be transparent in use,
+ * it needs to handle this timestamp adjustment itself. However,
+ * some control is available over the method used for adjustment,
+ * by means of the ProcessTimestampMethod setting.
+ *
+ * If ProcessTimestampMethod is set to ShiftTimestamp (the
+ * default), then the data passed to the wrapped plugin will be
+ * calculated from the same input data block as passed to the
+ * wrapper, but the timestamp passed to the plugin will be
+ * advanced by half of the window size.
+ *
+ * If ProcessTimestampMethod is set to ShiftData, then the
+ * timestamp passed to the wrapped plugin will be the same as that
+ * passed to the process call of the wrapper, but the data block
+ * used to calculate the input will be shifted back (earlier) by
+ * half of the window size, with half a block of zero padding at
+ * the start of the first process call. This has the advantage of
+ * preserving the first half block of audio without any
+ * deterioration from window shaping.
+ *
+ * If ProcessTimestampMethod is set to NoShift, then no adjustment
+ * will be made and the timestamps will be incorrect.
+ */
+ enum ProcessTimestampMethod {
+ ShiftTimestamp,
+ ShiftData,
+ NoShift
+ };
+
+ /**
+ * Set the method used for timestamp adjustment in plugins taking
+ * frequency-domain input. See the ProcessTimestampMethod
+ * documentation for details.
+ *
+ * This function must be called before the first call to
+ * process().
+ */
+ void setProcessTimestampMethod(ProcessTimestampMethod);
+
+ /**
+ * Retrieve the method used for timestamp adjustment in plugins
+ * taking frequency-domain input. See the ProcessTimestampMethod
+ * documentation for details.
+ */
+ ProcessTimestampMethod getProcessTimestampMethod() const;
+
+ /**
* Return the amount by which the timestamps supplied to process()
* are being incremented when they are passed to the plugin's own
* process() implementation.
@@ -116,9 +174,13 @@ public:
* timestamps) the host may need to be aware that this adjustment
* is taking place.
*
- * If the plugin requires time-domain input, this function will
- * return zero. The result of calling this function before
- * initialise() has been called is undefined.
+ * If the plugin requires time-domain input or the
+ * PluginInputDomainAdapter is configured with its
+ * ProcessTimestampMethod set to ShiftData instead of
+ * ShiftTimestamp, then this function will return zero.
+ *
+ * The result of calling this function before initialise() has
+ * been called is undefined.
*/
RealTime getTimestampAdjustment() const;
diff --git a/libs/vamp-sdk/vamp-hostsdk/PluginLoader.h b/libs/vamp-sdk/vamp-hostsdk/PluginLoader.h
index 4d1daffd25..eadaf03f92 100644
--- a/libs/vamp-sdk/vamp-hostsdk/PluginLoader.h
+++ b/libs/vamp-sdk/vamp-hostsdk/PluginLoader.h
@@ -6,7 +6,7 @@
An API for audio analysis and feature extraction plugins.
Centre for Digital Music, Queen Mary, University of London.
- Copyright 2006-2007 Chris Cannam and QMUL.
+ Copyright 2006-2009 Chris Cannam and QMUL.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
diff --git a/libs/vamp-sdk/vamp-hostsdk/PluginSummarisingAdapter.h b/libs/vamp-sdk/vamp-hostsdk/PluginSummarisingAdapter.h
index e9c14f5d2b..ba18a9a971 100644
--- a/libs/vamp-sdk/vamp-hostsdk/PluginSummarisingAdapter.h
+++ b/libs/vamp-sdk/vamp-hostsdk/PluginSummarisingAdapter.h
@@ -6,7 +6,7 @@
An API for audio analysis and feature extraction plugins.
Centre for Digital Music, Queen Mary, University of London.
- Copyright 2006-2008 Chris Cannam and QMUL.
+ Copyright 2006-2009 Chris Cannam and QMUL.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -156,7 +156,7 @@ public:
*/
enum AveragingMethod {
SampleAverage = 0,
- ContinuousTimeAverage = 1,
+ ContinuousTimeAverage = 1
};
/**
diff --git a/libs/vamp-sdk/vamp-hostsdk/PluginWrapper.h b/libs/vamp-sdk/vamp-hostsdk/PluginWrapper.h
index 6b246e9f69..2cc060548f 100644
--- a/libs/vamp-sdk/vamp-hostsdk/PluginWrapper.h
+++ b/libs/vamp-sdk/vamp-hostsdk/PluginWrapper.h
@@ -6,7 +6,7 @@
An API for audio analysis and feature extraction plugins.
Centre for Digital Music, Queen Mary, University of London.
- Copyright 2006-2007 Chris Cannam and QMUL.
+ Copyright 2006-2009 Chris Cannam and QMUL.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
diff --git a/libs/vamp-sdk/vamp-sdk/Plugin.h b/libs/vamp-sdk/vamp-sdk/Plugin.h
index 4709b19b67..9513671dde 100644
--- a/libs/vamp-sdk/vamp-sdk/Plugin.h
+++ b/libs/vamp-sdk/vamp-sdk/Plugin.h
@@ -152,12 +152,17 @@ public:
enum InputDomain { TimeDomain, FrequencyDomain };
/**
- * Get the plugin's required input domain. If this is TimeDomain,
- * the samples provided to the process() function (below) will be
- * in the time domain, as for a traditional audio processing
- * plugin. If this is FrequencyDomain, the host will carry out a
- * windowed FFT of size equal to the negotiated block size on the
- * data before passing the frequency bin data in to process().
+ * Get the plugin's required input domain.
+ *
+ * If this is TimeDomain, the samples provided to the process()
+ * function (below) will be in the time domain, as for a
+ * traditional audio processing plugin.
+ *
+ * If this is FrequencyDomain, the host will carry out a windowed
+ * FFT of size equal to the negotiated block size on the data
+ * before passing the frequency bin data in to process(). The
+ * input data for the FFT will be rotated so as to place the
+ * origin in the centre of the block.
* The plugin does not get to choose the window type -- the host
* will either let the user do so, or will use a Hanning window.
*/
diff --git a/libs/vamp-sdk/vamp-sdk/PluginBase.h b/libs/vamp-sdk/vamp-sdk/PluginBase.h
index 147ffdc153..db8987ef8f 100644
--- a/libs/vamp-sdk/vamp-sdk/PluginBase.h
+++ b/libs/vamp-sdk/vamp-sdk/PluginBase.h
@@ -40,9 +40,9 @@
#include <string>
#include <vector>
-#define VAMP_SDK_VERSION "2.0"
+#define VAMP_SDK_VERSION "3.5"
#define VAMP_SDK_MAJOR_VERSION 2
-#define VAMP_SDK_MINOR_VERSION 0
+#define VAMP_SDK_MINOR_VERSION 2
#include "plugguard.h"
_VAMP_SDK_PLUGSPACE_BEGIN(PluginBase.h)