Mercurial > hg > svapp
changeset 740:846970dbef17 audio-source-refactor
Use shared_ptr for plugin instances throughout
author | Chris Cannam |
---|---|
date | Fri, 20 Mar 2020 16:31:58 +0000 |
parents | ddfac001b543 |
children | 6508d9d216c7 |
files | audio/AudioCallbackPlaySource.cpp audio/EffectWrapper.cpp audio/TimeStretchWrapper.cpp audio/TimeStretchWrapper.h framework/TransformUserConfigurator.cpp framework/TransformUserConfigurator.h |
diffstat | 6 files changed, 88 insertions(+), 42 deletions(-) [+] |
line wrap: on
line diff
--- a/audio/AudioCallbackPlaySource.cpp Thu Mar 19 16:14:02 2020 +0000 +++ b/audio/AudioCallbackPlaySource.cpp Fri Mar 20 16:31:58 2020 +0000 @@ -988,6 +988,9 @@ void AudioCallbackPlaySource::setAuditioningEffect(std::shared_ptr<Auditionable> a) { + SVDEBUG << "AudioCallbackPlaySource::setAuditioningEffect(" << a << ")" + << endl; + auto plugin = std::dynamic_pointer_cast<RealTimePluginInstance>(a); if (a && !plugin) { SVCERR << "WARNING: AudioCallbackPlaySource::setAuditioningEffect: auditionable object " << a << " is not a real-time plugin instance" << endl;
--- a/audio/EffectWrapper.cpp Thu Mar 19 16:14:02 2020 +0000 +++ b/audio/EffectWrapper.cpp Fri Mar 20 16:31:58 2020 +0000 @@ -18,6 +18,8 @@ #include "base/Debug.h" +//#define DEBUG_EFFECT_WRAPPER 1 + using namespace std; static const int DEFAULT_RING_BUFFER_SIZE = 131071; @@ -39,6 +41,11 @@ { lock_guard<mutex> guard(m_mutex); +#ifdef DEBUG_EFFECT_WRAPPER + SVCERR << "EffectWrapper[" << this + << "]::setEffect(" << effect.lock() << ")" << endl; +#endif + m_effect = effect; m_failed = false; } @@ -48,6 +55,11 @@ { lock_guard<mutex> guard(m_mutex); +#ifdef DEBUG_EFFECT_WRAPPER + SVCERR << "EffectWrapper[" << this + << "]::setBypassed(" << bypassed << ")" << endl; +#endif + m_bypassed = bypassed; } @@ -64,9 +76,15 @@ { lock_guard<mutex> guard(m_mutex); +#ifdef DEBUG_EFFECT_WRAPPER + SVCERR << "EffectWrapper[" << this << "]::reset" << endl; +#endif + for (auto &rb: m_effectOutputBuffers) { rb.reset(); } + + m_failed = false; } int @@ -75,16 +93,33 @@ { lock_guard<mutex> guard(m_mutex); +#ifdef DEBUG_EFFECT_WRAPPER + SVCERR << "EffectWrapper[" << this << "]::getSourceSamples: " << nframes + << " frames across " << nchannels << " channels" << endl; +#endif + auto effect(m_effect.lock()); - if (!effect || m_bypassed || m_failed) { + if (!effect) { +#ifdef DEBUG_EFFECT_WRAPPER + SVCERR << "EffectWrapper::getSourceSamples: " + << "no effect is set" << endl; +#endif return m_source->getSourceSamples(samples, nchannels, nframes); } + if (m_bypassed || m_failed) { +#ifdef DEBUG_EFFECT_WRAPPER + SVCERR << "EffectWrapper::getSourceSamples: " + << "effect is bypassed or has failed" << endl; +#endif + return m_source->getSourceSamples(samples, nchannels, nframes); + } + static int warnings = 0; if (nchannels != m_channelCount) { if (warnings >= 0) { - SVCERR << "WARNING: getSourceSamples called for a number of channels different from that set with setSystemPlaybackChannelCount (" + SVCERR << "WARNING: EffectWrapper::getSourceSamples called for a number of channels different from that set with setSystemPlaybackChannelCount (" << nchannels << " vs " << m_channelCount << ")" << endl; if (++warnings == 6) { SVCERR << "(further warnings will be suppressed)" << endl; @@ -126,13 +161,13 @@ int blockSize = effect->getBufferSize(); int got = 0; - int offset = 0; while (got < nframes) { int read = 0; for (int c = 0; c < nchannels; ++c) { - read = m_effectOutputBuffers[c].read(samples[c], nframes - got); + read = m_effectOutputBuffers[c].read(samples[c] + got, + nframes - got); } got += read; @@ -142,6 +177,10 @@ int toRun = m_source->getSourceSamples(ib, nchannels, blockSize); if (toRun <= 0) break; +#ifdef DEBUG_EFFECT_WRAPPER + SVCERR << "EffectWrapper::getSourceSamples: Running effect " + << "for " << toRun << " frames" << endl; +#endif effect->run(Vamp::RealTime::zeroTime, toRun); for (int c = 0; c < nchannels; ++c) { @@ -158,6 +197,10 @@ { { lock_guard<mutex> guard(m_mutex); +#ifdef DEBUG_EFFECT_WRAPPER + SVCERR << "EffectWrapper[" << this + << "]::setSystemPlaybackChannelCount(" << count << ")" << endl; +#endif m_effectOutputBuffers.resize (count, RingBuffer<float>(DEFAULT_RING_BUFFER_SIZE)); m_channelCount = count;
--- a/audio/TimeStretchWrapper.cpp Thu Mar 19 16:14:02 2020 +0000 +++ b/audio/TimeStretchWrapper.cpp Fri Mar 20 16:31:58 2020 +0000 @@ -85,9 +85,6 @@ return m_source->getSourceSamples(samples, nchannels, nframes); } - sv_frame_t available; - sv_frame_t fedToStretcher = 0; - vector<float *> inputPtrs(m_channelCount, nullptr); for (int i = 0; i < m_channelCount; ++i) { inputPtrs[i] = m_inputs[i].data(); @@ -96,11 +93,12 @@ // The input block for a given output is approx output / ratio, // but we can't predict it exactly, for an adaptive timestretcher. + sv_frame_t available; + while ((available = m_stretcher->available()) < nframes) { - sv_frame_t reqd = sv_frame_t - (ceil(double(nframes - available) / m_timeRatio)); - reqd = std::max(reqd, sv_frame_t(m_stretcher->getSamplesRequired())); + int reqd = int(ceil(double(nframes - available) / m_timeRatio)); + reqd = std::max(reqd, int(m_stretcher->getSamplesRequired())); reqd = std::min(reqd, m_stretcherInputSize); if (reqd == 0) reqd = 1; @@ -126,12 +124,11 @@ lock_guard<mutex> guard(m_mutex); if (m_timeRatio == 1.0 || !m_channelCount || !m_sampleRate) { - SVDEBUG << "TimeStretchWrapper::checkStretcher: m_timeRatio = " - << m_timeRatio << ", m_channelCount = " << m_channelCount - << ", m_sampleRate = " << m_sampleRate - << ", no need for stretcher" << endl; if (m_stretcher) { - SVDEBUG << "(Deleting existing one)" << endl; + SVDEBUG << "TimeStretchWrapper::checkStretcher: m_timeRatio = " + << m_timeRatio << ", m_channelCount = " << m_channelCount + << ", m_sampleRate = " << m_sampleRate + << ", deleting existing stretcher" << endl; delete m_stretcher; m_stretcher = nullptr; } @@ -147,7 +144,7 @@ SVDEBUG << "TimeStretchWrapper::checkStretcher: creating stretcher with ratio " << m_timeRatio << endl; m_stretcher = new RubberBandStretcher - (m_sampleRate, + (size_t(round(m_sampleRate)), m_channelCount, RubberBandStretcher::OptionProcessRealTime, m_timeRatio);
--- a/audio/TimeStretchWrapper.h Thu Mar 19 16:14:02 2020 +0000 +++ b/audio/TimeStretchWrapper.h Fri Mar 20 16:31:58 2020 +0000 @@ -93,7 +93,7 @@ double m_timeRatio; std::vector<std::vector<float>> m_inputs; std::mutex m_mutex; - sv_frame_t m_stretcherInputSize; + int m_stretcherInputSize; int m_channelCount; sv_samplerate_t m_sampleRate;
--- a/framework/TransformUserConfigurator.cpp Thu Mar 19 16:14:02 2020 +0000 +++ b/framework/TransformUserConfigurator.cpp Fri Mar 20 16:31:58 2020 +0000 @@ -40,15 +40,20 @@ bool TransformUserConfigurator::getChannelRange(TransformId identifier, - Vamp::PluginBase *plugin, + std::shared_ptr<Vamp::PluginBase> plugin, int &minChannels, int &maxChannels) { if (plugin && plugin->getType() == "Feature Extraction Plugin") { - Vamp::Plugin *vp = static_cast<Vamp::Plugin *>(plugin); - SVDEBUG << "TransformUserConfigurator::getChannelRange: is a Vamp plugin" << endl; - minChannels = int(vp->getMinChannelCount()); - maxChannels = int(vp->getMaxChannelCount()); - return true; + auto vp = std::dynamic_pointer_cast<Vamp::Plugin>(plugin); + if (vp) { + SVDEBUG << "TransformUserConfigurator::getChannelRange: is a Vamp plugin" << endl; + minChannels = int(vp->getMinChannelCount()); + maxChannels = int(vp->getMaxChannelCount()); + return true; + } else { + SVCERR << "TransformUserConfigurator::getChannelRange: inconsistent plugin identity!" << endl; + return false; + } } else { SVDEBUG << "TransformUserConfigurator::getChannelRange: is not a Vamp plugin" << endl; return TransformFactory::getInstance()-> @@ -59,7 +64,7 @@ bool TransformUserConfigurator::configure(ModelTransformer::Input &input, Transform &transform, - Vamp::PluginBase *plugin, + std::shared_ptr<Vamp::PluginBase> plugin, ModelId &inputModel, AudioPlaySource *source, sv_frame_t startFrame, @@ -85,40 +90,35 @@ if (RealTimePluginFactory::instanceFor(id)) { RealTimePluginFactory *factory = RealTimePluginFactory::instanceFor(id); - const RealTimePluginDescriptor *desc = factory->getPluginDescriptor(id); + RealTimePluginDescriptor desc = factory->getPluginDescriptor(id); - if (desc->audioInputPortCount > 0 && - desc->audioOutputPortCount > 0 && - !desc->isSynth) { + if (desc.audioInputPortCount > 0 && + desc.audioOutputPortCount > 0 && + !desc.isSynth) { effect = true; } - if (desc->audioInputPortCount == 0) { + if (desc.audioInputPortCount == 0) { generator = true; } if (output != "A") { int outputNo = output.toInt(); - if (outputNo >= 0 && outputNo < int(desc->controlOutputPortCount)) { - outputLabel = desc->controlOutputPortNames[outputNo].c_str(); + if (outputNo >= 0 && outputNo < int(desc.controlOutputPortCount)) { + outputLabel = desc.controlOutputPortNames[outputNo].c_str(); } } - RealTimePluginInstance *rtp = - static_cast<RealTimePluginInstance *>(plugin); - - if (effect && source) { + auto auditionable = std::dynamic_pointer_cast<Auditionable>(plugin); + + if (effect && source && auditionable) { SVDEBUG << "Setting auditioning effect" << endl; - //!!! This requires a shared_ptr, but we don't manage our - //!!! plugin using shared_ptrs yet. Do this as a stopgap. - std::shared_ptr<Auditionable> auditionable - (std::make_shared<bool>(true), rtp); source->setAuditioningEffect(auditionable); } } else { - Vamp::Plugin *vp = static_cast<Vamp::Plugin *>(plugin); + auto vp = std::dynamic_pointer_cast<Vamp::Plugin>(plugin); frequency = (vp->getInputDomain() == Vamp::Plugin::FrequencyDomain);
--- a/framework/TransformUserConfigurator.h Thu Mar 19 16:14:02 2020 +0000 +++ b/framework/TransformUserConfigurator.h Fri Mar 20 16:31:58 2020 +0000 @@ -17,6 +17,8 @@ #include "transform/ModelTransformerFactory.h" +#include <memory> + class TransformUserConfigurator : public ModelTransformerFactory::UserConfigurator { public: @@ -24,7 +26,7 @@ bool configure(ModelTransformer::Input &input, Transform &transform, - Vamp::PluginBase *plugin, + std::shared_ptr<Vamp::PluginBase> plugin, ModelId &inputModel, AudioPlaySource *source, sv_frame_t startFrame, @@ -37,7 +39,8 @@ private: bool getChannelRange(TransformId identifier, - Vamp::PluginBase *plugin, int &min, int &max); + std::shared_ptr<Vamp::PluginBase> plugin, + int &min, int &max); };