From a0cb9dc8a0d85485f5fd4a1784b2af643f312436 Mon Sep 17 00:00:00 2001 From: Stefano D'Angelo Date: Tue, 9 Jan 2024 15:02:49 +0100 Subject: [PATCH] interesting parts of lv2 core done --- TODO | 1 + templates/lv2/data/manifest.ttl | 18 +++++++++++++++ templates/lv2/src/data.h | 11 +++++++++- templates/lv2/src/lv2.c | 39 ++++++++++++++++++++++----------- templates/lv2/tibia-index.js | 1 + test/product.json | 17 ++++++++++++-- 6 files changed, 71 insertions(+), 16 deletions(-) diff --git a/TODO b/TODO index 94b8acb..fb48ffe 100644 --- a/TODO +++ b/TODO @@ -9,3 +9,4 @@ * lv2: RDF/Turtle escape etc * lv2: extra data, see also - should use plugin.ttl? * lv2: i18n? +* #if > 0 -> dotjs diff --git a/templates/lv2/data/manifest.ttl b/templates/lv2/data/manifest.ttl index 3bca74d..b489708 100644 --- a/templates/lv2/data/manifest.ttl +++ b/templates/lv2/data/manifest.ttl @@ -47,6 +47,24 @@ {{?}} {{?p.optional}} lv2:portProperty lv2:connectionOptional ; +{{?}} +{{?p.integer}} + lv2:portProperty lv2:integer ; +{{?}} +{{?p.scalePoints}} + lv2:scalePoint [ +{{~Object.entries(p.scalePoints) :sp:j}} + rdfs:label "{{=sp[0]}}" ; + rdf:value {{=sp[1].toExponential()}} +{{?j < Object.entries(p.scalePoints).length - 1}} + ] , [ +{{??}} + ] ; +{{?}} +{{~}} +{{?}} +{{?p.list}} + lv2:portProperty lv2:enumeration ; {{?}} lv2:index {{=i}} {{?i < it.tibia.lv2.ports.length - 1}} diff --git a/templates/lv2/src/data.h b/templates/lv2/src/data.h index 257f1fe..e6e16f5 100644 --- a/templates/lv2/src/data.h +++ b/templates/lv2/src/data.h @@ -9,8 +9,10 @@ # define DATA_PARAM_BYPASS 1 # define DATA_PARAM_TOGGLED (1<<1) +# define DATA_PARAM_INTEGER (1<<2) static struct { + uint32_t index; float min; float max; float def; @@ -18,12 +20,19 @@ static struct { } param_data[DATA_PRODUCT_CONTROL_INPUTS_N] = { {{~it.tibia.lv2.ports.filter(x => x.type == "control" && x.direction == "input") :p}} { + /* .index = */ {{=p.paramIndex}}, /* .min = */ {{=p.minimum.toExponential()}}f, /* .max = */ {{=p.maximum.toExponential()}}f, /* .def = */ {{=p.defaultValue.toExponential()}}f, - /* .flags = */ 0{{?p.isBypass}} | DATA_PARAM_BYPASS{{?}}{{?p.toggled}} | DATA_PARAM_TOGGLED{{?}} + /* .flags = */ 0{{?p.isBypass}} | DATA_PARAM_BYPASS{{?}}{{?p.toggled}} | DATA_PARAM_TOGGLED{{?}}{{?p.integer}} | DATA_PARAM_INTEGER{{?}} }, {{~}} }; #endif + +#if DATA_PRODUCT_CONTROL_OUTPUTS_N > 0 +static uint32_t param_out_index[DATA_PRODUCT_CONTROL_OUTPUTS_N] = { + {{~it.tibia.lv2.ports.filter(x => x.type == "control" && x.direction == "output") :p}}{{=p.paramIndex}}, {{~}} +}; +#endif diff --git a/templates/lv2/src/lv2.c b/templates/lv2/src/lv2.c index 341ff6c..3bb2ca4 100644 --- a/templates/lv2/src/lv2.c +++ b/templates/lv2/src/lv2.c @@ -27,15 +27,15 @@ static LV2_Handle instantiate(const struct LV2_Descriptor * descriptor, double s plugin_init(&instance->p); plugin_set_sample_rate(&instance->p, sample_rate); #if DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N > 0 - for (size_t i = 0; i < DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N; i++) + for (uint32_t i = 0; i < DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N; i++) instance->x[i] = NULL; #endif #if DATA_PRODUCT_AUDIO_OUTPUT_CHANNELS_N > 0 - for (size_t i = 0; i < DATA_PRODUCT_AUDIO_OUTPUT_CHANNELS_N; i++) + for (uint32_t i = 0; i < DATA_PRODUCT_AUDIO_OUTPUT_CHANNELS_N; i++) instance->y[i] = NULL; #endif -#if DATA_PRODUCT_CONTROL_INPUTS_N > 0 - for (size_t i = 0; i < DATA_PRODUCT_CONTROL_INPUTS_N; i++) +#if (DATA_PRODUCT_CONTROL_INPUTS_N + DATA_PRODUCT_CONTROL_OUTPUTS_N) > 0 + for (uint32_t i = 0; i < DATA_PRODUCT_CONTROL_INPUTS_N + DATA_PRODUCT_CONTROL_OUTPUTS_N; i++) instance->c[i] = NULL; #endif return instance; @@ -65,9 +65,10 @@ static void connect_port(LV2_Handle instance, uint32_t port, void * data_locatio static void activate(LV2_Handle instance) { plugin_instance * i = (plugin_instance *)instance; #if DATA_PRODUCT_CONTROL_INPUTS_N > 0 - for (size_t j = 0; j < DATA_PRODUCT_CONTROL_INPUTS_N; j++) { - i->params[j] = i->c[j] != NULL ? *i->c[j] : param_data[j].def; - plugin_set_parameter(&i->p, j, i->params[j]); + for (uint32_t j = 0; j < DATA_PRODUCT_CONTROL_INPUTS_N; j++) { + uint32_t k = param_data[j].index; + i->params[j] = i->c[k] != NULL ? *i->c[k] : param_data[j].def; + plugin_set_parameter(&i->p, k, i->params[j]); } #endif plugin_reset(&i->p); @@ -81,25 +82,37 @@ static void run(LV2_Handle instance, uint32_t sample_count) { plugin_instance * i = (plugin_instance *)instance; #if DATA_PRODUCT_CONTROL_INPUTS_N > 0 - for (size_t j = 0; j < DATA_PRODUCT_CONTROL_INPUTS_N; j++) { - if (i->c[j] == NULL) + for (uint32_t j = 0; j < DATA_PRODUCT_CONTROL_INPUTS_N; j++) { + uint32_t k = param_data[j].index; + if (i->c[k] == NULL) continue; float v; if (param_data[j].flags & DATA_PARAM_BYPASS) - v = *i->c[j] > 0.f ? 0.f : 1.f; + v = *i->c[k] > 0.f ? 0.f : 1.f; else if (param_data[j].flags & DATA_PARAM_TOGGLED) - v = *i->c[j] > 0.f ? 1.f : 0.f; + v = *i->c[k] > 0.f ? 1.f : 0.f; + else if (param_data[j].flags & DATA_PARAM_INTEGER) + v = (int32_t)(*i->c[k] + 0.5f); else - v = clampf(*i->c[j], param_data[j].min, param_data[j].max); + v = *i->c[k]; + v = clampf(v, param_data[j].min, param_data[j].max); if (v != i->params[j]) { i->params[j] = v; - plugin_set_parameter(&i->p, j, v); + plugin_set_parameter(&i->p, k, v); } } #endif plugin_process(&i->p, i->x, i->y, sample_count); + +#if DATA_PRODUCT_CONTROL_OUTPUTS_N > 0 + for (uint32_t j = 0; j < DATA_PRODUCT_CONTROL_OUTPUTS_N; j++) { + uint32_t k = param_out_index[j]; + if (i->c[k] != NULL) + i->c[k] = plugin_get_parameter(&i->p, k); + } +#endif } static void cleanup(LV2_Handle instance) { diff --git a/templates/lv2/tibia-index.js b/templates/lv2/tibia-index.js index 299a9d7..b1fae05 100644 --- a/templates/lv2/tibia-index.js +++ b/templates/lv2/tibia-index.js @@ -32,6 +32,7 @@ module.exports = function (data, api) { var e = Object.create(p); e.type = "control"; e.symbol = data.lv2.parameterSymbols[i]; + e.paramIndex = i; data.tibia.lv2.ports.push(e); } diff --git a/test/product.json b/test/product.json index aeea18a..c4b6100 100644 --- a/test/product.json +++ b/test/product.json @@ -39,7 +39,14 @@ "minimum": -60.0, "maximum": 12.0, "toggled": false, - "optional": false + "optional": false, + "integer": false, + "scalePoints": { + "0": 0.0, + "Max": 12.0, + "Min": -60.0 + }, + "list": false }, { "name": "Bypass", @@ -53,7 +60,13 @@ "minimum": 0, "maximum": 1, "toggled": true, - "optional": true + "optional": true, + "integer": true, + "scalePoints": { + "Off": 0, + "On": 1 + }, + "list": true } ] }