Mercurial > hg > svcore
changeset 1832:7c92c644db20
Merge from branch audio-source-refactor. Various changes to memory management for plugins, ring buffers etc, for safer code further up the stack
author | Chris Cannam |
---|---|
date | Fri, 03 Apr 2020 12:12:02 +0100 |
parents | 498ed1e86f92 (current diff) 5f8fbbde08ff (diff) |
children | 21c792334c2e 804dd0c06f0e |
files | |
diffstat | 24 files changed, 235 insertions(+), 361 deletions(-) [+] |
line wrap: on
line diff
--- a/base/AudioPlaySource.h Fri Mar 27 10:06:03 2020 +0000 +++ b/base/AudioPlaySource.h Fri Apr 03 12:12:02 2020 +0100 @@ -18,6 +18,8 @@ #include "BaseTypes.h" +#include <memory> + struct Auditionable { virtual ~Auditionable() { } }; @@ -101,9 +103,11 @@ /** * Set a plugin or other subclass of Auditionable as an - * auditioning effect. + * auditioning effect. The Auditionable is shared with the caller: + * the expectation is that the caller may continue to modify its + * parameters etc during auditioning. */ - virtual void setAuditioningEffect(Auditionable *) = 0; + virtual void setAuditioningEffect(std::shared_ptr<Auditionable>) = 0; };
--- a/base/RingBuffer.h Fri Mar 27 10:06:03 2020 +0000 +++ b/base/RingBuffer.h Fri Apr 03 12:12:02 2020 +0100 @@ -26,8 +26,9 @@ #include "system/System.h" #include <bqvec/Barrier.h> +#include <bqvec/VectorOps.h> -#include <cstring> // memcpy, memset &c +#include <vector> //#define DEBUG_RINGBUFFER 1 @@ -38,10 +39,6 @@ /** * RingBuffer implements a lock-free ring buffer for one writer and N * readers, that is to be used to store a sample type T. - * - * For efficiency, RingBuffer frequently initialises samples by - * writing zeroes into their memory space, so T should normally be a - * simple type that can safely be set to zero using memset. */ template <typename T, int N = 1> @@ -68,21 +65,14 @@ int getSize() const; /** - * Return a new ring buffer (allocated with "new" -- caller must - * delete when no longer needed) of the given size, containing the - * same data as this one as perceived by reader 0 of this buffer. - * If another thread reads from or writes to this buffer during - * the call, the contents of the new buffer may be incomplete or + * Return a new ring buffer of the given size, containing the same + * data as this one as perceived by reader 0 of this buffer. If + * another thread reads from or writes to this buffer during the + * call, the contents of the new buffer may be incomplete or * inconsistent. If this buffer's data will not fit in the new - * size, the contents are undefined. + * size, the contents are undetermined. */ - RingBuffer<T, N> *resized(int newSize) const; - - /** - * Lock the ring buffer into physical memory. Returns true - * for success. - */ - bool mlock(); + RingBuffer<T, N> resized(int newSize) const; /** * Reset read and write pointers, thus emptying the buffer. @@ -164,42 +154,26 @@ */ int zero(int n); + RingBuffer(const RingBuffer &) =default; + RingBuffer &operator=(const RingBuffer &) =default; + protected: - T *m_buffer; - bool m_mlocked; - int m_writer; - int *m_readers; - int m_size; - int m_spare; - -private: - RingBuffer(const RingBuffer &); // not provided - RingBuffer &operator=(const RingBuffer &); // not provided + std::vector<T, breakfastquay::StlAllocator<T>> m_buffer; + int m_writer; + std::vector<int> m_readers; + int m_size; }; template <typename T, int N> RingBuffer<T, N>::RingBuffer(int n) : - m_buffer(new T[n + 1]), - m_mlocked(false), + m_buffer(n + 1, T()), m_writer(0), - m_readers(new int[N]), + m_readers(N, 0), m_size(n + 1) { #ifdef DEBUG_RINGBUFFER std::cerr << "RingBuffer<T," << N << ">[" << this << "]::RingBuffer(" << n << ")" << std::endl; #endif -/* - std::cerr << "note: sizeof(RingBuffer<T,N> = " << sizeof(RingBuffer<T,N>) << ")" << std::endl; - - std::cerr << "this = " << this << std::endl; - std::cerr << "&m_buffer = " << &m_buffer << std::endl; - std::cerr << "&m_mlocked = " << &m_mlocked << std::endl; - std::cerr << "&m_writer = " << &m_writer << std::endl; - std::cerr << "&m_readers = " << &m_readers << std::endl; - std::cerr << "&m_size = " << &m_size << std::endl; -*/ - - for (int i = 0; i < N; ++i) m_readers[i] = 0; } template <typename T, int N> @@ -208,13 +182,6 @@ #ifdef DEBUG_RINGBUFFER std::cerr << "RingBuffer<T," << N << ">[" << this << "]::~RingBuffer" << std::endl; #endif - - delete[] m_readers; - - if (m_mlocked) { - MUNLOCK((void *)m_buffer, m_size * sizeof(T)); - } - delete[] m_buffer; } template <typename T, int N> @@ -229,14 +196,14 @@ } template <typename T, int N> -RingBuffer<T, N> * +RingBuffer<T, N> RingBuffer<T, N>::resized(int newSize) const { #ifdef DEBUG_RINGBUFFER std::cerr << "RingBuffer<T," << N << ">[" << this << "]::resized(" << newSize << ")" << std::endl; #endif - RingBuffer<T, N> *newBuffer = new RingBuffer<T, N>(newSize); + RingBuffer<T, N> newBuffer(newSize); int w = m_writer; int r = m_readers[0]; @@ -251,15 +218,6 @@ } template <typename T, int N> -bool -RingBuffer<T, N>::mlock() -{ - if (MLOCK((void *)m_buffer, m_size * sizeof(T))) return false; - m_mlocked = true; - return true; -} - -template <typename T, int N> void RingBuffer<T, N>::reset() { @@ -268,7 +226,9 @@ #endif m_writer = 0; - for (int i = 0; i < N; ++i) m_readers[i] = 0; + for (int i = 0; i < N; ++i) { + m_readers[i] = 0; + } } template <typename T, int N> @@ -328,17 +288,17 @@ std::cerr << "WARNING: Only " << available << " samples available" << std::endl; #endif - memset(destination + available, 0, (n - available) * sizeof(T)); + breakfastquay::v_zero(destination + available, n - available); n = available; } if (n == 0) return n; int here = m_size - m_readers[R]; if (here >= n) { - memcpy(destination, m_buffer + m_readers[R], n * sizeof(T)); + breakfastquay::v_copy(destination, m_buffer.data() + m_readers[R], n); } else { - memcpy(destination, m_buffer + m_readers[R], here * sizeof(T)); - memcpy(destination + here, m_buffer, (n - here) * sizeof(T)); + breakfastquay::v_copy(destination, m_buffer.data() + m_readers[R], here); + breakfastquay::v_copy(destination + here, m_buffer.data(), n - here); } BQ_MBARRIER(); @@ -373,11 +333,11 @@ if (here >= n) { for (int i = 0; i < n; ++i) { - destination[i] += (m_buffer + m_readers[R])[i]; + destination[i] += (m_buffer.data() + m_readers[R])[i]; } } else { for (int i = 0; i < here; ++i) { - destination[i] += (m_buffer + m_readers[R])[i]; + destination[i] += (m_buffer.data() + m_readers[R])[i]; } for (int i = 0; i < (n - here); ++i) { destination[i + here] += m_buffer[i]; @@ -402,9 +362,7 @@ std::cerr << "WARNING: No sample available" << std::endl; #endif - T t; - memset(&t, 0, sizeof(T)); - return t; + return T(); } T value = m_buffer[m_readers[R]]; BQ_MBARRIER(); @@ -426,17 +384,17 @@ std::cerr << "WARNING: Only " << available << " samples available" << std::endl; #endif - memset(destination + available, 0, (n - available) * sizeof(T)); + breakfastquay::v_zero(destination + available, n - available); n = available; } if (n == 0) return n; int here = m_size - m_readers[R]; if (here >= n) { - memcpy(destination, m_buffer + m_readers[R], n * sizeof(T)); + breakfastquay::v_copy(destination, m_buffer.data() + m_readers[R], n); } else { - memcpy(destination, m_buffer + m_readers[R], here * sizeof(T)); - memcpy(destination + here, m_buffer, (n - here) * sizeof(T)); + breakfastquay::v_copy(destination, m_buffer.data() + m_readers[R], here); + breakfastquay::v_copy(destination + here, m_buffer.data(), n - here); } #ifdef DEBUG_RINGBUFFER @@ -459,9 +417,7 @@ std::cerr << "WARNING: No sample available" << std::endl; #endif - T t; - memset(&t, 0, sizeof(T)); - return t; + return T(); } T value = m_buffer[m_readers[R]]; return value; @@ -508,10 +464,10 @@ int here = m_size - m_writer; if (here >= n) { - memcpy(m_buffer + m_writer, source, n * sizeof(T)); + breakfastquay::v_copy(m_buffer.data() + m_writer, source, n); } else { - memcpy(m_buffer + m_writer, source, here * sizeof(T)); - memcpy(m_buffer, source + here, (n - here) * sizeof(T)); + breakfastquay::v_copy(m_buffer.data() + m_writer, source, here); + breakfastquay::v_copy(m_buffer.data(), source + here, n - here); } BQ_MBARRIER(); @@ -544,10 +500,10 @@ int here = m_size - m_writer; if (here >= n) { - memset(m_buffer + m_writer, 0, n * sizeof(T)); + breakfastquay::v_zero(m_buffer.data() + m_writer, n); } else { - memset(m_buffer + m_writer, 0, here * sizeof(T)); - memset(m_buffer, 0, (n - here) * sizeof(T)); + breakfastquay::v_zero(m_buffer.data() + m_writer, here); + breakfastquay::v_zero(m_buffer.data(), n - here); } BQ_MBARRIER();
--- a/plugin/DSSIPluginFactory.cpp Fri Mar 27 10:06:03 2020 +0000 +++ b/plugin/DSSIPluginFactory.cpp Fri Apr 03 12:12:02 2020 +0100 @@ -110,7 +110,7 @@ unloadUnusedLibraries(); } -RealTimePluginInstance * +std::shared_ptr<RealTimePluginInstance> DSSIPluginFactory::instantiatePlugin(QString identifier, int instrument, int position, @@ -124,10 +124,11 @@ if (descriptor) { - DSSIPluginInstance *instance = - new DSSIPluginInstance - (this, instrument, identifier, position, sampleRate, blockSize, channels, - descriptor); + auto instance = + std::shared_ptr<RealTimePluginInstance> + (new DSSIPluginInstance + (this, instrument, identifier, position, + sampleRate, blockSize, channels, descriptor)); m_instances.insert(instance); @@ -320,18 +321,18 @@ continue; } - RealTimePluginDescriptor *rtd = new RealTimePluginDescriptor; - rtd->name = ladspaDescriptor->Name; - rtd->label = ladspaDescriptor->Label; - rtd->maker = ladspaDescriptor->Maker; - rtd->copyright = ladspaDescriptor->Copyright; - rtd->category = ""; - rtd->isSynth = (descriptor->run_synth || + RealTimePluginDescriptor rtd; + rtd.name = ladspaDescriptor->Name; + rtd.label = ladspaDescriptor->Label; + rtd.maker = ladspaDescriptor->Maker; + rtd.copyright = ladspaDescriptor->Copyright; + rtd.category = ""; + rtd.isSynth = (descriptor->run_synth || descriptor->run_multiple_synths); - rtd->parameterCount = 0; - rtd->audioInputPortCount = 0; - rtd->audioOutputPortCount = 0; - rtd->controlOutputPortCount = 0; + rtd.parameterCount = 0; + rtd.audioInputPortCount = 0; + rtd.audioOutputPortCount = 0; + rtd.controlOutputPortCount = 0; QString identifier = PluginIdentifier::createIdentifier ("dssi", soname, ladspaDescriptor->Label); @@ -348,7 +349,7 @@ } if (category == "") { - string name = rtd->name; + string name = rtd.name; if (name.length() > 4 && name.substr(name.length() - 4) == " VST") { if (descriptor->run_synth || descriptor->run_multiple_synths) { @@ -360,7 +361,7 @@ } } - rtd->category = category.toStdString(); + rtd.category = category.toStdString(); // cerr << "Plugin id is " << ladspaDescriptor->UniqueID // << ", identifier is \"" << identifier @@ -399,20 +400,20 @@ for (unsigned long i = 0; i < ladspaDescriptor->PortCount; i++) { if (LADSPA_IS_PORT_CONTROL(ladspaDescriptor->PortDescriptors[i])) { if (LADSPA_IS_PORT_INPUT(ladspaDescriptor->PortDescriptors[i])) { - ++rtd->parameterCount; + ++rtd.parameterCount; } else { if (strcmp(ladspaDescriptor->PortNames[i], "latency") && strcmp(ladspaDescriptor->PortNames[i], "_latency")) { - ++rtd->controlOutputPortCount; - rtd->controlOutputPortNames.push_back + ++rtd.controlOutputPortCount; + rtd.controlOutputPortNames.push_back (ladspaDescriptor->PortNames[i]); } } } else { if (LADSPA_IS_PORT_INPUT(ladspaDescriptor->PortDescriptors[i])) { - ++rtd->audioInputPortCount; + ++rtd.audioInputPortCount; } else if (LADSPA_IS_PORT_OUTPUT(ladspaDescriptor->PortDescriptors[i])) { - ++rtd->audioOutputPortCount; + ++rtd.audioOutputPortCount; } } }
--- a/plugin/DSSIPluginFactory.h Fri Mar 27 10:06:03 2020 +0000 +++ b/plugin/DSSIPluginFactory.h Fri Apr 03 12:12:02 2020 +0100 @@ -37,12 +37,13 @@ void enumeratePlugins(std::vector<QString> &list) override; - RealTimePluginInstance *instantiatePlugin(QString identifier, - int clientId, - int position, - sv_samplerate_t sampleRate, - int blockSize, - int channels) override; + std::shared_ptr<RealTimePluginInstance> + instantiatePlugin(QString identifier, + int clientId, + int position, + sv_samplerate_t sampleRate, + int blockSize, + int channels) override; static std::vector<QString> getPluginPath();
--- a/plugin/FeatureExtractionPluginFactory.h Fri Mar 27 10:06:03 2020 +0000 +++ b/plugin/FeatureExtractionPluginFactory.h Fri Apr 03 12:12:02 2020 +0100 @@ -24,6 +24,8 @@ #include <QString> +#include <memory> + class FeatureExtractionPluginFactory { public: @@ -47,8 +49,8 @@ * blockSize or channels on this -- they're negotiated and handled * via initialize() on the plugin itself after loading. */ - virtual Vamp::Plugin *instantiatePlugin(QString identifier, - sv_samplerate_t inputSampleRate) = 0; + virtual std::shared_ptr<Vamp::Plugin> instantiatePlugin(QString identifier, + sv_samplerate_t inputSampleRate) = 0; /** * Get category metadata about a plugin (without instantiating it).
--- a/plugin/LADSPAPluginFactory.cpp Fri Mar 27 10:06:03 2020 +0000 +++ b/plugin/LADSPAPluginFactory.cpp Fri Apr 03 12:12:02 2020 +0100 @@ -51,12 +51,6 @@ LADSPAPluginFactory::~LADSPAPluginFactory() { - for (std::set<RealTimePluginInstance *>::iterator i = m_instances.begin(); - i != m_instances.end(); ++i) { - (*i)->setFactory(nullptr); - delete *i; - } - m_instances.clear(); unloadUnusedLibraries(); #ifdef HAVE_LRDF @@ -138,17 +132,17 @@ unloadUnusedLibraries(); } -const RealTimePluginDescriptor * +RealTimePluginDescriptor LADSPAPluginFactory::getPluginDescriptor(QString identifier) const { - std::map<QString, RealTimePluginDescriptor *>::const_iterator i = + std::map<QString, RealTimePluginDescriptor>::const_iterator i = m_rtDescriptors.find(identifier); if (i != m_rtDescriptors.end()) { return i->second; } - return nullptr; + return {}; } float @@ -334,7 +328,7 @@ } -RealTimePluginInstance * +std::shared_ptr<RealTimePluginInstance> LADSPAPluginFactory::instantiatePlugin(QString identifier, int instrument, int position, @@ -348,10 +342,11 @@ if (descriptor) { - LADSPAPluginInstance *instance = - new LADSPAPluginInstance - (this, instrument, identifier, position, sampleRate, blockSize, channels, - descriptor); + auto instance = + std::shared_ptr<RealTimePluginInstance> + (new LADSPAPluginInstance + (this, instrument, identifier, position, + sampleRate, blockSize, channels, descriptor)); m_instances.insert(instance); @@ -366,53 +361,6 @@ return nullptr; } -void -LADSPAPluginFactory::releasePlugin(RealTimePluginInstance *instance, - QString identifier) -{ - Profiler profiler("LADSPAPluginFactory::releasePlugin"); - - if (m_instances.find(instance) == m_instances.end()) { - cerr << "WARNING: LADSPAPluginFactory::releasePlugin: Not one of mine!" - << endl; - return; - } - - QString type, soname, label; - PluginIdentifier::parseIdentifier(identifier, type, soname, label); - - m_instances.erase(instance); - - bool stillInUse = false; - - for (std::set<RealTimePluginInstance *>::iterator ii = m_instances.begin(); - ii != m_instances.end(); ++ii) { - QString itype, isoname, ilabel; - PluginIdentifier::parseIdentifier((*ii)->getPluginIdentifier(), itype, isoname, ilabel); - if (isoname == soname) { -#ifdef DEBUG_LADSPA_PLUGIN_FACTORY - SVDEBUG << "LADSPAPluginFactory::releasePlugin: dll " << soname << " is still in use for plugin " << ilabel << endl; -#endif - stillInUse = true; - break; - } - } - - if (!stillInUse) { - if (soname != PluginIdentifier::BUILTIN_PLUGIN_SONAME) { -#ifdef DEBUG_LADSPA_PLUGIN_FACTORY - SVDEBUG << "LADSPAPluginFactory::releasePlugin: dll " << soname << " no longer in use, unloading" << endl; -#endif - unloadLibrary(soname); - } - } - -#ifdef DEBUG_LADSPA_PLUGIN_FACTORY - SVDEBUG << "LADSPAPluginFactory::releasePlugin(" - << identifier << ": now have " << m_instances.size() << " instances" << endl; -#endif -} - const LADSPA_Descriptor * LADSPAPluginFactory::getLADSPADescriptor(QString identifier) { @@ -525,31 +473,39 @@ void LADSPAPluginFactory::unloadUnusedLibraries() { + std::set<std::weak_ptr<RealTimePluginInstance>, + std::owner_less<std::weak_ptr<RealTimePluginInstance>>> toRemove; + + std::set<QString> soNamesInUse; + + for (auto wp: m_instances) { + if (auto p = wp.lock()) { + QString itype, isoname, ilabel; + PluginIdentifier::parseIdentifier(p->getPluginIdentifier(), + itype, isoname, ilabel); + soNamesInUse.insert(isoname); + } else { + toRemove.insert(wp); + } + } + + for (auto wp: toRemove) { + m_instances.erase(wp); + } + std::vector<QString> toUnload; - - for (LibraryHandleMap::iterator i = m_libraryHandles.begin(); + + for (auto i = m_libraryHandles.begin(); i != m_libraryHandles.end(); ++i) { - bool stillInUse = false; - - for (std::set<RealTimePluginInstance *>::iterator ii = m_instances.begin(); - ii != m_instances.end(); ++ii) { - - QString itype, isoname, ilabel; - PluginIdentifier::parseIdentifier((*ii)->getPluginIdentifier(), itype, isoname, ilabel); - if (isoname == i->first) { - stillInUse = true; - break; - } + if (soNamesInUse.find(i->first) == soNamesInUse.end()) { + toUnload.push_back(i->first); } - - if (!stillInUse) toUnload.push_back(i->first); } - for (std::vector<QString>::iterator i = toUnload.begin(); - i != toUnload.end(); ++i) { - if (*i != PluginIdentifier::BUILTIN_PLUGIN_SONAME) { - unloadLibrary(*i); + for (auto soname: toUnload) { + if (soname != PluginIdentifier::BUILTIN_PLUGIN_SONAME) { + unloadLibrary(soname); } } } @@ -707,17 +663,17 @@ int index = 0; while ((descriptor = fn(index))) { - RealTimePluginDescriptor *rtd = new RealTimePluginDescriptor; - rtd->name = descriptor->Name; - rtd->label = descriptor->Label; - rtd->maker = descriptor->Maker; - rtd->copyright = descriptor->Copyright; - rtd->category = ""; - rtd->isSynth = false; - rtd->parameterCount = 0; - rtd->audioInputPortCount = 0; - rtd->audioOutputPortCount = 0; - rtd->controlOutputPortCount = 0; + RealTimePluginDescriptor rtd; + rtd.name = descriptor->Name; + rtd.label = descriptor->Label; + rtd.maker = descriptor->Maker; + rtd.copyright = descriptor->Copyright; + rtd.category = ""; + rtd.isSynth = false; + rtd.parameterCount = 0; + rtd.audioInputPortCount = 0; + rtd.audioOutputPortCount = 0; + rtd.controlOutputPortCount = 0; QString identifier = PluginIdentifier::createIdentifier ("ladspa", soname, descriptor->Label); @@ -735,7 +691,7 @@ QString category = m_taxonomy[identifier]; if (category == "") { - string name = rtd->name; + string name = rtd.name; if (name.length() > 4 && name.substr(name.length() - 4) == " VST") { category = "VST effects"; @@ -743,7 +699,7 @@ } } - rtd->category = category.toStdString(); + rtd.category = category.toStdString(); // cerr << "Plugin id is " << descriptor->UniqueID // << ", category is \"" << (category ? category : QString("(none)")) @@ -781,20 +737,20 @@ for (int i = 0; i < (int)descriptor->PortCount; i++) { if (LADSPA_IS_PORT_CONTROL(descriptor->PortDescriptors[i])) { if (LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[i])) { - ++rtd->parameterCount; + ++rtd.parameterCount; } else { if (strcmp(descriptor->PortNames[i], "latency") && strcmp(descriptor->PortNames[i], "_latency")) { - ++rtd->controlOutputPortCount; - rtd->controlOutputPortNames.push_back + ++rtd.controlOutputPortCount; + rtd.controlOutputPortNames.push_back (descriptor->PortNames[i]); } } } else { if (LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[i])) { - ++rtd->audioInputPortCount; + ++rtd.audioInputPortCount; } else if (LADSPA_IS_PORT_OUTPUT(descriptor->PortDescriptors[i])) { - ++rtd->audioOutputPortCount; + ++rtd.audioOutputPortCount; } } }
--- a/plugin/LADSPAPluginFactory.h Fri Mar 27 10:06:03 2020 +0000 +++ b/plugin/LADSPAPluginFactory.h Fri Apr 03 12:12:02 2020 +0100 @@ -44,14 +44,16 @@ void enumeratePlugins(std::vector<QString> &list) override; - const RealTimePluginDescriptor *getPluginDescriptor(QString identifier) const override; + RealTimePluginDescriptor getPluginDescriptor(QString identifier) + const override; - RealTimePluginInstance *instantiatePlugin(QString identifier, - int clientId, - int position, - sv_samplerate_t sampleRate, - int blockSize, - int channels) override; + std::shared_ptr<RealTimePluginInstance> + instantiatePlugin(QString identifier, + int clientId, + int position, + sv_samplerate_t sampleRate, + int blockSize, + int channels) override; QString getPluginCategory(QString identifier) override; @@ -79,8 +81,6 @@ virtual void generateTaxonomy(QString uri, QString base); virtual void generateFallbackCategories(); - void releasePlugin(RealTimePluginInstance *, QString) override; - virtual const LADSPA_Descriptor *getLADSPADescriptor(QString identifier); void loadLibrary(QString soName); @@ -89,13 +89,14 @@ std::vector<QString> m_identifiers; std::map<QString, QString> m_libraries; // identifier -> full file path - std::map<QString, RealTimePluginDescriptor *> m_rtDescriptors; + std::map<QString, RealTimePluginDescriptor> m_rtDescriptors; std::map<QString, QString> m_taxonomy; std::map<unsigned long, QString> m_lrdfTaxonomy; std::map<unsigned long, std::map<int, float> > m_portDefaults; - std::set<RealTimePluginInstance *> m_instances; + std::set<std::weak_ptr<RealTimePluginInstance>, + std::owner_less<std::weak_ptr<RealTimePluginInstance>>> m_instances; typedef std::map<QString, void *> LibraryHandleMap; LibraryHandleMap m_libraryHandles;
--- a/plugin/NativeVampPluginFactory.cpp Fri Mar 27 10:06:03 2020 +0000 +++ b/plugin/NativeVampPluginFactory.cpp Fri Apr 03 12:12:02 2020 +0100 @@ -297,13 +297,13 @@ } } -Vamp::Plugin * +std::shared_ptr<Vamp::Plugin> NativeVampPluginFactory::instantiatePlugin(QString identifier, sv_samplerate_t inputSampleRate) { Profiler profiler("NativeVampPluginFactory::instantiatePlugin"); - Vamp::Plugin *rv = nullptr; + std::shared_ptr<Vamp::Plugin> rv = nullptr; Vamp::PluginHostAdapter *plugin = nullptr; const VampPluginDescriptor *descriptor = nullptr; @@ -363,7 +363,8 @@ if (plugin) { m_handleMap[plugin] = libraryHandle; - rv = new PluginDeletionNotifyAdapter(plugin, this); + rv = std::shared_ptr<Vamp::Plugin> + (new PluginDeletionNotifyAdapter(plugin, this)); } #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE @@ -384,7 +385,7 @@ } void -NativeVampPluginFactory::pluginDeleted(Vamp::Plugin *plugin) +NativeVampPluginFactory::pluginDeleted(Vamp::Plugin* plugin) { void *handle = m_handleMap[plugin]; if (!handle) return; @@ -480,15 +481,13 @@ catlist.push_back(s.toStdString()); } - Vamp::Plugin *p = instantiatePlugin(identifier, 44100); + std::shared_ptr<Vamp::Plugin> p = instantiatePlugin(identifier, 44100); if (!p) return {}; auto psd = piper_vamp::PluginStaticData::fromPlugin(pluginKey, catlist, - p); + p.get()); - delete p; - m_pluginData[identifier] = psd; return psd; }
--- a/plugin/NativeVampPluginFactory.h Fri Mar 27 10:06:03 2020 +0000 +++ b/plugin/NativeVampPluginFactory.h Fri Apr 03 12:12:02 2020 +0100 @@ -40,7 +40,7 @@ virtual piper_vamp::PluginStaticData getPluginStaticData(QString identifier) override; - virtual Vamp::Plugin *instantiatePlugin(QString identifier, + virtual std::shared_ptr<Vamp::Plugin> instantiatePlugin(QString identifier, sv_samplerate_t inputSampleRate) override;
--- a/plugin/PiperVampPluginFactory.cpp Fri Mar 27 10:06:03 2020 +0000 +++ b/plugin/PiperVampPluginFactory.cpp Fri Apr 03 12:12:02 2020 +0100 @@ -166,7 +166,7 @@ return rv; } -Vamp::Plugin * +std::shared_ptr<Vamp::Plugin> PiperVampPluginFactory::instantiatePlugin(QString identifier, sv_samplerate_t inputSampleRate) { @@ -197,7 +197,7 @@ return nullptr; } - return ap; + return std::shared_ptr<Vamp::Plugin>(ap); } piper_vamp::PluginStaticData
--- a/plugin/PiperVampPluginFactory.h Fri Mar 27 10:06:03 2020 +0000 +++ b/plugin/PiperVampPluginFactory.h Fri Apr 03 12:12:02 2020 +0100 @@ -43,8 +43,8 @@ virtual piper_vamp::PluginStaticData getPluginStaticData(QString identifier) override; - virtual Vamp::Plugin *instantiatePlugin(QString identifier, - sv_samplerate_t inputSampleRate) + virtual std::shared_ptr<Vamp::Plugin> instantiatePlugin(QString identifier, + sv_samplerate_t inputSampleRate) override; virtual QString getPluginCategory(QString identifier) override;
--- a/plugin/PluginXml.cpp Fri Mar 27 10:06:03 2020 +0000 +++ b/plugin/PluginXml.cpp Fri Apr 03 12:12:02 2020 +0100 @@ -30,7 +30,10 @@ #include <iostream> -PluginXml::PluginXml(Vamp::PluginBase *plugin) : +using std::shared_ptr; +using std::dynamic_pointer_cast; + +PluginXml::PluginXml(shared_ptr<Vamp::PluginBase> plugin) : m_plugin(plugin) { } @@ -90,8 +93,7 @@ .arg(m_plugin->getParameter(i->identifier)); } - RealTimePluginInstance *rtpi = - dynamic_cast<RealTimePluginInstance *>(m_plugin); + auto rtpi = dynamic_pointer_cast<RealTimePluginInstance>(m_plugin); if (rtpi) { std::map<std::string, std::string> configurePairs = rtpi->getConfigurePairs(); @@ -138,8 +140,7 @@ cerr << "WARNING: PluginXml::setParameters: Plugin version does not match (attributes have " << version << ", my version is " << m_plugin->getPluginVersion() << ")" << endl; } - RealTimePluginInstance *rtpi = - dynamic_cast<RealTimePluginInstance *>(m_plugin); + auto rtpi = dynamic_pointer_cast<RealTimePluginInstance>(m_plugin); if (rtpi) { QString config = attrs.value("configuration"); if (config != "") {
--- a/plugin/PluginXml.h Fri Mar 27 10:06:03 2020 +0000 +++ b/plugin/PluginXml.h Fri Apr 03 12:12:02 2020 +0100 @@ -19,20 +19,22 @@ #include "base/XmlExportable.h" #include <vamp-hostsdk/PluginBase.h> +#include <memory> + class QXmlAttributes; class PluginXml : public XmlExportable { public: - PluginXml(Vamp::PluginBase *plugin); + PluginXml(std::shared_ptr<Vamp::PluginBase> plugin); virtual ~PluginXml(); /** * Export plugin settings to XML. */ void toXml(QTextStream &stream, - QString indent = "", - QString extraAttributes = "") const override; + QString indent = "", + QString extraAttributes = "") const override; /** * Set the parameters and program of a plugin from a set of XML @@ -53,7 +55,7 @@ protected: QString stripInvalidParameterNameCharacters(QString) const; - Vamp::PluginBase *m_plugin; + std::shared_ptr<Vamp::PluginBase> m_plugin; }; #endif
--- a/plugin/RealTimePluginFactory.h Fri Mar 27 10:06:03 2020 +0000 +++ b/plugin/RealTimePluginFactory.h Fri Apr 03 12:12:02 2020 +0100 @@ -24,6 +24,7 @@ #include <QString> #include <vector> +#include <memory> #include "base/Debug.h" #include "base/BaseTypes.h" @@ -80,12 +81,12 @@ /** * Get some basic information about a plugin (rapidly). */ - virtual const RealTimePluginDescriptor *getPluginDescriptor(QString identifier) const = 0; + virtual RealTimePluginDescriptor getPluginDescriptor(QString identifier) const = 0; /** * Instantiate a plugin. */ - virtual RealTimePluginInstance *instantiatePlugin(QString identifier, + virtual std::shared_ptr<RealTimePluginInstance> instantiatePlugin(QString identifier, int clientId, int position, sv_samplerate_t sampleRate, @@ -108,10 +109,6 @@ protected: RealTimePluginFactory() { } - // for call by RealTimePluginInstance dtor - virtual void releasePlugin(RealTimePluginInstance *, QString identifier) = 0; - friend class RealTimePluginInstance; - static sv_samplerate_t m_sampleRate; };
--- a/plugin/RealTimePluginInstance.cpp Fri Mar 27 10:06:03 2020 +0000 +++ b/plugin/RealTimePluginInstance.cpp Fri Apr 03 12:12:02 2020 +0100 @@ -28,12 +28,5 @@ RealTimePluginInstance::~RealTimePluginInstance() { -// SVDEBUG << "RealTimePluginInstance::~RealTimePluginInstance" << endl; - - if (m_factory) { -// SVDEBUG << "Asking factory to release " << m_identifier << endl; - - m_factory->releasePlugin(this, m_identifier); - } }
--- a/plugin/RealTimePluginInstance.h Fri Mar 27 10:06:03 2020 +0000 +++ b/plugin/RealTimePluginInstance.h Fri Apr 03 12:12:02 2020 +0100 @@ -134,8 +134,6 @@ virtual void discardEvents() { } virtual void setIdealChannelCount(int channels) = 0; // must also silence(); may also re-instantiate - void setFactory(RealTimePluginFactory *f) { m_factory = f; } // ew - std::string getType() const override { return "Real-Time Plugin"; } typedef std::map<std::string, std::string> ConfigurationPairMap; @@ -151,8 +149,6 @@ QString m_identifier; ConfigurationPairMap m_configurationData; - - friend class PluginFactory; };
--- a/transform/FeatureExtractionModelTransformer.cpp Fri Mar 27 10:06:03 2020 +0000 +++ b/transform/FeatureExtractionModelTransformer.cpp Fri Apr 03 12:12:02 2020 +0100 @@ -266,7 +266,8 @@ << QThread::currentThreadId() << endl; try { - delete m_plugin; + m_plugin = {}; // does not necessarily delete, as it's a + // shared_ptr, but in the design case it will } catch (const std::exception &e) { // A destructor shouldn't throw an exception. But at one point // (now fixed) our plugin stub destructor could have @@ -274,7 +275,6 @@ SVCERR << "FeatureExtractionModelTransformer: caught exception while deleting plugin: " << e.what() << endl; m_message = e.what(); } - m_plugin = nullptr; m_descriptors.clear(); }
--- a/transform/FeatureExtractionModelTransformer.h Fri Mar 27 10:06:03 2020 +0000 +++ b/transform/FeatureExtractionModelTransformer.h Fri Apr 03 12:12:02 2020 +0100 @@ -58,7 +58,7 @@ void run() override; - Vamp::Plugin *m_plugin; + std::shared_ptr<Vamp::Plugin> m_plugin; // descriptors per transform std::vector<Vamp::Plugin::OutputDescriptor> m_descriptors;
--- a/transform/ModelTransformerFactory.cpp Fri Mar 27 10:06:03 2020 +0000 +++ b/transform/ModelTransformerFactory.cpp Fri Apr 03 12:12:02 2020 +0100 @@ -40,6 +40,8 @@ using std::vector; using std::set; using std::map; +using std::shared_ptr; +using std::make_shared; ModelTransformerFactory * ModelTransformerFactory::m_instance = new ModelTransformerFactory; @@ -110,7 +112,7 @@ SVDEBUG << "ModelTransformer: last configuration for identifier " << transform.getIdentifier() << ": " << configurationXml << endl; - Vamp::PluginBase *plugin = nullptr; + shared_ptr<Vamp::PluginBase> plugin; if (RealTimePluginFactory::instanceFor(id)) { @@ -127,20 +129,16 @@ channels = source->getTargetChannelCount(); } - RealTimePluginInstance *rtp = factory->instantiatePlugin + plugin = factory->instantiatePlugin (id, 0, 0, sampleRate, blockSize, channels); - plugin = rtp; - } else { SVDEBUG << "ModelTransformerFactory::getConfigurationForTransform: instantiating Vamp plugin" << endl; - Vamp::Plugin *vp = + plugin = FeatureExtractionPluginFactory::instance()->instantiatePlugin (id, float(defaultSampleRate)); - - plugin = vp; } if (plugin) { @@ -172,10 +170,6 @@ makeContextConsistentWithPlugin(transform, plugin); configurationXml = PluginXml(plugin).toXmlString(); - - SVDEBUG << "ModelTransformerFactory::getConfigurationForTransform: got configuration, deleting plugin" << endl; - - delete plugin; } if (ok) {
--- a/transform/ModelTransformerFactory.h Fri Mar 27 10:06:03 2020 +0000 +++ b/transform/ModelTransformerFactory.h Fri Apr 03 12:12:02 2020 +0100 @@ -29,6 +29,7 @@ #include <map> #include <set> #include <vector> +#include <memory> class AudioPlaySource; @@ -45,7 +46,7 @@ public: virtual bool configure(ModelTransformer::Input &input, Transform &transform, - Vamp::PluginBase *plugin, + std::shared_ptr<Vamp::PluginBase> plugin, ModelId &inputModel, AudioPlaySource *source, sv_frame_t startFrame,
--- a/transform/RealTimeEffectModelTransformer.cpp Fri Mar 27 10:06:03 2020 +0000 +++ b/transform/RealTimeEffectModelTransformer.cpp Fri Apr 03 12:12:02 2020 +0100 @@ -108,7 +108,6 @@ RealTimeEffectModelTransformer::~RealTimeEffectModelTransformer() { - delete m_plugin; } void
--- a/transform/RealTimeEffectModelTransformer.h Fri Mar 27 10:06:03 2020 +0000 +++ b/transform/RealTimeEffectModelTransformer.h Fri Apr 03 12:12:02 2020 +0100 @@ -34,7 +34,7 @@ void awaitOutputModels() override { } // they're created synchronously QString m_units; - RealTimePluginInstance *m_plugin; + std::shared_ptr<RealTimePluginInstance> m_plugin; int m_outputNo; };
--- a/transform/TransformFactory.cpp Fri Mar 27 10:06:03 2020 +0000 +++ b/transform/TransformFactory.cpp Fri Apr 03 12:12:02 2020 +0100 @@ -513,38 +513,38 @@ continue; } - const RealTimePluginDescriptor *descriptor = + RealTimePluginDescriptor descriptor = factory->getPluginDescriptor(pluginId); - if (!descriptor) { + if (descriptor.name == "") { cerr << "WARNING: TransformFactory::populateTransforms: Failed to query plugin " << pluginId << endl; continue; } -//!!! if (descriptor->controlOutputPortCount == 0 || -// descriptor->audioInputPortCount == 0) continue; +//!!! if (descriptor.controlOutputPortCount == 0 || +// descriptor.audioInputPortCount == 0) continue; -// cout << "TransformFactory::populateRealTimePlugins: plugin " << pluginId << " has " << descriptor->controlOutputPortCount << " control output ports, " << descriptor->audioOutputPortCount << " audio outputs, " << descriptor->audioInputPortCount << " audio inputs" << endl; +// cout << "TransformFactory::populateRealTimePlugins: plugin " << pluginId << " has " << descriptor.controlOutputPortCount << " control output ports, " << descriptor.audioOutputPortCount << " audio outputs, " << descriptor.audioInputPortCount << " audio inputs" << endl; - QString pluginName = descriptor->name.c_str(); + QString pluginName = descriptor.name.c_str(); QString category = factory->getPluginCategory(pluginId); - bool configurable = (descriptor->parameterCount > 0); - QString maker = descriptor->maker.c_str(); + bool configurable = (descriptor.parameterCount > 0); + QString maker = descriptor.maker.c_str(); if (maker == "") maker = tr("<unknown maker>"); - if (descriptor->audioInputPortCount > 0) { + if (descriptor.audioInputPortCount > 0) { - for (int j = 0; j < (int)descriptor->controlOutputPortCount; ++j) { + for (int j = 0; j < (int)descriptor.controlOutputPortCount; ++j) { QString transformId = QString("%1:%2").arg(pluginId).arg(j); QString userName; QString units; QString portName; - if (j < (int)descriptor->controlOutputPortNames.size() && - descriptor->controlOutputPortNames[j] != "") { + if (j < (int)descriptor.controlOutputPortNames.size() && + descriptor.controlOutputPortNames[j] != "") { - portName = descriptor->controlOutputPortNames[j].c_str(); + portName = descriptor.controlOutputPortNames[j].c_str(); userName = tr("%1: %2") .arg(pluginName) @@ -554,7 +554,7 @@ units = unitRE.cap(1); } - } else if (descriptor->controlOutputPortCount > 1) { + } else if (descriptor.controlOutputPortCount > 1) { userName = tr("%1: Output %2") .arg(pluginName) @@ -593,9 +593,9 @@ } } - if (!descriptor->isSynth || descriptor->audioInputPortCount > 0) { + if (!descriptor.isSynth || descriptor.audioInputPortCount > 0) { - if (descriptor->audioOutputPortCount > 0) { + if (descriptor.audioOutputPortCount > 0) { QString transformId = QString("%1:A").arg(pluginId); TransformDescription::Type type = TransformDescription::Effects; @@ -604,7 +604,7 @@ .arg(pluginName) .arg(maker); - if (descriptor->audioInputPortCount == 0) { + if (descriptor.audioInputPortCount == 0) { type = TransformDescription::Generator; QString description = tr("Generate audio signal using \"%1\" plugin (from %2)") .arg(pluginName) @@ -753,25 +753,24 @@ SVDEBUG << "TransformFactory::getDefaultTransformFor: identifier \"" << id << "\"" << endl; - Vamp::PluginBase *plugin = instantiateDefaultPluginFor(id, rate); + std::shared_ptr<Vamp::PluginBase> plugin = instantiateDefaultPluginFor(id, rate); if (plugin) { t.setPluginVersion(QString("%1").arg(plugin->getPluginVersion())); setParametersFromPlugin(t, plugin); makeContextConsistentWithPlugin(t, plugin); - delete plugin; } return t; } -Vamp::PluginBase * +std::shared_ptr<Vamp::PluginBase> TransformFactory::instantiatePluginFor(const Transform &transform) { SVDEBUG << "TransformFactory::instantiatePluginFor: identifier \"" << transform.getIdentifier() << "\"" << endl; - Vamp::PluginBase *plugin = instantiateDefaultPluginFor + std::shared_ptr<Vamp::PluginBase> plugin = instantiateDefaultPluginFor (transform.getIdentifier(), transform.getSampleRate()); if (plugin) { @@ -781,7 +780,7 @@ return plugin; } -Vamp::PluginBase * +std::shared_ptr<Vamp::PluginBase> TransformFactory::instantiateDefaultPluginFor(TransformId identifier, sv_samplerate_t rate) { @@ -790,7 +789,7 @@ if (rate == 0) rate = 44100.0; QString pluginId = t.getPluginIdentifier(); - Vamp::PluginBase *plugin = nullptr; + std::shared_ptr<Vamp::PluginBase> plugin = nullptr; if (t.getType() == Transform::FeatureExtraction) { @@ -824,24 +823,6 @@ return plugin; } -Vamp::Plugin * -TransformFactory::downcastVampPlugin(Vamp::PluginBase *plugin) -{ - Vamp::Plugin *vp = dynamic_cast<Vamp::Plugin *>(plugin); - if (!vp) { -// cerr << "makeConsistentWithPlugin: not a Vamp::Plugin" << endl; - vp = dynamic_cast<Vamp::PluginHostAdapter *>(plugin); //!!! why? -} - if (!vp) { -// cerr << "makeConsistentWithPlugin: not a Vamp::PluginHostAdapter" << endl; - vp = dynamic_cast<Vamp::HostExt::PluginWrapper *>(plugin); //!!! no, I mean really why? - } - if (!vp) { -// cerr << "makeConsistentWithPlugin: not a Vamp::HostExt::PluginWrapper" << endl; - } - return vp; -} - bool TransformFactory::haveTransform(TransformId identifier) { @@ -894,12 +875,12 @@ return Vamp::Plugin::TimeDomain; } - Vamp::Plugin *plugin = - downcastVampPlugin(instantiateDefaultPluginFor(identifier, 0)); + std::shared_ptr<Vamp::Plugin> plugin = + std::dynamic_pointer_cast<Vamp::Plugin> + (instantiateDefaultPluginFor(identifier, 0)); if (plugin) { Vamp::Plugin::InputDomain d = plugin->getInputDomain(); - delete plugin; return d; } @@ -922,13 +903,15 @@ if (RealTimePluginFactory::instanceFor(id)) { - const RealTimePluginDescriptor *descriptor = + RealTimePluginDescriptor descriptor = RealTimePluginFactory::instanceFor(id)-> getPluginDescriptor(id); - if (!descriptor) return false; + if (descriptor.name == "") { + return false; + } - min = descriptor->audioInputPortCount; - max = descriptor->audioInputPortCount; + min = descriptor.audioInputPortCount; + max = descriptor.audioInputPortCount; return true; @@ -949,7 +932,7 @@ void TransformFactory::setParametersFromPlugin(Transform &transform, - Vamp::PluginBase *plugin) + std::shared_ptr<Vamp::PluginBase> plugin) { Transform::ParameterMap pmap; @@ -976,8 +959,8 @@ transform.setProgram(plugin->getCurrentProgram().c_str()); } - RealTimePluginInstance *rtpi = - dynamic_cast<RealTimePluginInstance *>(plugin); + std::shared_ptr<RealTimePluginInstance> rtpi = + std::dynamic_pointer_cast<RealTimePluginInstance>(plugin); Transform::ConfigurationMap cmap; @@ -997,14 +980,14 @@ void TransformFactory::setPluginParameters(const Transform &transform, - Vamp::PluginBase *plugin) + std::shared_ptr<Vamp::PluginBase> plugin) { //!!! check plugin & API version (see e.g. PluginXml::setParameters) //!!! check that this is the right plugin! - RealTimePluginInstance *rtpi = - dynamic_cast<RealTimePluginInstance *>(plugin); + std::shared_ptr<RealTimePluginInstance> rtpi = + std::dynamic_pointer_cast<RealTimePluginInstance>(plugin); if (rtpi) { const Transform::ConfigurationMap &cmap = transform.getConfiguration(); @@ -1035,9 +1018,10 @@ void TransformFactory::makeContextConsistentWithPlugin(Transform &transform, - Vamp::PluginBase *plugin) + std::shared_ptr<Vamp::PluginBase> plugin) { - const Vamp::Plugin *vp = downcastVampPlugin(plugin); + std::shared_ptr<Vamp::Plugin> vp = + std::dynamic_pointer_cast<Vamp::Plugin>(plugin); if (!vp) { // time domain input for real-time effects plugin @@ -1078,8 +1062,7 @@ SVDEBUG << "TransformFactory::getPluginConfigurationXml: identifier \"" << t.getIdentifier() << "\"" << endl; - Vamp::PluginBase *plugin = instantiateDefaultPluginFor - (t.getIdentifier(), 0); + auto plugin = instantiateDefaultPluginFor(t.getIdentifier(), 0); if (!plugin) { SVDEBUG << "TransformFactory::getPluginConfigurationXml: " << "Unable to instantiate plugin for transform \"" @@ -1091,7 +1074,6 @@ QTextStream out(&xml); PluginXml(plugin).toXml(out); - delete plugin; return xml; } @@ -1103,8 +1085,7 @@ SVDEBUG << "TransformFactory::setParametersFromPluginConfigurationXml: identifier \"" << t.getIdentifier() << "\"" << endl; - Vamp::PluginBase *plugin = instantiateDefaultPluginFor - (t.getIdentifier(), 0); + auto plugin = instantiateDefaultPluginFor(t.getIdentifier(), 0); if (!plugin) { SVDEBUG << "TransformFactory::setParametersFromPluginConfigurationXml: " << "Unable to instantiate plugin for transform \"" @@ -1114,7 +1095,6 @@ PluginXml(plugin).setParametersFromXml(xml); setParametersFromPlugin(t, plugin); - delete plugin; } TransformFactory::SearchResults
--- a/transform/TransformFactory.h Fri Mar 27 10:06:03 2020 +0000 +++ b/transform/TransformFactory.h Fri Apr 03 12:12:02 2020 +0100 @@ -88,7 +88,8 @@ * with different parameters and execution context settings. * Return the default one for the given transform. */ - Transform getDefaultTransformFor(TransformId identifier, sv_samplerate_t rate = 0); + Transform getDefaultTransformFor(TransformId identifier, + sv_samplerate_t rate = 0); /** * Full name of a transform, suitable for putting on a menu. @@ -138,19 +139,9 @@ * Vamp::PluginBase, but not necessarily a Vamp::Plugin (only if * the transform was a feature-extraction type -- call * downcastVampPlugin if you only want Vamp::Plugins). Returns - * NULL if no suitable plugin was available. - * - * The returned plugin is owned by the caller, and should be - * deleted (using "delete") when no longer needed. + * nullptr if no suitable plugin was available. */ - Vamp::PluginBase *instantiatePluginFor(const Transform &transform); - - /** - * Convert a Vamp::PluginBase to a Vamp::Plugin, if it is one. - * Return NULL otherwise. This ill-fitting convenience function - * is really just a dynamic_cast wrapper. - */ - Vamp::Plugin *downcastVampPlugin(Vamp::PluginBase *); + std::shared_ptr<Vamp::PluginBase> instantiatePluginFor(const Transform &transform); /** * Set the plugin parameters, program and configuration strings on @@ -158,20 +149,20 @@ * Note that no check is made whether the plugin is actually the * "correct" one for the transform. */ - void setParametersFromPlugin(Transform &transform, Vamp::PluginBase *plugin); + void setParametersFromPlugin(Transform &transform, std::shared_ptr<Vamp::PluginBase> plugin); /** * Set the parameters, program and configuration strings on the * given plugin from the given Transform object. */ - void setPluginParameters(const Transform &transform, Vamp::PluginBase *plugin); + void setPluginParameters(const Transform &transform, std::shared_ptr<Vamp::PluginBase> plugin); /** * If the given Transform object has no processing step and block * sizes set, set them to appropriate defaults for the given * plugin. */ - void makeContextConsistentWithPlugin(Transform &transform, Vamp::PluginBase *plugin); + void makeContextConsistentWithPlugin(Transform &transform, std::shared_ptr<Vamp::PluginBase> plugin); /** * Retrieve a <plugin ... /> XML fragment that describes the @@ -216,7 +207,7 @@ void populateFeatureExtractionPlugins(TransformDescriptionMap &); void populateRealTimePlugins(TransformDescriptionMap &); - Vamp::PluginBase *instantiateDefaultPluginFor(TransformId id, sv_samplerate_t rate); + std::shared_ptr<Vamp::PluginBase> instantiateDefaultPluginFor(TransformId id, sv_samplerate_t rate); QMutex m_transformsMutex; QMutex m_uninstalledTransformsMutex;