lv2 mailto and better uris (no need for ui uri) + expertimental lv2-next
This commit is contained in:
parent
10896d7d5b
commit
355cc690fb
1
templates/lv2-next/README.md
Normal file
1
templates/lv2-next/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
This is experimental and broken, do not use this.
|
95
templates/lv2-next/data/manifest.ttl.in
Normal file
95
templates/lv2-next/data/manifest.ttl.in
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
{{~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 <mailto:{{=it.company.email}}> ;
|
||||||
|
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 .
|
||||||
|
{{?}}
|
78
templates/lv2-next/src/data.h
Normal file
78
templates/lv2-next/src/data.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
{{?}}
|
495
templates/lv2-next/src/lv2.c
Normal file
495
templates/lv2-next/src/lv2.c
Normal file
@ -0,0 +1,495 @@
|
|||||||
|
/*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* File author: Stefano D'Angelo
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#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 <string.h>
|
||||||
|
|
||||||
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
|
# include <xmmintrin.h>
|
||||||
|
# include <pmmintrin.h>
|
||||||
|
#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) {
|
||||||
|
ui_instance *instance = (ui_instance *)handle;
|
||||||
|
if (instance->has_touch) {
|
||||||
|
index = index_to_param[index];
|
||||||
|
instance->touch.touch(instance->touch.handle, index, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
ui_instance *instance = (ui_instance *)handle;
|
||||||
|
if (instance->has_touch) {
|
||||||
|
index = index_to_param[index];
|
||||||
|
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
|
136
templates/lv2-next/tibia-index.js
Normal file
136
templates/lv2-next/tibia-index.js
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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);
|
||||||
|
};
|
@ -15,7 +15,7 @@
|
|||||||
doap:maintainer [
|
doap:maintainer [
|
||||||
a foaf:Organization ;
|
a foaf:Organization ;
|
||||||
foaf:name "{{=it.company.name}}" ;
|
foaf:name "{{=it.company.name}}" ;
|
||||||
foaf:mbox "{{=it.company.email}}" ;
|
foaf:mbox <mailto:{{=it.company.email}}> ;
|
||||||
rdfs:seeAlso {{=it.tibia.lv2.ttlURI(it.company.url)}}
|
rdfs:seeAlso {{=it.tibia.lv2.ttlURI(it.company.url)}}
|
||||||
] ;
|
] ;
|
||||||
lv2:minorVersion {{=/^([0-9]+)\./.exec(it.lv2.version)[1]}} ;
|
lv2:minorVersion {{=/^([0-9]+)\./.exec(it.lv2.version)[1]}} ;
|
||||||
@ -25,8 +25,8 @@
|
|||||||
lv2:optionalFeature log:log ;
|
lv2:optionalFeature log:log ;
|
||||||
{{?}}
|
{{?}}
|
||||||
lv2:optionalFeature lv2:hardRTCapable ;
|
lv2:optionalFeature lv2:hardRTCapable ;
|
||||||
{{?it.lv2.ui}}
|
{{?it.product.ui}}
|
||||||
ui:ui {{=it.tibia.lv2.ttlURI(it.lv2.ui.uri)}} ;
|
ui:ui plugin:ui ;
|
||||||
{{?}}
|
{{?}}
|
||||||
lv2:port [
|
lv2:port [
|
||||||
{{~it.tibia.lv2.ports :p:i}}
|
{{~it.tibia.lv2.ports :p:i}}
|
||||||
@ -121,8 +121,8 @@
|
|||||||
{{?}}
|
{{?}}
|
||||||
{{~}}
|
{{~}}
|
||||||
|
|
||||||
{{?it.lv2.ui}}
|
{{?it.product.ui}}
|
||||||
{{=it.tibia.lv2.ttlURI(it.lv2.ui.uri)}}
|
plugin:ui
|
||||||
a ui:@UI_TYPE@ ;
|
a ui:@UI_TYPE@ ;
|
||||||
ui:binary <{{=it.product.bundleName}}@DLL_SUFFIX@> ;
|
ui:binary <{{=it.product.bundleName}}@DLL_SUFFIX@> ;
|
||||||
{{?!it.product.ui.userResizable}}
|
{{?!it.product.ui.userResizable}}
|
||||||
|
@ -65,9 +65,9 @@ static uint32_t param_out_index[DATA_PRODUCT_CONTROL_OUTPUTS_N] = {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{{?it.lv2.ui}}
|
{{?it.product.ui}}
|
||||||
#define DATA_UI
|
#define DATA_UI
|
||||||
#define DATA_LV2_UI_URI "{{=it.tibia.CGetUTF8StringLiteral(it.tibia.lv2.expandURI(it.lv2.ui.uri))}}"
|
#define DATA_LV2_UI_URI "{{=it.tibia.CGetUTF8StringLiteral(it.tibia.lv2.expandURI(it.lv2.uri + '#ui'))}}"
|
||||||
#define DATA_UI_USER_RESIZABLE {{=it.product.ui.userResizable ? 1 : 0}}
|
#define DATA_UI_USER_RESIZABLE {{=it.product.ui.userResizable ? 1 : 0}}
|
||||||
|
|
||||||
#if DATA_PRODUCT_CONTROL_INPUTS_N > 0
|
#if DATA_PRODUCT_CONTROL_INPUTS_N > 0
|
||||||
|
@ -67,7 +67,12 @@ module.exports = function (data, api, outputCommon, outputData) {
|
|||||||
ports: [],
|
ports: [],
|
||||||
|
|
||||||
ttlURI: function (uri) {
|
ttlURI: function (uri) {
|
||||||
return uri.charAt(0) == "@" ? uri.substring(1) : "<" + uri + ">";
|
if (uri.charAt(0) == "@") {
|
||||||
|
if (uri.indexOf("#") == -1)
|
||||||
|
return uri.substring(1);
|
||||||
|
uri = data.tibia.lv2.expandURI(uri);
|
||||||
|
}
|
||||||
|
return "<" + uri + ">";
|
||||||
},
|
},
|
||||||
|
|
||||||
expandURI: function (uri) {
|
expandURI: function (uri) {
|
||||||
@ -82,6 +87,8 @@ module.exports = function (data, api, outputCommon, outputData) {
|
|||||||
for (var id in data.lv2.prefixes)
|
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: 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 buses = data.product.buses;
|
||||||
var audioPorts = [];
|
var audioPorts = [];
|
||||||
var midiPorts = [];
|
var midiPorts = [];
|
||||||
|
@ -6,9 +6,6 @@
|
|||||||
"uri": "@example:tibia_test",
|
"uri": "@example:tibia_test",
|
||||||
"project": "@example:project",
|
"project": "@example:project",
|
||||||
"types": [ "@lv2:AmplifierPlugin" ],
|
"types": [ "@lv2:AmplifierPlugin" ],
|
||||||
"version": "1.0",
|
"version": "1.0"
|
||||||
"ui": {
|
|
||||||
"uri": "@example:tibia_test_ui"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user