Mercurial > hg > piper-cpp
comparison json/VampJson.h @ 5:6e8607ebad03
Promote the more successful experiments (todo: get them to build again)
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Fri, 13 May 2016 13:48:59 +0100 |
parents | |
children | d8358afe3f2c |
comparison
equal
deleted
inserted
replaced
4:25499f505d0e | 5:6e8607ebad03 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 #ifndef VAMP_JSON_H | |
4 #define VAMP_JSON_H | |
5 | |
6 #include <vector> | |
7 #include <string> | |
8 #include <sstream> | |
9 #include <stdexcept> | |
10 | |
11 #include <json11/json11.hpp> | |
12 #include <base-n/include/basen.hpp> | |
13 | |
14 #include <vamp-hostsdk/Plugin.h> | |
15 #include <vamp-hostsdk/PluginLoader.h> | |
16 | |
17 class VampJson | |
18 { | |
19 public: | |
20 class Failure : virtual public std::runtime_error { | |
21 public: | |
22 Failure(std::string s) : runtime_error(s) { } | |
23 }; | |
24 | |
25 template <typename T> | |
26 static json11::Json | |
27 fromBasicDescriptor(const T &t) { | |
28 return json11::Json::object { | |
29 { "identifier", t.identifier }, | |
30 { "name", t.name }, | |
31 { "description", t.description } | |
32 }; | |
33 } | |
34 | |
35 template <typename T> | |
36 static void | |
37 toBasicDescriptor(json11::Json j, T &t) { | |
38 if (!j.is_object()) { | |
39 throw Failure("object expected for basic descriptor content"); | |
40 } | |
41 if (!j["identifier"].is_string()) { | |
42 throw Failure("string expected for identifier"); | |
43 } | |
44 t.identifier = j["identifier"].string_value(); | |
45 t.name = j["name"].string_value(); | |
46 t.description = j["description"].string_value(); | |
47 } | |
48 | |
49 template <typename T> | |
50 static json11::Json | |
51 fromValueExtents(const T &t) { | |
52 return json11::Json::object { | |
53 { "min", t.minValue }, | |
54 { "max", t.maxValue } | |
55 }; | |
56 } | |
57 | |
58 template <typename T> | |
59 static bool | |
60 toValueExtents(json11::Json j, T &t) { | |
61 if (j["extents"].is_null()) { | |
62 return false; | |
63 } else if (j["extents"].is_object()) { | |
64 if (j["extents"]["min"].is_number() && | |
65 j["extents"]["max"].is_number()) { | |
66 t.minValue = j["extents"]["min"].number_value(); | |
67 t.maxValue = j["extents"]["max"].number_value(); | |
68 return true; | |
69 } else { | |
70 throw Failure("numbers expected for min and max"); | |
71 } | |
72 } else { | |
73 throw Failure("object expected for extents (if present)"); | |
74 } | |
75 } | |
76 | |
77 static json11::Json | |
78 fromRealTime(const Vamp::RealTime &r) { | |
79 return json11::Json::object { | |
80 { "s", r.sec }, | |
81 { "n", r.nsec } | |
82 }; | |
83 } | |
84 | |
85 static Vamp::RealTime | |
86 toRealTime(json11::Json j) { | |
87 json11::Json sec = j["s"]; | |
88 json11::Json nsec = j["n"]; | |
89 if (!sec.is_number() || !nsec.is_number()) { | |
90 throw Failure("invalid Vamp::RealTime object " + j.dump()); | |
91 } | |
92 return Vamp::RealTime(sec.int_value(), nsec.int_value()); | |
93 } | |
94 | |
95 static std::string | |
96 fromSampleType(Vamp::Plugin::OutputDescriptor::SampleType type) { | |
97 switch (type) { | |
98 case Vamp::Plugin::OutputDescriptor::OneSamplePerStep: | |
99 return "OneSamplePerStep"; | |
100 case Vamp::Plugin::OutputDescriptor::FixedSampleRate: | |
101 return "FixedSampleRate"; | |
102 case Vamp::Plugin::OutputDescriptor::VariableSampleRate: | |
103 return "VariableSampleRate"; | |
104 } | |
105 return ""; | |
106 } | |
107 | |
108 static Vamp::Plugin::OutputDescriptor::SampleType | |
109 toSampleType(std::string text) { | |
110 if (text == "OneSamplePerStep") { | |
111 return Vamp::Plugin::OutputDescriptor::OneSamplePerStep; | |
112 } else if (text == "FixedSampleRate") { | |
113 return Vamp::Plugin::OutputDescriptor::FixedSampleRate; | |
114 } else if (text == "VariableSampleRate") { | |
115 return Vamp::Plugin::OutputDescriptor::VariableSampleRate; | |
116 } else { | |
117 throw Failure("invalid sample type string: " + text); | |
118 } | |
119 } | |
120 | |
121 static json11::Json | |
122 fromOutputDescriptor(const Vamp::Plugin::OutputDescriptor &desc) { | |
123 json11::Json::object jo { | |
124 { "basic", fromBasicDescriptor(desc) }, | |
125 { "unit", desc.unit }, | |
126 { "sampleType", fromSampleType(desc.sampleType) }, | |
127 { "sampleRate", desc.sampleRate }, | |
128 { "hasDuration", desc.hasDuration } | |
129 }; | |
130 if (desc.hasFixedBinCount) { | |
131 jo["binCount"] = int(desc.binCount); | |
132 jo["binNames"] = json11::Json::array | |
133 (desc.binNames.begin(), desc.binNames.end()); | |
134 } | |
135 if (desc.hasKnownExtents) { | |
136 jo["extents"] = fromValueExtents(desc); | |
137 } | |
138 if (desc.isQuantized) { | |
139 jo["quantizeStep"] = desc.quantizeStep; | |
140 } | |
141 return json11::Json(jo); | |
142 } | |
143 | |
144 static Vamp::Plugin::OutputDescriptor | |
145 toOutputDescriptor(json11::Json j) { | |
146 | |
147 Vamp::Plugin::OutputDescriptor od; | |
148 if (!j.is_object()) { | |
149 throw Failure("object expected for output descriptor"); | |
150 } | |
151 | |
152 toBasicDescriptor(j["basic"], od); | |
153 | |
154 od.unit = j["unit"].string_value(); | |
155 | |
156 od.sampleType = toSampleType(j["sampleType"].string_value()); | |
157 | |
158 if (!j["sampleRate"].is_number()) { | |
159 throw Failure("number expected for sample rate"); | |
160 } | |
161 od.sampleRate = j["sampleRate"].number_value(); | |
162 od.hasDuration = j["hasDuration"].bool_value(); | |
163 | |
164 if (j["binCount"].is_number() && j["binCount"].int_value() > 0) { | |
165 od.hasFixedBinCount = true; | |
166 od.binCount = j["binCount"].int_value(); | |
167 for (auto &n: j["binNames"].array_items()) { | |
168 if (!n.is_string()) { | |
169 throw Failure("string expected for bin name"); | |
170 } | |
171 od.binNames.push_back(n.string_value()); | |
172 } | |
173 } else { | |
174 od.hasFixedBinCount = false; | |
175 } | |
176 | |
177 bool extentsPresent = toValueExtents(j, od); | |
178 od.hasKnownExtents = extentsPresent; | |
179 | |
180 if (j["quantizeStep"].is_number()) { | |
181 od.isQuantized = true; | |
182 od.quantizeStep = j["quantizeStep"].number_value(); | |
183 } else { | |
184 od.isQuantized = false; | |
185 } | |
186 | |
187 return od; | |
188 } | |
189 | |
190 static json11::Json | |
191 fromParameterDescriptor(const Vamp::PluginBase::ParameterDescriptor &desc) { | |
192 | |
193 json11::Json::object jo { | |
194 { "basic", fromBasicDescriptor(desc) }, | |
195 { "unit", desc.unit }, | |
196 { "extents", fromValueExtents(desc) }, | |
197 { "defaultValue", desc.defaultValue }, | |
198 { "valueNames", json11::Json::array | |
199 (desc.valueNames.begin(), desc.valueNames.end()) } | |
200 }; | |
201 if (desc.isQuantized) { | |
202 jo["quantizeStep"] = desc.quantizeStep; | |
203 } | |
204 return json11::Json(jo); | |
205 } | |
206 | |
207 static Vamp::PluginBase::ParameterDescriptor | |
208 toParameterDescriptor(json11::Json j) { | |
209 | |
210 Vamp::PluginBase::ParameterDescriptor pd; | |
211 if (!j.is_object()) { | |
212 throw Failure("object expected for parameter descriptor"); | |
213 } | |
214 | |
215 toBasicDescriptor(j["basic"], pd); | |
216 | |
217 pd.unit = j["unit"].string_value(); | |
218 | |
219 bool extentsPresent = toValueExtents(j, pd); | |
220 if (!extentsPresent) { | |
221 throw Failure("extents must be present in parameter descriptor"); | |
222 } | |
223 | |
224 if (!j["defaultValue"].is_number()) { | |
225 throw Failure("number expected for default value"); | |
226 } | |
227 | |
228 pd.defaultValue = j["defaultValue"].number_value(); | |
229 | |
230 pd.valueNames.clear(); | |
231 for (auto &n: j["valueNames"].array_items()) { | |
232 if (!n.is_string()) { | |
233 throw Failure("string expected for value name"); | |
234 } | |
235 pd.valueNames.push_back(n.string_value()); | |
236 } | |
237 | |
238 if (j["quantizeStep"].is_number()) { | |
239 pd.isQuantized = true; | |
240 pd.quantizeStep = j["quantizeStep"].number_value(); | |
241 } else { | |
242 pd.isQuantized = false; | |
243 } | |
244 | |
245 return pd; | |
246 } | |
247 | |
248 static std::string | |
249 fromFloatBuffer(const float *buffer, size_t nfloats) { | |
250 // must use char pointers, otherwise the converter will only | |
251 // encode every 4th byte (as it will count up in float* steps) | |
252 const char *start = reinterpret_cast<const char *>(buffer); | |
253 const char *end = reinterpret_cast<const char *>(buffer + nfloats); | |
254 std::string encoded; | |
255 bn::encode_b64(start, end, back_inserter(encoded)); | |
256 return encoded; | |
257 } | |
258 | |
259 static std::vector<float> | |
260 toFloatBuffer(std::string encoded) { | |
261 std::string decoded; | |
262 bn::decode_b64(encoded.begin(), encoded.end(), back_inserter(decoded)); | |
263 const float *buffer = reinterpret_cast<const float *>(decoded.c_str()); | |
264 size_t n = decoded.size() / sizeof(float); | |
265 return std::vector<float>(buffer, buffer + n); | |
266 } | |
267 | |
268 static json11::Json | |
269 fromFeature(const Vamp::Plugin::Feature &f) { | |
270 | |
271 json11::Json::object jo; | |
272 if (f.values.size() > 0) { | |
273 jo["b64values"] = fromFloatBuffer(f.values.data(), f.values.size()); | |
274 } | |
275 if (f.label != "") { | |
276 jo["label"] = f.label; | |
277 } | |
278 if (f.hasTimestamp) { | |
279 jo["timestamp"] = fromRealTime(f.timestamp); | |
280 } | |
281 if (f.hasDuration) { | |
282 jo["duration"] = fromRealTime(f.duration); | |
283 } | |
284 return json11::Json(jo); | |
285 } | |
286 | |
287 static Vamp::Plugin::Feature | |
288 toFeature(json11::Json j) { | |
289 | |
290 Vamp::Plugin::Feature f; | |
291 if (!j.is_object()) { | |
292 throw Failure("object expected for feature"); | |
293 } | |
294 if (j["timestamp"].is_object()) { | |
295 f.timestamp = toRealTime(j["timestamp"]); | |
296 f.hasTimestamp = true; | |
297 } | |
298 if (j["duration"].is_object()) { | |
299 f.duration = toRealTime(j["duration"]); | |
300 f.hasDuration = true; | |
301 } | |
302 if (j["b64values"].is_string()) { | |
303 f.values = toFloatBuffer(j["b64values"].string_value()); | |
304 } else if (j["values"].is_array()) { | |
305 for (auto v : j["values"].array_items()) { | |
306 f.values.push_back(v.number_value()); | |
307 } | |
308 } | |
309 f.label = j["label"].string_value(); | |
310 return f; | |
311 } | |
312 | |
313 static json11::Json | |
314 fromFeatureSet(const Vamp::Plugin::FeatureSet &fs) { | |
315 | |
316 json11::Json::object jo; | |
317 for (const auto &fsi : fs) { | |
318 std::vector<json11::Json> fj; | |
319 for (const Vamp::Plugin::Feature &f: fsi.second) { | |
320 fj.push_back(fromFeature(f)); | |
321 } | |
322 std::stringstream sstr; | |
323 sstr << fsi.first; | |
324 std::string n = sstr.str(); | |
325 jo[n] = fj; | |
326 } | |
327 return json11::Json(jo); | |
328 } | |
329 | |
330 static Vamp::Plugin::FeatureList | |
331 toFeatureList(json11::Json j) { | |
332 | |
333 Vamp::Plugin::FeatureList fl; | |
334 if (!j.is_array()) { | |
335 throw Failure("array expected for feature list"); | |
336 } | |
337 for (const json11::Json &fj : j.array_items()) { | |
338 fl.push_back(toFeature(fj)); | |
339 } | |
340 return fl; | |
341 } | |
342 | |
343 static Vamp::Plugin::FeatureSet | |
344 toFeatureSet(json11::Json j) { | |
345 | |
346 Vamp::Plugin::FeatureSet fs; | |
347 if (!j.is_object()) { | |
348 throw Failure("object expected for feature set"); | |
349 } | |
350 for (auto &entry : j.object_items()) { | |
351 std::string nstr = entry.first; | |
352 size_t count = 0; | |
353 int n = stoi(nstr, &count); | |
354 if (n < 0 || fs.find(n) != fs.end() || count < nstr.size()) { | |
355 throw Failure("invalid or duplicate numerical index for output"); | |
356 } | |
357 fs[n] = toFeatureList(entry.second); | |
358 } | |
359 return fs; | |
360 } | |
361 | |
362 static std::string | |
363 fromInputDomain(Vamp::Plugin::InputDomain domain) { | |
364 | |
365 switch (domain) { | |
366 case Vamp::Plugin::TimeDomain: | |
367 return "TimeDomain"; | |
368 case Vamp::Plugin::FrequencyDomain: | |
369 return "FrequencyDomain"; | |
370 } | |
371 return ""; | |
372 } | |
373 | |
374 static Vamp::Plugin::InputDomain | |
375 toInputDomain(std::string text) { | |
376 | |
377 if (text == "TimeDomain") { | |
378 return Vamp::Plugin::TimeDomain; | |
379 } else if (text == "FrequencyDomain") { | |
380 return Vamp::Plugin::FrequencyDomain; | |
381 } else { | |
382 throw Failure("invalid input domain string: " + text); | |
383 } | |
384 } | |
385 | |
386 static json11::Json | |
387 fromPluginStaticData(const Vamp::HostExt::PluginStaticData &d) { | |
388 | |
389 json11::Json::object jo; | |
390 jo["pluginKey"] = d.pluginKey; | |
391 jo["basic"] = fromBasicDescriptor(d.basic); | |
392 jo["maker"] = d.maker; | |
393 jo["copyright"] = d.copyright; | |
394 jo["pluginVersion"] = d.pluginVersion; | |
395 | |
396 json11::Json::array cat; | |
397 for (const std::string &c: d.category) cat.push_back(c); | |
398 jo["category"] = cat; | |
399 | |
400 jo["minChannelCount"] = d.minChannelCount; | |
401 jo["maxChannelCount"] = d.maxChannelCount; | |
402 | |
403 json11::Json::array params; | |
404 Vamp::PluginBase::ParameterList vparams = d.parameters; | |
405 for (auto &p: vparams) params.push_back(fromParameterDescriptor(p)); | |
406 jo["parameters"] = params; | |
407 | |
408 json11::Json::array progs; | |
409 Vamp::PluginBase::ProgramList vprogs = d.programs; | |
410 for (auto &p: vprogs) progs.push_back(p); | |
411 jo["programs"] = progs; | |
412 | |
413 jo["inputDomain"] = fromInputDomain(d.inputDomain); | |
414 | |
415 json11::Json::array outinfo; | |
416 auto vouts = d.basicOutputInfo; | |
417 for (auto &o: vouts) outinfo.push_back(fromBasicDescriptor(o)); | |
418 jo["basicOutputInfo"] = outinfo; | |
419 | |
420 return json11::Json(jo); | |
421 } | |
422 | |
423 static Vamp::HostExt::PluginStaticData | |
424 toPluginStaticData(json11::Json j) { | |
425 | |
426 std::string err; | |
427 if (!j.has_shape({ | |
428 { "pluginKey", json11::Json::STRING }, | |
429 { "pluginVersion", json11::Json::NUMBER }, | |
430 { "minChannelCount", json11::Json::NUMBER }, | |
431 { "maxChannelCount", json11::Json::NUMBER }, | |
432 { "inputDomain", json11::Json::STRING }}, err)) { | |
433 throw Failure("malformed plugin static data: " + err); | |
434 } | |
435 | |
436 if (!j["basicOutputInfo"].is_array()) { | |
437 throw Failure("array expected for basic output info"); | |
438 } | |
439 | |
440 if (!j["maker"].is_null() && | |
441 !j["maker"].is_string()) { | |
442 throw Failure("string expected for maker"); | |
443 } | |
444 | |
445 if (!j["copyright"].is_null() && | |
446 !j["copyright"].is_string()) { | |
447 throw Failure("string expected for copyright"); | |
448 } | |
449 | |
450 if (!j["category"].is_null() && | |
451 !j["category"].is_array()) { | |
452 throw Failure("array expected for category"); | |
453 } | |
454 | |
455 if (!j["parameters"].is_null() && | |
456 !j["parameters"].is_array()) { | |
457 throw Failure("array expected for parameters"); | |
458 } | |
459 | |
460 if (!j["programs"].is_null() && | |
461 !j["programs"].is_array()) { | |
462 throw Failure("array expected for programs"); | |
463 } | |
464 | |
465 if (!j["inputDomain"].is_null() && | |
466 !j["inputDomain"].is_string()) { | |
467 throw Failure("string expected for inputDomain"); | |
468 } | |
469 | |
470 if (!j["basicOutputInfo"].is_null() && | |
471 !j["basicOutputInfo"].is_array()) { | |
472 throw Failure("array expected for basicOutputInfo"); | |
473 } | |
474 | |
475 Vamp::HostExt::PluginStaticData psd; | |
476 | |
477 psd.pluginKey = j["pluginKey"].string_value(); | |
478 | |
479 toBasicDescriptor(j["basic"], psd.basic); | |
480 | |
481 psd.maker = j["maker"].string_value(); | |
482 psd.copyright = j["copyright"].string_value(); | |
483 psd.pluginVersion = j["pluginVersion"].int_value(); | |
484 | |
485 for (const auto &c : j["category"].array_items()) { | |
486 if (!c.is_string()) { | |
487 throw Failure("strings expected in category array"); | |
488 } | |
489 psd.category.push_back(c.string_value()); | |
490 } | |
491 | |
492 psd.minChannelCount = j["minChannelCount"].int_value(); | |
493 psd.maxChannelCount = j["maxChannelCount"].int_value(); | |
494 | |
495 for (const auto &p : j["parameters"].array_items()) { | |
496 auto pd = toParameterDescriptor(p); | |
497 psd.parameters.push_back(pd); | |
498 } | |
499 | |
500 for (const auto &p : j["programs"].array_items()) { | |
501 if (!p.is_string()) { | |
502 throw Failure("strings expected in programs array"); | |
503 } | |
504 psd.programs.push_back(p.string_value()); | |
505 } | |
506 | |
507 psd.inputDomain = toInputDomain(j["inputDomain"].string_value()); | |
508 | |
509 for (const auto &bo : j["basicOutputInfo"].array_items()) { | |
510 Vamp::HostExt::PluginStaticData::Basic b; | |
511 toBasicDescriptor(bo, b); | |
512 psd.basicOutputInfo.push_back(b); | |
513 } | |
514 | |
515 return psd; | |
516 } | |
517 | |
518 static json11::Json | |
519 fromPluginConfiguration(const Vamp::HostExt::PluginConfiguration &c) { | |
520 | |
521 json11::Json::object jo; | |
522 | |
523 json11::Json::object paramValues; | |
524 for (auto &vp: c.parameterValues) { | |
525 paramValues[vp.first] = vp.second; | |
526 } | |
527 jo["parameterValues"] = paramValues; | |
528 | |
529 if (c.currentProgram != "") { | |
530 jo["currentProgram"] = c.currentProgram; | |
531 } | |
532 | |
533 jo["channelCount"] = c.channelCount; | |
534 jo["stepSize"] = c.stepSize; | |
535 jo["blockSize"] = c.blockSize; | |
536 | |
537 return json11::Json(jo); | |
538 } | |
539 | |
540 static Vamp::HostExt::PluginConfiguration | |
541 toPluginConfiguration(json11::Json j) { | |
542 | |
543 std::string err; | |
544 if (!j.has_shape({ | |
545 { "channelCount", json11::Json::NUMBER }, | |
546 { "stepSize", json11::Json::NUMBER }, | |
547 { "blockSize", json11::Json::NUMBER } }, err)) { | |
548 throw Failure("malformed plugin configuration: " + err); | |
549 } | |
550 | |
551 if (!j["parameterValues"].is_null() && | |
552 !j["parameterValues"].is_object()) { | |
553 throw Failure("object expected for parameter values"); | |
554 } | |
555 | |
556 for (auto &pv : j["parameterValues"].object_items()) { | |
557 if (!pv.second.is_number()) { | |
558 throw Failure("number expected for parameter value"); | |
559 } | |
560 } | |
561 | |
562 if (!j["currentProgram"].is_null() && | |
563 !j["currentProgram"].is_string()) { | |
564 throw Failure("string expected for program name"); | |
565 } | |
566 | |
567 Vamp::HostExt::PluginConfiguration config; | |
568 | |
569 config.channelCount = j["channelCount"].number_value(); | |
570 config.stepSize = j["stepSize"].number_value(); | |
571 config.blockSize = j["blockSize"].number_value(); | |
572 | |
573 for (auto &pv : j["parameterValues"].object_items()) { | |
574 config.parameterValues[pv.first] = pv.second.number_value(); | |
575 } | |
576 | |
577 if (j["currentProgram"].is_string()) { | |
578 config.currentProgram = j["currentProgram"].string_value(); | |
579 } | |
580 | |
581 return config; | |
582 } | |
583 | |
584 static json11::Json | |
585 fromAdapterFlags(int flags) { | |
586 | |
587 json11::Json::array arr; | |
588 | |
589 if (flags & Vamp::HostExt::PluginLoader::ADAPT_INPUT_DOMAIN) { | |
590 arr.push_back("AdaptInputDomain"); | |
591 } | |
592 if (flags & Vamp::HostExt::PluginLoader::ADAPT_CHANNEL_COUNT) { | |
593 arr.push_back("AdaptChannelCount"); | |
594 } | |
595 if (flags & Vamp::HostExt::PluginLoader::ADAPT_BUFFER_SIZE) { | |
596 arr.push_back("AdaptBufferSize"); | |
597 } | |
598 | |
599 return json11::Json(arr); | |
600 } | |
601 | |
602 static Vamp::HostExt::PluginLoader::AdapterFlags | |
603 toAdapterFlags(json11::Json j) { | |
604 | |
605 if (!j.is_array()) { | |
606 throw Failure("array expected for adapter flags"); | |
607 } | |
608 int flags = 0x0; | |
609 | |
610 for (auto &jj: j.array_items()) { | |
611 if (!jj.is_string()) { | |
612 throw Failure("string expected for adapter flag"); | |
613 } | |
614 std::string text = jj.string_value(); | |
615 if (text == "AdaptInputDomain") { | |
616 flags |= Vamp::HostExt::PluginLoader::ADAPT_INPUT_DOMAIN; | |
617 } else if (text == "AdaptChannelCount") { | |
618 flags |= Vamp::HostExt::PluginLoader::ADAPT_CHANNEL_COUNT; | |
619 } else if (text == "AdaptBufferSize") { | |
620 flags |= Vamp::HostExt::PluginLoader::ADAPT_BUFFER_SIZE; | |
621 } else if (text == "AdaptAllSafe") { | |
622 flags |= Vamp::HostExt::PluginLoader::ADAPT_ALL_SAFE; | |
623 } else if (text == "AdaptAll") { | |
624 flags |= Vamp::HostExt::PluginLoader::ADAPT_ALL; | |
625 } else { | |
626 throw Failure("invalid adapter flag string: " + text); | |
627 } | |
628 } | |
629 | |
630 return Vamp::HostExt::PluginLoader::AdapterFlags(flags); | |
631 } | |
632 | |
633 static json11::Json | |
634 fromLoadRequest(Vamp::HostExt::LoadRequest req) { | |
635 | |
636 json11::Json::object jo; | |
637 jo["pluginKey"] = req.pluginKey; | |
638 jo["inputSampleRate"] = req.inputSampleRate; | |
639 jo["adapterFlags"] = fromAdapterFlags(req.adapterFlags); | |
640 return json11::Json(jo); | |
641 } | |
642 | |
643 static Vamp::HostExt::LoadRequest | |
644 toLoadRequest(json11::Json j) { | |
645 | |
646 std::string err; | |
647 | |
648 if (!j.has_shape({ | |
649 { "pluginKey", json11::Json::STRING }, | |
650 { "inputSampleRate", json11::Json::NUMBER }, | |
651 { "adapterFlags", json11::Json::ARRAY } }, err)) { | |
652 throw VampJson::Failure("malformed load request: " + err); | |
653 } | |
654 | |
655 Vamp::HostExt::LoadRequest req; | |
656 req.pluginKey = j["pluginKey"].string_value(); | |
657 req.inputSampleRate = j["inputSampleRate"].number_value(); | |
658 req.adapterFlags = toAdapterFlags(j["adapterFlags"]); | |
659 return req; | |
660 } | |
661 }; | |
662 | |
663 | |
664 #endif |