diff --git a/templates/lv2/src/data.h b/templates/lv2/src/data.h index e6e16f5..ec84ceb 100644 --- a/templates/lv2/src/data.h +++ b/templates/lv2/src/data.h @@ -24,7 +24,7 @@ static struct { /* .min = */ {{=p.minimum.toExponential()}}f, /* .max = */ {{=p.maximum.toExponential()}}f, /* .def = */ {{=p.defaultValue.toExponential()}}f, - /* .flags = */ 0{{?p.isBypass}} | DATA_PARAM_BYPASS{{?}}{{?p.toggled}} | DATA_PARAM_TOGGLED{{?}}{{?p.integer}} | DATA_PARAM_INTEGER{{?}} + /* .flags = */ {{?p.isBypass}}DATA_PARAM_BYPASS{{??p.isLatency}}DATA_PARAM_INTEGER{{??}}0{{?p.toggled}} | DATA_PARAM_TOGGLED{{?}}{{?p.integer}} | DATA_PARAM_INTEGER{{?}}{{?}} }, {{~}} }; diff --git a/templates/lv2/tibia-index.js b/templates/lv2/tibia-index.js index 548bb51..f888b34 100644 --- a/templates/lv2/tibia-index.js +++ b/templates/lv2/tibia-index.js @@ -4,13 +4,39 @@ var sep = path.sep; module.exports = function (data, api) { data.tibia.lv2 = { prefixes: [ - { id: "doap", uri: "http://usefulinc.com/ns/doap#" }, - { id: "foaf", uri: "http://xmlns.com/foaf/0.1/" }, - { 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#" }, - { id: "units", uri: "http://lv2plug.in/ns/extensions/units#" } + { id: "doap", uri: "http://usefulinc.com/ns/doap#" }, + { id: "foaf", uri: "http://xmlns.com/foaf/0.1/" }, + { 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#" }, + { id: "units", uri: "http://lv2plug.in/ns/extensions/units#" } ], + 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) { @@ -50,32 +76,6 @@ module.exports = function (data, api) { data.tibia.lv2.ports.sort((a, b) => a.type != b.type ? (a.type == "audio" ? -1 : 1) : (a.direction != b.direction ? (a.direction == "input" ? -1 : 1) : 0)); - data.tibia.lv2.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" - }; api.generateFileFromTemplateFile(`data${sep}manifest.ttl`, `data${sep}manifest.ttl`, data); api.copyFile(`src${sep}lv2.c`, `src${sep}lv2.c`); diff --git a/templates/vst3/src/data.h b/templates/vst3/src/data.h index 6761a52..f9634c1 100644 --- a/templates/vst3/src/data.h +++ b/templates/vst3/src/data.h @@ -8,8 +8,8 @@ static Steinberg_char16 dataProductNameW[64] = { {{~Array.from(it.product.name).slice(0, 63) :c}}0x{{=c.charCodeAt(0).toString(16)}}, {{~}}0 }; static Steinberg_char16 dataProductVersionW[64] = { {{~Array.from(it.product.version + "." + it.product.buildVersion).slice(0, 63) :c}}0x{{=c.charCodeAt(0).toString(16)}}, {{~}}0 }; -#define DATA_VST3_SDK_VERSION "VST 3.7.4 | Tibia" -static Steinberg_char16 dataVST3SDKVersionW[64] = { {{~Array.from("VST 3.7.4 | Tibia") :c}}0x{{=c.charCodeAt(0).toString(16)}}, {{~}}0 }; +#define DATA_VST3_SDK_VERSION "VST 3.7.9" +static Steinberg_char16 dataVST3SDKVersionW[64] = { {{~Array.from("VST 3.7.9") :c}}0x{{=c.charCodeAt(0).toString(16)}}, {{~}}0 }; static Steinberg_char16 dataVST3ControllerNameW[64] = { {{~Array.from(it.product.name + " Controller").slice(0, 63) :c}}0x{{=c.charCodeAt(0).toString(16)}}, {{~}}0 }; @@ -93,21 +93,56 @@ static struct Steinberg_Vst_BusInfo busInfoAudioInput[DATA_PRODUCT_BUSES_EVENT_O }; #endif -#define DATA_PRODUCT_PARAMETERS_N {{=it.product.parameters.length}} +#define DATA_PRODUCT_PARAMETERS_N {{=it.product.parameters.filter(x => !x.isLatency).length}} #if DATA_PRODUCT_PARAMETERS_N > 0 static struct Steinberg_Vst_ParameterInfo parameterInfo[DATA_PRODUCT_PARAMETERS_N] = { -{{~it.product.parameters :p:i}} +{{~it.product.parameters.filter(x => !x.isLatency) :p:i}} { /* .id = */ {{=i}}, +{{?p.isBypass}} + /* .title = */ { {{~Array.from("Bypass") :c}}0x{{=c.charCodeAt(0).toString(16)}}, {{~}}0 }, + /* .shortTitle = */ { {{~Array.from("Bypass") :c}}0x{{=c.charCodeAt(0).toString(16)}}, {{~}}0 }, + /* .units = */ { 0 }, + /* .stepCount = */ 1, + /* .defaultNormalizedValue = */ 0.0, + /* .unitId = */ 0, + /* .flags = */ Steinberg_Vst_ParameterInfo_ParameterFlags_kIsBypass | Steinberg_Vst_ParameterInfo_ParameterFlags_kCanAutomate +{{??}} /* .title = */ { {{~Array.from(p.name) :c}}0x{{=c.charCodeAt(0).toString(16)}}, {{~}}0 }, /* .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.toExponential()}}, + /* .units = */ { {{~Array.from(p.unit in it.tibia.vst3.units ? it.tibia.vst3.units[p.unit] : "") :c}}0x{{=c.charCodeAt(0).toString(16)}}, {{~}}0 }, + /* .stepCount = */ {{?p.toggled}}1{{??p.list && p.scalePoints.length > 1}}Number(1 / (p.scalePoints.length - 1)).toExponential(){{??p.integer && "maximum" in p && "minimum" in p}}Number(p.maximum - p.minimum).toExponential(){{??}}0{{?}}, + /* .defaultNormalizedValue = */ {{="defaultValue" in p && "maximum" in p && "minimum" in p ? Number((p.defaultValue - p.minimum) / (p.maximum - p.minimum)).toExponential() : 0.0}}, /* .unitId = */ 0, - /* .flags = */ {{?p.isBypass}}Steinberg_Vst_ParameterInfo_ParameterFlags_kIsBypass | {{?}}{{?p.direction == "input"}}Steinberg_Vst_ParameterInfo_ParameterFlags_kCanAutomate{{??}}Steinberg_Vst_ParameterInfo_ParameterFlags_kIsReadOnly{{?}} + /* .flags = */ {{?p.direction == "input"}}Steinberg_Vst_ParameterInfo_ParameterFlags_kCanAutomate{{??}}Steinberg_Vst_ParameterInfo_ParameterFlags_kIsReadOnly{{?}} +{{?}} + }, +{{~}} +}; + +# define DATA_PARAM_BYPASS 1 +# define DATA_PARAM_TOGGLED (1<<1) +# define DATA_PARAM_INTEGER (1<<2) + +static struct { + size_t index; + double min; + double max; + uint32_t flags; + // scalePoints? +} parameterData[DATA_PRODUCT_PARAMETERS_N] = { +{{~it.product.parameters.filter(x => !x.isLatency) :p:i}} + { + /* .index = */ {{=p.paramIndex}}, + /* .min = */ {{="minimum" in p ? p.minimum.toExponential() : 0.0}}, + /* .max = */ {{="maximum" in p ? p.maximum.toExponential() : 0.0}}, + /* .flags = */ {{?p.isBypass}}DATA_PARAM_BYPASS{{??}}0{{?p.toggled}} | DATA_PARAM_TOGGLED{{?}}{{?p.integer}} | DATA_PARAM_INTEGER{{?}}{{?}} }, {{~}} }; #endif + +{{?it.product.parameters.find(x => x.isLatency)}} +# define DATA_PARAM_LATENCY_INDEX {{=it.product.parameters.find(x => x.isLatency).paramIndex}} +{{?}} diff --git a/templates/vst3/src/vst3.c b/templates/vst3/src/vst3.c index 78bdb17..1a6c23f 100644 --- a/templates/vst3/src/vst3.c +++ b/templates/vst3/src/vst3.c @@ -762,7 +762,7 @@ static Steinberg_tresult factoryCreateInstance(void *thisInterface, Steinberg_FI TRACE("createInstance\n"); if (memcmp(cid, dataPluginCID, sizeof(Steinberg_TUID)) == 0) { TRACE(" plugin\n"); - size_t offset; // FIXME: does it actually work like this? or is offset always 0? + size_t offset; // does it actually work like this? or is offset always 0? this seems to be correct and works... if ((memcmp(iid, Steinberg_FUnknown_iid, sizeof(Steinberg_TUID)) == 0) || (memcmp(iid, Steinberg_IPluginBase_iid, sizeof(Steinberg_TUID)) != 0) || (memcmp(iid, Steinberg_Vst_IComponent_iid, sizeof(Steinberg_TUID)) != 0)) { @@ -883,6 +883,7 @@ static Steinberg_tresult factoryGetClassInfoUnicode(void* thisInterface, Steinbe static Steinberg_tresult factorySetHostContext(void* thisInterface, struct Steinberg_FUnknown* context) { TRACE("factory set host context\n"); + //XXX: Linux run loop... return Steinberg_kNotImplemented; } diff --git a/templates/vst3/tibia-index.js b/templates/vst3/tibia-index.js index d5ad8cf..a9a3a66 100644 --- a/templates/vst3/tibia-index.js +++ b/templates/vst3/tibia-index.js @@ -2,6 +2,38 @@ var path = require("path"); var sep = path.sep; module.exports = function (data, api) { + data.tibia.vst3 = { + units: { + "bar": "bars", + "beat": "beats", + "bpm": "BPM", + "cent": "ct", + "cm": "cm", + "coef": "", + "db": "dB", + "degree": "deg", + "frame": "frames", + "hz": "Hz", + "inch": "\"", + "khz": "kHz", + "km": "km", + "m": "m", + "mhz": "MHz", + "midiNote": "MIDI note", + "mile": "mi", + "min": "mins", + "mm": "mm", + "ms": "ms", + "oct": "octaves", + "pc": "%", + "s": "s", + "semitone12TET": "semi" + } + }; + + for (var i = 0; i < data.product.parameters.length; i++) + data.product.parameters[i].paramIndex = i; + api.generateFileFromTemplateFile(`data${sep}Info.plist`, `data${sep}Info.plist`, data); api.copyFile(`src${sep}vst3.c`, `src${sep}vst3.c`); api.generateFileFromTemplateFile(`src${sep}data.h`, `src${sep}data.h`, data); diff --git a/test/product.json b/test/product.json index 1caef84..40bab97 100644 --- a/test/product.json +++ b/test/product.json @@ -30,8 +30,6 @@ { "name": "Gain", "shortName": "Gain", - "units": "dB", - "steps": 0, "direction": "input", "isBypass": false, "isLatency": false, @@ -52,8 +50,6 @@ { "name": "Bypass", "shortName": "Bypass", - "units": "", - "steps": 1, "direction": "input", "isBypass": true, "isLatency": false, @@ -67,7 +63,8 @@ "Off": 0, "On": 1 }, - "list": true + "list": true, + "unit": "" } ] }