cannam@208: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ cannam@208: /* cannam@208: Piper C++ cannam@208: cannam@208: An API for audio analysis and feature extraction plugins. cannam@208: cannam@208: Centre for Digital Music, Queen Mary, University of London. cannam@208: Copyright 2006-2017 Chris Cannam and QMUL. cannam@208: cannam@208: Permission is hereby granted, free of charge, to any person cannam@208: obtaining a copy of this software and associated documentation cannam@208: files (the "Software"), to deal in the Software without cannam@208: restriction, including without limitation the rights to use, copy, cannam@208: modify, merge, publish, distribute, sublicense, and/or sell copies cannam@208: of the Software, and to permit persons to whom the Software is cannam@208: furnished to do so, subject to the following conditions: cannam@208: cannam@208: The above copyright notice and this permission notice shall be cannam@208: included in all copies or substantial portions of the Software. cannam@208: cannam@208: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, cannam@208: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF cannam@208: MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND cannam@208: NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR cannam@208: ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF cannam@208: CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION cannam@208: WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. cannam@208: cannam@208: Except as contained in this notice, the names of the Centre for cannam@208: Digital Music; Queen Mary, University of London; and Chris Cannam cannam@208: shall not be used in advertising or otherwise to promote the sale, cannam@208: use or other dealings in this Software without prior written cannam@208: authorization. cannam@208: */ cannam@208: cannam@208: #ifndef PIPER_AUTO_PLUGIN_H cannam@208: #define PIPER_AUTO_PLUGIN_H cannam@208: cannam@208: #include "ProcessQtTransport.h" cannam@208: #include "../CapnpRRClient.h" cannam@208: #include "../Exceptions.h" cannam@208: cannam@208: #include cannam@208: cannam@208: namespace piper_vamp { cannam@208: namespace client { cannam@208: cannam@208: /** cannam@208: * This "plugin" make the Piper client abstraction behave like a local cannam@208: * Vamp plugin, with its own server that lasts only for the lifetime cannam@208: * of this plugin and serves only it. cannam@208: * cannam@208: * Note that any method may throw ServerCrashed, RequestTimedOut or cannam@208: * ProtocolError exceptions. cannam@208: */ cannam@208: class PiperAutoPlugin : public Vamp::Plugin cannam@208: { cannam@208: public: cannam@208: PiperAutoPlugin(std::string serverName, cannam@208: std::string pluginKey, cannam@208: float inputSampleRate, cannam@208: int adapterFlags, cannam@208: LogCallback *logger) : // logger may be nullptr for cerr cannam@208: Vamp::Plugin(inputSampleRate), cannam@208: m_logger(logger), cannam@208: m_transport(serverName, "capnp", logger), cannam@208: m_client(&m_transport, logger) cannam@208: { cannam@208: LoadRequest req; cannam@208: req.pluginKey = pluginKey; cannam@208: req.inputSampleRate = inputSampleRate; cannam@208: req.adapterFlags = adapterFlags; cannam@208: try { cannam@208: LoadResponse resp = m_client.load(req); cannam@208: m_plugin = resp.plugin; cannam@208: } catch (ServerCrashed c) { cannam@208: log(std::string("PiperAutoPlugin: Server crashed: ") + c.what()); cannam@208: m_plugin = 0; cannam@208: } cannam@208: } cannam@208: cannam@208: virtual ~PiperAutoPlugin() { cannam@208: delete m_plugin; cannam@208: } cannam@208: cannam@208: bool isOK() const { cannam@208: return (m_plugin != nullptr); cannam@208: } cannam@208: cannam@208: virtual std::string getIdentifier() const { cannam@208: return getPlugin()->getIdentifier(); cannam@208: } cannam@208: cannam@208: virtual std::string getName() const { cannam@208: return getPlugin()->getName(); cannam@208: } cannam@208: cannam@208: virtual std::string getDescription() const { cannam@208: return getPlugin()->getDescription(); cannam@208: } cannam@208: cannam@208: virtual std::string getMaker() const { cannam@208: return getPlugin()->getMaker(); cannam@208: } cannam@208: cannam@208: virtual std::string getCopyright() const { cannam@208: return getPlugin()->getCopyright(); cannam@208: } cannam@208: cannam@208: virtual int getPluginVersion() const { cannam@208: return getPlugin()->getPluginVersion(); cannam@208: } cannam@208: cannam@208: virtual ParameterList getParameterDescriptors() const { cannam@208: return getPlugin()->getParameterDescriptors(); cannam@208: } cannam@208: cannam@208: virtual float getParameter(std::string name) const { cannam@208: return getPlugin()->getParameter(name); cannam@208: } cannam@208: cannam@208: virtual void setParameter(std::string name, float value) { cannam@208: getPlugin()->setParameter(name, value); cannam@208: } cannam@208: cannam@208: virtual ProgramList getPrograms() const { cannam@208: return getPlugin()->getPrograms(); cannam@208: } cannam@208: cannam@208: virtual std::string getCurrentProgram() const { cannam@208: return getPlugin()->getCurrentProgram(); cannam@208: } cannam@208: cannam@208: virtual void selectProgram(std::string program) { cannam@208: getPlugin()->selectProgram(program); cannam@208: } cannam@208: cannam@208: virtual bool initialise(size_t inputChannels, cannam@208: size_t stepSize, cannam@208: size_t blockSize) { cannam@208: return getPlugin()->initialise(inputChannels, stepSize, blockSize); cannam@208: } cannam@208: cannam@208: virtual void reset() { cannam@208: getPlugin()->reset(); cannam@208: } cannam@208: cannam@208: virtual InputDomain getInputDomain() const { cannam@208: return getPlugin()->getInputDomain(); cannam@208: } cannam@208: cannam@208: virtual size_t getPreferredBlockSize() const { cannam@208: return getPlugin()->getPreferredBlockSize(); cannam@208: } cannam@208: cannam@208: virtual size_t getPreferredStepSize() const { cannam@208: return getPlugin()->getPreferredStepSize(); cannam@208: } cannam@208: cannam@208: virtual size_t getMinChannelCount() const { cannam@208: return getPlugin()->getMinChannelCount(); cannam@208: } cannam@208: cannam@208: virtual size_t getMaxChannelCount() const { cannam@208: return getPlugin()->getMaxChannelCount(); cannam@208: } cannam@208: cannam@208: virtual OutputList getOutputDescriptors() const { cannam@208: return getPlugin()->getOutputDescriptors(); cannam@208: } cannam@208: cannam@208: virtual FeatureSet process(const float *const *inputBuffers, cannam@208: Vamp::RealTime timestamp) { cannam@208: return getPlugin()->process(inputBuffers, timestamp); cannam@208: } cannam@208: cannam@208: virtual FeatureSet getRemainingFeatures() { cannam@208: return getPlugin()->getRemainingFeatures(); cannam@208: } cannam@208: cannam@208: private: cannam@208: LogCallback *m_logger; cannam@208: ProcessQtTransport m_transport; cannam@208: CapnpRRClient m_client; cannam@208: Vamp::Plugin *m_plugin; cannam@208: Vamp::Plugin *getPlugin() const { cannam@208: if (!m_plugin) { cannam@208: log("PiperAutoPlugin: getPlugin() failed (caller should have called PiperAutoPlugin::isOK)"); cannam@208: throw std::logic_error("Plugin load failed"); cannam@208: } cannam@208: return m_plugin; cannam@208: } cannam@208: cannam@208: void log(std::string message) const { cannam@208: if (m_logger) m_logger->log(message); cannam@208: else std::cerr << message << std::endl; cannam@208: } cannam@208: }; cannam@208: cannam@208: } cannam@208: } cannam@208: cannam@208: #endif cannam@208: cannam@208: