From 824c5f54d8a8a7d206172e7cf158b89ed745ef1f Mon Sep 17 00:00:00 2001 From: Stefano D'Angelo Date: Tue, 2 Jan 2024 18:38:46 +0100 Subject: [PATCH] beginning of lv2 --- TODO | 5 ++- templates/lv2/.tibia-index.js.swp | Bin 0 -> 12288 bytes templates/lv2/data/manifest.ttl | 31 ++++++++++++++ templates/lv2/src/data.h | 1 + templates/lv2/src/lv2.c | 19 +++++++++ templates/lv2/src/plugin.h | 28 +++++++++++++ templates/lv2/tibia-index.js | 63 +++++++++++++++++++++++++++++ templates/vst3/.tibia-index.js.swp | Bin 0 -> 12288 bytes templates/vst3/src/.data.h.swp | Bin 0 -> 16384 bytes templates/vst3/src/data.h | 2 +- test/company.json | 6 +-- test/lv2.json | 10 +++++ test/run.sh | 3 +- 13 files changed, 162 insertions(+), 6 deletions(-) create mode 100644 templates/lv2/.tibia-index.js.swp create mode 100644 templates/lv2/data/manifest.ttl create mode 100644 templates/lv2/src/data.h create mode 100644 templates/lv2/src/lv2.c create mode 100644 templates/lv2/src/plugin.h create mode 100644 templates/lv2/tibia-index.js create mode 100644 templates/vst3/.tibia-index.js.swp create mode 100644 templates/vst3/src/.data.h.swp create mode 100644 test/lv2.json 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 0000000000000000000000000000000000000000..b8c0902eb854e755a975e91323ebf04469693ef3 GIT binary patch literal 12288 zcmeI2KWrRD6viiM$OQt3e-fgZtdX)O-_4#c4L-+l0L7A}kO)H3SO)Li&E8G4x4Z1l z=FS+0285uXfd(Q`01_1v6%>?oDFQVGNGK&pbTmltz1cmV?_wJ%UBs;P-R{i1dGqEs zZ+2yQ+KsDgFY!guV7MM-?DpEn^5*4R?8|_$Ov}KJVrn_`3geC+_Tx+o^VE$8zKZtg zaietTr80>#Pph`_JuL@G=xdpI;q_)wS65M2j>NTWA0M{L60ijBfk3W<`g14P>E?pj z>T}LX{`g~8?!l4mVhLCRmVhN-30MM_fF)oFSOWJe0i7ISZzK4lzt6&^OQr&?)FB^xJX9euaL4K7p=5FGDVLr^46| z(C5%+&`s!5Xc;;VeUJGMA>!~3G=c_@4_$`NL-w)+ECEZv60ijR?*w+Ht|eCS6D2xv zvbCyq4lI=|(*~hj3ogd`{77Xwb2qcJ^Xzselbs~YdnywB%^KgQvRV$(laWkud~j8T zay5+yua?INsl3No*Vq1xtKBMk7`rQGFx3^u5=Cb!h@xiPjE7ZrSjDJ9HNqU16f|}cr#cf!p7mWxQB*2YWLtxF9P(w}llroGcH1KI2c^Mv zKjjjw+gxuYvc(-g@2c3T@vcf`N2@q$@wV74)HrpeD!Ox8uu2f8+$BHP;HR;K+ZnWX z`hFD2FhhBMzRI^@NH%TQm?2)sGnuWc4S3jfpb7^H4kk7tlu=Ljm$)kZkef*}x)=&c z8h7)K7H#q?0u^eRx+A`PmX8EYjV~{cCkHeI!~ep!FTF%$eQ>@wMtB#&P8{hp4yPF= zcQZ^3Ly*Q{+C0=({V)ev815+-glULmcA|-&A_UCx5QufMtB^=jOC-Ju)~^2ns&p8O?GWnm(`HMwOq$?l|XEF|ZsZe$>74%36!>vL|CAPSdSXa1(!fe9#U%=kS%; zkgFW;l`~E;S^PR@9f|_4y8}ltZ?YC&-=NXVPo-EoC+!9qwiW_{)4tY8%kzfAp%|VP zaoY2mjYh+3EO;=hXPv$r_;U_7OEl?!NcV-s#YL~t^qS4O@vs$Xe^ie$a$+W4dO;@4 zdO;O^nE>C5%$fC0oXXjL-PliNJK}{E_)HF{FBy$HCS_uR1)E82N_jTGTQ8IX wi$?E$R87{5lCj3|`86wN_KKv0N_^cH_>e9!^Iky-m8pCq#~a^usFgO}zjw62s{jB1 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..1e557514b52d68b7e6fd6177a644f269be4688fa GIT binary patch literal 12288 zcmeI2!EO^V5QZn5sGxw_Q*S14NTlEtda9}(sgy%|fpU(s>uucbuFcx1f~wM6pP-LW zi6`OG3p@n82jgTLLEol>nS=A009sH0T2KI5C8!X009sH0T2LzB_yCyqOYq&D^J)w|Nnpc`~SyN zqVF8vIKFTkaBOhg@VZNmLypHBQTLDo4Fo^{1V8`;KmY_l00ck)1VCU(2%PWGigHFC z=~7pGAA8T_dats@`}%%%oVWUgI?*rBymsfOs`9cp>32l`_b^pKwd+EOb)V)%`z+76 zP*lyv^MYP>V8h$7@xizHzDlO=bNT4VlyVrQeN5Gm zMVY}T7#><^G2enK5`!z11j0Ir)3h|0;y9+VNNg)!2UTsgtnEp%VzX=Qj-v$E zMQ{L#GhDdvp(0ccAOr#mQZH~oTo4ix5=i_5;0P5U@yvSHSv&qrid3Yr^knVbnRniK z=AEx+Hl@jx%o2S}nI!n!L&zT!udz1^-;%EwAueaDx@C(eeLtpM*3EU><%;*MVsGe% z)g{M8-(bvPRojhmqh#nY&Niy1&Y2tAba_1HI^|eJ=en}q#elpe8ITO@gMm9qe0s|3 z>PMmv();c$?!%VMDjARrNCqSWk^#wpWI!??8ITP8-x%Q41LOrbeZY78G5>l~$MvB9 z`-Fcz+40=}DKC-%$$(@)G9Vd{3`hnf1CjyBfMh^2AQ_Mh+<*+|6+)hbUyq9oKhFPy z{r}~=2`K>A?jqz*;BDX-Faun=laSx;Ammrz3J?Pn;Fa46c^Q}ke!q>7cYq?G0tbK( zBZQm<4g-e(<5ogGKTODHzy+WV{Cx=Dfq!lxqybz2RN&gpguDk_0ycm+a2xOego#Dq z8weO*16P4Bflq*sfmeY?fuB&nAAz?328jC30sHwxBC&_5QeM|Bi97VvIN&E!e6=%&ab{P5xd z1cX}3^Fps}bulPXc`dfpqeMT!65giq3J9XX(l>%Ys3X`eCLKrLR#qK*W2~fzhiI;H zqcI7)iLwYpCuLVyl8;S}E8H${$FSDMre?sLMWI*}8vytml zzEA%!#kY?SqZB`QC>y@~y;Q$<`Mav$PX9_ljcbMCd@8A?Pv@4;L?V%Bv)RRaaf(|j zrSO*An(b^i8d33Xo;MViZOaXh#A-3KK*jrW{*Y!eCxtr+T3Av~Ynkj~CY#ofX3QID zy)sj|th$_ATud)(NUBXuG{dpmv*|w1;(eaYjL!{pIB(Y03~P|H{w%V~(a`-iCqwt! z91PtT&UI;u4q9d+5pO(2H}u*A#EU5d{3>OmBAN%Yq8L}FXC`QT8e{8VoAF_7PR&lx z>6xKyP7iDI#02%GfWdA~4Qq08f}Rjgb}<>|85oin<1BF8v>&IWn7`Pk4 zSRdj-wm{ktwpxt&-FauJB4+KWS+6ULp19MUvzXtXIXgS!Et)!J|Ii#EmI3q;8l^iq zqvMKe8f7+yQfK3PSRL{j=VWbl>X{qGJF4 zv~!cYqGG0NU!(YCWs^&3(Z8Yw>xbxdp-GxrNv-lNyXkK?PUtcNn)Y5#XwpKUMYTJF z3+D#CPiO|Kx_djJ>7{D7>(BiTXxdYbazL{yEM#Co&Bb}t-VRHyb6ojy^~ho6xzRtY UhBz!~MpgS^i9GfD4@Ss;0TQ`y*Z=?k literal 0 HcmV?d00001 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