From d78a375c9527a63f2cf93b4860a50918f7e1e75d Mon Sep 17 00:00:00 2001 From: Stefano D'Angelo Date: Tue, 13 May 2025 16:16:48 +0200 Subject: [PATCH] removed lv2-next --- templates/lv2-next/README.md | 1 - templates/lv2-next/data/manifest.ttl.in | 95 ----- templates/lv2-next/src/data.h | 78 ---- templates/lv2-next/src/lv2.c | 499 ------------------------ templates/lv2-next/tibia-index.js | 136 ------- 5 files changed, 809 deletions(-) delete mode 100644 templates/lv2-next/README.md delete mode 100644 templates/lv2-next/data/manifest.ttl.in delete mode 100644 templates/lv2-next/src/data.h delete mode 100644 templates/lv2-next/src/lv2.c delete mode 100644 templates/lv2-next/tibia-index.js diff --git a/templates/lv2-next/README.md b/templates/lv2-next/README.md deleted file mode 100644 index e8c5011..0000000 --- a/templates/lv2-next/README.md +++ /dev/null @@ -1 +0,0 @@ -This is experimental and broken, do not use this. diff --git a/templates/lv2-next/data/manifest.ttl.in b/templates/lv2-next/data/manifest.ttl.in deleted file mode 100644 index a9998c8..0000000 --- a/templates/lv2-next/data/manifest.ttl.in +++ /dev/null @@ -1,95 +0,0 @@ -{{~it.tibia.lv2.prefixes :p}} -@prefix {{=p.id}}: <{{=p.uri}}> . -{{~}} - -{{~it.product.parameters :p}} -plugin:{{=p.id}} - a lv2:Parameter ; - rdfs:label "{{=p.name}}" ; - lv2:name "{{=p.name}}" ; -{{?"shortName" in p}} - lv2:shortName "{{=p.shortName.substring(0, 16)}}" ; -{{?}} - lv2:symbol "{{=p.id}}" ; - rdfs:range atom:Float . -{{~}} - -{{=it.tibia.lv2.ttlURI(it.lv2.uri)}} - a lv2:Plugin ; -{{~it.lv2.types :t}} - a {{=it.tibia.lv2.ttlURI(t)}} ; -{{~}} -{{?it.lv2.project}} - lv2:project {{=it.tibia.lv2.ttlURI(it.lv2.project)}} ; -{{?}} - lv2:binary <{{=it.product.bundleName}}@DLL_SUFFIX@> ; - doap:name "{{=it.product.name}}" ; - doap:maintainer [ - a foaf:Organization ; - foaf:name "{{=it.company.name}}" ; - foaf:mbox ; - rdfs:seeAlso {{=it.tibia.lv2.ttlURI(it.company.url)}} - ] ; - lv2:minorVersion {{=/^([0-9]+)\./.exec(it.lv2.version)[1]}} ; - lv2:microVersion {{=/^[0-9]+\.([0-9]+)/.exec(it.lv2.version)[1]}} ; -{{?it.tibia.lv2.ports.find(p => p.type == "midi" || p.type == "param")}} - lv2:requiredFeature urid:map ; - lv2:optionalFeature log:log ; -{{?}} -{{?it.product.parameters.find(p => p.direction == "input")}} - patch:writable {{=it.product.parameters.filter(p => p.direction == "input").map(p => "plugin:" + p.id).join(" , ")}} ; -{{?}} -{{?it.product.parameters.find(p => p.direction == "output")}} - patch:readable {{=it.product.parameters.filter(p => p.direction == "output").map(p => "plugin:" + p.id).join(" , ")}} ; -{{?}} - lv2:optionalFeature lv2:hardRTCapable ; -{{?it.product.ui}} - ui:ui plugin:ui ; -{{?}} - lv2:port [ -{{~it.tibia.lv2.ports :p:i}} - a {{?p.type == "control"}}lv2:ControlPort{{??(p.type == "midi" || p.type == "param")}}atom:AtomPort{{??}}{{?p.cv}}lv2:CVPort{{??}}lv2:AudioPort{{?}}{{?}} , - {{?p.direction == "input"}}lv2:InputPort{{??}}lv2:OutputPort{{?}} ; - lv2:name "{{=p.name}}" ; -{{?"shortName" in p}} - lv2:shortName "{{=p.shortName.substring(0, 16)}}" ; -{{?}} - lv2:symbol "{{=p.id}}" ; -{{?p.type == "param"}} - atom:bufferType atom:Sequence ; - atom:supports atom:Object ; - atom:supports patch:Message ; -{{??p.type == "midi"}} - atom:bufferType atom:Sequence ; - atom:supports midi:MidiEvent ; -{{?}} -{{?p.sidechain}} - lv2:portProperty lv2:isSideChain ; -{{?}} -{{?p.control}} - lv2:designation lv2:control ; -{{?}} -{{?p.optional}} - lv2:portProperty lv2:connectionOptional ; -{{?}} - lv2:index {{=i}} -{{?i < it.tibia.lv2.ports.length - 1}} - ] , [ -{{??}} - ] . -{{?}} -{{~}} - -{{?it.product.ui}} -plugin:ui - a ui:@UI_TYPE@ ; - ui:binary <{{=it.product.bundleName}}@DLL_SUFFIX@> ; -{{?!it.product.ui.userResizable}} - lv2:optionalFeature ui:noUserResize ; # doesn't work as lv2:requiredFeature, don't ask me why -{{?!it.product.ui.selfResizable}} - lv2:optionalFeature ui:fixedSize ; -{{?}} -{{?}} - lv2:requiredFeature ui:idleInterface ; - lv2:extensionData ui:idleInterface . -{{?}} diff --git a/templates/lv2-next/src/data.h b/templates/lv2-next/src/data.h deleted file mode 100644 index cf5e8b5..0000000 --- a/templates/lv2-next/src/data.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Tibia - * - * Copyright (C) 2024 Orastron Srl unipersonale - * - * Tibia is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3 of the License. - * - * Tibia is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tibia. If not, see . - * - * File author: Stefano D'Angelo - */ - -#define DATA_LV2_URI "{{=it.tibia.CGetUTF8StringLiteral(it.tibia.lv2.expandURI(it.lv2.uri))}}" - -#define DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "input").reduce((s, x) => s += x.channels == "mono" ? 1 : 2, 0)}} -#define DATA_PRODUCT_AUDIO_OUTPUT_CHANNELS_N {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "output").reduce((s, x) => s += x.channels == "mono" ? 1 : 2, 0)}} -#define DATA_PRODUCT_MIDI_INPUTS_N {{=it.product.buses.filter(x => x.type == "midi" && x.direction == "input").length}} -#define DATA_PRODUCT_MIDI_OUTPUTS_N {{=it.product.buses.filter(x => x.type == "midi" && x.direction == "output").length}} -#define DATA_PRODUCT_CONTROL_INPUTS_N {{=it.product.parameters.filter(x => x.direction == "input").length}} -#define DATA_PRODUCT_CONTROL_OUTPUTS_N {{=it.product.parameters.filter(x => x.direction == "output").length}} - -#if DATA_PRODUCT_MIDI_INPUTS_N > 0 -static uint32_t midi_in_index[DATA_PRODUCT_MIDI_INPUTS_N] = { - {{~it.tibia.lv2.ports.filter(x => x.type == "midi" && x.direction == "input") :p}}{{=p.busIndex}}, {{~}} -}; -#endif - -#if DATA_PRODUCT_CONTROL_INPUTS_N > 0 - -# 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; - uint32_t flags; -} 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 = */ {{?p.isBypass}}DATA_PARAM_BYPASS{{??p.isLatency}}DATA_PARAM_INTEGER{{??}}0{{?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 - -{{?it.lv2.ui}} -#define DATA_UI -#define DATA_LV2_UI_URI "{{=it.tibia.CGetUTF8StringLiteral(it.tibia.lv2.expandURI(it.lv2.ui.uri))}}" -#define DATA_UI_USER_RESIZABLE {{=it.product.ui.userResizable ? 1 : 0}} - -#if DATA_PRODUCT_CONTROL_INPUTS_N > 0 -static uint32_t index_to_param[DATA_PRODUCT_CONTROL_INPUTS_N + DATA_PRODUCT_CONTROL_OUTPUTS_N] = { - {{~it.tibia.lv2.ports.filter(x => x.type == "control").map((e, i) => ({ i: i, pi: e.paramIndex })).sort((a, b) => a.pi - b.pi) :p}}{{=p.i + it.tibia.lv2.ports.filter(x => x.type != "control").length}}, {{~}} -}; -#endif -{{?}} diff --git a/templates/lv2-next/src/lv2.c b/templates/lv2-next/src/lv2.c deleted file mode 100644 index 4734804..0000000 --- a/templates/lv2-next/src/lv2.c +++ /dev/null @@ -1,499 +0,0 @@ -/* - * Tibia - * - * Copyright (C) 2024 Orastron Srl unipersonale - * - * Tibia is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3 of the License. - * - * Tibia is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tibia. If not, see . - * - * File author: Stefano D'Angelo - */ - -#include -#include - -#include "data.h" -#include "plugin_api.h" -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-function" -#include "plugin.h" -#ifdef DATA_UI -# include "plugin_ui.h" -#endif -#pragma GCC diagnostic pop - -#include "lv2/core/lv2.h" -#include "lv2/core/lv2_util.h" -#include "lv2/log/log.h" -#include "lv2/log/logger.h" -#include "lv2/urid/urid.h" -#if DATA_PRODUCT_MIDI_INPUTS_N + DATA_PRODUCT_MIDI_OUTPUTS_N > 0 -# include "lv2/atom/util.h" -# include "lv2/atom/atom.h" -# include "lv2/midi/midi.h" -#endif -#ifdef DATA_UI -# include "lv2/ui/ui.h" -#endif - -#include - -#if defined(__i386__) || defined(__x86_64__) -# include -# include -#endif - -static inline float clampf(float x, float m, float M) { - return x < m ? m : (x > M ? M : x); -} - -static float adjust_param(size_t index, float value) { - if (param_data[index].flags & DATA_PARAM_BYPASS) - value = value > 0.f ? 0.f : 1.f; - else if (param_data[index].flags & DATA_PARAM_TOGGLED) - value = value > 0.f ? 1.f : 0.f; - else if (param_data[index].flags & DATA_PARAM_INTEGER) - value = (int32_t)(value + (value >= 0.f ? 0.5f : -0.5f)); - return clampf(value, param_data[index].min, param_data[index].max); -} - -typedef struct { - plugin p; -#if DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N > 0 - const float * x[DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N]; -#endif -#if DATA_PRODUCT_AUDIO_OUTPUT_CHANNELS_N > 0 - float * y[DATA_PRODUCT_AUDIO_OUTPUT_CHANNELS_N]; -#endif -#if DATA_PRODUCT_MIDI_INPUTS_N > 0 - const LV2_Atom_Sequence * x_midi[DATA_PRODUCT_MIDI_INPUTS_N]; -#endif -#if DATA_PRODUCT_MIDI_OUTPUTS_N > 0 - LV2_Atom_Sequence * y_midi[DATA_PRODUCT_MIDI_OUTPUTS_N]; -#endif -#if (DATA_PRODUCT_CONTROL_INPUTS_N + DATA_PRODUCT_CONTROL_OUTPUTS_N) > 0 - float * c[DATA_PRODUCT_CONTROL_INPUTS_N + DATA_PRODUCT_CONTROL_OUTPUTS_N]; -#endif -#if DATA_PRODUCT_CONTROL_INPUTS_N > 0 - float params[DATA_PRODUCT_CONTROL_INPUTS_N]; -#endif - void * mem; - char * bundle_path; - LV2_Log_Logger logger; - LV2_URID_Map * map; -#if DATA_PRODUCT_MIDI_INPUTS_N + DATA_PRODUCT_MIDI_OUTPUTS_N > 0 - LV2_URID uri_midi_MidiEvent; -#endif -} plugin_instance; - -static const char * get_bundle_path_cb(void *handle) { - plugin_instance *instance = (plugin_instance *)handle; - return instance->bundle_path; -} - -static LV2_Handle instantiate(const struct LV2_Descriptor * descriptor, double sample_rate, const char * bundle_path, const LV2_Feature * const * features) { - (void)descriptor; - (void)bundle_path; - - plugin_instance *instance = malloc(sizeof(plugin_instance)); - if (instance == NULL) - goto err_instance; - - instance->bundle_path = strdup(bundle_path); - if (instance->bundle_path == NULL) - goto err_bundle_path; - - // from https://lv2plug.in/book - const char* missing = lv2_features_query(features, - LV2_LOG__log, &instance->logger.log, false, - LV2_URID__map, &instance->map, true, - NULL); - - lv2_log_logger_set_map(&instance->logger, instance->map); - if (missing) { - lv2_log_error(&instance->logger, "Missing feature <%s>\n", missing); - goto err_urid; - } - -#if DATA_PRODUCT_MIDI_INPUTS_N + DATA_PRODUCT_MIDI_OUTPUTS_N > 0 - instance->uri_midi_MidiEvent = instance->map->map(instance->map->handle, LV2_MIDI__MidiEvent); -#endif - - plugin_callbacks cbs = { - /* .handle = */ (void *)instance, - /* .format = */ "lv2", - /* .get_bindir = */ get_bundle_path_cb, - /* .get_datadir = */ get_bundle_path_cb - }; - plugin_init(&instance->p, &cbs); - - plugin_set_sample_rate(&instance->p, sample_rate); - size_t req = plugin_mem_req(&instance->p); - if (req != 0) { - instance->mem = malloc(req); - if (instance->mem == NULL) { - lv2_log_error(&instance->logger, "Not enough memory\n"); - goto err_mem; - } - plugin_mem_set(&instance->p, instance->mem); - } else - instance->mem = NULL; - -#if DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N > 0 - 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 (uint32_t i = 0; i < DATA_PRODUCT_AUDIO_OUTPUT_CHANNELS_N; i++) - instance->y[i] = NULL; -#endif -#if DATA_PRODUCT_MIDI_INPUTS_N > 0 - for (uint32_t i = 0; i < DATA_PRODUCT_MIDI_INPUTS_N; i++) - instance->x_midi[i] = NULL; -#endif -#if DATA_PRODUCT_MIDI_OUTPUTS_N > 0 - for (uint32_t i = 0; i < DATA_PRODUCT_MIDI_OUTPUTS_N; i++) - instance->y_midi[i] = NULL; -#endif -#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; - -err_mem: - plugin_fini(&instance->p); -err_urid: - free(instance->bundle_path); -err_bundle_path: - free(instance); -err_instance: - return NULL; -} - -static void connect_port(LV2_Handle instance, uint32_t port, void * data_location) { - plugin_instance * i = (plugin_instance *)instance; -#if DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N > 0 - if (port < DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N) { - i->x[port] = data_location; - return; - } - port -= DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N; -#endif -#if DATA_PRODUCT_AUDIO_OUTPUT_CHANNELS_N > 0 - if (port < DATA_PRODUCT_AUDIO_OUTPUT_CHANNELS_N) { - i->y[port] = data_location; - return; - } - port -= DATA_PRODUCT_AUDIO_OUTPUT_CHANNELS_N; -#endif -#if DATA_PRODUCT_MIDI_INPUTS_N > 0 - if (port < DATA_PRODUCT_MIDI_INPUTS_N) { - i->x_midi[port] = data_location; - return; - } - port -= DATA_PRODUCT_MIDI_INPUTS_N; -#endif -#if DATA_PRODUCT_MIDI_OUTPUTS_N > 0 - if (port < DATA_PRODUCT_MIDI_OUTPUTS_N) { - i->y_midi[port] = data_location; - return; - } - port -= DATA_PRODUCT_MIDI_OUTPUTS_N; -#endif -#if (DATA_PRODUCT_CONTROL_INPUTS_N + DATA_PRODUCT_CONTROL_OUTPUTS_N) > 0 - i->c[port] = data_location; -#endif -} - -static void activate(LV2_Handle instance) { - plugin_instance * i = (plugin_instance *)instance; -#if DATA_PRODUCT_CONTROL_INPUTS_N > 0 - for (uint32_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, param_data[j].index, i->params[j]); - } -#endif - plugin_reset(&i->p); -} - -static void run(LV2_Handle instance, uint32_t sample_count) { - plugin_instance * i = (plugin_instance *)instance; - -#if defined(__aarch64__) - uint64_t fpcr; - __asm__ __volatile__ ("mrs %0, fpcr" : "=r"(fpcr)); - __asm__ __volatile__ ("msr fpcr, %0" :: "r"(fpcr | 0x1000000)); // enable FZ -#elif defined(__i386__) || defined(__x86_64__) - const unsigned int flush_zero_mode = _MM_GET_FLUSH_ZERO_MODE(); - const unsigned int denormals_zero_mode = _MM_GET_DENORMALS_ZERO_MODE(); - - _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); - _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); -#endif - -#if DATA_PRODUCT_CONTROL_INPUTS_N > 0 - for (uint32_t j = 0; j < DATA_PRODUCT_CONTROL_INPUTS_N; j++) { - if (i->c[j] == NULL) - continue; - float v = adjust_param(j, *i->c[j]); - if (v != i->params[j]) { - i->params[j] = v; - plugin_set_parameter(&i->p, param_data[j].index, v); - } - } -#endif - - // from https://lv2plug.in/book -#if DATA_PRODUCT_MIDI_INPUTS_N > 0 - for (size_t j = 0; j < DATA_PRODUCT_MIDI_INPUTS_N; j++) { - if (i->x_midi[j] == NULL) - continue; - LV2_ATOM_SEQUENCE_FOREACH(i->x_midi[j], ev) { - if (ev->body.type == i->uri_midi_MidiEvent) { - const uint8_t * data = (const uint8_t *)(ev + 1); - if ((data[0] & 0xf0) != 0xf0) - plugin_midi_msg_in(&i->p, midi_in_index[j], data); - } - } - } -#endif - -#if DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N > 0 - const float ** x = i->x; -#else - const float ** x = NULL; -#endif -#if DATA_PRODUCT_AUDIO_OUTPUT_CHANNELS_N > 0 - float ** y = i-> y; -#else - float ** y = NULL; -#endif - plugin_process(&i->p, x, 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); - } -#else - (void)plugin_get_parameter; -#endif - -#if defined(__aarch64__) - __asm__ __volatile__ ("msr fpcr, %0" : : "r"(fpcr)); -#elif defined(__i386__) || defined(__x86_64__) - _MM_SET_FLUSH_ZERO_MODE(flush_zero_mode); - _MM_SET_DENORMALS_ZERO_MODE(denormals_zero_mode); -#endif -} - -static void cleanup(LV2_Handle instance) { - plugin_instance * i = (plugin_instance *)instance; - plugin_fini(&i->p); - if (i->mem) - free(i->mem); - free(i->bundle_path); - free(instance); -} - -static const LV2_Descriptor descriptor = { - /* .URI = */ DATA_LV2_URI, - /* .instantiate = */ instantiate, - /* .connect_port = */ connect_port, - /* .activate = */ activate, - /* .run = */ run, - /* .deactivate = */ NULL, - /* .cleanup = */ cleanup, - /* .extension_data = */ NULL -}; - -LV2_SYMBOL_EXPORT const LV2_Descriptor * lv2_descriptor(uint32_t index) { - return index == 0 ? &descriptor : NULL; -} - -#ifdef DATA_UI -typedef struct { - plugin_ui * ui; - char * bundle_path; -# if DATA_PRODUCT_CONTROL_INPUTS_N > 0 - LV2UI_Write_Function write; - LV2UI_Controller controller; - char has_touch; - LV2UI_Touch touch; -# endif -} ui_instance; - -# define CONTROL_INPUT_INDEX_OFFSET ( \ - DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N \ - + DATA_PRODUCT_AUDIO_OUTPUT_CHANNELS_N \ - + DATA_PRODUCT_MIDI_INPUTS_N \ - + DATA_PRODUCT_MIDI_OUTPUTS_N ) -# define CONTROL_OUTPUT_INDEX_OFFSET (CONTROL_INPUT_INDEX_OFFSET + DATA_PRODUCT_CONTROL_INPUTS_N) - -static const char * ui_get_bundle_path_cb(void *handle) { - ui_instance *instance = (ui_instance *)handle; - return instance->bundle_path; -} - -# if DATA_PRODUCT_CONTROL_INPUTS_N > 0 -static void ui_set_parameter_begin_cb(void *handle, size_t index, float value) { - ui_instance *instance = (ui_instance *)handle; - if (instance->has_touch) { - index = index_to_param[index]; - instance->touch.touch(instance->touch.handle, index, true); - value = adjust_param(index - CONTROL_INPUT_INDEX_OFFSET, value); - instance->write(instance->controller, index, sizeof(float), 0, &value); - } -} - -static void ui_set_parameter_cb(void *handle, size_t index, float value) { - ui_instance *instance = (ui_instance *)handle; - index = index_to_param[index]; - value = adjust_param(index - CONTROL_INPUT_INDEX_OFFSET, value); - instance->write(instance->controller, index, sizeof(float), 0, &value); -} - -static void ui_set_parameter_end_cb(void *handle, size_t index, float value) { - ui_instance *instance = (ui_instance *)handle; - if (instance->has_touch) { - index = index_to_param[index]; - value = adjust_param(index - CONTROL_INPUT_INDEX_OFFSET, value); - instance->write(instance->controller, index, sizeof(float), 0, &value); - instance->touch.touch(instance->touch.handle, index, false); - } -} -# endif - -static LV2UI_Handle ui_instantiate(const LV2UI_Descriptor * descriptor, const char * plugin_uri, const char * bundle_path, LV2UI_Write_Function write_function, LV2UI_Controller controller, LV2UI_Widget * widget, const LV2_Feature * const * features) { - (void)descriptor; - (void)plugin_uri; - - ui_instance *instance = malloc(sizeof(ui_instance)); - if (instance == NULL) - goto err_instance; - - instance->bundle_path = strdup(bundle_path); - if (instance->bundle_path == NULL) - goto err_bundle_path; - - char has_parent = 0; - void *parent = NULL; - instance->has_touch = 0; - for (size_t i = 0; features[i] != NULL; i++) { - if (!strcmp(features[i]->URI, LV2_UI__parent)) { - has_parent = 1; - parent = features[i]->data; - } - if (!strcmp(features[i]->URI, LV2_UI__touch)) { - instance->has_touch = 1; - instance->touch = *((LV2UI_Touch *)features[i]->data); - } - } - - plugin_ui_callbacks cbs = { - /* .handle = */ (void *)instance, - /* .format = */ "lv2", - /* .get_bindir = */ ui_get_bundle_path_cb, - /* .get_datadir = */ ui_get_bundle_path_cb, -# if DATA_PRODUCT_CONTROL_INPUTS_N > 0 - /* .set_parameter_begin = */ ui_set_parameter_begin_cb, - /* .set_parameter = */ ui_set_parameter_cb, - /* .set_parameter_end = */ ui_set_parameter_end_cb -# else - /* .set_parameter_begin = */ NULL, - /* .set_parameter = */ NULL, - /* .set_parameter_end = */ NULL -# endif - }; -# if DATA_PRODUCT_CONTROL_INPUTS_N > 0 - instance->write = write_function; - instance->controller = controller; -# else - (void)write_function; - (void)controller; -# endif - instance->ui = plugin_ui_create(has_parent, parent, &cbs); - if (instance->ui == NULL) - goto err_create; - - *widget = instance->ui->widget; - return instance; - -err_create: - free(instance->bundle_path); -err_bundle_path: - free(instance); -err_instance: - *widget = NULL; - return NULL; -} - -static void ui_cleanup(LV2UI_Handle handle) { - ui_instance *instance = (ui_instance *)handle; - plugin_ui_free(instance->ui); - free(instance->bundle_path); - free(instance); -} - -# if DATA_PRODUCT_CONTROL_INPUTS_N + DATA_PRODUCT_CONTROL_OUTPUTS_N > 0 -static void ui_port_event(LV2UI_Handle handle, uint32_t port_index, uint32_t buffer_size, uint32_t format, const void * buffer) { - (void)buffer_size; - (void)format; - - ui_instance *instance = (ui_instance *)handle; -# if DATA_PRODUCT_CONTROL_INPUTS_N > 0 - if (port_index < CONTROL_OUTPUT_INDEX_OFFSET) { - size_t index = port_index - CONTROL_INPUT_INDEX_OFFSET; - plugin_ui_set_parameter(instance->ui, param_data[index].index, adjust_param(index, *((float *)buffer))); - } -# endif -# if DATA_PRODUCT_CONTROL_OUTPUTS_N > 0 -# if DATA_PRODUCT_CONTROL_INPUTS_N > 0 - else -# endif - plugin_ui_set_parameter(instance->ui, param_out_index[port_index - CONTROL_OUTPUT_INDEX_OFFSET], *((float *)buffer)); -# endif -} -# endif - -static int ui_idle(LV2UI_Handle handle) { - ui_instance *instance = (ui_instance *)handle; - plugin_ui_idle(instance->ui); - return 0; -} - -static const void * ui_extension_data(const char * uri) { - static const LV2UI_Idle_Interface idle = { ui_idle }; - if (!strcmp(uri, LV2_UI__idleInterface)) - return &idle; - return NULL; -} - -static const LV2UI_Descriptor ui_descriptor = { - /* .URI = */ DATA_LV2_UI_URI, - /* .instantiate = */ ui_instantiate, - /* .cleanup = */ ui_cleanup, -# if DATA_PRODUCT_CONTROL_INPUTS_N + DATA_PRODUCT_CONTROL_OUTPUTS_N > 0 - /* .port_event = */ ui_port_event, -# else - /* .port_event = */ NULL, -# endif - /* .extension_data = */ ui_extension_data -}; - -LV2_SYMBOL_EXPORT const LV2UI_Descriptor * lv2ui_descriptor(uint32_t index) { - return index == 0 ? &ui_descriptor : NULL; -} -#endif diff --git a/templates/lv2-next/tibia-index.js b/templates/lv2-next/tibia-index.js deleted file mode 100644 index f8b96af..0000000 --- a/templates/lv2-next/tibia-index.js +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Tibia - * - * Copyright (C) 2024 Orastron Srl unipersonale - * - * Tibia is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3 of the License. - * - * Tibia is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tibia. If not, see . - * - * File author: Stefano D'Angelo - */ - -var path = require("path"); -var sep = path.sep; - -module.exports = function (data, api, outputCommon, outputData) { - if (outputData) { - data.tibia.lv2 = { - prefixes: [ - { id: "atom", uri: "http://lv2plug.in/ns/ext/atom#" }, - { id: "doap", uri: "http://usefulinc.com/ns/doap#" }, - { id: "foaf", uri: "http://xmlns.com/foaf/0.1/" }, - { id: "log", uri: "http://lv2plug.in/ns/ext/log#" }, - { id: "lv2", uri: "http://lv2plug.in/ns/lv2core#" }, - { id: "midi", uri: "http://lv2plug.in/ns/ext/midi#" }, - { id: "patch", uri: "http://lv2plug.in/ns/ext/patch#" }, - { id: "pprops", uri: "http://lv2plug.in/ns/ext/port-props#" }, - { id: "rdf", uri: "http://www.w3.org/1999/02/22-rdf-syntax-ns#" }, - { id: "rdfs", uri: "http://www.w3.org/2000/01/rdf-schema#" }, - { id: "ui", uri: "http://lv2plug.in/ns/extensions/ui#" }, - { id: "units", uri: "http://lv2plug.in/ns/extensions/units#" }, - { id: "urid", uri: "http://lv2plug.in/ns/ext/urid#" } - ], - units: { - "bar": "@units:bar", - "beat": "@units:beat", - "bpm": "@units:bpm", - "cent": "@units:cent", - "cm": "@units:cm", - "coef": "@units:coef", - "db": "@units:db", - "degree": "@units:degree", - "frame": "@units:frame", - "hz": "@units:hz", - "inch": "@units:inch", - "khz": "@units:khz", - "km": "@units:km", - "m": "@units:m", - "mhz": "@units:mhz", - "midiNote": "@units:midiNote", - "mile": "@units:mile", - "min": "@units:min", - "mm": "@units:mm", - "ms": "@units:ms", - "oct": "@units:oct", - "pc": "@units:pc", - "s": "@units:s", - "semitone12TET": "@units:semitone12TET" - }, - ports: [], - - ttlURI: function (uri) { - if (uri.charAt(0) == "@") { - if (uri.indexOf("#") == -1) - return uri.substring(1); - uri = data.tibia.lv2.expandURI(uri); - } - return "<" + uri + ">"; - }, - - expandURI: function (uri) { - if (uri.charAt(0) != "@") - return uri; - var i = uri.indexOf(":"); - var p = uri.substring(1, uri.indexOf(":")); - return data.tibia.lv2.prefixes.find(x => x.id == p).uri + uri.substring(i + 1); - } - }; - - for (var id in data.lv2.prefixes) - data.tibia.lv2.prefixes.push({ id: id, uri: data.lv2.prefixes[id] }); - - data.tibia.lv2.prefixes.push({ id: "plugin", uri: data.tibia.lv2.expandURI(data.lv2.uri) + "#" }); - - var buses = data.product.buses; - var audioPorts = []; - var midiPorts = []; - for (var bi = 0; bi < buses.length; bi++) { - var b = buses[bi]; - if (b.type == "audio") { - if (b.channels == "mono") { - var e = { type: "audio", direction: b.direction, name: b.name, sidechain: b.sidechain, cv: b.cv, optional: b.optional, busIndex: bi, id: b.id }; - audioPorts.push(e); - } else { - var e = { type: "audio", direction: b.direction, name: b.name + " Left", shortName: b.shortName + " L", sidechain: b.sidechain, cv: b.cv, busIndex: bi, id: b.id + "_l" }; - audioPorts.push(e); - var e = { type: "audio", direction: b.direction, name: b.name + " Right", shortName: b.shortName + " R", sidechain: b.sidechain, cv: b.cv, busIndex: bi, id: b.id + "_r" }; - audioPorts.push(e); - } - } else { - var e = { type: "midi", direction: b.direction, name: b.name, sidechain: b.sidechain, control: b.control, optional: b.optional, busIndex: bi, id: b.id }; - midiPorts.push(e); - } - } - audioPorts.sort((a, b) => a.direction != b.direction ? (a.direction == "input" ? -1 : 1) : 0); - midiPorts.sort((a, b) => a.direction != b.direction ? (a.direction == "input" ? -1 : 1) : 0); - data.tibia.lv2.ports.push.apply(data.tibia.lv2.ports, audioPorts); - data.tibia.lv2.ports.push.apply(data.tibia.lv2.ports, midiPorts); - - var hasCtrlIn = false; - var hasCtrlOut = false; - for (var i = 0; i < data.product.parameters.length && !(hasCtrlIn && hasCtrlOut); i++) { - var p = data.product.parameters[i]; - if (p.direction == "input") - hasCtrlIn = true; - else - hasCtrlOut = true; - } - if (hasCtrlIn) - data.tibia.lv2.ports.push({ type: "param", direction: "input", name: "Control in", id: "control_in", control: true }); - if (hasCtrlOut) - data.tibia.lv2.ports.push({ type: "param", direction: "output", name: "Control out", id: "control_out", control: true }); - } - - api.generateFileFromTemplateFile(`data${sep}manifest.ttl.in`, `data${sep}manifest.ttl.in`, data); - api.copyFile(`src${sep}lv2.c`, `src${sep}lv2.c`); - api.generateFileFromTemplateFile(`src${sep}data.h`, `src${sep}data.h`, data); -};