more vst + update nots

This commit is contained in:
Stefano D'Angelo 2024-01-11 06:54:34 +01:00
parent 44fa0d9881
commit 468826463b
8 changed files with 95 additions and 20 deletions

1
TODO
View File

@ -11,3 +11,4 @@
* lv2: i18n?
* #if > 0 -> dotjs
* more mappings, lv2 port props
* latency mechanism, see https://steinbergmedia.github.io/vst3_dev_portal/pages/Technical+Documentation/Workflow+Diagrams/Get+Latency+Call+Sequence.html, https://steinbergmedia.github.io/vst3_doc/vstinterfaces/classSteinberg_1_1Vst_1_1IAudioProcessor.html#af8884671ccefe68e0a86e72413a0fcf8, https://steinbergmedia.github.io/vst3_dev_portal/pages/Technical+Documentation/Workflow+Diagrams/Audio+Processor+Call+Sequence.html

63
notes
View File

@ -23,4 +23,67 @@ product {
bundleName:
VST3: plugin folder name, plugin .dll name, Info.plist
LV2: plugin folder name, plugin .dll name, manifest.ttl plugin lv2:binary
buses: ...
parameters: [
{
name:
parameter name string, required
VST3: ParameterInfo title
LV2: manifest.ttl lv2:port lv2:name
shortName:
parameter short name string, required
VST3: ParameterInfo shortTitle
LV2: manifest.ttl lv2:port lv2:shortName
direction:
"input" or "output", required
VST3: ParameterInfo flags
LV2: manifest.ttl lv2:port a
isBypass:
parameter is bypass/enabled? boolean - lots of implications, default false
VST3: ParameterInfo, controller get/set parameter/state
LV2: manifest.ttl lv2:port, run() (set parameter)
isLatency:
parameter is latency output? boolean - lots of implications, default false
VST3: TBD
LV2: manifest.ttl lv2:port, run() (set parameter)
defaultValue:
default value, number, mapped, required for non-bypass input
VST3: ParameterInfo defaultNormalizedValue, controller initialize
LV2: manifest.ttl lv2:port lv2:default, activate() (set initial parameter)
minimum:
minimum value, number, mapped, required for non-bypass input
VST3: ParameterInfo stepCount, defaultNormalizedValue, controller get/set parameter (value clamped)
LV2: manifest.ttl lv2:port lv2:minimum, run() (set parameter, value clamped)
LV2:
maximum:
maximum value, number, mapped, required for non-bypass input
VST3: ParameterInfo stepCount, defaultNormalizedValue, controller get/set parameter (value clamped)
LV2: manifest.ttl lv2:port lv2:maximum, run() (set parameter, value clamped)
toggled:
parameter is on/off? boolean, default false
VST3: ParameterInfo stepCount, controller set parameter/state
LV2: manifest.ttl lv2:port lv2:portProperty lv2:toggled, run() (set parameter)
optional:
parameter is optionally connected? boolean, default false
VST3: not used
LV2: manifest.ttl lv2:port lv2:portProperty lv2:connectionOptional
integer:
parameter values are integers? boolean, default false
VST3: ParameterInfo stepCount, controller set parameter/state
LV2: manifest.ttl lv2:port lv2:portProperty lv2:integer, run() (set parameter)
scalePoints:
{ "label1": value1, "label2", value2, ... }
labeled values, default none
VST3: TBD
LV2: manifest.ttl lv2:port lv2:scalePoint
list:
parameter is a list (using scalePoints values)? default false
VST3: TBD
LV2: manifest.ttl lv2:port lv2:enumeration - run() (set parameter) TBD?
unit:
unit of measure (from predefined list, see tibia-index.js), default ""
VST3: ParameterInfo units
LV2: manifest.ttl lv2:port units:unit
}
]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -9,7 +9,6 @@
// https://github.com/rubberduck-vba/Rubberduck/wiki/COM-in-plain-C
// https://devblogs.microsoft.com/oldnewthing/20040205-00/?p=40733
#ifdef NDEBUG
# define TRACE(...) /* do nothing */
#else
@ -256,6 +255,7 @@ static Steinberg_tresult pluginSetState(void* thisInterface, struct Steinberg_I
if (IS_BIG_ENDIAN)
v.u = SWAP_UINT32(v.u);
p->parameters[i] = v.f;
//XXX
plugin_set_parameter(&p->p, i, v.f);
}
#endif
@ -360,6 +360,7 @@ static Steinberg_tresult pluginSetProcessing(void* thisInterface, Steinberg_TBoo
static Steinberg_tresult pluginProcess(void* thisInterface, struct Steinberg_Vst_ProcessData* data) {
TRACE("plugin IAudioProcessor process\n");
//TBD
// IComponentHandler::restartComponent (kLatencyChanged), see https://steinbergmedia.github.io/vst3_dev_portal/pages/Technical+Documentation/Workflow+Diagrams/Get+Latency+Call+Sequence.html
return Steinberg_kResultOk;
}
@ -481,6 +482,24 @@ static Steinberg_tresult controllerTerminate(void* thisInterface) {
return Steinberg_kResultOk;
}
static double clamp(double x, double m, double M) {
return x < m ? m : (x > M ? M : x);
}
static double parameterMap(Steinberg_Vst_ParamID id, double v) {
return parameterData[id].min + (parameterData[id].max - parameterData[id].min) * v;
}
static double parameterUnmap(Steinberg_Vst_ParamID id, double v) {
return (v - parameterData[id].min) / (parameterData[id].max - parameterData[id].min);
}
static double parameterAdjust(Steinberg_Vst_ParamID id, double v) {
v = parameterData[id].flags & (DATA_PARAM_BYPASS | DATA_PARAM_TOGGLED) ? v >= 0.5 ? 1.0 : 0.0
: (parameterData[id].flags & DATA_PARAM_INTEGER ? (int32_t)(v + 0.5) : v);
return clamp(v, parameterData[id].min, parameterData[id].max);
}
static Steinberg_tresult controllerSetComponentState(void* thisInterface, struct Steinberg_IBStream* state) {
TRACE("controller set component state %p %p\n", thisInterface, (void *)state);
if (state == NULL)
@ -497,7 +516,7 @@ static Steinberg_tresult controllerSetComponentState(void* thisInterface, struct
return Steinberg_kResultFalse;
if (IS_BIG_ENDIAN)
v.u = SWAP_UINT32(v.u);
c->parameters[i] = v.f;
c->parameters[i] = parameterAdjust(i, v.f);
}
#endif
TRACE(" ok\n");
@ -569,14 +588,6 @@ static void dToStr(double v, Steinberg_Vst_String128 s, int precision) {
s[i] = '\0';
}
static double parameterMap(Steinberg_Vst_ParamID id, double v) {
return parameterData[id].min + (parameterData[id].max - parameterData[id].min) * v;
}
static double parameterUnmap(Steinberg_Vst_ParamID id, double v) {
return (v - parameterData[id].min) / (parameterData[id].max - parameterData[id].min);
}
static Steinberg_tresult controllerGetParamStringByValue(void* thisInterface, Steinberg_Vst_ParamID id, Steinberg_Vst_ParamValue valueNormalized, Steinberg_Vst_String128 string) {
TRACE("controller get param string by value\n");
if (id >= DATA_PRODUCT_PARAMETERS_N)
@ -637,7 +648,7 @@ static Steinberg_Vst_ParamValue controllerGetParamNormalized(void* thisInterface
TRACE("controller get param normalized\n");
#if DATA_PRODUCT_PARAMETERS_N > 0
controller *c = (controller *)thisInterface;
return parameterMap(id, c->parameters[id]);
return parameterUnmap(id, c->parameters[id]);
#else
return 0.0;
#endif
@ -649,7 +660,7 @@ static Steinberg_tresult controllerSetParamNormalized(void* thisInterface, Stein
if (id >= DATA_PRODUCT_PARAMETERS_N)
return Steinberg_kResultFalse;
controller *c = (controller *)thisInterface;
c->parameters[id] = parameterMap(id, value);
c->parameters[id] = parameterAdjust(id, parameterMap(id, value));
return Steinberg_kResultTrue;
#else
return Steinberg_kResultFalse;

View File

@ -8,6 +8,6 @@
"types": [ "@lv2:AmplifierPlugin" ],
"version": "1.0",
"busSymbols": [ "input", "output" ],
"parameterSymbols": [ "gain", "bypass" ]
"parameterSymbols": [ "gain", "enabled" ]
}
}

View File

@ -5,21 +5,21 @@ typedef struct plugin {
char bypass;
} plugin;
void plugin_init(plugin *instance) {
static void plugin_init(plugin *instance) {
instance->gain = 1.f;
instance->bypass = 0;
}
void plugin_fini(plugin *instance) {
static void plugin_fini(plugin *instance) {
}
void plugin_set_sample_rate(plugin *instance, float sample_rate) {
static void plugin_set_sample_rate(plugin *instance, float sample_rate) {
}
void plugin_reset(plugin *instance) {
static void plugin_reset(plugin *instance) {
}
void plugin_set_parameter(plugin *instance, size_t index, float value) {
static void plugin_set_parameter(plugin *instance, size_t index, float value) {
switch (index) {
case 0:
instance->gain = value;
@ -30,12 +30,12 @@ void plugin_set_parameter(plugin *instance, size_t index, float value) {
}
}
float plugin_get_parameter(plugin *instance, size_t index) {
static float plugin_get_parameter(plugin *instance, size_t index) {
// no output parameters
return 0.f;
}
void plugin_process(plugin *instance, const float **inputs, float **outputs, size_t n_samples) {
static void plugin_process(plugin *instance, const float **inputs, float **outputs, size_t n_samples) {
const float g = instance->bypass ? 1.f : powf(10.f, 0.05f * instance->gain);
for (size_t i = 0; i < n_samples; i++)
outputs[0][i] = g * inputs[0][i];