upgrade VAMP SDK to latest (or newer) version

git-svn-id: svn://localhost/ardour2/branches/3.0@9030 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2011-03-02 12:38:17 +00:00
parent 3deba1921b
commit 730cdb38bc
16 changed files with 329 additions and 90 deletions

View file

@ -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;

View file

@ -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

View file

@ -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)

View file

@ -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,24 +83,33 @@ 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;
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;
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();
// std::cerr << " to " << timestamp << std::endl;
}
for (int c = 0; c < m_channels; ++c) {
@ -430,29 +463,87 @@ 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);
}
#ifndef HAVE_FFTW3
void

View file

@ -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,26 +270,39 @@ 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();

View file

@ -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

View file

@ -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

View file

@ -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
@ -169,6 +169,11 @@ PluginAdapterBase::Impl::getDescriptor()
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: "
<< "API version " << plugin->getVampApiVersion()
@ -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;

View file

@ -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

View file

@ -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

View file

@ -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;
@ -99,6 +100,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
@ -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;

View file

@ -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

View file

@ -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
};
/**

View file

@ -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

View file

@ -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.
*/

View file

@ -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)