mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-16 11:46:25 +01:00
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:
parent
3deba1921b
commit
730cdb38bc
16 changed files with 329 additions and 90 deletions
|
|
@ -6,8 +6,8 @@
|
||||||
An API for audio analysis and feature extraction plugins.
|
An API for audio analysis and feature extraction plugins.
|
||||||
|
|
||||||
Centre for Digital Music, Queen Mary, University of London.
|
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.
|
This file by Mark Levy and Chris Cannam, Copyright 2007-2009 QMUL.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
Permission is hereby granted, free of charge, to any person
|
||||||
obtaining a copy of this software and associated documentation
|
obtaining a copy of this software and associated documentation
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "vamp-hostsdk/PluginBufferingAdapter.h"
|
#include "vamp-hostsdk/PluginBufferingAdapter.h"
|
||||||
|
#include "vamp-hostsdk/PluginInputDomainAdapter.h"
|
||||||
|
|
||||||
using std::vector;
|
using std::vector;
|
||||||
using std::map;
|
using std::map;
|
||||||
|
|
@ -652,6 +653,14 @@ PluginBufferingAdapter::Impl::processBlock(FeatureSet& allFeatureSets)
|
||||||
|
|
||||||
FeatureSet featureSet = m_plugin->process(m_buffers, timestamp);
|
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();
|
for (FeatureSet::iterator iter = featureSet.begin();
|
||||||
iter != featureSet.end(); ++iter) {
|
iter != featureSet.end(); ++iter) {
|
||||||
|
|
||||||
|
|
@ -667,14 +676,14 @@ PluginBufferingAdapter::Impl::processBlock(FeatureSet& allFeatureSets)
|
||||||
|
|
||||||
case OutputDescriptor::OneSamplePerStep:
|
case OutputDescriptor::OneSamplePerStep:
|
||||||
// use our internal timestamp, always
|
// use our internal timestamp, always
|
||||||
featureList[i].timestamp = timestamp;
|
featureList[i].timestamp = timestamp + adjustment;
|
||||||
featureList[i].hasTimestamp = true;
|
featureList[i].hasTimestamp = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OutputDescriptor::FixedSampleRate:
|
case OutputDescriptor::FixedSampleRate:
|
||||||
// use our internal timestamp if feature lacks one
|
// use our internal timestamp if feature lacks one
|
||||||
if (!featureList[i].hasTimestamp) {
|
if (!featureList[i].hasTimestamp) {
|
||||||
featureList[i].timestamp = timestamp;
|
featureList[i].timestamp = timestamp + adjustment;
|
||||||
featureList[i].hasTimestamp = true;
|
featureList[i].hasTimestamp = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
An API for audio analysis and feature extraction plugins.
|
An API for audio analysis and feature extraction plugins.
|
||||||
|
|
||||||
Centre for Digital Music, Queen Mary, University of London.
|
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
|
Permission is hereby granted, free of charge, to any person
|
||||||
obtaining a copy of this software and associated documentation
|
obtaining a copy of this software and associated documentation
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,8 @@
|
||||||
#include "vamp-hostsdk/PluginHostAdapter.h"
|
#include "vamp-hostsdk/PluginHostAdapter.h"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 0 )
|
#if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 2 )
|
||||||
#error Incorrect Vamp SDK header included (not the expected 2.0 SDK)
|
#error Unexpected version of Vamp SDK header included
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_VAMP_SDK_HOSTSPACE_BEGIN(PluginHostAdapter.cpp)
|
_VAMP_SDK_HOSTSPACE_BEGIN(PluginHostAdapter.cpp)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
An API for audio analysis and feature extraction plugins.
|
An API for audio analysis and feature extraction plugins.
|
||||||
|
|
||||||
Centre for Digital Music, Queen Mary, University of London.
|
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
|
This file is based in part on Don Cross's public domain FFT
|
||||||
implementation.
|
implementation.
|
||||||
|
|
@ -83,24 +83,33 @@ public:
|
||||||
~Impl();
|
~Impl();
|
||||||
|
|
||||||
bool initialise(size_t channels, size_t stepSize, size_t blockSize);
|
bool initialise(size_t channels, size_t stepSize, size_t blockSize);
|
||||||
|
void reset();
|
||||||
|
|
||||||
size_t getPreferredStepSize() const;
|
size_t getPreferredStepSize() const;
|
||||||
size_t getPreferredBlockSize() const;
|
size_t getPreferredBlockSize() const;
|
||||||
|
|
||||||
FeatureSet process(const float *const *inputBuffers, RealTime timestamp);
|
FeatureSet process(const float *const *inputBuffers, RealTime timestamp);
|
||||||
|
|
||||||
|
void setProcessTimestampMethod(ProcessTimestampMethod m);
|
||||||
|
ProcessTimestampMethod getProcessTimestampMethod() const;
|
||||||
|
|
||||||
RealTime getTimestampAdjustment() const;
|
RealTime getTimestampAdjustment() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Plugin *m_plugin;
|
Plugin *m_plugin;
|
||||||
float m_inputSampleRate;
|
float m_inputSampleRate;
|
||||||
int m_channels;
|
int m_channels;
|
||||||
|
int m_stepSize;
|
||||||
int m_blockSize;
|
int m_blockSize;
|
||||||
float **m_freqbuf;
|
float **m_freqbuf;
|
||||||
|
|
||||||
double *m_ri;
|
double *m_ri;
|
||||||
double *m_window;
|
double *m_window;
|
||||||
|
|
||||||
|
ProcessTimestampMethod m_method;
|
||||||
|
int m_processCount;
|
||||||
|
float **m_shiftBuffers;
|
||||||
|
|
||||||
#ifdef HAVE_FFTW3
|
#ifdef HAVE_FFTW3
|
||||||
fftw_plan m_plan;
|
fftw_plan m_plan;
|
||||||
fftw_complex *m_cbuf;
|
fftw_complex *m_cbuf;
|
||||||
|
|
@ -111,6 +120,9 @@ protected:
|
||||||
double *ri, double *ii, double *ro, double *io);
|
double *ri, double *ii, double *ro, double *io);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
FeatureSet processShiftingTimestamp(const float *const *inputBuffers, RealTime timestamp);
|
||||||
|
FeatureSet processShiftingData(const float *const *inputBuffers, RealTime timestamp);
|
||||||
|
|
||||||
size_t makeBlockSizeAcceptable(size_t) const;
|
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);
|
return m_impl->initialise(channels, stepSize, blockSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PluginInputDomainAdapter::reset()
|
||||||
|
{
|
||||||
|
m_impl->reset();
|
||||||
|
}
|
||||||
|
|
||||||
Plugin::InputDomain
|
Plugin::InputDomain
|
||||||
PluginInputDomainAdapter::getInputDomain() const
|
PluginInputDomainAdapter::getInputDomain() const
|
||||||
{
|
{
|
||||||
|
|
@ -155,6 +173,18 @@ PluginInputDomainAdapter::process(const float *const *inputBuffers, RealTime tim
|
||||||
return m_impl->process(inputBuffers, timestamp);
|
return m_impl->process(inputBuffers, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PluginInputDomainAdapter::setProcessTimestampMethod(ProcessTimestampMethod m)
|
||||||
|
{
|
||||||
|
m_impl->setProcessTimestampMethod(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginInputDomainAdapter::ProcessTimestampMethod
|
||||||
|
PluginInputDomainAdapter::getProcessTimestampMethod() const
|
||||||
|
{
|
||||||
|
return m_impl->getProcessTimestampMethod();
|
||||||
|
}
|
||||||
|
|
||||||
RealTime
|
RealTime
|
||||||
PluginInputDomainAdapter::getTimestampAdjustment() const
|
PluginInputDomainAdapter::getTimestampAdjustment() const
|
||||||
{
|
{
|
||||||
|
|
@ -166,10 +196,14 @@ PluginInputDomainAdapter::Impl::Impl(Plugin *plugin, float inputSampleRate) :
|
||||||
m_plugin(plugin),
|
m_plugin(plugin),
|
||||||
m_inputSampleRate(inputSampleRate),
|
m_inputSampleRate(inputSampleRate),
|
||||||
m_channels(0),
|
m_channels(0),
|
||||||
|
m_stepSize(0),
|
||||||
m_blockSize(0),
|
m_blockSize(0),
|
||||||
m_freqbuf(0),
|
m_freqbuf(0),
|
||||||
m_ri(0),
|
m_ri(0),
|
||||||
m_window(0),
|
m_window(0),
|
||||||
|
m_method(ShiftTimestamp),
|
||||||
|
m_processCount(0),
|
||||||
|
m_shiftBuffers(0),
|
||||||
#ifdef HAVE_FFTW3
|
#ifdef HAVE_FFTW3
|
||||||
m_plan(0),
|
m_plan(0),
|
||||||
m_cbuf(0)
|
m_cbuf(0)
|
||||||
|
|
@ -184,6 +218,13 @@ PluginInputDomainAdapter::Impl::~Impl()
|
||||||
{
|
{
|
||||||
// the adapter will delete the plugin
|
// 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) {
|
if (m_channels > 0) {
|
||||||
for (int c = 0; c < m_channels; ++c) {
|
for (int c = 0; c < m_channels; ++c) {
|
||||||
delete[] m_freqbuf[c];
|
delete[] m_freqbuf[c];
|
||||||
|
|
@ -215,6 +256,7 @@ PluginInputDomainAdapter::Impl::initialise(size_t channels, size_t stepSize, siz
|
||||||
{
|
{
|
||||||
if (m_plugin->getInputDomain() == TimeDomain) {
|
if (m_plugin->getInputDomain() == TimeDomain) {
|
||||||
|
|
||||||
|
m_stepSize = int(stepSize);
|
||||||
m_blockSize = int(blockSize);
|
m_blockSize = int(blockSize);
|
||||||
m_channels = int(channels);
|
m_channels = int(channels);
|
||||||
|
|
||||||
|
|
@ -222,12 +264,12 @@ PluginInputDomainAdapter::Impl::initialise(size_t channels, size_t stepSize, siz
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blockSize < 2) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blockSize & (blockSize-1)) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -251,6 +293,7 @@ PluginInputDomainAdapter::Impl::initialise(size_t channels, size_t stepSize, siz
|
||||||
delete[] m_window;
|
delete[] m_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_stepSize = int(stepSize);
|
||||||
m_blockSize = int(blockSize);
|
m_blockSize = int(blockSize);
|
||||||
m_channels = int(channels);
|
m_channels = int(channels);
|
||||||
|
|
||||||
|
|
@ -275,9 +318,18 @@ PluginInputDomainAdapter::Impl::initialise(size_t channels, size_t stepSize, siz
|
||||||
m_io = new double[m_blockSize];
|
m_io = new double[m_blockSize];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
m_processCount = 0;
|
||||||
|
|
||||||
return m_plugin->initialise(channels, stepSize, blockSize);
|
return m_plugin->initialise(channels, stepSize, blockSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PluginInputDomainAdapter::Impl::reset()
|
||||||
|
{
|
||||||
|
m_processCount = 0;
|
||||||
|
m_plugin->reset();
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
PluginInputDomainAdapter::Impl::getPreferredStepSize() const
|
PluginInputDomainAdapter::Impl::getPreferredStepSize() const
|
||||||
{
|
{
|
||||||
|
|
@ -311,7 +363,7 @@ PluginInputDomainAdapter::Impl::makeBlockSizeAcceptable(size_t blockSize) const
|
||||||
{
|
{
|
||||||
if (blockSize < 2) {
|
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;
|
<< "supported, increasing from " << blockSize << " to 2" << std::endl;
|
||||||
blockSize = 2;
|
blockSize = 2;
|
||||||
|
|
||||||
|
|
@ -340,7 +392,7 @@ PluginInputDomainAdapter::Impl::makeBlockSizeAcceptable(size_t blockSize) const
|
||||||
nearest = nearest*2;
|
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;
|
blockSize = nearest;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -354,12 +406,26 @@ PluginInputDomainAdapter::Impl::getTimestampAdjustment() const
|
||||||
{
|
{
|
||||||
if (m_plugin->getInputDomain() == TimeDomain) {
|
if (m_plugin->getInputDomain() == TimeDomain) {
|
||||||
return RealTime::zeroTime;
|
return RealTime::zeroTime;
|
||||||
|
} else if (m_method == ShiftData || m_method == NoShift) {
|
||||||
|
return RealTime::zeroTime;
|
||||||
} else {
|
} else {
|
||||||
return RealTime::frame2RealTime
|
return RealTime::frame2RealTime
|
||||||
(m_blockSize/2, int(m_inputSampleRate + 0.5));
|
(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
|
Plugin::FeatureSet
|
||||||
PluginInputDomainAdapter::Impl::process(const float *const *inputBuffers,
|
PluginInputDomainAdapter::Impl::process(const float *const *inputBuffers,
|
||||||
RealTime timestamp)
|
RealTime timestamp)
|
||||||
|
|
@ -368,53 +434,20 @@ PluginInputDomainAdapter::Impl::process(const float *const *inputBuffers,
|
||||||
return m_plugin->process(inputBuffers, timestamp);
|
return m_plugin->process(inputBuffers, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The timestamp supplied should be (according to the Vamp::Plugin
|
if (m_method == ShiftTimestamp || m_method == NoShift) {
|
||||||
// spec) the time of the start of the time-domain input block.
|
return processShiftingTimestamp(inputBuffers, timestamp);
|
||||||
// However, we want to pass to the plugin an FFT output calculated
|
} else {
|
||||||
// from the block of samples _centred_ on that timestamp.
|
return processShiftingData(inputBuffers, 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;
|
|
||||||
|
|
||||||
|
Plugin::FeatureSet
|
||||||
|
PluginInputDomainAdapter::Impl::processShiftingTimestamp(const float *const *inputBuffers,
|
||||||
|
RealTime timestamp)
|
||||||
|
{
|
||||||
|
if (m_method == ShiftTimestamp) {
|
||||||
timestamp = timestamp + getTimestampAdjustment();
|
timestamp = timestamp + getTimestampAdjustment();
|
||||||
|
}
|
||||||
// std::cerr << " to " << timestamp << std::endl;
|
|
||||||
|
|
||||||
for (int c = 0; c < m_channels; ++c) {
|
for (int c = 0; c < m_channels; ++c) {
|
||||||
|
|
||||||
|
|
@ -430,29 +463,87 @@ PluginInputDomainAdapter::Impl::process(const float *const *inputBuffers,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_FFTW3
|
#ifdef HAVE_FFTW3
|
||||||
|
|
||||||
fftw_execute(m_plan);
|
fftw_execute(m_plan);
|
||||||
|
|
||||||
for (int i = 0; i <= m_blockSize/2; ++i) {
|
for (int i = 0; i <= m_blockSize/2; ++i) {
|
||||||
m_freqbuf[c][i * 2] = float(m_cbuf[i][0]);
|
m_freqbuf[c][i * 2] = float(m_cbuf[i][0]);
|
||||||
m_freqbuf[c][i * 2 + 1] = float(m_cbuf[i][1]);
|
m_freqbuf[c][i * 2 + 1] = float(m_cbuf[i][1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
fft(m_blockSize, false, m_ri, 0, m_ro, m_io);
|
fft(m_blockSize, false, m_ri, 0, m_ro, m_io);
|
||||||
|
|
||||||
for (int i = 0; i <= m_blockSize/2; ++i) {
|
for (int i = 0; i <= m_blockSize/2; ++i) {
|
||||||
m_freqbuf[c][i * 2] = float(m_ro[i]);
|
m_freqbuf[c][i * 2] = float(m_ro[i]);
|
||||||
m_freqbuf[c][i * 2 + 1] = float(m_io[i]);
|
m_freqbuf[c][i * 2 + 1] = float(m_io[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_plugin->process(m_freqbuf, timestamp);
|
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
|
#ifndef HAVE_FFTW3
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
An API for audio analysis and feature extraction plugins.
|
An API for audio analysis and feature extraction plugins.
|
||||||
|
|
||||||
Centre for Digital Music, Queen Mary, University of London.
|
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
|
Permission is hereby granted, free of charge, to any person
|
||||||
obtaining a copy of this software and associated documentation
|
obtaining a copy of this software and associated documentation
|
||||||
|
|
@ -270,26 +270,39 @@ PluginLoader::Impl::enumeratePlugins(PluginKey forPlugin)
|
||||||
(handle, "vampGetPluginDescriptor");
|
(handle, "vampGetPluginDescriptor");
|
||||||
|
|
||||||
if (!fn) {
|
if (!fn) {
|
||||||
|
if (forPlugin != "") {
|
||||||
|
cerr << "Vamp::HostExt::PluginLoader: No vampGetPluginDescriptor function found in library \""
|
||||||
|
<< fullPath << "\"" << endl;
|
||||||
|
}
|
||||||
unloadLibrary(handle);
|
unloadLibrary(handle);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
const VampPluginDescriptor *descriptor = 0;
|
const VampPluginDescriptor *descriptor = 0;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
while ((descriptor = fn(VAMP_API_VERSION, index))) {
|
while ((descriptor = fn(VAMP_API_VERSION, index))) {
|
||||||
++index;
|
++index;
|
||||||
if (identifier != "") {
|
if (identifier != "") {
|
||||||
if (descriptor->identifier != identifier) continue;
|
if (descriptor->identifier != identifier) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
found = true;
|
||||||
PluginKey key = composePluginKey(*fi, descriptor->identifier);
|
PluginKey key = composePluginKey(*fi, descriptor->identifier);
|
||||||
// std::cerr << "enumerate: " << key << " (path: " << fullPath << ")" << std::endl;
|
|
||||||
if (m_pluginLibraryNameMap.find(key) ==
|
if (m_pluginLibraryNameMap.find(key) ==
|
||||||
m_pluginLibraryNameMap.end()) {
|
m_pluginLibraryNameMap.end()) {
|
||||||
m_pluginLibraryNameMap[key] = fullPath;
|
m_pluginLibraryNameMap[key] = fullPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!found && forPlugin != "") {
|
||||||
|
cerr << "Vamp::HostExt::PluginLoader: Plugin \""
|
||||||
|
<< identifier << "\" not found in library \""
|
||||||
|
<< fullPath << "\"" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
unloadLibrary(handle);
|
unloadLibrary(handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -345,9 +358,11 @@ PluginLoader::Impl::getLibraryPathForPlugin(PluginKey plugin)
|
||||||
{
|
{
|
||||||
if (m_pluginLibraryNameMap.find(plugin) == m_pluginLibraryNameMap.end()) {
|
if (m_pluginLibraryNameMap.find(plugin) == m_pluginLibraryNameMap.end()) {
|
||||||
if (m_allPluginsEnumerated) return "";
|
if (m_allPluginsEnumerated) return "";
|
||||||
|
cerr << "plug not found enumerate" << endl;
|
||||||
enumeratePlugins(plugin);
|
enumeratePlugins(plugin);
|
||||||
}
|
}
|
||||||
if (m_pluginLibraryNameMap.find(plugin) == m_pluginLibraryNameMap.end()) {
|
if (m_pluginLibraryNameMap.find(plugin) == m_pluginLibraryNameMap.end()) {
|
||||||
|
cerr << "plug not found enumerate" << endl;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return m_pluginLibraryNameMap[plugin];
|
return m_pluginLibraryNameMap[plugin];
|
||||||
|
|
@ -365,7 +380,10 @@ PluginLoader::Impl::loadPlugin(PluginKey key,
|
||||||
}
|
}
|
||||||
|
|
||||||
string fullPath = getLibraryPathForPlugin(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);
|
void *handle = loadLibrary(fullPath);
|
||||||
if (!handle) return 0;
|
if (!handle) return 0;
|
||||||
|
|
@ -375,6 +393,8 @@ PluginLoader::Impl::loadPlugin(PluginKey key,
|
||||||
(handle, "vampGetPluginDescriptor");
|
(handle, "vampGetPluginDescriptor");
|
||||||
|
|
||||||
if (!fn) {
|
if (!fn) {
|
||||||
|
cerr << "Vamp::HostExt::PluginLoader: No vampGetPluginDescriptor function found in library \""
|
||||||
|
<< fullPath << "\"" << endl;
|
||||||
unloadLibrary(handle);
|
unloadLibrary(handle);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -513,7 +533,21 @@ PluginLoader::Impl::loadLibrary(string path)
|
||||||
{
|
{
|
||||||
void *handle = 0;
|
void *handle = 0;
|
||||||
#ifdef _WIN32
|
#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());
|
handle = LoadLibrary(path.c_str());
|
||||||
|
#endif
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
cerr << "Vamp::HostExt::PluginLoader: Unable to load library \""
|
cerr << "Vamp::HostExt::PluginLoader: Unable to load library \""
|
||||||
<< path << "\"" << endl;
|
<< path << "\"" << endl;
|
||||||
|
|
@ -564,8 +598,41 @@ PluginLoader::Impl::listFiles(string dir, string extension)
|
||||||
vector<string> files;
|
vector<string> files;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
string expression = dir + "\\*." + extension;
|
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;
|
WIN32_FIND_DATA data;
|
||||||
HANDLE fh = FindFirstFile(expression.c_str(), &data);
|
HANDLE fh = FindFirstFile(expression.c_str(), &data);
|
||||||
if (fh == INVALID_HANDLE_VALUE) return files;
|
if (fh == INVALID_HANDLE_VALUE) return files;
|
||||||
|
|
@ -577,7 +644,7 @@ PluginLoader::Impl::listFiles(string dir, string extension)
|
||||||
}
|
}
|
||||||
|
|
||||||
FindClose(fh);
|
FindClose(fh);
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
|
|
||||||
size_t extlen = extension.length();
|
size_t extlen = extension.length();
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
An API for audio analysis and feature extraction plugins.
|
An API for audio analysis and feature extraction plugins.
|
||||||
|
|
||||||
Centre for Digital Music, Queen Mary, University of London.
|
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
|
Permission is hereby granted, free of charge, to any person
|
||||||
obtaining a copy of this software and associated documentation
|
obtaining a copy of this software and associated documentation
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
An API for audio analysis and feature extraction plugins.
|
An API for audio analysis and feature extraction plugins.
|
||||||
|
|
||||||
Centre for Digital Music, Queen Mary, University of London.
|
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
|
Permission is hereby granted, free of charge, to any person
|
||||||
obtaining a copy of this software and associated documentation
|
obtaining a copy of this software and associated documentation
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,8 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 0 )
|
#if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 2 )
|
||||||
#error Incorrect Vamp SDK header included (not the expected 2.0 SDK)
|
#error Unexpected version of Vamp SDK header included
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -169,6 +169,11 @@ PluginAdapterBase::Impl::getDescriptor()
|
||||||
|
|
||||||
Plugin *plugin = m_base->createPlugin(48000);
|
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) {
|
if (plugin->getVampApiVersion() != VAMP_API_VERSION) {
|
||||||
std::cerr << "Vamp::PluginAdapterBase::Impl::getDescriptor: ERROR: "
|
std::cerr << "Vamp::PluginAdapterBase::Impl::getDescriptor: ERROR: "
|
||||||
<< "API version " << plugin->getVampApiVersion()
|
<< "API version " << plugin->getVampApiVersion()
|
||||||
|
|
@ -583,7 +588,7 @@ PluginAdapterBase::Impl::vampGetRemainingFeatures(VampPluginHandle handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PluginAdapterBase::Impl::vampReleaseFeatureSet(VampFeatureList */*fs*/)
|
PluginAdapterBase::Impl::vampReleaseFeatureSet(VampFeatureList *fs)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||||
std::cerr << "PluginAdapterBase::Impl::vampReleaseFeatureSet" << std::endl;
|
std::cerr << "PluginAdapterBase::Impl::vampReleaseFeatureSet" << std::endl;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
An API for audio analysis and feature extraction plugins.
|
An API for audio analysis and feature extraction plugins.
|
||||||
|
|
||||||
Centre for Digital Music, Queen Mary, University of London.
|
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.
|
This file by Mark Levy and Chris Cannam, Copyright 2007-2008 QMUL.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
Permission is hereby granted, free of charge, to any person
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
An API for audio analysis and feature extraction plugins.
|
An API for audio analysis and feature extraction plugins.
|
||||||
|
|
||||||
Centre for Digital Music, Queen Mary, University of London.
|
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
|
Permission is hereby granted, free of charge, to any person
|
||||||
obtaining a copy of this software and associated documentation
|
obtaining a copy of this software and associated documentation
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
An API for audio analysis and feature extraction plugins.
|
An API for audio analysis and feature extraction plugins.
|
||||||
|
|
||||||
Centre for Digital Music, Queen Mary, University of London.
|
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
|
Permission is hereby granted, free of charge, to any person
|
||||||
obtaining a copy of this software and associated documentation
|
obtaining a copy of this software and associated documentation
|
||||||
|
|
@ -91,6 +91,7 @@ public:
|
||||||
virtual ~PluginInputDomainAdapter();
|
virtual ~PluginInputDomainAdapter();
|
||||||
|
|
||||||
bool initialise(size_t channels, size_t stepSize, size_t blockSize);
|
bool initialise(size_t channels, size_t stepSize, size_t blockSize);
|
||||||
|
void reset();
|
||||||
|
|
||||||
InputDomain getInputDomain() const;
|
InputDomain getInputDomain() const;
|
||||||
|
|
||||||
|
|
@ -99,6 +100,63 @@ public:
|
||||||
|
|
||||||
FeatureSet process(const float *const *inputBuffers, RealTime timestamp);
|
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()
|
* Return the amount by which the timestamps supplied to process()
|
||||||
* are being incremented when they are passed to the plugin's own
|
* 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
|
* timestamps) the host may need to be aware that this adjustment
|
||||||
* is taking place.
|
* is taking place.
|
||||||
*
|
*
|
||||||
* If the plugin requires time-domain input, this function will
|
* If the plugin requires time-domain input or the
|
||||||
* return zero. The result of calling this function before
|
* PluginInputDomainAdapter is configured with its
|
||||||
* initialise() has been called is undefined.
|
* 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;
|
RealTime getTimestampAdjustment() const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
An API for audio analysis and feature extraction plugins.
|
An API for audio analysis and feature extraction plugins.
|
||||||
|
|
||||||
Centre for Digital Music, Queen Mary, University of London.
|
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
|
Permission is hereby granted, free of charge, to any person
|
||||||
obtaining a copy of this software and associated documentation
|
obtaining a copy of this software and associated documentation
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
An API for audio analysis and feature extraction plugins.
|
An API for audio analysis and feature extraction plugins.
|
||||||
|
|
||||||
Centre for Digital Music, Queen Mary, University of London.
|
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
|
Permission is hereby granted, free of charge, to any person
|
||||||
obtaining a copy of this software and associated documentation
|
obtaining a copy of this software and associated documentation
|
||||||
|
|
@ -156,7 +156,7 @@ public:
|
||||||
*/
|
*/
|
||||||
enum AveragingMethod {
|
enum AveragingMethod {
|
||||||
SampleAverage = 0,
|
SampleAverage = 0,
|
||||||
ContinuousTimeAverage = 1,
|
ContinuousTimeAverage = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
An API for audio analysis and feature extraction plugins.
|
An API for audio analysis and feature extraction plugins.
|
||||||
|
|
||||||
Centre for Digital Music, Queen Mary, University of London.
|
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
|
Permission is hereby granted, free of charge, to any person
|
||||||
obtaining a copy of this software and associated documentation
|
obtaining a copy of this software and associated documentation
|
||||||
|
|
|
||||||
|
|
@ -152,12 +152,17 @@ public:
|
||||||
enum InputDomain { TimeDomain, FrequencyDomain };
|
enum InputDomain { TimeDomain, FrequencyDomain };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the plugin's required input domain. If this is TimeDomain,
|
* Get the plugin's required input domain.
|
||||||
* the samples provided to the process() function (below) will be
|
*
|
||||||
* in the time domain, as for a traditional audio processing
|
* If this is TimeDomain, the samples provided to the process()
|
||||||
* plugin. If this is FrequencyDomain, the host will carry out a
|
* function (below) will be in the time domain, as for a
|
||||||
* windowed FFT of size equal to the negotiated block size on the
|
* traditional audio processing plugin.
|
||||||
* data before passing the frequency bin data in to process().
|
*
|
||||||
|
* 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
|
* 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.
|
* will either let the user do so, or will use a Hanning window.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,9 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#define VAMP_SDK_VERSION "2.0"
|
#define VAMP_SDK_VERSION "3.5"
|
||||||
#define VAMP_SDK_MAJOR_VERSION 2
|
#define VAMP_SDK_MAJOR_VERSION 2
|
||||||
#define VAMP_SDK_MINOR_VERSION 0
|
#define VAMP_SDK_MINOR_VERSION 2
|
||||||
|
|
||||||
#include "plugguard.h"
|
#include "plugguard.h"
|
||||||
_VAMP_SDK_PLUGSPACE_BEGIN(PluginBase.h)
|
_VAMP_SDK_PLUGSPACE_BEGIN(PluginBase.h)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue