beginning of lv2

This commit is contained in:
Stefano D'Angelo 2024-01-02 18:38:46 +01:00
parent e00ac8003b
commit 824c5f54d8
13 changed files with 162 additions and 6 deletions

5
TODO
View File

@ -4,5 +4,8 @@
* type audio + sidechain + cv... to think about
* check all return codes and algos wrt official impl
* escape string and max lengths
* printf -> trace
* EXPORT symbols, visibility hidden
* vst3: IEditController2, IUnitInfo, IConnectionPoint
* lv2: RDF/Turtle escape etc
* lv2: extra data, see also - should use plugin.ttl?
* lv2: i18n?

Binary file not shown.

View File

@ -0,0 +1,31 @@
{{~it.tibia.lv2.prefixes :p}}
@prefix {{=p.id}}: <{{=p.uri}}> .
{{~}}
{{=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}}.so> ;
doap:name "{{=it.product.name}}" ;
lv2:optionalFeature lv2:hardRTCapable ;
lv2:port [
{{~it.tibia.lv2.ports :p:i}}
a {{?p.type == "control"}}lv2:ControlPort{{??}}lv2:AudioPort{{?}} ,
{{?p.direction == "input"}}lv2:InputPort{{??}}lv2:OutputPort{{?}} ;
lv2:name "{{=p.name}}" ;
lv2:symbol "{{=p.symbol}}" ;
{{?p.defaultValue}}
lv2:default {{=p.defaultValue.toExponential()}} ;
{{?}}
lv2:index {{=i}}
{{?i < it.tibia.lv2.ports.length - 1}}
] , [
{{??}}
] .
{{?}}
{{~}}

1
templates/lv2/src/data.h Normal file
View File

@ -0,0 +1 @@
#define DATA_LV2_URI "{{=it.tibia.CGetUTF8StringLiteral(it.tibia.lv2.expandURI(it.lv2.uri))}}"

19
templates/lv2/src/lv2.c Normal file
View File

@ -0,0 +1,19 @@
#include "lv2/core/lv2.h"
#include "data.h"
#include "plugin.h"
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;
}

View File

@ -0,0 +1,28 @@
typedef struct plugin {
// FILL ME
char abc;
} plugin;
void plugin_init(plugin *instance) {
// WRITE ME
}
void plugin_fini(plugin *instance) {
// WRITE ME
}
void plugin_set_sample_rate(plugin *instance, float sample_rate) {
// WRITE ME
}
void plugin_reset(plugin *instance) {
// WRITE ME
}
void plugin_set_parameter(plugin *instance, size_t index, float value) {
// WRITE ME
}
void plugin_process(plugin *instance, const float **inputs, float **outputs, size_t n_samples) {
// WRITE ME
}

View File

@ -0,0 +1,63 @@
var path = require("path");
var sep = path.sep;
module.exports = function (data, api) {
data.tibia.lv2 = {
prefixes: [
{ id: "doap", uri: "http://usefulinc.com/ns/doap#" },
{ id: "lv2", uri: "http://lv2plug.in/ns/lv2core#" },
{ id: "rdf", uri: "http://www.w3.org/1999/02/22-rdf-syntax-ns#" },
{ id: "rdfs", uri: "http://www.w3.org/2000/01/rdf-schema#" }
],
ports: [],
ttlURI: function (uri) {
return uri.charAt(0) == "@" ? uri.substring(1) : "<" + 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] });
var symbols = {};
function getSymbol(name) {
name = name.toLowerCase().replace(/[^0-9a-z]/g, "_");
var n = name;
var i = 1;
while (n in symbols) {
n = name + i;
i++;
}
return n;
}
for (var i = 0; i < data.product.parameters.length; i++) {
var p = data.product.parameters[i];
var e = { type: "control", direction: p.direction, name: p.name, defaultValue: p.defaultValue };
e.symbol = getSymbol(p.shortName);
data.tibia.lv2.ports.push(e);
}
var audioBuses = data.product.buses.filter(x => x.type == "audio");
for (var i = 0; i < audioBuses.length; i++) {
var b = audioBuses[i];
for (var j = 0; j < b.channels; j++) {
var e = { type: "audio", direction: b.direction, name: b.name };
e.symbol = getSymbol(b.name);
data.tibia.lv2.ports.push(e);
}
}
api.generateFileFromTemplateFile(`data${sep}manifest.ttl`, `data${sep}manifest.ttl`, data);
api.copyFile(`src${sep}lv2.c`, `src${sep}lv2.c`);
api.generateFileFromTemplateFile(`src${sep}data.h`, `src${sep}data.h`, data);
api.copyFileIfNotExists(`src${sep}plugin.h`, `src${sep}plugin.h`);
};

Binary file not shown.

Binary file not shown.

View File

@ -104,7 +104,7 @@ static struct Steinberg_Vst_ParameterInfo parameterInfo[DATA_PLUGIN_PARAMETERS_N
/* .shortTitle = */ { {{~Array.from(p.shortName) :c}}0x{{=c.charCodeAt(0).toString(16)}}, {{~}}0 },
/* .units = */ { {{~Array.from(p.units) :c}}0x{{=c.charCodeAt(0).toString(16)}}, {{~}}0 },
/* .stepCount = */ {{=p.steps}},
/* .defaultNormalizedValue = */ {{=p.defaultValue}},
/* .defaultNormalizedValue = */ {{=p.defaultValue.toExponential()}},
/* .unitId = */ 0,
/* .flags = */ {{?p.isBypass}}Steinberg_Vst_ParameterInfo_ParameterFlags_kIsBypass | {{?}}{{?p.direction == "input"}}Steinberg_Vst_ParameterInfo_ParameterFlags_kCanAutomate{{??}}Steinberg_Vst_ParameterInfo_ParameterFlags_kIsReadOnly{{?}}
},

View File

@ -1,7 +1,7 @@
{
"company": {
"name": "Orastron",
"url": "https://www.orastron.com",
"email": "info@orastron.com"
"name": "Example company",
"url": "https://www.example.com/",
"email": "info@example.com"
}
}

10
test/lv2.json Normal file
View File

@ -0,0 +1,10 @@
{
"lv2": {
"prefixes": {
"example": "https://www.example.com/"
},
"uri": "@example:tibia_test",
"project": "@example:project",
"types": [ "@lv2:AmplifierPlugin" ]
}
}

View File

@ -1,4 +1,5 @@
#!/bin/sh
dir=`dirname $0`
$dir/../tibia $dir/product.json,$dir/company.json,$dir/vst3.json $dir/../templates/vst3 $dir/../out
$dir/../tibia $dir/product.json,$dir/company.json,$dir/vst3.json $dir/../templates/vst3 $dir/../out/vst3
$dir/../tibia $dir/product.json,$dir/company.json,$dir/lv2.json $dir/../templates/lv2 $dir/../out/lv2