5 #ifndef _RNBO_Presets_H_
6 #define _RNBO_Presets_H_
12 #include "RNBO_PatcherState.h"
17 using Preset = PatcherState;
20 using PresetPtr = std::shared_ptr<Preset>;
23 class DummyPreset :
public PatcherState
26 bool isDummy()
const override {
return true; }
32 #include "RNBO_Debug.h"
34 RNBO_PUSH_DISABLE_WARNINGS
35 #include "3rdparty/json/json.hpp"
36 RNBO_POP_DISABLE_WARNINGS
38 #include "RNBO_Utils.h"
41 #include "3rdparty/cppcodec/base64_rfc4648.hpp"
43 using base64 = cppcodec::base64_rfc4648;
53 using PresetMap = StateMap;
94 bool isDummy()
const override {
return true; }
109 #ifndef RNBO_NOJSONPRESETS
111 using Json = nlohmann::json;
113 static Json convertPresetToJSONObj(
const Preset& preset) {
115 for (
auto const& entry : preset) {
116 const char *key = entry.first.c_str();
117 auto type = entry.second.getType();
120 float value = (float)entry.second;
125 double value = (double)entry.second;
131 const list& value = entry.second;
132 for (
size_t i = 0; i < value.
length; i++) {
133 j.push_back(value[i]);
138 case ValueHolder::STRING: {
139 const char * str = entry.second;
144 const Preset& subPreset = entry.second;
145 json[key] = convertPresetToJSONObj(subPreset);
149 Index size = entry.second.getSubStateMapSize();
152 for (
Index i = 0; i < size; i++) {
153 const Preset& subPreset = entry.second[i];
154 j.push_back(convertPresetToJSONObj(subPreset));
160 case ValueHolder::UINT32: {
161 UInt32 value = (UInt32)entry.second;
165 case ValueHolder::UINT64: {
166 UInt64 value = (UInt64)entry.second;
174 binJson[
"binary"] =
true;
175 std::string binaryString = base64::encode(buffer.data, buffer.sizeInBytes);
176 binJson[
"data"] = binaryString;
179 switch (buffer.type.type) {
181 typeJson[
"type"] =
"Untyped";
184 typeJson[
"type"] =
"Float32AudioBuffer";
187 typeJson[
"type"] =
"Float64AudioBuffer";
190 typeJson[
"type"] =
"TypedArray";
198 typeJson[
"channels"] = buffer.type.audioBufferInfo.channels;
199 typeJson[
"samplerate"] = buffer.type.audioBufferInfo.samplerate;
202 binJson[
"type"] = typeJson;
207 case ValueHolder::EXTERNAL:
208 case ValueHolder::EVENTTARGET:
209 case ValueHolder::DATAREF:
210 case ValueHolder::MULTIREF:
211 case ValueHolder::SIGNAL:
212 case ValueHolder::BOOLEAN:
213 case ValueHolder::INTVALUE:
224 static std::string convertPresetToJSON(
const Preset& preset) {
225 return convertPresetToJSONObj(preset).dump();
228 static void convertJSONObjToPreset(Json& json, Preset& preset) {
229 for (Json::iterator it = json.begin(); it != json.end(); it++) {
230 const char* key = it.key().c_str();
231 if (it->is_number()) {
232 number value = it.value();
235 else if (it->is_string()) {
236 std::string value = it.value();
237 preset[key] = value.c_str();
239 else if (it->is_array()) {
242 if (j[0].is_number()) {
244 for (Index i = 0; i < j.size(); i++) {
249 else if (j[0].is_object()) {
250 for (Index i = 0; i < j.size(); i++) {
251 Preset& subPreset = preset[key][i];
252 convertJSONObjToPreset(j[i], subPreset);
257 else if (it->is_object()) {
259 if (j.contains(
"binary") && j[
"binary"] ==
true) {
260 SerializedBuffer buffer;
262 if (j.contains(
"data") && j[
"data"].is_string()) {
263 std::string data = j[
"data"];
264 size_t size = base64::decoded_max_size(data.length());
266 buffer.data = (uint8_t *)malloc(size);
267 buffer.sizeInBytes = base64::decode(buffer.data, size, data);
270 if (j.contains(
"type") && j[
"type"].is_object()) {
271 auto& typeJson = j.at(
"type");
272 std::string type = typeJson[
"type"];
273 if (type ==
"Float32AudioBuffer") {
274 buffer.type = Float32AudioBuffer(typeJson[
"channels"], typeJson[
"samplerate"]);
276 else if (type ==
"Float64AudioBuffer") {
277 buffer.type = Float64AudioBuffer(typeJson[
"channels"], typeJson[
"samplerate"]);
279 else if (type ==
"TypedArray") {
285 buffer.type = UntypedDataBuffer();
289 preset[key] = buffer;
293 convertJSONObjToPreset(j, subPreset);
300 static void convertJSONArrayToPresetList(std::string jsonString, std::vector<std::shared_ptr<NamedPresetEntry>>& presetList) {
301 Json json = Json::parse(jsonString);
302 for (Json::iterator it = json.begin(); it != json.end(); it++) {
303 if (it->is_object()) {
305 std::shared_ptr<NamedPresetEntry> entry(
new NamedPresetEntry);
306 std::string name = j[
"name"];
307 Json presetPayload = j[
"preset"];
309 PresetPtr preset = std::make_shared<Preset>();
310 convertJSONObjToPreset(presetPayload, *preset);
311 entry->preset = preset;
312 presetList.push_back(entry);
320 Json json = Json::parse(jsonString);
321 convertJSONObjToPreset(json, *preset);
326 static void copyPreset(
const Preset& src, Preset &dst)
328 for (
auto const& entry : src) {
329 const char *key = entry.first.c_str();
330 auto type = entry.second.getType();
333 float value = (float)entry.second;
338 double value = (double)entry.second;
342 case ValueHolder::UINT32: {
343 UInt32 value = (UInt32)entry.second;
347 case ValueHolder::UINT64: {
348 UInt64 value = (UInt64)entry.second;
354 const list& srclist = entry.second;
356 for (Index i = 0; i < srclist.length; i++) {
357 dstlist.
push(srclist[i]);
363 const Preset& preset = entry.second;
364 copyPreset(preset, dst[key]);
368 Index size = entry.second.getSubStateMapSize();
370 for (Index i = 0; i < size; i++) {
371 const Preset& preset = entry.second[i];
372 Preset& dstSubPreset = dst[key][i];
373 copyPreset(preset, dstSubPreset);
378 case ValueHolder::STRING:
380 RNBO_ASSERT(strcmp(key,
"__presetid") == 0);
383 SerializedBuffer tmp = (SerializedBuffer&)entry.second;
388 case ValueHolder::EXTERNAL:
389 case ValueHolder::EVENTTARGET:
390 case ValueHolder::DATAREF:
391 case ValueHolder::MULTIREF:
392 case ValueHolder::SIGNAL:
393 case ValueHolder::BOOLEAN:
394 case ValueHolder::INTVALUE:
403 #endif // RNBO_NOJSONPRESETS
407 #endif // RNBO_NOPRESETS
409 #endif // _RNBO_Presets_H_