forked from MrBesen/soundboard
120 lines
3.1 KiB
C++
120 lines
3.1 KiB
C++
// This file contains the json parsing components required for the config to work
|
|
|
|
#include <nlohmann/json.hpp>
|
|
using json = nlohmann::json;
|
|
|
|
#include "config.h"
|
|
|
|
// json::array -> std::vector
|
|
template<typename T>
|
|
static void readVector(std::vector<T>& v, const json& j) {
|
|
v.clear();
|
|
v.reserve(j.size());
|
|
std::copy(j.begin(), j.end(), std::insert_iterator<std::vector<T>>(v, v.begin()));
|
|
}
|
|
|
|
// std::vector -> json::array
|
|
template<typename T>
|
|
static void writeVector(json& j, const std::vector<T>& v) {
|
|
j = json::array();
|
|
std::copy(v.begin(), v.end(), std::insert_iterator<json>(j, j.begin()));
|
|
}
|
|
|
|
void from_json(const json& j, Config::AudioConfig& ac) {
|
|
readVector(ac.devices, j.value("devices", json::array()));
|
|
}
|
|
|
|
void from_json(const json& j, Config::SampleConfig& sc) {
|
|
sc.file = j.value("file", "");
|
|
sc.offset = j.value("offset", 0);
|
|
sc.length = j.value("length", 0);
|
|
sc.volume = j.value("volume", 1.f);
|
|
}
|
|
|
|
void from_json(const json& j, Config::ButtonConfig& bc) {
|
|
bc.name = j.value("name", "");
|
|
bc.key = j.value("key", "");
|
|
bc.width = j.value("width", Config::ButtonConfig::DEFAULTWIDTH);
|
|
|
|
// make it possible to volume control all samples from one value
|
|
float volume = j.value("value", 1.0);
|
|
|
|
if(j.contains("samples")) {
|
|
// sample liste
|
|
readVector(bc.samples, j["samples"]);
|
|
for(Config::SampleConfig& sc : bc.samples) {
|
|
sc.volume *= volume;
|
|
}
|
|
} else if(j.contains("file")) {
|
|
bc.samples.push_back(j); // implizit cast
|
|
}
|
|
}
|
|
|
|
void from_json(const json& j, Config::RootConfig& rc) {
|
|
rc.audio = j.value<Config::AudioConfig>("audio", {});
|
|
json barr = j.value("buttons", json::array());
|
|
if(barr.is_array() && !barr.empty()) {
|
|
rc.buttons.reserve(barr.size());
|
|
for(const json& line : barr) {
|
|
std::vector<Config::ButtonConfig> btns;
|
|
readVector(btns, line);
|
|
rc.buttons.push_back(btns);
|
|
}
|
|
}
|
|
rc.audioPath = j.value("audioPath", "");
|
|
}
|
|
|
|
|
|
void to_json(json& j, const Config::AudioConfig& ac) {
|
|
json devarr = json::array();
|
|
writeVector(devarr, ac.devices);
|
|
j["devices"] = devarr;
|
|
}
|
|
|
|
void to_json(json& j, const Config::SampleConfig& sc) {
|
|
j["file"] = sc.file;
|
|
if(sc.offset != 0)
|
|
j["offset"] = sc.offset;
|
|
if(sc.length != 0)
|
|
j["length"] = sc.length;
|
|
if(sc.volume != 1.f)
|
|
j["volume"] = sc.volume;
|
|
}
|
|
|
|
void to_json(json& j, const Config::ButtonConfig& bc) {
|
|
j["name"] = bc.name;
|
|
|
|
if(!bc.key.empty())
|
|
j["key"] = bc.key;
|
|
|
|
if(bc.width != Config::ButtonConfig::DEFAULTWIDTH)
|
|
j["width"] = bc.width;
|
|
|
|
if(bc.samples.size() == 1) {
|
|
//dont use a json array when only one sample is present (inline instead)
|
|
to_json(j, bc.samples.at(0));
|
|
} else if(!bc.samples.empty()) {
|
|
json samples = json::array();
|
|
writeVector(samples, bc.samples);
|
|
j["samples"] = samples;
|
|
}
|
|
}
|
|
|
|
void to_json(json& j, const Config::RootConfig& rc) {
|
|
j["audio"] = rc.audio;
|
|
j["audioPath"] = rc.audioPath;
|
|
json buttonarr = json::array();
|
|
|
|
for(const std::vector<Config::ButtonConfig>& row : rc.buttons) {
|
|
if(row.empty()) continue;
|
|
json jsonrow = json::array();
|
|
|
|
for(const Config::ButtonConfig& btn : row) {
|
|
jsonrow.push_back(btn); // implicit convert btn to json
|
|
}
|
|
|
|
buttonarr.push_back(jsonrow);
|
|
}
|
|
|
|
j["buttons"] = buttonarr;
|
|
} |