From 730cdb38bcefc6dd2af7bd62b3be42f0d4c57000 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 2 Mar 2011 12:38:17 +0000 Subject: upgrade VAMP SDK to latest (or newer) version git-svn-id: svn://localhost/ardour2/branches/3.0@9030 d708f5d6-7413-0410-9779-e7cbd77b26cf --- .../src/vamp-hostsdk/PluginBufferingAdapter.cpp | 17 +- .../src/vamp-hostsdk/PluginChannelAdapter.cpp | 2 +- .../src/vamp-hostsdk/PluginHostAdapter.cpp | 4 +- .../src/vamp-hostsdk/PluginInputDomainAdapter.cpp | 201 +++++++++++++++------ libs/vamp-sdk/src/vamp-hostsdk/PluginLoader.cpp | 77 +++++++- .../src/vamp-hostsdk/PluginSummarisingAdapter.cpp | 2 +- libs/vamp-sdk/src/vamp-hostsdk/PluginWrapper.cpp | 2 +- libs/vamp-sdk/src/vamp-sdk/PluginAdapter.cpp | 11 +- .../vamp-sdk/vamp-hostsdk/PluginBufferingAdapter.h | 2 +- libs/vamp-sdk/vamp-hostsdk/PluginChannelAdapter.h | 2 +- .../vamp-hostsdk/PluginInputDomainAdapter.h | 70 ++++++- libs/vamp-sdk/vamp-hostsdk/PluginLoader.h | 2 +- .../vamp-hostsdk/PluginSummarisingAdapter.h | 4 +- libs/vamp-sdk/vamp-hostsdk/PluginWrapper.h | 2 +- libs/vamp-sdk/vamp-sdk/Plugin.h | 17 +- libs/vamp-sdk/vamp-sdk/PluginBase.h | 4 +- 16 files changed, 329 insertions(+), 90 deletions(-) (limited to 'libs/vamp-sdk') 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 #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(m_plugin); + RealTime adjustment; + if (wrapper) { + PluginInputDomainAdapter *ida = + wrapper->getWrapper(); + 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 -#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 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 #include -#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; @@ -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; 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 #include -#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) -- cgit v1.2.3