| c@5 | 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */ | 
| c@5 | 2 | 
| c@18 | 3 /* | 
| c@18 | 4     VamPipe | 
| c@18 | 5 | 
| c@18 | 6     Centre for Digital Music, Queen Mary, University of London. | 
| c@18 | 7     Copyright 2015-2016 QMUL. | 
| c@18 | 8 | 
| c@18 | 9     Permission is hereby granted, free of charge, to any person | 
| c@18 | 10     obtaining a copy of this software and associated documentation | 
| c@18 | 11     files (the "Software"), to deal in the Software without | 
| c@18 | 12     restriction, including without limitation the rights to use, copy, | 
| c@18 | 13     modify, merge, publish, distribute, sublicense, and/or sell copies | 
| c@18 | 14     of the Software, and to permit persons to whom the Software is | 
| c@18 | 15     furnished to do so, subject to the following conditions: | 
| c@18 | 16 | 
| c@18 | 17     The above copyright notice and this permission notice shall be | 
| c@18 | 18     included in all copies or substantial portions of the Software. | 
| c@18 | 19 | 
| c@18 | 20     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | 
| c@18 | 21     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | 
| c@18 | 22     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | 
| c@18 | 23     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR | 
| c@18 | 24     ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | 
| c@18 | 25     CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | 
| c@18 | 26     WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | 
| c@18 | 27 | 
| c@18 | 28     Except as contained in this notice, the names of the Centre for | 
| c@18 | 29     Digital Music; Queen Mary, University of London; and Chris Cannam | 
| c@18 | 30     shall not be used in advertising or otherwise to promote the sale, | 
| c@18 | 31     use or other dealings in this Software without prior written | 
| c@18 | 32     authorization. | 
| c@18 | 33 */ | 
| c@18 | 34 | 
| c@5 | 35 #include "vamp.capnp.h" | 
| c@5 | 36 | 
| c@5 | 37 #include <capnp/message.h> | 
| c@5 | 38 #include <capnp/serialize-packed.h> | 
| c@5 | 39 | 
| c@5 | 40 #include <vamp-hostsdk/Plugin.h> | 
| c@5 | 41 #include <vamp-hostsdk/PluginLoader.h> | 
| c@5 | 42 #include <vamp-hostsdk/PluginStaticData.h> | 
| c@5 | 43 | 
| c@10 | 44 #include "bits/PluginHandleMapper.h" | 
| c@10 | 45 | 
| c@5 | 46 namespace vampipe | 
| c@5 | 47 { | 
| c@5 | 48 | 
| c@5 | 49 /** | 
| c@5 | 50  * Convert the structures laid out in the Vamp SDK classes into Cap'n | 
| c@6 | 51  * Proto structures (and back again). | 
| c@5 | 52  * | 
| c@6 | 53  * At least some of this will be necessary for any implementation | 
| c@6 | 54  * using Cap'n Proto that uses the C++ Vamp SDK to provide its | 
| c@6 | 55  * reference structures. An implementation could alternatively use the | 
| c@6 | 56  * Cap'n Proto structures directly, and interact with Vamp plugins | 
| c@6 | 57  * using the Vamp C API, without using the C++ Vamp SDK classes at | 
| c@18 | 58  * all. That would avoid a lot of copying (in Cap'n Proto style). | 
| c@5 | 59  */ | 
| c@6 | 60 class VampnProto | 
| c@5 | 61 { | 
| c@5 | 62 public: | 
| c@5 | 63     typedef ::capnp::MallocMessageBuilder MsgBuilder; | 
| c@5 | 64 | 
| c@5 | 65     template <typename T, typename B> | 
| c@5 | 66     static void buildBasicDescriptor(B &basic, const T &t) { | 
| c@5 | 67         basic.setIdentifier(t.identifier); | 
| c@5 | 68         basic.setName(t.name); | 
| c@5 | 69         basic.setDescription(t.description); | 
| c@5 | 70     } | 
| c@5 | 71 | 
| c@5 | 72     template <typename T, typename B> | 
| c@5 | 73     static void readBasicDescriptor(T &t, const B &basic) { | 
| c@5 | 74         t.identifier = basic.getIdentifier(); | 
| c@5 | 75         t.name = basic.getName(); | 
| c@5 | 76         t.description = basic.getDescription(); | 
| c@5 | 77     } | 
| c@5 | 78 | 
| c@5 | 79     template <typename T, typename M> | 
| c@5 | 80     static void buildValueExtents(M &m, const T &t) { | 
| c@5 | 81         m.setMinValue(t.minValue); | 
| c@5 | 82         m.setMaxValue(t.maxValue); | 
| c@5 | 83     } | 
| c@5 | 84 | 
| c@5 | 85     template <typename T, typename M> | 
| c@5 | 86     static void readValueExtents(T &t, const M &m) { | 
| c@5 | 87         t.minValue = m.getMinValue(); | 
| c@5 | 88         t.maxValue = m.getMaxValue(); | 
| c@5 | 89     } | 
| c@5 | 90 | 
| c@5 | 91     static void buildRealTime(RealTime::Builder &b, const Vamp::RealTime &t) { | 
| c@5 | 92         b.setSec(t.sec); | 
| c@5 | 93         b.setNsec(t.nsec); | 
| c@5 | 94     } | 
| c@5 | 95 | 
| c@5 | 96     static void readRealTime(Vamp::RealTime &t, const RealTime::Reader &r) { | 
| c@5 | 97         t.sec = r.getSec(); | 
| c@5 | 98         t.nsec = r.getNsec(); | 
| c@5 | 99     } | 
| c@5 | 100 | 
| c@5 | 101     static SampleType | 
| c@5 | 102     fromSampleType(Vamp::Plugin::OutputDescriptor::SampleType t) { | 
| c@5 | 103         switch (t) { | 
| c@5 | 104         case Vamp::Plugin::OutputDescriptor::OneSamplePerStep: | 
| c@5 | 105             return SampleType::ONE_SAMPLE_PER_STEP; | 
| c@5 | 106         case Vamp::Plugin::OutputDescriptor::FixedSampleRate: | 
| c@5 | 107             return SampleType::FIXED_SAMPLE_RATE; | 
| c@5 | 108         case Vamp::Plugin::OutputDescriptor::VariableSampleRate: | 
| c@5 | 109             return SampleType::VARIABLE_SAMPLE_RATE; | 
| c@5 | 110         } | 
| c@5 | 111         throw std::logic_error("unexpected Vamp SampleType enum value"); | 
| c@5 | 112     } | 
| c@5 | 113 | 
| c@5 | 114     static Vamp::Plugin::OutputDescriptor::SampleType | 
| c@5 | 115     toSampleType(SampleType t) { | 
| c@5 | 116         switch (t) { | 
| c@5 | 117         case SampleType::ONE_SAMPLE_PER_STEP: | 
| c@5 | 118             return Vamp::Plugin::OutputDescriptor::OneSamplePerStep; | 
| c@5 | 119         case SampleType::FIXED_SAMPLE_RATE: | 
| c@5 | 120             return Vamp::Plugin::OutputDescriptor::FixedSampleRate; | 
| c@5 | 121         case SampleType::VARIABLE_SAMPLE_RATE: | 
| c@5 | 122             return Vamp::Plugin::OutputDescriptor::VariableSampleRate; | 
| c@5 | 123         } | 
| c@5 | 124         throw std::logic_error("unexpected Capnp SampleType enum value"); | 
| c@5 | 125     } | 
| c@5 | 126 | 
| c@5 | 127     static void | 
| c@5 | 128     buildOutputDescriptor(OutputDescriptor::Builder &b, | 
| c@5 | 129                           const Vamp::Plugin::OutputDescriptor &od) { | 
| c@5 | 130 | 
| c@5 | 131         auto basic = b.initBasic(); | 
| c@5 | 132         buildBasicDescriptor(basic, od); | 
| c@5 | 133 | 
| c@5 | 134         b.setUnit(od.unit); | 
| c@5 | 135 | 
| c@5 | 136         b.setSampleType(fromSampleType(od.sampleType)); | 
| c@5 | 137         b.setSampleRate(od.sampleRate); | 
| c@5 | 138         b.setHasDuration(od.hasDuration); | 
| c@5 | 139 | 
| c@5 | 140         b.setHasFixedBinCount(od.hasFixedBinCount); | 
| c@5 | 141         if (od.hasFixedBinCount) { | 
| c@5 | 142             b.setBinCount(od.binCount); | 
| c@5 | 143             if (od.binNames.size() > 0) { | 
| c@5 | 144                 auto binNames = b.initBinNames(od.binNames.size()); | 
| c@5 | 145                 for (size_t i = 0; i < od.binNames.size(); ++i) { | 
| c@5 | 146                     binNames.set(i, od.binNames[i]); | 
| c@5 | 147                 } | 
| c@5 | 148             } | 
| c@5 | 149         } | 
| c@5 | 150 | 
| c@5 | 151         b.setHasKnownExtents(od.hasKnownExtents); | 
| c@5 | 152         if (od.hasKnownExtents) { | 
| c@5 | 153             buildValueExtents(b, od); | 
| c@5 | 154         } | 
| c@5 | 155 | 
| c@5 | 156         b.setIsQuantized(od.isQuantized); | 
| c@5 | 157         if (od.isQuantized) { | 
| c@5 | 158             b.setQuantizeStep(od.quantizeStep); | 
| c@5 | 159         } | 
| c@5 | 160     } | 
| c@5 | 161 | 
| c@5 | 162     static void | 
| c@5 | 163     readOutputDescriptor(Vamp::Plugin::OutputDescriptor &od, | 
| c@5 | 164                          const OutputDescriptor::Reader &r) { | 
| c@5 | 165 | 
| c@5 | 166         readBasicDescriptor(od, r.getBasic()); | 
| c@5 | 167 | 
| c@5 | 168         od.unit = r.getUnit(); | 
| c@5 | 169 | 
| c@5 | 170         od.sampleType = toSampleType(r.getSampleType()); | 
| c@5 | 171         od.sampleRate = r.getSampleRate(); | 
| c@5 | 172         od.hasDuration = r.getHasDuration(); | 
| c@5 | 173 | 
| c@5 | 174         od.hasFixedBinCount = r.getHasFixedBinCount(); | 
| c@5 | 175         if (od.hasFixedBinCount) { | 
| c@5 | 176             od.binCount = r.getBinCount(); | 
| c@13 | 177             od.binNames.clear(); | 
| c@5 | 178             for (const auto &n: r.getBinNames()) { | 
| c@5 | 179                 od.binNames.push_back(n); | 
| c@5 | 180             } | 
| c@5 | 181         } | 
| c@5 | 182 | 
| c@5 | 183         od.hasKnownExtents = r.getHasKnownExtents(); | 
| c@5 | 184         if (od.hasKnownExtents) { | 
| c@5 | 185             readValueExtents(od, r); | 
| c@5 | 186         } | 
| c@5 | 187 | 
| c@5 | 188         od.isQuantized = r.getIsQuantized(); | 
| c@5 | 189         if (od.isQuantized) { | 
| c@5 | 190             od.quantizeStep = r.getQuantizeStep(); | 
| c@5 | 191         } | 
| c@5 | 192     } | 
| c@5 | 193 | 
| c@5 | 194     static void | 
| c@5 | 195     buildParameterDescriptor(ParameterDescriptor::Builder &b, | 
| c@5 | 196                              const Vamp::Plugin::ParameterDescriptor &pd) { | 
| c@5 | 197 | 
| c@5 | 198         auto basic = b.initBasic(); | 
| c@5 | 199         buildBasicDescriptor(basic, pd); | 
| c@5 | 200 | 
| c@5 | 201         b.setUnit(pd.unit); | 
| c@5 | 202 | 
| c@5 | 203         buildValueExtents(b, pd); | 
| c@5 | 204 | 
| c@5 | 205         b.setDefaultValue(pd.defaultValue); | 
| c@5 | 206 | 
| c@5 | 207         b.setIsQuantized(pd.isQuantized); | 
| c@5 | 208         if (pd.isQuantized) { | 
| c@5 | 209             b.setQuantizeStep(pd.quantizeStep); | 
| c@5 | 210         } | 
| c@5 | 211 | 
| c@5 | 212         if (pd.valueNames.size() > 0) { | 
| c@5 | 213             auto valueNames = b.initValueNames(pd.valueNames.size()); | 
| c@5 | 214             for (size_t i = 0; i < pd.valueNames.size(); ++i) { | 
| c@5 | 215                 valueNames.set(i, pd.valueNames[i]); | 
| c@5 | 216             } | 
| c@5 | 217         } | 
| c@5 | 218     } | 
| c@5 | 219 | 
| c@5 | 220     static void | 
| c@5 | 221     readParameterDescriptor(Vamp::Plugin::ParameterDescriptor &pd, | 
| c@5 | 222                             const ParameterDescriptor::Reader &r) { | 
| c@5 | 223 | 
| c@5 | 224         readBasicDescriptor(pd, r.getBasic()); | 
| c@5 | 225 | 
| c@5 | 226         pd.unit = r.getUnit(); | 
| c@5 | 227 | 
| c@5 | 228         readValueExtents(pd, r); | 
| c@5 | 229 | 
| c@5 | 230         pd.defaultValue = r.getDefaultValue(); | 
| c@5 | 231 | 
| c@5 | 232         pd.isQuantized = r.getIsQuantized(); | 
| c@5 | 233         if (pd.isQuantized) { | 
| c@5 | 234             pd.quantizeStep = r.getQuantizeStep(); | 
| c@5 | 235         } | 
| c@5 | 236 | 
| c@13 | 237         pd.valueNames.clear(); | 
| c@5 | 238         for (const auto &n: r.getValueNames()) { | 
| c@5 | 239             pd.valueNames.push_back(n); | 
| c@5 | 240         } | 
| c@5 | 241     } | 
| c@5 | 242 | 
| c@5 | 243     static void | 
| c@5 | 244     buildFeature(Feature::Builder &b, | 
| c@5 | 245                  const Vamp::Plugin::Feature &f) { | 
| c@5 | 246 | 
| c@5 | 247         b.setHasTimestamp(f.hasTimestamp); | 
| c@5 | 248         if (f.hasTimestamp) { | 
| c@5 | 249             auto timestamp = b.initTimestamp(); | 
| c@5 | 250             buildRealTime(timestamp, f.timestamp); | 
| c@5 | 251         } | 
| c@5 | 252 | 
| c@5 | 253         b.setHasDuration(f.hasDuration); | 
| c@5 | 254         if (f.hasDuration) { | 
| c@5 | 255             auto duration = b.initDuration(); | 
| c@5 | 256             buildRealTime(duration, f.duration); | 
| c@5 | 257         } | 
| c@5 | 258 | 
| c@5 | 259         b.setLabel(f.label); | 
| c@5 | 260 | 
| c@5 | 261         if (f.values.size() > 0) { | 
| c@5 | 262             auto values = b.initValues(f.values.size()); | 
| c@5 | 263             for (size_t i = 0; i < f.values.size(); ++i) { | 
| c@5 | 264                 values.set(i, f.values[i]); | 
| c@5 | 265             } | 
| c@5 | 266         } | 
| c@5 | 267     } | 
| c@5 | 268 | 
| c@5 | 269     static void | 
| c@5 | 270     readFeature(Vamp::Plugin::Feature &f, | 
| c@5 | 271                 const Feature::Reader &r) { | 
| c@5 | 272 | 
| c@5 | 273         f.hasTimestamp = r.getHasTimestamp(); | 
| c@5 | 274         if (f.hasTimestamp) { | 
| c@5 | 275             readRealTime(f.timestamp, r.getTimestamp()); | 
| c@5 | 276         } | 
| c@5 | 277 | 
| c@5 | 278         f.hasDuration = r.getHasDuration(); | 
| c@5 | 279         if (f.hasDuration) { | 
| c@5 | 280             readRealTime(f.duration, r.getDuration()); | 
| c@5 | 281         } | 
| c@5 | 282 | 
| c@5 | 283         f.label = r.getLabel(); | 
| c@5 | 284 | 
| c@13 | 285         f.values.clear(); | 
| c@5 | 286         for (auto v: r.getValues()) { | 
| c@5 | 287             f.values.push_back(v); | 
| c@5 | 288         } | 
| c@5 | 289     } | 
| c@5 | 290 | 
| c@5 | 291     static void | 
| c@5 | 292     buildFeatureSet(FeatureSet::Builder &b, | 
| c@5 | 293                     const Vamp::Plugin::FeatureSet &fs) { | 
| c@5 | 294 | 
| c@5 | 295         auto featureset = b.initFeaturePairs(fs.size()); | 
| c@5 | 296         int ix = 0; | 
| c@5 | 297         for (const auto &fsi : fs) { | 
| c@5 | 298             auto fspair = featureset[ix]; | 
| c@5 | 299             fspair.setOutput(fsi.first); | 
| c@5 | 300             auto featurelist = fspair.initFeatures(fsi.second.size()); | 
| c@5 | 301             for (size_t j = 0; j < fsi.second.size(); ++j) { | 
| c@5 | 302                 auto feature = featurelist[j]; | 
| c@5 | 303                 buildFeature(feature, fsi.second[j]); | 
| c@5 | 304             } | 
| c@5 | 305             ++ix; | 
| c@5 | 306         } | 
| c@5 | 307     } | 
| c@5 | 308 | 
| c@5 | 309     static void | 
| c@5 | 310     readFeatureSet(Vamp::Plugin::FeatureSet &fs, | 
| c@5 | 311                    const FeatureSet::Reader &r) { | 
| c@5 | 312 | 
| c@13 | 313         fs.clear(); | 
| c@5 | 314         for (const auto &p: r.getFeaturePairs()) { | 
| c@5 | 315             Vamp::Plugin::FeatureList vfl; | 
| c@5 | 316             for (const auto &f: p.getFeatures()) { | 
| c@5 | 317                 Vamp::Plugin::Feature vf; | 
| c@5 | 318                 readFeature(vf, f); | 
| c@5 | 319                 vfl.push_back(vf); | 
| c@5 | 320             } | 
| c@5 | 321             fs[p.getOutput()] = vfl; | 
| c@5 | 322         } | 
| c@5 | 323     } | 
| c@5 | 324 | 
| c@5 | 325     static InputDomain | 
| c@5 | 326     fromInputDomain(Vamp::Plugin::InputDomain d) { | 
| c@5 | 327         switch(d) { | 
| c@5 | 328         case Vamp::Plugin::TimeDomain: | 
| c@5 | 329             return InputDomain::TIME_DOMAIN; | 
| c@5 | 330         case Vamp::Plugin::FrequencyDomain: | 
| c@5 | 331             return InputDomain::FREQUENCY_DOMAIN; | 
| c@5 | 332         default: | 
| c@5 | 333             throw std::logic_error("unexpected Vamp InputDomain enum value"); | 
| c@5 | 334         } | 
| c@5 | 335     } | 
| c@5 | 336 | 
| c@5 | 337     static Vamp::Plugin::InputDomain | 
| c@5 | 338     toInputDomain(InputDomain d) { | 
| c@5 | 339         switch(d) { | 
| c@5 | 340         case InputDomain::TIME_DOMAIN: | 
| c@5 | 341             return Vamp::Plugin::TimeDomain; | 
| c@5 | 342         case InputDomain::FREQUENCY_DOMAIN: | 
| c@5 | 343             return Vamp::Plugin::FrequencyDomain; | 
| c@5 | 344         default: | 
| c@5 | 345             throw std::logic_error("unexpected Capnp InputDomain enum value"); | 
| c@5 | 346         } | 
| c@5 | 347     } | 
| c@5 | 348 | 
| c@5 | 349     static void | 
| c@5 | 350     buildPluginStaticData(PluginStaticData::Builder &b, | 
| c@5 | 351                           const Vamp::HostExt::PluginStaticData &d) { | 
| c@5 | 352 | 
| c@5 | 353         b.setPluginKey(d.pluginKey); | 
| c@5 | 354 | 
| c@5 | 355         auto basic = b.initBasic(); | 
| c@5 | 356         buildBasicDescriptor(basic, d.basic); | 
| c@5 | 357 | 
| c@5 | 358         b.setMaker(d.maker); | 
| c@5 | 359         b.setCopyright(d.copyright); | 
| c@5 | 360         b.setPluginVersion(d.pluginVersion); | 
| c@5 | 361 | 
| c@5 | 362         auto clist = b.initCategory(d.category.size()); | 
| c@5 | 363         for (size_t i = 0; i < d.category.size(); ++i) { | 
| c@5 | 364             clist.set(i, d.category[i]); | 
| c@5 | 365         } | 
| c@5 | 366 | 
| c@5 | 367         b.setMinChannelCount(d.minChannelCount); | 
| c@5 | 368         b.setMaxChannelCount(d.maxChannelCount); | 
| c@5 | 369 | 
| c@5 | 370         const auto &vparams = d.parameters; | 
| c@5 | 371         auto plist = b.initParameters(vparams.size()); | 
| c@5 | 372         for (size_t i = 0; i < vparams.size(); ++i) { | 
| c@5 | 373             auto pd = plist[i]; | 
| c@5 | 374             buildParameterDescriptor(pd, vparams[i]); | 
| c@5 | 375         } | 
| c@5 | 376 | 
| c@5 | 377         const auto &vprogs = d.programs; | 
| c@5 | 378         auto pglist = b.initPrograms(vprogs.size()); | 
| c@5 | 379         for (size_t i = 0; i < vprogs.size(); ++i) { | 
| c@5 | 380             pglist.set(i, vprogs[i]); | 
| c@5 | 381         } | 
| c@5 | 382 | 
| c@5 | 383         b.setInputDomain(fromInputDomain(d.inputDomain)); | 
| c@5 | 384 | 
| c@5 | 385         const auto &vouts = d.basicOutputInfo; | 
| c@5 | 386         auto olist = b.initBasicOutputInfo(vouts.size()); | 
| c@5 | 387         for (size_t i = 0; i < vouts.size(); ++i) { | 
| c@5 | 388             auto od = olist[i]; | 
| c@5 | 389             buildBasicDescriptor(od, vouts[i]); | 
| c@5 | 390         } | 
| c@5 | 391     } | 
| c@5 | 392 | 
| c@5 | 393     static void | 
| c@5 | 394     readPluginStaticData(Vamp::HostExt::PluginStaticData &d, | 
| c@5 | 395                          const PluginStaticData::Reader &r) { | 
| c@5 | 396 | 
| c@5 | 397         d.pluginKey = r.getPluginKey(); | 
| c@5 | 398 | 
| c@5 | 399         readBasicDescriptor(d.basic, r.getBasic()); | 
| c@5 | 400 | 
| c@5 | 401         d.maker = r.getMaker(); | 
| c@5 | 402         d.copyright = r.getCopyright(); | 
| c@5 | 403         d.pluginVersion = r.getPluginVersion(); | 
| c@5 | 404 | 
| c@13 | 405         d.category.clear(); | 
| c@5 | 406         for (auto c: r.getCategory()) { | 
| c@5 | 407             d.category.push_back(c); | 
| c@5 | 408         } | 
| c@5 | 409 | 
| c@5 | 410         d.minChannelCount = r.getMinChannelCount(); | 
| c@5 | 411         d.maxChannelCount = r.getMaxChannelCount(); | 
| c@5 | 412 | 
| c@13 | 413         d.parameters.clear(); | 
| c@5 | 414         for (auto p: r.getParameters()) { | 
| c@5 | 415             Vamp::Plugin::ParameterDescriptor pd; | 
| c@5 | 416             readParameterDescriptor(pd, p); | 
| c@5 | 417             d.parameters.push_back(pd); | 
| c@5 | 418         } | 
| c@5 | 419 | 
| c@13 | 420         d.programs.clear(); | 
| c@5 | 421         for (auto p: r.getPrograms()) { | 
| c@5 | 422             d.programs.push_back(p); | 
| c@5 | 423         } | 
| c@5 | 424 | 
| c@5 | 425         d.inputDomain = toInputDomain(r.getInputDomain()); | 
| c@5 | 426 | 
| c@13 | 427         d.basicOutputInfo.clear(); | 
| c@5 | 428         for (auto o: r.getBasicOutputInfo()) { | 
| c@5 | 429             Vamp::HostExt::PluginStaticData::Basic b; | 
| c@5 | 430             readBasicDescriptor(b, o); | 
| c@5 | 431             d.basicOutputInfo.push_back(b); | 
| c@5 | 432         } | 
| c@5 | 433     } | 
| c@5 | 434 | 
| c@5 | 435     static void | 
| c@5 | 436     buildPluginConfiguration(PluginConfiguration::Builder &b, | 
| c@5 | 437                              const Vamp::HostExt::PluginConfiguration &c) { | 
| c@5 | 438 | 
| c@5 | 439         const auto &vparams = c.parameterValues; | 
| c@5 | 440         auto params = b.initParameterValues(vparams.size()); | 
| c@5 | 441         int i = 0; | 
| c@5 | 442         for (const auto &pp : vparams) { | 
| c@5 | 443             auto param = params[i++]; | 
| c@5 | 444             param.setParameter(pp.first); | 
| c@5 | 445             param.setValue(pp.second); | 
| c@5 | 446         } | 
| c@5 | 447 | 
| c@5 | 448         b.setCurrentProgram(c.currentProgram); | 
| c@5 | 449         b.setChannelCount(c.channelCount); | 
| c@5 | 450         b.setStepSize(c.stepSize); | 
| c@5 | 451         b.setBlockSize(c.blockSize); | 
| c@5 | 452     } | 
| c@5 | 453 | 
| c@5 | 454     static void | 
| c@5 | 455     readPluginConfiguration(Vamp::HostExt::PluginConfiguration &c, | 
| c@5 | 456                             const PluginConfiguration::Reader &r) { | 
| c@5 | 457 | 
| c@5 | 458         for (const auto &pp: r.getParameterValues()) { | 
| c@5 | 459             c.parameterValues[pp.getParameter()] = pp.getValue(); | 
| c@5 | 460         } | 
| c@5 | 461 | 
| c@5 | 462         c.currentProgram = r.getCurrentProgram(); | 
| c@5 | 463         c.channelCount = r.getChannelCount(); | 
| c@5 | 464         c.stepSize = r.getStepSize(); | 
| c@5 | 465         c.blockSize = r.getBlockSize(); | 
| c@5 | 466     } | 
| c@5 | 467 | 
| c@5 | 468     static void | 
| c@5 | 469     buildLoadRequest(LoadRequest::Builder &r, | 
| c@5 | 470                      const Vamp::HostExt::LoadRequest &req) { | 
| c@5 | 471 | 
| c@5 | 472         r.setPluginKey(req.pluginKey); | 
| c@5 | 473         r.setInputSampleRate(req.inputSampleRate); | 
| c@5 | 474 | 
| c@5 | 475         std::vector<AdapterFlag> flags; | 
| c@5 | 476         if (req.adapterFlags & Vamp::HostExt::PluginLoader::ADAPT_INPUT_DOMAIN) { | 
| c@5 | 477             flags.push_back(AdapterFlag::ADAPT_INPUT_DOMAIN); | 
| c@5 | 478         } | 
| c@5 | 479         if (req.adapterFlags & Vamp::HostExt::PluginLoader::ADAPT_CHANNEL_COUNT) { | 
| c@5 | 480             flags.push_back(AdapterFlag::ADAPT_CHANNEL_COUNT); | 
| c@5 | 481         } | 
| c@5 | 482         if (req.adapterFlags & Vamp::HostExt::PluginLoader::ADAPT_BUFFER_SIZE) { | 
| c@5 | 483             flags.push_back(AdapterFlag::ADAPT_BUFFER_SIZE); | 
| c@5 | 484         } | 
| c@5 | 485 | 
| c@5 | 486         auto f = r.initAdapterFlags(flags.size()); | 
| c@5 | 487         for (size_t i = 0; i < flags.size(); ++i) { | 
| c@5 | 488             f.set(i, flags[i]); | 
| c@5 | 489         } | 
| c@5 | 490     } | 
| c@5 | 491 | 
| c@5 | 492     static void | 
| c@5 | 493     readLoadRequest(Vamp::HostExt::LoadRequest &req, | 
| c@5 | 494                     const LoadRequest::Reader &r) { | 
| c@5 | 495 | 
| c@5 | 496         req.pluginKey = r.getPluginKey(); | 
| c@5 | 497         req.inputSampleRate = r.getInputSampleRate(); | 
| c@5 | 498 | 
| c@5 | 499         int flags = 0; | 
| c@5 | 500         for (const auto &a: r.getAdapterFlags()) { | 
| c@5 | 501             if (a == AdapterFlag::ADAPT_INPUT_DOMAIN) { | 
| c@5 | 502                 flags |= Vamp::HostExt::PluginLoader::ADAPT_INPUT_DOMAIN; | 
| c@5 | 503             } | 
| c@5 | 504             if (a == AdapterFlag::ADAPT_CHANNEL_COUNT) { | 
| c@5 | 505                 flags |= Vamp::HostExt::PluginLoader::ADAPT_CHANNEL_COUNT; | 
| c@5 | 506             } | 
| c@5 | 507             if (a == AdapterFlag::ADAPT_BUFFER_SIZE) { | 
| c@5 | 508                 flags |= Vamp::HostExt::PluginLoader::ADAPT_BUFFER_SIZE; | 
| c@5 | 509             } | 
| c@5 | 510         } | 
| c@5 | 511         req.adapterFlags = flags; | 
| c@5 | 512     } | 
| c@10 | 513 | 
| c@10 | 514     static void | 
| c@10 | 515     buildLoadResponse(LoadResponse::Builder &b, | 
| c@10 | 516                       const Vamp::HostExt::LoadResponse &resp, | 
| c@10 | 517                       PluginHandleMapper &mapper) { | 
| c@10 | 518 | 
| c@10 | 519         b.setPluginHandle(mapper.pluginToHandle(resp.plugin)); | 
| c@10 | 520         auto sd = b.initStaticData(); | 
| c@10 | 521         buildPluginStaticData(sd, resp.staticData); | 
| c@10 | 522         auto conf = b.initDefaultConfiguration(); | 
| c@10 | 523         buildPluginConfiguration(conf, resp.defaultConfiguration); | 
| c@10 | 524     } | 
| c@10 | 525 | 
| c@10 | 526     static void | 
| c@10 | 527     readLoadResponse(Vamp::HostExt::LoadResponse &resp, | 
| c@10 | 528                      const LoadResponse::Reader &r, | 
| c@10 | 529                      PluginHandleMapper &mapper) { | 
| c@10 | 530 | 
| c@10 | 531         resp.plugin = mapper.handleToPlugin(r.getPluginHandle()); | 
| c@10 | 532         readPluginStaticData(resp.staticData, r.getStaticData()); | 
| c@10 | 533         readPluginConfiguration(resp.defaultConfiguration, | 
| c@10 | 534                                 r.getDefaultConfiguration()); | 
| c@10 | 535     } | 
| c@13 | 536 | 
| c@13 | 537     static void | 
| c@13 | 538     buildConfigurationRequest(ConfigurationRequest::Builder &b, | 
| c@13 | 539                               const Vamp::HostExt::ConfigurationRequest &cr, | 
| c@13 | 540                               PluginHandleMapper &mapper) { | 
| c@13 | 541 | 
| c@13 | 542         b.setPluginHandle(mapper.pluginToHandle(cr.plugin)); | 
| c@13 | 543         auto c = b.initConfiguration(); | 
| c@13 | 544         buildPluginConfiguration(c, cr.configuration); | 
| c@13 | 545     } | 
| c@13 | 546 | 
| c@13 | 547     static void | 
| c@13 | 548     readConfigurationRequest(Vamp::HostExt::ConfigurationRequest &cr, | 
| c@13 | 549                              const ConfigurationRequest::Reader &r, | 
| c@13 | 550                              PluginHandleMapper &mapper) { | 
| c@13 | 551 | 
| c@13 | 552         auto h = r.getPluginHandle(); | 
| c@13 | 553         cr.plugin = mapper.handleToPlugin(h); | 
| c@13 | 554         auto c = r.getConfiguration(); | 
| c@13 | 555         readPluginConfiguration(cr.configuration, c); | 
| c@13 | 556     } | 
| c@13 | 557 | 
| c@13 | 558     static void | 
| c@13 | 559     buildConfigurationResponse(ConfigurationResponse::Builder &b, | 
| c@13 | 560                                const Vamp::HostExt::ConfigurationResponse &cr) { | 
| c@13 | 561 | 
| c@13 | 562         auto olist = b.initOutputs(cr.outputs.size()); | 
| c@13 | 563         for (size_t i = 0; i < cr.outputs.size(); ++i) { | 
| c@13 | 564             auto od = olist[i]; | 
| c@13 | 565             buildOutputDescriptor(od, cr.outputs[i]); | 
| c@13 | 566         } | 
| c@13 | 567     } | 
| c@13 | 568 | 
| c@13 | 569     static void | 
| c@13 | 570     readConfigurationResponse(Vamp::HostExt::ConfigurationResponse &cr, | 
| c@13 | 571                               const ConfigurationResponse::Reader &r) { | 
| c@13 | 572 | 
| c@13 | 573         cr.outputs.clear(); | 
| c@13 | 574         for (const auto &o: r.getOutputs()) { | 
| c@13 | 575             Vamp::Plugin::OutputDescriptor desc; | 
| c@13 | 576             readOutputDescriptor(desc, o); | 
| c@13 | 577             cr.outputs.push_back(desc); | 
| c@13 | 578         } | 
| c@13 | 579     } | 
| c@14 | 580 | 
| c@14 | 581     static void | 
| c@14 | 582     buildProcessInput(ProcessInput::Builder &b, | 
| c@14 | 583                       Vamp::RealTime timestamp, | 
| c@14 | 584                       const std::vector<std::vector<float> > &buffers) { | 
| c@14 | 585 | 
| c@14 | 586         auto t = b.initTimestamp(); | 
| c@14 | 587         buildRealTime(t, timestamp); | 
| c@14 | 588         auto vv = b.initInputBuffers(buffers.size()); | 
| c@14 | 589         for (size_t ch = 0; ch < buffers.size(); ++ch) { | 
| c@14 | 590             const int n = int(buffers[ch].size()); | 
| c@14 | 591             vv.init(ch, n); | 
| c@14 | 592             auto v = vv[ch]; | 
| c@14 | 593             for (int i = 0; i < n; ++i) { | 
| c@14 | 594                 v.set(i, buffers[ch][i]); | 
| c@14 | 595             } | 
| c@14 | 596         } | 
| c@14 | 597     } | 
| c@14 | 598 | 
| c@14 | 599     static void | 
| c@14 | 600     readProcessInput(Vamp::RealTime ×tamp, | 
| c@14 | 601                      std::vector<std::vector<float> > &buffers, | 
| c@14 | 602                      const ProcessInput::Reader &b) { | 
| c@14 | 603 | 
| c@14 | 604         readRealTime(timestamp, b.getTimestamp()); | 
| c@14 | 605         buffers.clear(); | 
| c@14 | 606         for (const auto &v: b.getInputBuffers()) { | 
| c@14 | 607             std::vector<float> buf; | 
| c@14 | 608             for (auto x: v) { | 
| c@14 | 609                 buf.push_back(x); | 
| c@14 | 610             } | 
| c@14 | 611             buffers.push_back(buf); | 
| c@14 | 612         } | 
| c@14 | 613     } | 
| c@14 | 614 | 
| c@14 | 615     static void | 
| c@14 | 616     buildProcessRequest(ProcessRequest::Builder &b, | 
| c@14 | 617                         const Vamp::HostExt::ProcessRequest &pr, | 
| c@14 | 618                         PluginHandleMapper &mapper) { | 
| c@14 | 619 | 
| c@14 | 620         b.setPluginHandle(mapper.pluginToHandle(pr.plugin)); | 
| c@14 | 621         auto input = b.initInput(); | 
| c@14 | 622         buildProcessInput(input, pr.timestamp, pr.inputBuffers); | 
| c@14 | 623     } | 
| c@14 | 624 | 
| c@14 | 625     static void | 
| c@14 | 626     readProcessRequest(Vamp::HostExt::ProcessRequest &pr, | 
| c@14 | 627                        const ProcessRequest::Reader &r, | 
| c@14 | 628                        PluginHandleMapper &mapper) { | 
| c@14 | 629 | 
| c@14 | 630         auto h = r.getPluginHandle(); | 
| c@14 | 631         pr.plugin = mapper.handleToPlugin(h); | 
| c@14 | 632         readProcessInput(pr.timestamp, pr.inputBuffers, r.getInput()); | 
| c@14 | 633     } | 
| c@14 | 634 | 
| c@14 | 635     static void | 
| c@15 | 636     buildProcessResponse(ProcessResponse::Builder &b, | 
| c@15 | 637                          const Vamp::HostExt::ProcessResponse &pr) { | 
| c@15 | 638 | 
| c@15 | 639         auto f = b.initFeatures(); | 
| c@15 | 640         buildFeatureSet(f, pr.features); | 
| c@15 | 641     } | 
| c@15 | 642 | 
| c@15 | 643     static void | 
| c@15 | 644     readProcessResponse(Vamp::HostExt::ProcessResponse &pr, | 
| c@15 | 645                         const ProcessResponse::Reader &r) { | 
| c@15 | 646 | 
| c@15 | 647         readFeatureSet(pr.features, r.getFeatures()); | 
| c@15 | 648     } | 
| c@15 | 649 | 
| c@15 | 650     static void | 
| c@15 | 651     buildVampRequest_List(VampRequest::Builder &b) { | 
| c@14 | 652         b.getRequest().setList(); | 
| c@14 | 653     } | 
| c@14 | 654 | 
| c@14 | 655     static void | 
| c@15 | 656     buildVampResponse_List(VampResponse::Builder &b, | 
| c@17 | 657                            std::string errorText, | 
| c@17 | 658                            const std::vector<Vamp::HostExt::PluginStaticData> &d) { | 
| c@15 | 659         b.setSuccess(errorText == ""); | 
| c@15 | 660         b.setErrorText(errorText); | 
| c@24 | 661         auto r = b.getResponse().initList(); | 
| c@24 | 662         auto p = r.initPlugins(d.size()); | 
| c@15 | 663         for (size_t i = 0; i < d.size(); ++i) { | 
| c@24 | 664             auto pd = p[i]; | 
| c@24 | 665             buildPluginStaticData(pd, d[i]); | 
| c@15 | 666         } | 
| c@15 | 667     } | 
| c@15 | 668 | 
| c@15 | 669     static void | 
| c@15 | 670     buildVampRequest_Load(VampRequest::Builder &b, | 
| c@15 | 671                           const Vamp::HostExt::LoadRequest &req) { | 
| c@14 | 672         auto u = b.getRequest().initLoad(); | 
| c@14 | 673         buildLoadRequest(u, req); | 
| c@14 | 674     } | 
| c@14 | 675 | 
| c@14 | 676     static void | 
| c@15 | 677     buildVampResponse_Load(VampResponse::Builder &b, | 
| c@15 | 678                            const Vamp::HostExt::LoadResponse &resp, | 
| c@15 | 679                            PluginHandleMapper &mapper) { | 
| c@17 | 680         b.setSuccess(resp.plugin != 0); | 
| c@17 | 681         b.setErrorText(""); | 
| c@15 | 682         auto u = b.getResponse().initLoad(); | 
| c@15 | 683         buildLoadResponse(u, resp, mapper); | 
| c@15 | 684     } | 
| c@15 | 685 | 
| c@15 | 686     static void | 
| c@15 | 687     buildVampRequest_Configure(VampRequest::Builder &b, | 
| c@15 | 688                                const Vamp::HostExt::ConfigurationRequest &cr, | 
| c@15 | 689                                PluginHandleMapper &mapper) { | 
| c@14 | 690         auto u = b.getRequest().initConfigure(); | 
| c@14 | 691         buildConfigurationRequest(u, cr, mapper); | 
| c@14 | 692     } | 
| c@14 | 693 | 
| c@14 | 694     static void | 
| c@15 | 695     buildVampResponse_Configure(VampResponse::Builder &b, | 
| c@15 | 696                                 const Vamp::HostExt::ConfigurationResponse &cr) { | 
| c@17 | 697         b.setSuccess(!cr.outputs.empty()); | 
| c@17 | 698         b.setErrorText(""); | 
| c@15 | 699         auto u = b.getResponse().initConfigure(); | 
| c@15 | 700         buildConfigurationResponse(u, cr); | 
| c@15 | 701     } | 
| c@15 | 702 | 
| c@15 | 703     static void | 
| c@15 | 704     buildVampRequest_Process(VampRequest::Builder &b, | 
| c@15 | 705                              const Vamp::HostExt::ProcessRequest &pr, | 
| c@15 | 706                              PluginHandleMapper &mapper) { | 
| c@14 | 707         auto u = b.getRequest().initProcess(); | 
| c@14 | 708         buildProcessRequest(u, pr, mapper); | 
| c@14 | 709     } | 
| c@15 | 710 | 
| c@15 | 711     static void | 
| c@15 | 712     buildVampResponse_Process(VampResponse::Builder &b, | 
| c@23 | 713                               const Vamp::HostExt::ProcessResponse &pr) { | 
| c@17 | 714         b.setSuccess(true); | 
| c@17 | 715         b.setErrorText(""); | 
| c@15 | 716         auto u = b.getResponse().initProcess(); | 
| c@15 | 717         buildProcessResponse(u, pr); | 
| c@15 | 718     } | 
| c@17 | 719 | 
| c@17 | 720     static void | 
| c@23 | 721     buildVampRequest_Finish(VampRequest::Builder &b, | 
| c@23 | 722                             Vamp::Plugin *p, | 
| c@23 | 723                             PluginHandleMapper &mapper) { | 
| c@17 | 724 | 
| c@23 | 725         auto u = b.getRequest().initFinish(); | 
| c@23 | 726         u.setPluginHandle(mapper.pluginToHandle(p)); | 
| c@17 | 727     } | 
| c@17 | 728 | 
| c@17 | 729     static void | 
| c@17 | 730     buildVampResponse_Finish(VampResponse::Builder &b, | 
| c@17 | 731                              const Vamp::HostExt::ProcessResponse &pr) { | 
| c@17 | 732 | 
| c@17 | 733         buildVampResponse_Process(b, pr); | 
| c@17 | 734     } | 
| c@5 | 735 }; | 
| c@5 | 736 | 
| c@5 | 737 } | 
| c@5 | 738 | 
| c@5 | 739 |