Mercurial > hg > vamp-plugin-sdk
changeset 288:283e15f6e548
* The beginnings of making the shift-timestamp or shift-data behaviour
of PluginInputDomainAdapter into an option
author | cannam |
---|---|
date | Tue, 15 Sep 2009 16:24:53 +0000 |
parents | f3b1ba71a305 |
children | 3e5ab1c7ea8c |
files | src/vamp-hostsdk/PluginInputDomainAdapter.cpp vamp-hostsdk/PluginInputDomainAdapter.h |
diffstat | 2 files changed, 135 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/src/vamp-hostsdk/PluginInputDomainAdapter.cpp Thu Sep 10 15:21:34 2009 +0000 +++ b/src/vamp-hostsdk/PluginInputDomainAdapter.cpp Tue Sep 15 16:24:53 2009 +0000 @@ -83,11 +83,15 @@ ~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,18 @@ 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; + FeatureSet prepadProcess(const float *const *inputBuffers, + RealTime timestamp); + #ifdef HAVE_FFTW3 fftw_plan m_plan; fftw_complex *m_cbuf; @@ -131,6 +141,12 @@ return m_impl->initialise(channels, stepSize, blockSize); } +void +PluginInputDomainAdapter::reset() +{ + m_impl->reset(); +} + Plugin::InputDomain PluginInputDomainAdapter::getInputDomain() const { @@ -155,6 +171,18 @@ 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 +194,13 @@ 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), #ifdef HAVE_FFTW3 m_plan(0), m_cbuf(0) @@ -215,6 +246,7 @@ { if (m_plugin->getInputDomain() == TimeDomain) { + m_stepSize = int(stepSize); m_blockSize = int(blockSize); m_channels = int(channels); @@ -251,6 +283,7 @@ delete[] m_window; } + m_stepSize = int(stepSize); m_blockSize = int(blockSize); m_channels = int(channels); @@ -275,9 +308,18 @@ 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 { @@ -360,6 +402,18 @@ } } +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) @@ -412,7 +466,15 @@ // std::cerr << "PluginInputDomainAdapter: sampleRate " << m_inputSampleRate << ", blocksize " << m_blockSize << ", adjusting time from " << timestamp; - timestamp = timestamp + getTimestampAdjustment(); + //!!! update the above comment for ProcessTimestampMethod + + FeatureSet fs; + if (m_method == ShiftTimestamp) { + timestamp = timestamp + getTimestampAdjustment(); + } else if (m_processCount == 0) { + fs = prepadProcess(inputBuffers, timestamp); + } + ++m_processCount; // std::cerr << " to " << timestamp << std::endl; @@ -450,7 +512,28 @@ #endif } - return m_plugin->process(m_freqbuf, timestamp); + FeatureSet pfs(m_plugin->process(m_freqbuf, timestamp)); + + if (!fs.empty()) { // add any prepad results back in + for (FeatureSet::const_iterator i = pfs.begin(); i != pfs.end(); ++i) { + for (FeatureList::const_iterator j = i->second.begin(); + j != i->second.end(); ++j) { + fs[i->first].push_back(*j); + } + } + pfs = fs; + } + + return pfs; +} + +Plugin::FeatureSet +PluginInputDomainAdapter::Impl::prepadProcess(const float *const *inputBuffers, + RealTime timestamp) +{ + FeatureSet fs; + //!!! + return fs; } #ifndef HAVE_FFTW3
--- a/vamp-hostsdk/PluginInputDomainAdapter.h Thu Sep 10 15:21:34 2009 +0000 +++ b/vamp-hostsdk/PluginInputDomainAdapter.h Tue Sep 15 16:24:53 2009 +0000 @@ -91,6 +91,7 @@ virtual ~PluginInputDomainAdapter(); bool initialise(size_t channels, size_t stepSize, size_t blockSize); + void reset(); InputDomain getInputDomain() const; @@ -100,6 +101,48 @@ 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 API mandates that the timestamp passed to the plugin + * for time-domain input should be the time of the first sample in + * the block, but the timestamp passed for frequency-domain input + * should be the timestamp of the centre of the block. + * + * Since we claim to permit the code that uses this plugin wrapper + * not to care whether the plugin itself has time or frequency + * domain input, that means that we need to ensure this timestamp + * is correctly adjusted ourselves, and the way we handle this is + * controlled by the ProcessTimestampMethod. + * + * If ProcessTimestampMethod is 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 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 padding at the start of + * the first process call. + * + * This function must be called before the first call to + * process(). + */ + enum ProcessTimestampMethod { + ShiftTimestamp, + ShiftData + }; + + void setProcessTimestampMethod(ProcessTimestampMethod); + ProcessTimestampMethod getProcessTimestampMethod() const; + + /** * Return the amount by which the timestamps supplied to process() * are being incremented when they are passed to the plugin's own * process() implementation. @@ -116,9 +159,13 @@ * 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;