Mercurial > hg > piper-cpp
changeset 49:f3f7561233d6
Begin plugin output id / index mapping for use in feature sets
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Fri, 16 Sep 2016 14:13:21 +0100 |
parents | ce6cb3308bd7 |
children | 12e3b396544c |
files | bits/PluginOutputIdMapper.h capnproto/VampnProto.h capnproto/vamp.capnp json/VampJson.h |
diffstat | 4 files changed, 196 insertions(+), 93 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bits/PluginOutputIdMapper.h Fri Sep 16 14:13:21 2016 +0100 @@ -0,0 +1,88 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vampipe + + 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 VAMPIPE_PLUGIN_ID_MAPPER_H +#define VAMPIPE_PLUGIN_ID_MAPPER_H + +#include <vamp-hostsdk/Plugin.h> + +#include <map> +#include <string> + +namespace vampipe { + +class PluginOutputIdMapper +{ +// NB not threadsafe. Does this matter? + +//!!! simplify. A single vector is almost certainly faster. + +public: + PluginOutputIdMapper(Vamp::Plugin *p) : m_plugin(p) { } + + class NotFound : virtual public std::runtime_error { + public: + NotFound() : runtime_error("output id or index not found in mapper") { } + }; + + int idToIndex(std::string outputId) const { + if (m_idIndexMap.empty()) populate(); + auto i = m_idIndexMap.find(outputId); + if (i == m_idIndexMap.end()) throw NotFound(); + return i->second; + } + + std::string indexToId(int index) const { + if (m_ids.empty()) populate(); + if (index < 0 || size_t(index) >= m_ids.size()) throw NotFound(); + return m_ids[index]; + } + +private: + Vamp::Plugin *m_plugin; + mutable std::vector<std::string> m_ids; + mutable std::map<std::string, int> m_idIndexMap; + + void populate() const { + Vamp::Plugin::OutputList outputs = m_plugin->getOutputDescriptors(); + for (const auto &d: outputs) { + m_idIndexMap[d.identifier] = m_ids.size(); + m_ids.push_back(d.identifier); + } + } +}; + +} + +#endif
--- a/capnproto/VampnProto.h Wed Sep 14 14:43:37 2016 +0100 +++ b/capnproto/VampnProto.h Fri Sep 16 14:13:21 2016 +0100 @@ -42,6 +42,7 @@ #include <vamp-hostsdk/PluginStaticData.h> #include "bits/PluginHandleMapper.h" +#include "bits/PluginOutputIdMapper.h" #include "bits/RequestResponseType.h" namespace vampipe @@ -294,13 +295,14 @@ static void buildFeatureSet(FeatureSet::Builder &b, - const Vamp::Plugin::FeatureSet &fs) { + const Vamp::Plugin::FeatureSet &fs, + const PluginOutputIdMapper &omapper) { auto featureset = b.initFeaturePairs(fs.size()); int ix = 0; for (const auto &fsi : fs) { auto fspair = featureset[ix]; - fspair.setOutput(fsi.first); + fspair.setOutput(omapper.indexToId(fsi.first)); auto featurelist = fspair.initFeatures(fsi.second.size()); for (size_t j = 0; j < fsi.second.size(); ++j) { auto feature = featurelist[j]; @@ -312,7 +314,8 @@ static void readFeatureSet(Vamp::Plugin::FeatureSet &fs, - const FeatureSet::Reader &r) { + const FeatureSet::Reader &r, + const PluginOutputIdMapper &omapper) { fs.clear(); auto pp = r.getFeaturePairs(); @@ -324,7 +327,7 @@ readFeature(vf, f); vfl.push_back(vf); } - fs[p.getOutput()] = vfl; + fs[omapper.idToIndex(p.getOutput())] = vfl; } } @@ -526,9 +529,9 @@ static void buildLoadResponse(LoadResponse::Builder &b, const Vamp::HostExt::LoadResponse &resp, - PluginHandleMapper &mapper) { + PluginHandleMapper &pmapper) { - b.setPluginHandle(mapper.pluginToHandle(resp.plugin)); + b.setPluginHandle(pmapper.pluginToHandle(resp.plugin)); auto sd = b.initStaticData(); buildPluginStaticData(sd, resp.staticData); auto conf = b.initDefaultConfiguration(); @@ -538,9 +541,9 @@ static void readLoadResponse(Vamp::HostExt::LoadResponse &resp, const LoadResponse::Reader &r, - PluginHandleMapper &mapper) { + PluginHandleMapper &pmapper) { - resp.plugin = mapper.handleToPlugin(r.getPluginHandle()); + resp.plugin = pmapper.handleToPlugin(r.getPluginHandle()); readPluginStaticData(resp.staticData, r.getStaticData()); readPluginConfiguration(resp.defaultConfiguration, r.getDefaultConfiguration()); @@ -549,9 +552,9 @@ static void buildConfigurationRequest(ConfigurationRequest::Builder &b, const Vamp::HostExt::ConfigurationRequest &cr, - PluginHandleMapper &mapper) { + PluginHandleMapper &pmapper) { - b.setPluginHandle(mapper.pluginToHandle(cr.plugin)); + b.setPluginHandle(pmapper.pluginToHandle(cr.plugin)); auto c = b.initConfiguration(); buildPluginConfiguration(c, cr.configuration); } @@ -559,10 +562,10 @@ static void readConfigurationRequest(Vamp::HostExt::ConfigurationRequest &cr, const ConfigurationRequest::Reader &r, - PluginHandleMapper &mapper) { + PluginHandleMapper &pmapper) { auto h = r.getPluginHandle(); - cr.plugin = mapper.handleToPlugin(h); + cr.plugin = pmapper.handleToPlugin(h); auto c = r.getConfiguration(); readPluginConfiguration(cr.configuration, c); } @@ -629,9 +632,9 @@ static void buildProcessRequest(ProcessRequest::Builder &b, const Vamp::HostExt::ProcessRequest &pr, - PluginHandleMapper &mapper) { + PluginHandleMapper &pmapper) { - b.setPluginHandle(mapper.pluginToHandle(pr.plugin)); + b.setPluginHandle(pmapper.pluginToHandle(pr.plugin)); auto input = b.initInput(); buildProcessInput(input, pr.timestamp, pr.inputBuffers); } @@ -639,26 +642,28 @@ static void readProcessRequest(Vamp::HostExt::ProcessRequest &pr, const ProcessRequest::Reader &r, - PluginHandleMapper &mapper) { + PluginHandleMapper &pmapper) { auto h = r.getPluginHandle(); - pr.plugin = mapper.handleToPlugin(h); + pr.plugin = pmapper.handleToPlugin(h); readProcessInput(pr.timestamp, pr.inputBuffers, r.getInput()); } static void buildProcessResponse(ProcessResponse::Builder &b, - const Vamp::HostExt::ProcessResponse &pr) { + const Vamp::HostExt::ProcessResponse &pr, + const PluginOutputIdMapper &omapper) { auto f = b.initFeatures(); - buildFeatureSet(f, pr.features); + buildFeatureSet(f, pr.features, omapper); } static void readProcessResponse(Vamp::HostExt::ProcessResponse &pr, - const ProcessResponse::Reader &r) { + const ProcessResponse::Reader &r, + const PluginOutputIdMapper &omapper) { - readFeatureSet(pr.features, r.getFeatures()); + readFeatureSet(pr.features, r.getFeatures(), omapper); } static void @@ -690,19 +695,19 @@ static void buildVampResponse_Load(VampResponse::Builder &b, const Vamp::HostExt::LoadResponse &resp, - PluginHandleMapper &mapper) { + PluginHandleMapper &pmapper) { b.setSuccess(resp.plugin != 0); b.setErrorText(""); auto u = b.getResponse().initLoad(); - buildLoadResponse(u, resp, mapper); + buildLoadResponse(u, resp, pmapper); } static void buildVampRequest_Configure(VampRequest::Builder &b, const Vamp::HostExt::ConfigurationRequest &cr, - PluginHandleMapper &mapper) { + PluginHandleMapper &pmapper) { auto u = b.getRequest().initConfigure(); - buildConfigurationRequest(u, cr, mapper); + buildConfigurationRequest(u, cr, pmapper); } static void @@ -717,34 +722,36 @@ static void buildVampRequest_Process(VampRequest::Builder &b, const Vamp::HostExt::ProcessRequest &pr, - PluginHandleMapper &mapper) { + PluginHandleMapper &pmapper) { auto u = b.getRequest().initProcess(); - buildProcessRequest(u, pr, mapper); + buildProcessRequest(u, pr, pmapper); } static void buildVampResponse_Process(VampResponse::Builder &b, - const Vamp::HostExt::ProcessResponse &pr) { + const Vamp::HostExt::ProcessResponse &pr, + const PluginOutputIdMapper &omapper) { b.setSuccess(true); b.setErrorText(""); auto u = b.getResponse().initProcess(); - buildProcessResponse(u, pr); + buildProcessResponse(u, pr, omapper); } static void buildVampRequest_Finish(VampRequest::Builder &b, Vamp::Plugin *p, - PluginHandleMapper &mapper) { + PluginHandleMapper &pmapper) { auto u = b.getRequest().initFinish(); - u.setPluginHandle(mapper.pluginToHandle(p)); + u.setPluginHandle(pmapper.pluginToHandle(p)); } static void buildVampResponse_Finish(VampResponse::Builder &b, - const Vamp::HostExt::ProcessResponse &pr) { + const Vamp::HostExt::ProcessResponse &pr, + const PluginOutputIdMapper &omapper) { - buildVampResponse_Process(b, pr); + buildVampResponse_Process(b, pr, omapper); } static RRType @@ -817,24 +824,24 @@ static void readVampResponse_Load(Vamp::HostExt::LoadResponse &resp, const VampResponse::Reader &r, - PluginHandleMapper &mapper) { + PluginHandleMapper &pmapper) { if (getRequestResponseType(r) != RRType::Load) { throw std::logic_error("not a load response"); } resp = {}; if (r.getSuccess()) { - readLoadResponse(resp, r.getResponse().getLoad(), mapper); + readLoadResponse(resp, r.getResponse().getLoad(), pmapper); } } static void readVampRequest_Configure(Vamp::HostExt::ConfigurationRequest &req, const VampRequest::Reader &r, - PluginHandleMapper &mapper) { + PluginHandleMapper &pmapper) { if (getRequestResponseType(r) != RRType::Configure) { throw std::logic_error("not a configuration request"); } - readConfigurationRequest(req, r.getRequest().getConfigure(), mapper); + readConfigurationRequest(req, r.getRequest().getConfigure(), pmapper); } static void @@ -852,45 +859,47 @@ static void readVampRequest_Process(Vamp::HostExt::ProcessRequest &req, const VampRequest::Reader &r, - PluginHandleMapper &mapper) { + PluginHandleMapper &pmapper) { if (getRequestResponseType(r) != RRType::Process) { throw std::logic_error("not a process request"); } - readProcessRequest(req, r.getRequest().getProcess(), mapper); + readProcessRequest(req, r.getRequest().getProcess(), pmapper); } static void readVampResponse_Process(Vamp::HostExt::ProcessResponse &resp, - const VampResponse::Reader &r) { + const VampResponse::Reader &r, + const PluginOutputIdMapper &omapper) { if (getRequestResponseType(r) != RRType::Process) { throw std::logic_error("not a process response"); } resp = {}; if (r.getSuccess()) { - readProcessResponse(resp, r.getResponse().getProcess()); + readProcessResponse(resp, r.getResponse().getProcess(), omapper); } } static void readVampRequest_Finish(Vamp::Plugin *&finishPlugin, const VampRequest::Reader &r, - PluginHandleMapper &mapper) { + PluginHandleMapper &pmapper) { if (getRequestResponseType(r) != RRType::Finish) { throw std::logic_error("not a finish request"); } - finishPlugin = mapper.handleToPlugin + finishPlugin = pmapper.handleToPlugin (r.getRequest().getFinish().getPluginHandle()); } static void readVampResponse_Finish(Vamp::HostExt::ProcessResponse &resp, - const VampResponse::Reader &r) { + const VampResponse::Reader &r, + const PluginOutputIdMapper &omapper) { if (getRequestResponseType(r) != RRType::Finish) { throw std::logic_error("not a finish response"); } resp = {}; if (r.getSuccess()) { - readProcessResponse(resp, r.getResponse().getFinish()); + readProcessResponse(resp, r.getResponse().getFinish(), omapper); } } };
--- a/capnproto/vamp.capnp Wed Sep 14 14:43:37 2016 +0100 +++ b/capnproto/vamp.capnp Fri Sep 16 14:13:21 2016 +0100 @@ -96,7 +96,7 @@ struct FeatureSet { struct FSPair { - output @0 :Int32; + output @0 :Text; features @1 :List(Feature) = []; } featurePairs @0 :List(FSPair); @@ -144,14 +144,15 @@ input @1 :ProcessInput; } +struct ProcessResponse { + pluginHandle @0 :Int32; + features @1 :FeatureSet; +} + struct FinishRequest { pluginHandle @0 :Int32; } -struct ProcessResponse { - features @0 :FeatureSet; -} - struct VampRequest { request :union { list @0 :Void;
--- a/json/VampJson.h Wed Sep 14 14:43:37 2016 +0100 +++ b/json/VampJson.h Fri Sep 16 14:13:21 2016 +0100 @@ -47,6 +47,7 @@ #include <vamp-hostsdk/PluginLoader.h> #include "bits/PluginHandleMapper.h" +#include "bits/PluginOutputIdMapper.h" #include "bits/RequestResponseType.h" namespace vampipe { @@ -392,6 +393,7 @@ static json11::Json fromFeatureSet(const Vamp::Plugin::FeatureSet &fs, + const PluginOutputIdMapper &omapper, BufferSerialisation serialisation) { json11::Json::object jo; @@ -400,10 +402,7 @@ for (const Vamp::Plugin::Feature &f: fsi.second) { fj.push_back(fromFeature(f, serialisation)); } - std::stringstream sstr; - sstr << fsi.first; - std::string n = sstr.str(); - jo[n] = fj; + jo[omapper.indexToId(fsi.first)] = fj; } return json11::Json(jo); } @@ -423,18 +422,18 @@ } static Vamp::Plugin::FeatureSet - toFeatureSet(json11::Json j, BufferSerialisation &serialisation) { + toFeatureSet(json11::Json j, + const PluginOutputIdMapper &omapper, + BufferSerialisation &serialisation) { Vamp::Plugin::FeatureSet fs; if (!j.is_object()) { throw Failure("object expected for feature set"); } for (auto &entry : j.object_items()) { - std::string nstr = entry.first; - size_t count = 0; - int n = stoi(nstr, &count); - if (n < 0 || fs.find(n) != fs.end() || count < nstr.size()) { - throw Failure("invalid or duplicate numerical index for output"); + int n = omapper.idToIndex(entry.first); + if (fs.find(n) != fs.end()) { + throw Failure("duplicate numerical index for output"); } fs[n] = toFeatureList(entry.second, serialisation); } @@ -744,10 +743,10 @@ static json11::Json fromLoadResponse(const Vamp::HostExt::LoadResponse &resp, - const PluginHandleMapper &mapper) { + const PluginHandleMapper &pmapper) { json11::Json::object jo; - jo["pluginHandle"] = double(mapper.pluginToHandle(resp.plugin)); + jo["pluginHandle"] = double(pmapper.pluginToHandle(resp.plugin)); jo["staticData"] = fromPluginStaticData(resp.staticData); jo["defaultConfiguration"] = fromPluginConfiguration(resp.defaultConfiguration); @@ -756,7 +755,7 @@ static Vamp::HostExt::LoadResponse toLoadResponse(json11::Json j, - const PluginHandleMapper &mapper) { + const PluginHandleMapper &pmapper) { std::string err; @@ -768,7 +767,7 @@ } Vamp::HostExt::LoadResponse resp; - resp.plugin = mapper.handleToPlugin(j["pluginHandle"].int_value()); + resp.plugin = pmapper.handleToPlugin(j["pluginHandle"].int_value()); resp.staticData = toPluginStaticData(j["staticData"]); resp.defaultConfiguration = toPluginConfiguration(j["defaultConfiguration"]); return resp; @@ -776,11 +775,11 @@ static json11::Json fromConfigurationRequest(const Vamp::HostExt::ConfigurationRequest &cr, - const PluginHandleMapper &mapper) { + const PluginHandleMapper &pmapper) { json11::Json::object jo; - jo["pluginHandle"] = mapper.pluginToHandle(cr.plugin); + jo["pluginHandle"] = pmapper.pluginToHandle(cr.plugin); jo["configuration"] = fromPluginConfiguration(cr.configuration); return json11::Json(jo); @@ -788,7 +787,7 @@ static Vamp::HostExt::ConfigurationRequest toConfigurationRequest(json11::Json j, - const PluginHandleMapper &mapper) { + const PluginHandleMapper &pmapper) { std::string err; @@ -799,7 +798,7 @@ } Vamp::HostExt::ConfigurationRequest cr; - cr.plugin = mapper.handleToPlugin(j["pluginHandle"].int_value()); + cr.plugin = pmapper.handleToPlugin(j["pluginHandle"].int_value()); cr.configuration = toPluginConfiguration(j["configuration"]); return cr; } @@ -836,11 +835,11 @@ static json11::Json fromProcessRequest(const Vamp::HostExt::ProcessRequest &r, - const PluginHandleMapper &mapper, + const PluginHandleMapper &pmapper, BufferSerialisation serialisation) { json11::Json::object jo; - jo["pluginHandle"] = mapper.pluginToHandle(r.plugin); + jo["pluginHandle"] = pmapper.pluginToHandle(r.plugin); json11::Json::object io; io["timestamp"] = fromRealTime(r.timestamp); @@ -865,7 +864,7 @@ static Vamp::HostExt::ProcessRequest toProcessRequest(json11::Json j, - const PluginHandleMapper &mapper, + const PluginHandleMapper &pmapper, BufferSerialisation &serialisation) { std::string err; @@ -885,7 +884,7 @@ } Vamp::HostExt::ProcessRequest r; - r.plugin = mapper.handleToPlugin(j["pluginHandle"].int_value()); + r.plugin = pmapper.handleToPlugin(j["pluginHandle"].int_value()); r.timestamp = toRealTime(input["timestamp"]); @@ -951,23 +950,23 @@ static json11::Json fromVampResponse_Load(const Vamp::HostExt::LoadResponse &resp, - const PluginHandleMapper &mapper) { + const PluginHandleMapper &pmapper) { json11::Json::object jo; jo["type"] = "load"; jo["success"] = (resp.plugin != 0); jo["errorText"] = ""; - jo["content"] = fromLoadResponse(resp, mapper); + jo["content"] = fromLoadResponse(resp, pmapper); return json11::Json(jo); } static json11::Json fromVampRequest_Configure(const Vamp::HostExt::ConfigurationRequest &req, - const PluginHandleMapper &mapper) { + const PluginHandleMapper &pmapper) { json11::Json::object jo; jo["type"] = "configure"; - jo["content"] = fromConfigurationRequest(req, mapper); + jo["content"] = fromConfigurationRequest(req, pmapper); return json11::Json(jo); } @@ -984,48 +983,50 @@ static json11::Json fromVampRequest_Process(const Vamp::HostExt::ProcessRequest &req, - const PluginHandleMapper &mapper, + const PluginHandleMapper &pmapper, BufferSerialisation serialisation) { json11::Json::object jo; jo["type"] = "process"; - jo["content"] = fromProcessRequest(req, mapper, serialisation); + jo["content"] = fromProcessRequest(req, pmapper, serialisation); return json11::Json(jo); } static json11::Json fromVampResponse_Process(const Vamp::HostExt::ProcessResponse &resp, + const PluginOutputIdMapper &omapper, BufferSerialisation serialisation) { json11::Json::object jo; jo["type"] = "process"; jo["success"] = true; jo["errorText"] = ""; - jo["content"] = fromFeatureSet(resp.features, serialisation); + jo["content"] = fromFeatureSet(resp.features, omapper, serialisation); return json11::Json(jo); } static json11::Json fromVampRequest_Finish(Vamp::Plugin *p, - const PluginHandleMapper &mapper) { + const PluginHandleMapper &pmapper) { json11::Json::object jo; jo["type"] = "finish"; json11::Json::object fo; - fo["pluginHandle"] = mapper.pluginToHandle(p); + fo["pluginHandle"] = pmapper.pluginToHandle(p); jo["content"] = fo; return json11::Json(jo); } static json11::Json fromVampResponse_Finish(const Vamp::HostExt::ProcessResponse &resp, + const PluginOutputIdMapper &omapper, BufferSerialisation serialisation) { json11::Json::object jo; jo["type"] = "finish"; jo["success"] = true; jo["errorText"] = ""; - jo["content"] = fromFeatureSet(resp.features, serialisation); + jo["content"] = fromFeatureSet(resp.features, omapper, serialisation); return json11::Json(jo); } @@ -1116,20 +1117,20 @@ } static Vamp::HostExt::LoadResponse - toVampResponse_Load(json11::Json j, const PluginHandleMapper &mapper) { + toVampResponse_Load(json11::Json j, const PluginHandleMapper &pmapper) { Vamp::HostExt::LoadResponse resp; if (successful(j)) { - resp = toLoadResponse(j["content"], mapper); + resp = toLoadResponse(j["content"], pmapper); } return resp; } static Vamp::HostExt::ConfigurationRequest - toVampRequest_Configure(json11::Json j, const PluginHandleMapper &mapper) { + toVampRequest_Configure(json11::Json j, const PluginHandleMapper &pmapper) { checkTypeField(j, "configure"); - return toConfigurationRequest(j["content"], mapper); + return toConfigurationRequest(j["content"], pmapper); } static Vamp::HostExt::ConfigurationResponse @@ -1143,36 +1144,40 @@ } static Vamp::HostExt::ProcessRequest - toVampRequest_Process(json11::Json j, const PluginHandleMapper &mapper, + toVampRequest_Process(json11::Json j, const PluginHandleMapper &pmapper, BufferSerialisation &serialisation) { checkTypeField(j, "process"); - return toProcessRequest(j["content"], mapper, serialisation); + return toProcessRequest(j["content"], pmapper, serialisation); } static Vamp::HostExt::ProcessResponse - toVampResponse_Process(json11::Json j, BufferSerialisation &serialisation) { + toVampResponse_Process(json11::Json j, + const PluginOutputIdMapper &omapper, + BufferSerialisation &serialisation) { Vamp::HostExt::ProcessResponse resp; if (successful(j)) { - resp.features = toFeatureSet(j["content"], serialisation); + resp.features = toFeatureSet(j["content"], omapper, serialisation); } return resp; } static Vamp::Plugin * - toVampRequest_Finish(json11::Json j, const PluginHandleMapper &mapper) { + toVampRequest_Finish(json11::Json j, const PluginHandleMapper &pmapper) { checkTypeField(j, "finish"); - return mapper.handleToPlugin(j["content"]["pluginHandle"].int_value()); + return pmapper.handleToPlugin(j["content"]["pluginHandle"].int_value()); } static Vamp::HostExt::ProcessResponse - toVampResponse_Finish(json11::Json j, BufferSerialisation &serialisation) { + toVampResponse_Finish(json11::Json j, + const PluginOutputIdMapper &omapper, + BufferSerialisation &serialisation) { Vamp::HostExt::ProcessResponse resp; if (successful(j)) { - resp.features = toFeatureSet(j["content"], serialisation); + resp.features = toFeatureSet(j["content"], omapper, serialisation); } return resp; }