diff --git a/TODO b/TODO index 76c44ef..94b8acb 100644 --- a/TODO +++ b/TODO @@ -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? diff --git a/templates/lv2/.tibia-index.js.swp b/templates/lv2/.tibia-index.js.swp new file mode 100644 index 0000000..b8c0902 Binary files /dev/null and b/templates/lv2/.tibia-index.js.swp differ diff --git a/templates/lv2/data/manifest.ttl b/templates/lv2/data/manifest.ttl new file mode 100644 index 0000000..7d5670d --- /dev/null +++ b/templates/lv2/data/manifest.ttl @@ -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}} + ] , [ +{{??}} + ] . +{{?}} +{{~}} diff --git a/templates/lv2/src/data.h b/templates/lv2/src/data.h new file mode 100644 index 0000000..75360a0 --- /dev/null +++ b/templates/lv2/src/data.h @@ -0,0 +1 @@ +#define DATA_LV2_URI "{{=it.tibia.CGetUTF8StringLiteral(it.tibia.lv2.expandURI(it.lv2.uri))}}" diff --git a/templates/lv2/src/lv2.c b/templates/lv2/src/lv2.c new file mode 100644 index 0000000..bbe4bdb --- /dev/null +++ b/templates/lv2/src/lv2.c @@ -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; +} diff --git a/templates/lv2/src/plugin.h b/templates/lv2/src/plugin.h new file mode 100644 index 0000000..e7f186b --- /dev/null +++ b/templates/lv2/src/plugin.h @@ -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 +} diff --git a/templates/lv2/tibia-index.js b/templates/lv2/tibia-index.js new file mode 100644 index 0000000..00c374f --- /dev/null +++ b/templates/lv2/tibia-index.js @@ -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`); +}; diff --git a/templates/vst3/.tibia-index.js.swp b/templates/vst3/.tibia-index.js.swp new file mode 100644 index 0000000..1e55751 Binary files /dev/null and b/templates/vst3/.tibia-index.js.swp differ diff --git a/templates/vst3/src/.data.h.swp b/templates/vst3/src/.data.h.swp new file mode 100644 index 0000000..3b28983 Binary files /dev/null and b/templates/vst3/src/.data.h.swp differ diff --git a/templates/vst3/src/data.h b/templates/vst3/src/data.h index 793d3b5..e9aec18 100644 --- a/templates/vst3/src/data.h +++ b/templates/vst3/src/data.h @@ -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{{?}} }, diff --git a/test/company.json b/test/company.json index 6a3f64b..32f0f2e 100644 --- a/test/company.json +++ b/test/company.json @@ -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" } } diff --git a/test/lv2.json b/test/lv2.json new file mode 100644 index 0000000..994c838 --- /dev/null +++ b/test/lv2.json @@ -0,0 +1,10 @@ +{ + "lv2": { + "prefixes": { + "example": "https://www.example.com/" + }, + "uri": "@example:tibia_test", + "project": "@example:project", + "types": [ "@lv2:AmplifierPlugin" ] + } +} diff --git a/test/run.sh b/test/run.sh index 8ec5f68..e3dcb9b 100755 --- a/test/run.sh +++ b/test/run.sh @@ -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