Mercurial > hg > piper-cpp
changeset 214:0906984b9496
Merge pull request #5 from piper-audio/dev/rename-pluginstub
Dev/rename pluginstub
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Thu, 09 Feb 2017 14:41:29 +0000 |
parents | 8183c3be5592 (current diff) a69724686f0b (diff) |
children | 8dff3213f77c |
files | vamp-client/PluginStub.h vamp-client/qt/AutoPlugin.h |
diffstat | 11 files changed, 688 insertions(+), 685 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Thu Feb 09 14:19:38 2017 +0000 +++ b/Makefile Thu Feb 09 14:41:29 2017 +0000 @@ -110,17 +110,19 @@ test/vamp-client/tst_PluginStub.o: vamp-support/PluginConfiguration.h test/vamp-client/tst_PluginStub.o: vamp-client/PluginClient.h test/vamp-client/tst_PluginStub.o: vamp-support/PluginConfiguration.h -test/vamp-client/tst_PluginStub.o: vamp-client/PluginStub.h +test/vamp-client/tst_PluginStub.o: vamp-client/PiperVampPlugin.h test/vamp-client/tst_PluginStub.o: vamp-support/PluginStaticData.h test/vamp-client/tst_PluginStub.o: vamp-client/PluginClient.h vamp-client/qt/test.o: vamp-client/qt/ProcessQtTransport.h vamp-client/qt/test.o: vamp-client/SynchronousTransport.h -vamp-client/qt/test.o: vamp-client/Exceptions.h vamp-client/qt/AutoPlugin.h +vamp-client/qt/test.o: vamp-client/Exceptions.h +vamp-client/qt/test.o: vamp-client/qt/PiperAutoPlugin.h vamp-client/qt/test.o: vamp-client/CapnpRRClient.h vamp-client/Loader.h vamp-client/qt/test.o: vamp-support/RequestResponse.h vamp-client/qt/test.o: vamp-support/PluginStaticData.h vamp-client/qt/test.o: vamp-support/PluginConfiguration.h -vamp-client/qt/test.o: vamp-client/PluginClient.h vamp-client/PluginStub.h +vamp-client/qt/test.o: vamp-client/PluginClient.h +vamp-client/qt/test.o: vamp-client/PiperVampPlugin.h vamp-client/qt/test.o: vamp-support/PluginStaticData.h vamp-client/qt/test.o: vamp-support/PluginConfiguration.h vamp-client/qt/test.o: vamp-client/SynchronousTransport.h
--- a/test/vamp-client/tst_PluginStub.cpp Thu Feb 09 14:19:38 2017 +0000 +++ b/test/vamp-client/tst_PluginStub.cpp Thu Feb 09 14:41:29 2017 +0000 @@ -1,7 +1,7 @@ #include "catch/catch.hpp" #include "vamp-client/Loader.h" #include "vamp-client/PluginClient.h" -#include "vamp-client/PluginStub.h" +#include "vamp-client/PiperVampPlugin.h" #include "vamp-support/RequestResponse.h" #include <vector> @@ -11,14 +11,14 @@ // This stub fakes the interaction with a Piper server // Here we only need to implement the configure method -// due to testing only the initialise implemention of PluginStub +// due to testing only the initialise implemention of PiperVampPlugin class StubClient : public PluginClient { public: StubClient(PluginStaticData staticData) : m_staticData(staticData) {} ConfigurationResponse - configure(PluginStub* plugin, + configure(PiperVampPlugin* plugin, PluginConfiguration config) override { const float scale = plugin->getParameter("framing-scale"); @@ -42,7 +42,7 @@ } Vamp::Plugin::FeatureSet - process(PluginStub* /*plugin*/, + process(PiperVampPlugin* /*plugin*/, AudioBuffer /*channels*/, Vamp::RealTime /*timestamp*/) override { @@ -50,13 +50,13 @@ } Vamp::Plugin::FeatureSet - finish(PluginStub* /*plugin*/) override + finish(PiperVampPlugin* /*plugin*/) override { return {}; } void - reset(PluginStub* /*plugin*/, PluginConfiguration /*config*/) override + reset(PiperVampPlugin* /*plugin*/, PluginConfiguration /*config*/) override {} private: PluginStaticData m_staticData; @@ -93,7 +93,7 @@ StubClient stub {staticData}; - PluginStub vampPiperAdapter { + PiperVampPlugin vampPiperAdapter { &stub, "stub", // plugin key 44100.0, // sample rate
--- a/vamp-client/CapnpRRClient.h Thu Feb 09 14:19:38 2017 +0000 +++ b/vamp-client/CapnpRRClient.h Thu Feb 09 14:41:29 2017 +0000 @@ -38,7 +38,7 @@ #include "Loader.h" #include "PluginClient.h" -#include "PluginStub.h" +#include "PiperVampPlugin.h" #include "SynchronousTransport.h" #include "vamp-support/AssignedPluginHandleMapper.h" @@ -149,7 +149,7 @@ // Loader methods: ListResponse - listPluginData(const ListRequest &req) override { + list(const ListRequest &req) override { LOG_E("CapnpRRClient::listPluginData called"); @@ -177,7 +177,7 @@ } LoadResponse - loadPlugin(const LoadRequest &req) override { + load(const LoadRequest &req) override { LOG_E("CapnpRRClient::loadPlugin called"); @@ -190,12 +190,12 @@ resp.staticData, resp.defaultConfiguration); - Vamp::Plugin *plugin = new PluginStub(this, - req.pluginKey, - req.inputSampleRate, - req.adapterFlags, - resp.staticData, - resp.defaultConfiguration); + Vamp::Plugin *plugin = new PiperVampPlugin(this, + req.pluginKey, + req.inputSampleRate, + req.adapterFlags, + resp.staticData, + resp.defaultConfiguration); m_mapper.addPlugin(handle, plugin); @@ -210,7 +210,7 @@ virtual ConfigurationResponse - configure(PluginStub *plugin, + configure(PiperVampPlugin *plugin, PluginConfiguration config) override { LOG_E("CapnpRRClient::configure called"); @@ -247,7 +247,7 @@ virtual Vamp::Plugin::FeatureSet - process(PluginStub *plugin, + process(PiperVampPlugin *plugin, std::vector<std::vector<float> > inputBuffers, Vamp::RealTime timestamp) override { @@ -284,7 +284,7 @@ } virtual Vamp::Plugin::FeatureSet - finish(PluginStub *plugin) override { + finish(PiperVampPlugin *plugin) override { LOG_E("CapnpRRClient::finish called"); @@ -323,7 +323,7 @@ } virtual void - reset(PluginStub *plugin, + reset(PiperVampPlugin *plugin, PluginConfiguration config) override { // Reload the plugin on the server side, and configure it as requested
--- a/vamp-client/Loader.h Thu Feb 09 14:19:38 2017 +0000 +++ b/vamp-client/Loader.h Thu Feb 09 14:41:29 2017 +0000 @@ -44,8 +44,8 @@ class Loader { public: - virtual ListResponse listPluginData(const ListRequest &) = 0; - virtual LoadResponse loadPlugin(const LoadRequest &) = 0; + virtual ListResponse list(const ListRequest &) = 0; + virtual LoadResponse load(const LoadRequest &) = 0; }; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vamp-client/PiperVampPlugin.h Thu Feb 09 14:41:29 2017 +0000 @@ -0,0 +1,413 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ +/* + Piper C++ + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006-2017 Chris Cannam and QMUL. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef PIPER_VAMP_PLUGIN_H +#define PIPER_VAMP_PLUGIN_H + +#include <vamp-hostsdk/Plugin.h> +#include <vamp-hostsdk/PluginLoader.h> + +#include "vamp-support/PluginStaticData.h" +#include "vamp-support/PluginConfiguration.h" + +#include "PluginClient.h" + +#include <cstdint> +#include <iostream> + +namespace piper_vamp { +namespace client { + +/** + * PiperVampPlugin presents a Piper feature extractor in the form of a + * Vamp plugin. + */ +class PiperVampPlugin : public Vamp::Plugin +{ + enum State { + /** + * The plugin's corresponding Piper feature extractor has been + * loaded but no subsequent state change has happened. This is + * the initial state of PiperVampPlugin on construction, since + * it is associated with a pre-loaded handle. + */ + Loaded, + + /** + * The plugin has been configured, and the step and block size + * received from the host in its last call to initialise() + * match those that were returned in the configuration + * response (i.e. the server's desired step and block + * size). Our m_config record reflects these correct + * values. The plugin is ready to process. + */ + Configured, + + /** + * The plugin has been configured, but the step and block size + * received from the host in its last call to initialise() + * differ from those returned by the server in the + * configuration response. Our initialise() call therefore + * returned false, and the plugin cannot be used until the + * host calls initialise() again with the "correct" step and + * block size. Our m_config record reflects these correct + * values, so the host can retrieve them through + * getPreferredStepSize and getPreferredBlockSize. + */ + Misconfigured, + + /** + * The finish() function has been called and the plugin + * unloaded. No further plugin activity is possible. + */ + Finished, + + /** + * A call has failed unrecoverably. No further plugin activity + * is possible. + */ + Failed + }; + +public: + PiperVampPlugin(PluginClient *client, + std::string pluginKey, + float inputSampleRate, + int adapterFlags, + PluginStaticData psd, + PluginConfiguration defaultConfig) : + Plugin(inputSampleRate), + m_client(client), + m_key(pluginKey), + m_adapterFlags(adapterFlags), + m_state(Loaded), + m_psd(psd), + m_defaultConfig(defaultConfig), + m_config(defaultConfig) + { } + + virtual ~PiperVampPlugin() { + if (m_state != Finished && m_state != Failed) { + try { + (void)m_client->finish(this); + } catch (const std::exception &e) { + // Finish can throw, but our destructor must not + std::cerr << "WARNING: PiperVampPlugin::~PiperVampPlugin: caught exception from finish(): " << e.what() << std::endl; + } + } + } + + virtual std::string getIdentifier() const { + return m_psd.basic.identifier; + } + + virtual std::string getName() const { + return m_psd.basic.name; + } + + virtual std::string getDescription() const { + return m_psd.basic.description; + } + + virtual std::string getMaker() const { + return m_psd.maker; + } + + virtual std::string getCopyright() const { + return m_psd.copyright; + } + + virtual int getPluginVersion() const { + return m_psd.pluginVersion; + } + + virtual ParameterList getParameterDescriptors() const { + return m_psd.parameters; + } + + virtual float getParameter(std::string name) const { + if (m_config.parameterValues.find(name) != m_config.parameterValues.end()) { + return m_config.parameterValues.at(name); + } else { + return 0.f; + } + } + + virtual void setParameter(std::string name, float value) { + if (m_state == Failed) { + throw std::logic_error("Plugin is in failed state"); + } + if (m_state != Loaded) { + m_state = Failed; + throw std::logic_error("Can't set parameter after plugin initialised"); + } + m_config.parameterValues[name] = value; + } + + virtual ProgramList getPrograms() const { + return m_psd.programs; + } + + virtual std::string getCurrentProgram() const { + return m_config.currentProgram; + } + + virtual void selectProgram(std::string program) { + if (m_state == Failed) { + throw std::logic_error("Plugin is in failed state"); + } + if (m_state != Loaded) { + m_state = Failed; + throw std::logic_error("Can't select program after plugin initialised"); + } + m_config.currentProgram = program; + } + + virtual bool initialise(size_t inputChannels, + size_t stepSize, + size_t blockSize) { + + if (m_state == Failed) { + throw std::logic_error("Plugin is in failed state"); + } + + if (m_state == Misconfigured) { + if (int(stepSize) == m_config.framing.stepSize && + int(blockSize) == m_config.framing.blockSize) { + m_state = Configured; + return true; + } else { + return false; + } + } + + if (m_state != Loaded) { + m_state = Failed; + throw std::logic_error("Plugin has already been initialised"); + } + + m_config.channelCount = int(inputChannels); + m_config.framing.stepSize = int(stepSize); + m_config.framing.blockSize = int(blockSize); + + try { + auto response = m_client->configure(this, m_config); + m_outputs = response.outputs; + + // Update with the new preferred step and block size now + // that the plugin has taken into account its parameter + // settings. If the values passed in to initialise() + // weren't suitable, then this ensures that a subsequent + // call to getPreferredStepSize/BlockSize on this plugin + // object will at least get acceptable values from now on + m_config.framing = response.framing; + + // And if they didn't match up with the passed-in ones, + // lodge ourselves in Misconfigured state and report + // failure so as to provoke the host to call initialise() + // again before any processing. + if (m_config.framing.stepSize != int(stepSize) || + m_config.framing.blockSize != int(blockSize)) { + m_state = Misconfigured; + return false; + } + + } catch (const std::exception &e) { + m_state = Failed; + throw; + } + + if (!m_outputs.empty()) { + m_state = Configured; + return true; + } else { + return false; + } + } + + virtual void reset() { + + if (m_state == Failed) { + throw std::logic_error("Plugin is in failed state"); + } + if (m_state == Loaded || m_state == Misconfigured) { + // reset is a no-op if the plugin hasn't been initialised yet + return; + } + + try { + m_client->reset(this, m_config); + } catch (const std::exception &e) { + m_state = Failed; + throw; + } + + m_state = Configured; + } + + virtual InputDomain getInputDomain() const { + return m_psd.inputDomain; + } + + virtual size_t getPreferredBlockSize() const { + // Return this from m_config instead of m_defaultConfig, so + // that it gets updated in the event of an initialise() call + // that fails for the wrong value + return m_config.framing.blockSize; + } + + virtual size_t getPreferredStepSize() const { + // Return this from m_config instead of m_defaultConfig, so + // that it gets updated in the event of an initialise() call + // that fails for the wrong value + return m_config.framing.stepSize; + } + + virtual size_t getMinChannelCount() const { + return m_psd.minChannelCount; + } + + virtual size_t getMaxChannelCount() const { + return m_psd.maxChannelCount; + } + + virtual OutputList getOutputDescriptors() const { + + if (m_state == Failed) { + throw std::logic_error("Plugin is in failed state"); + } + if (m_state == Configured) { + return m_outputs; + } + + //!!! todo: figure out for which hosts (and adapters?) it may + //!!! be a problem that the output descriptors are incomplete + //!!! here. Any such hosts/adapters are broken, but I bet they + //!!! exist + + OutputList staticOutputs; + for (const auto &o: m_psd.basicOutputInfo) { + OutputDescriptor od; + od.identifier = o.identifier; + od.name = o.name; + od.description = o.description; + staticOutputs.push_back(od); + } + return staticOutputs; + } + + virtual FeatureSet process(const float *const *inputBuffers, + Vamp::RealTime timestamp) { + + if (m_state == Failed) { + throw std::logic_error("Plugin is in failed state"); + } + if (m_state == Loaded || m_state == Misconfigured) { + m_state = Failed; + throw std::logic_error("Plugin has not been initialised"); + } + if (m_state == Finished) { + m_state = Failed; + throw std::logic_error("Plugin has already been disposed of"); + } + + std::vector<std::vector<float> > vecbuf; + for (int c = 0; c < m_config.channelCount; ++c) { + vecbuf.push_back(std::vector<float> + (inputBuffers[c], + inputBuffers[c] + m_config.framing.blockSize)); + } + + try { + return m_client->process(this, vecbuf, timestamp); + } catch (const std::exception &e) { + m_state = Failed; + throw; + } + } + + virtual FeatureSet getRemainingFeatures() { + + if (m_state == Failed) { + throw std::logic_error("Plugin is in failed state"); + } + if (m_state == Loaded || m_state == Misconfigured) { + m_state = Failed; + throw std::logic_error("Plugin has not been configured"); + } + if (m_state == Finished) { + m_state = Failed; + throw std::logic_error("Plugin has already been disposed of"); + } + + m_state = Finished; + + try { + return m_client->finish(this); + } catch (const std::exception &e) { + m_state = Failed; + throw; + } + } + + // Not Plugin methods, but needed by the PluginClient to support reloads: + + virtual float getInputSampleRate() const { + return m_inputSampleRate; + } + + virtual std::string getPluginKey() const { + return m_key; + } + + virtual int getAdapterFlags() const { + return m_adapterFlags; + } + +private: + PluginClient *m_client; + std::string m_key; + int m_adapterFlags; + State m_state; + PluginStaticData m_psd; + OutputList m_outputs; + PluginConfiguration m_defaultConfig; + PluginConfiguration m_config; +}; + +} +} + +#endif
--- a/vamp-client/PluginClient.h Thu Feb 09 14:19:38 2017 +0000 +++ b/vamp-client/PluginClient.h Thu Feb 09 14:41:29 2017 +0000 @@ -41,7 +41,7 @@ namespace piper_vamp { namespace client { -class PluginStub; +class PiperVampPlugin; /** * Interface for a client that accepts Vamp-like structures (Plugin @@ -54,22 +54,22 @@ public: virtual ConfigurationResponse - configure(PluginStub *plugin, + configure(PiperVampPlugin *plugin, PluginConfiguration config) = 0; virtual Vamp::Plugin::FeatureSet - process(PluginStub *plugin, + process(PiperVampPlugin *plugin, std::vector<std::vector<float> > inputBuffers, Vamp::RealTime timestamp) = 0; virtual Vamp::Plugin::FeatureSet - finish(PluginStub *plugin) = 0; + finish(PiperVampPlugin *plugin) = 0; virtual void - reset(PluginStub *plugin, + reset(PiperVampPlugin *plugin, PluginConfiguration config) = 0; };
--- a/vamp-client/PluginStub.h Thu Feb 09 14:19:38 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,412 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ -/* - Piper C++ - - An API for audio analysis and feature extraction plugins. - - Centre for Digital Music, Queen Mary, University of London. - Copyright 2006-2016 Chris Cannam and QMUL. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR - ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the names of the Centre for - Digital Music; Queen Mary, University of London; and Chris Cannam - shall not be used in advertising or otherwise to promote the sale, - use or other dealings in this Software without prior written - authorization. -*/ - -#ifndef PIPER_PLUGIN_STUB_H -#define PIPER_PLUGIN_STUB_H - -#include <vamp-hostsdk/Plugin.h> -#include <vamp-hostsdk/PluginLoader.h> - -#include "vamp-support/PluginStaticData.h" -#include "vamp-support/PluginConfiguration.h" - -#include "PluginClient.h" - -#include <cstdint> -#include <iostream> - -namespace piper_vamp { -namespace client { - -/** - * PluginStub presents a Piper feature extractor in the form of a Vamp plugin. - */ -class PluginStub : public Vamp::Plugin -{ - enum State { - /** - * The plugin's corresponding Piper feature extractor has been - * loaded but no subsequent state change has happened. This is - * the initial state of PluginStub on construction, since it - * is associated with a pre-loaded handle. - */ - Loaded, - - /** - * The plugin has been configured, and the step and block size - * received from the host in its last call to initialise() - * match those that were returned in the configuration - * response (i.e. the server's desired step and block - * size). Our m_config record reflects these correct - * values. The plugin is ready to process. - */ - Configured, - - /** - * The plugin has been configured, but the step and block size - * received from the host in its last call to initialise() - * differ from those returned by the server in the - * configuration response. Our initialise() call therefore - * returned false, and the plugin cannot be used until the - * host calls initialise() again with the "correct" step and - * block size. Our m_config record reflects these correct - * values, so the host can retrieve them through - * getPreferredStepSize and getPreferredBlockSize. - */ - Misconfigured, - - /** - * The finish() function has been called and the plugin - * unloaded. No further plugin activity is possible. - */ - Finished, - - /** - * A call has failed unrecoverably. No further plugin activity - * is possible. - */ - Failed - }; - -public: - PluginStub(PluginClient *client, - std::string pluginKey, - float inputSampleRate, - int adapterFlags, - PluginStaticData psd, - PluginConfiguration defaultConfig) : - Plugin(inputSampleRate), - m_client(client), - m_key(pluginKey), - m_adapterFlags(adapterFlags), - m_state(Loaded), - m_psd(psd), - m_defaultConfig(defaultConfig), - m_config(defaultConfig) - { } - - virtual ~PluginStub() { - if (m_state != Finished && m_state != Failed) { - try { - (void)m_client->finish(this); - } catch (const std::exception &e) { - // Finish can throw, but our destructor must not - std::cerr << "WARNING: PluginStub::~PluginStub: caught exception from finish(): " << e.what() << std::endl; - } - } - } - - virtual std::string getIdentifier() const { - return m_psd.basic.identifier; - } - - virtual std::string getName() const { - return m_psd.basic.name; - } - - virtual std::string getDescription() const { - return m_psd.basic.description; - } - - virtual std::string getMaker() const { - return m_psd.maker; - } - - virtual std::string getCopyright() const { - return m_psd.copyright; - } - - virtual int getPluginVersion() const { - return m_psd.pluginVersion; - } - - virtual ParameterList getParameterDescriptors() const { - return m_psd.parameters; - } - - virtual float getParameter(std::string name) const { - if (m_config.parameterValues.find(name) != m_config.parameterValues.end()) { - return m_config.parameterValues.at(name); - } else { - return 0.f; - } - } - - virtual void setParameter(std::string name, float value) { - if (m_state == Failed) { - throw std::logic_error("Plugin is in failed state"); - } - if (m_state != Loaded) { - m_state = Failed; - throw std::logic_error("Can't set parameter after plugin initialised"); - } - m_config.parameterValues[name] = value; - } - - virtual ProgramList getPrograms() const { - return m_psd.programs; - } - - virtual std::string getCurrentProgram() const { - return m_config.currentProgram; - } - - virtual void selectProgram(std::string program) { - if (m_state == Failed) { - throw std::logic_error("Plugin is in failed state"); - } - if (m_state != Loaded) { - m_state = Failed; - throw std::logic_error("Can't select program after plugin initialised"); - } - m_config.currentProgram = program; - } - - virtual bool initialise(size_t inputChannels, - size_t stepSize, - size_t blockSize) { - - if (m_state == Failed) { - throw std::logic_error("Plugin is in failed state"); - } - - if (m_state == Misconfigured) { - if (int(stepSize) == m_config.framing.stepSize && - int(blockSize) == m_config.framing.blockSize) { - m_state = Configured; - return true; - } else { - return false; - } - } - - if (m_state != Loaded) { - m_state = Failed; - throw std::logic_error("Plugin has already been initialised"); - } - - m_config.channelCount = int(inputChannels); - m_config.framing.stepSize = int(stepSize); - m_config.framing.blockSize = int(blockSize); - - try { - auto response = m_client->configure(this, m_config); - m_outputs = response.outputs; - - // Update with the new preferred step and block size now - // that the plugin has taken into account its parameter - // settings. If the values passed in to initialise() - // weren't suitable, then this ensures that a subsequent - // call to getPreferredStepSize/BlockSize on this plugin - // object will at least get acceptable values from now on - m_config.framing = response.framing; - - // And if they didn't match up with the passed-in ones, - // lodge ourselves in Misconfigured state and report - // failure so as to provoke the host to call initialise() - // again before any processing. - if (m_config.framing.stepSize != int(stepSize) || - m_config.framing.blockSize != int(blockSize)) { - m_state = Misconfigured; - return false; - } - - } catch (const std::exception &e) { - m_state = Failed; - throw; - } - - if (!m_outputs.empty()) { - m_state = Configured; - return true; - } else { - return false; - } - } - - virtual void reset() { - - if (m_state == Failed) { - throw std::logic_error("Plugin is in failed state"); - } - if (m_state == Loaded || m_state == Misconfigured) { - // reset is a no-op if the plugin hasn't been initialised yet - return; - } - - try { - m_client->reset(this, m_config); - } catch (const std::exception &e) { - m_state = Failed; - throw; - } - - m_state = Configured; - } - - virtual InputDomain getInputDomain() const { - return m_psd.inputDomain; - } - - virtual size_t getPreferredBlockSize() const { - // Return this from m_config instead of m_defaultConfig, so - // that it gets updated in the event of an initialise() call - // that fails for the wrong value - return m_config.framing.blockSize; - } - - virtual size_t getPreferredStepSize() const { - // Return this from m_config instead of m_defaultConfig, so - // that it gets updated in the event of an initialise() call - // that fails for the wrong value - return m_config.framing.stepSize; - } - - virtual size_t getMinChannelCount() const { - return m_psd.minChannelCount; - } - - virtual size_t getMaxChannelCount() const { - return m_psd.maxChannelCount; - } - - virtual OutputList getOutputDescriptors() const { - - if (m_state == Failed) { - throw std::logic_error("Plugin is in failed state"); - } - if (m_state == Configured) { - return m_outputs; - } - - //!!! todo: figure out for which hosts (and adapters?) it may - //!!! be a problem that the output descriptors are incomplete - //!!! here. Any such hosts/adapters are broken, but I bet they - //!!! exist - - OutputList staticOutputs; - for (const auto &o: m_psd.basicOutputInfo) { - OutputDescriptor od; - od.identifier = o.identifier; - od.name = o.name; - od.description = o.description; - staticOutputs.push_back(od); - } - return staticOutputs; - } - - virtual FeatureSet process(const float *const *inputBuffers, - Vamp::RealTime timestamp) { - - if (m_state == Failed) { - throw std::logic_error("Plugin is in failed state"); - } - if (m_state == Loaded || m_state == Misconfigured) { - m_state = Failed; - throw std::logic_error("Plugin has not been initialised"); - } - if (m_state == Finished) { - m_state = Failed; - throw std::logic_error("Plugin has already been disposed of"); - } - - std::vector<std::vector<float> > vecbuf; - for (int c = 0; c < m_config.channelCount; ++c) { - vecbuf.push_back(std::vector<float> - (inputBuffers[c], - inputBuffers[c] + m_config.framing.blockSize)); - } - - try { - return m_client->process(this, vecbuf, timestamp); - } catch (const std::exception &e) { - m_state = Failed; - throw; - } - } - - virtual FeatureSet getRemainingFeatures() { - - if (m_state == Failed) { - throw std::logic_error("Plugin is in failed state"); - } - if (m_state == Loaded || m_state == Misconfigured) { - m_state = Failed; - throw std::logic_error("Plugin has not been configured"); - } - if (m_state == Finished) { - m_state = Failed; - throw std::logic_error("Plugin has already been disposed of"); - } - - m_state = Finished; - - try { - return m_client->finish(this); - } catch (const std::exception &e) { - m_state = Failed; - throw; - } - } - - // Not Plugin methods, but needed by the PluginClient to support reloads: - - virtual float getInputSampleRate() const { - return m_inputSampleRate; - } - - virtual std::string getPluginKey() const { - return m_key; - } - - virtual int getAdapterFlags() const { - return m_adapterFlags; - } - -private: - PluginClient *m_client; - std::string m_key; - int m_adapterFlags; - State m_state; - PluginStaticData m_psd; - OutputList m_outputs; - PluginConfiguration m_defaultConfig; - PluginConfiguration m_config; -}; - -} -} - -#endif
--- a/vamp-client/qt/AutoPlugin.h Thu Feb 09 14:19:38 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,235 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ -/* - Piper C++ - - An API for audio analysis and feature extraction plugins. - - Centre for Digital Music, Queen Mary, University of London. - Copyright 2006-2016 Chris Cannam and QMUL. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR - ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the names of the Centre for - Digital Music; Queen Mary, University of London; and Chris Cannam - shall not be used in advertising or otherwise to promote the sale, - use or other dealings in this Software without prior written - authorization. -*/ - -#ifndef PIPER_AUTO_PLUGIN_H -#define PIPER_AUTO_PLUGIN_H - -#include "ProcessQtTransport.h" -#include "../CapnpRRClient.h" -#include "../Exceptions.h" - -#include <cstdint> - -namespace piper_vamp { -namespace client { - -/** - * AutoPlugin presents a Piper feature extractor in the form of a Vamp - * plugin, managing its own single-use server instance. That is, the - * distinguishing quality of AutoPlugin (in comparison with - * PluginStub) is that it runs and terminates its own Piper server, - * whose lifetime matches that of the plugin. - * - * Example usage: - * - * Vamp::Plugin *plugin = - * new AutoPlugin("piper-server-name.exe", - * "vamp-example-plugins:zerocrossing", - * 44100.0f, - * Vamp::HostExt::PluginLoader::ADAPT_ALL_SAFE, - * nullptr); - * plugin->initialise(...); - * plugin->process(...); <-- in the normal way for a Vamp plugin - * delete plugin; <-- causes the server to exit - * - * AutoPlugin makes use of the Loader and PluginClient interfaces, - * providing them its own transport layer object for its single server. - * - * Note that any method may throw ServerCrashed, RequestTimedOut or - * ProtocolError exceptions. - */ -class AutoPlugin : public Vamp::Plugin -{ -public: - /** - * Construct an AutoPlugin that runs an instance of the Piper - * server with the given server name (executable path), requesting - * the given plugin key from the server. - * - * \param adapterFlags a bitwise OR of the values in the - * Vamp::HostExt::PluginLoader::AdapterFlags enumeration - * - * \param logger an optional callback for log messages. Pass a - * null pointer to use cerr instead. - */ - AutoPlugin(std::string serverName, - std::string pluginKey, - float inputSampleRate, - int adapterFlags, - LogCallback *logger) : - Vamp::Plugin(inputSampleRate), - m_logger(logger), - m_transport(serverName, "capnp", logger), - m_client(&m_transport, logger) - { - LoadRequest req; - req.pluginKey = pluginKey; - req.inputSampleRate = inputSampleRate; - req.adapterFlags = adapterFlags; - try { - LoadResponse resp = m_client.loadPlugin(req); - m_plugin = resp.plugin; - } catch (ServerCrashed c) { - log(std::string("AutoPlugin: Server crashed: ") + c.what()); - m_plugin = 0; - } - } - - virtual ~AutoPlugin() { - delete m_plugin; - // The transport is a plain data member and will be deleted - // here, which will have the effect of terminating the server - } - - bool isOK() const { - return (m_plugin != nullptr); - } - - virtual std::string getIdentifier() const { - return getPlugin()->getIdentifier(); - } - - virtual std::string getName() const { - return getPlugin()->getName(); - } - - virtual std::string getDescription() const { - return getPlugin()->getDescription(); - } - - virtual std::string getMaker() const { - return getPlugin()->getMaker(); - } - - virtual std::string getCopyright() const { - return getPlugin()->getCopyright(); - } - - virtual int getPluginVersion() const { - return getPlugin()->getPluginVersion(); - } - - virtual ParameterList getParameterDescriptors() const { - return getPlugin()->getParameterDescriptors(); - } - - virtual float getParameter(std::string name) const { - return getPlugin()->getParameter(name); - } - - virtual void setParameter(std::string name, float value) { - getPlugin()->setParameter(name, value); - } - - virtual ProgramList getPrograms() const { - return getPlugin()->getPrograms(); - } - - virtual std::string getCurrentProgram() const { - return getPlugin()->getCurrentProgram(); - } - - virtual void selectProgram(std::string program) { - getPlugin()->selectProgram(program); - } - - virtual bool initialise(size_t inputChannels, - size_t stepSize, - size_t blockSize) { - return getPlugin()->initialise(inputChannels, stepSize, blockSize); - } - - virtual void reset() { - getPlugin()->reset(); - } - - virtual InputDomain getInputDomain() const { - return getPlugin()->getInputDomain(); - } - - virtual size_t getPreferredBlockSize() const { - return getPlugin()->getPreferredBlockSize(); - } - - virtual size_t getPreferredStepSize() const { - return getPlugin()->getPreferredStepSize(); - } - - virtual size_t getMinChannelCount() const { - return getPlugin()->getMinChannelCount(); - } - - virtual size_t getMaxChannelCount() const { - return getPlugin()->getMaxChannelCount(); - } - - virtual OutputList getOutputDescriptors() const { - return getPlugin()->getOutputDescriptors(); - } - - virtual FeatureSet process(const float *const *inputBuffers, - Vamp::RealTime timestamp) { - return getPlugin()->process(inputBuffers, timestamp); - } - - virtual FeatureSet getRemainingFeatures() { - return getPlugin()->getRemainingFeatures(); - } - -private: - LogCallback *m_logger; - ProcessQtTransport m_transport; - CapnpRRClient m_client; - Vamp::Plugin *m_plugin; - Vamp::Plugin *getPlugin() const { - if (!m_plugin) { - log("AutoPlugin: getPlugin() failed (caller should have called AutoPlugin::isOK)"); - throw std::logic_error("Plugin load failed"); - } - return m_plugin; - } - - void log(std::string message) const { - if (m_logger) m_logger->log(message); - else std::cerr << message << std::endl; - } -}; - -} -} - -#endif - -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vamp-client/qt/PiperAutoPlugin.h Thu Feb 09 14:41:29 2017 +0000 @@ -0,0 +1,235 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ +/* + Piper C++ + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006-2017 Chris Cannam and QMUL. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef PIPER_AUTO_PLUGIN_H +#define PIPER_AUTO_PLUGIN_H + +#include "ProcessQtTransport.h" +#include "../CapnpRRClient.h" +#include "../Exceptions.h" + +#include <cstdint> + +namespace piper_vamp { +namespace client { + +/** + * AutoPlugin presents a Piper feature extractor in the form of a Vamp + * plugin, managing its own single-use server instance. That is, the + * distinguishing quality of AutoPlugin (in comparison with + * PluginStub) is that it runs and terminates its own Piper server, + * whose lifetime matches that of the plugin. + * + * Example usage: + * + * Vamp::Plugin *plugin = + * new AutoPlugin("piper-server-name.exe", + * "vamp-example-plugins:zerocrossing", + * 44100.0f, + * Vamp::HostExt::PluginLoader::ADAPT_ALL_SAFE, + * nullptr); + * plugin->initialise(...); + * plugin->process(...); <-- in the normal way for a Vamp plugin + * delete plugin; <-- causes the server to exit + * + * AutoPlugin makes use of the Loader and PluginClient interfaces, + * providing them its own transport layer object for its single server. + * + * Note that any method may throw ServerCrashed, RequestTimedOut or + * ProtocolError exceptions. + */ +class PiperAutoPlugin : public Vamp::Plugin +{ +public: + /** + * Construct a PiperAutoPlugin that runs an instance of the Piper + * server with the given server name (executable path), requesting + * the given plugin key from the server. + * + * \param adapterFlags a bitwise OR of the values in the + * Vamp::HostExt::PluginLoader::AdapterFlags enumeration + * + * \param logger an optional callback for log messages. Pass a + * null pointer to use cerr instead. + */ + PiperAutoPlugin(std::string serverName, + std::string pluginKey, + float inputSampleRate, + int adapterFlags, + LogCallback *logger) : // logger may be nullptr for cerr + Vamp::Plugin(inputSampleRate), + m_logger(logger), + m_transport(serverName, "capnp", logger), + m_client(&m_transport, logger) + { + LoadRequest req; + req.pluginKey = pluginKey; + req.inputSampleRate = inputSampleRate; + req.adapterFlags = adapterFlags; + try { + LoadResponse resp = m_client.load(req); + m_plugin = resp.plugin; + } catch (ServerCrashed c) { + log(std::string("PiperAutoPlugin: Server crashed: ") + c.what()); + m_plugin = 0; + } + } + + virtual ~PiperAutoPlugin() { + delete m_plugin; + // The transport is a plain data member and will be deleted + // here, which will have the effect of terminating the server + } + + bool isOK() const { + return (m_plugin != nullptr); + } + + virtual std::string getIdentifier() const { + return getPlugin()->getIdentifier(); + } + + virtual std::string getName() const { + return getPlugin()->getName(); + } + + virtual std::string getDescription() const { + return getPlugin()->getDescription(); + } + + virtual std::string getMaker() const { + return getPlugin()->getMaker(); + } + + virtual std::string getCopyright() const { + return getPlugin()->getCopyright(); + } + + virtual int getPluginVersion() const { + return getPlugin()->getPluginVersion(); + } + + virtual ParameterList getParameterDescriptors() const { + return getPlugin()->getParameterDescriptors(); + } + + virtual float getParameter(std::string name) const { + return getPlugin()->getParameter(name); + } + + virtual void setParameter(std::string name, float value) { + getPlugin()->setParameter(name, value); + } + + virtual ProgramList getPrograms() const { + return getPlugin()->getPrograms(); + } + + virtual std::string getCurrentProgram() const { + return getPlugin()->getCurrentProgram(); + } + + virtual void selectProgram(std::string program) { + getPlugin()->selectProgram(program); + } + + virtual bool initialise(size_t inputChannels, + size_t stepSize, + size_t blockSize) { + return getPlugin()->initialise(inputChannels, stepSize, blockSize); + } + + virtual void reset() { + getPlugin()->reset(); + } + + virtual InputDomain getInputDomain() const { + return getPlugin()->getInputDomain(); + } + + virtual size_t getPreferredBlockSize() const { + return getPlugin()->getPreferredBlockSize(); + } + + virtual size_t getPreferredStepSize() const { + return getPlugin()->getPreferredStepSize(); + } + + virtual size_t getMinChannelCount() const { + return getPlugin()->getMinChannelCount(); + } + + virtual size_t getMaxChannelCount() const { + return getPlugin()->getMaxChannelCount(); + } + + virtual OutputList getOutputDescriptors() const { + return getPlugin()->getOutputDescriptors(); + } + + virtual FeatureSet process(const float *const *inputBuffers, + Vamp::RealTime timestamp) { + return getPlugin()->process(inputBuffers, timestamp); + } + + virtual FeatureSet getRemainingFeatures() { + return getPlugin()->getRemainingFeatures(); + } + +private: + LogCallback *m_logger; + ProcessQtTransport m_transport; + CapnpRRClient m_client; + Vamp::Plugin *m_plugin; + Vamp::Plugin *getPlugin() const { + if (!m_plugin) { + log("PiperAutoPlugin: getPlugin() failed (caller should have called PiperAutoPlugin::isOK)"); + throw std::logic_error("Plugin load failed"); + } + return m_plugin; + } + + void log(std::string message) const { + if (m_logger) m_logger->log(message); + else std::cerr << message << std::endl; + } +}; + +} +} + +#endif + +
--- a/vamp-client/qt/test.cpp Thu Feb 09 14:19:38 2017 +0000 +++ b/vamp-client/qt/test.cpp Thu Feb 09 14:41:29 2017 +0000 @@ -35,7 +35,7 @@ #include "ProcessQtTransport.h" #include "CapnpRRClient.h" -#include "AutoPlugin.h" +#include "PiperAutoPlugin.h" #include <stdexcept> @@ -60,7 +60,7 @@ piper_vamp::client::CapnpRRClient client(&transport, nullptr); - piper_vamp::ListResponse lr = client.listPluginData({}); + piper_vamp::ListResponse lr = client.list({}); cerr << "Plugins available:" << endl; int i = 1; for (const auto &p: lr.available) { @@ -70,7 +70,7 @@ piper_vamp::LoadRequest req; req.pluginKey = "vamp-example-plugins:zerocrossing"; req.inputSampleRate = 16; - piper_vamp::LoadResponse resp = client.loadPlugin(req); + piper_vamp::LoadResponse resp = client.load(req); Vamp::Plugin *plugin = resp.plugin; if (!plugin->initialise(1, 4, 4)) { @@ -107,13 +107,13 @@ delete plugin; - // Let's try a crazy AutoPlugin + // Let's try a crazy PiperAutoPlugin - piper_vamp::client::AutoPlugin ap + piper_vamp::client::PiperAutoPlugin ap (argv[1], "vamp-example-plugins:zerocrossing", 16, 0, nullptr); if (!ap.isOK()) { - cerr << "AutoPlugin creation failed" << endl; + cerr << "PiperAutoPlugin creation failed" << endl; } else { if (!ap.initialise(1, 4, 4)) { cerr << "initialisation failed" << endl;
--- a/vamp-client/qt/test.pro Thu Feb 09 14:19:38 2017 +0000 +++ b/vamp-client/qt/test.pro Thu Feb 09 14:41:29 2017 +0000 @@ -32,11 +32,11 @@ HEADERS += \ ProcessQtTransport.h \ - AutoPlugin.h \ + PiperAutoPlugin.h \ ../CapnpRRClient.h \ ../Loader.h \ ../PluginClient.h \ - ../PluginStub.h \ + ../PiperVampPlugin.h \ ../SynchronousTransport.h