aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHanspeter Portner <dev@open-music-kontrollers.ch>2017-05-09 21:11:26 +0200
committerHanspeter Portner <dev@open-music-kontrollers.ch>2017-05-09 21:11:26 +0200
commitc537f9db3fd2e34df6cd9de08af6661fa0bcb815 (patch)
treecd60b1650dfd09d3cdf09c65b4a5ec2d6c613373
parent641076534cbe9ea02093e071b8b958787e13af84 (diff)
downloadsynthpod-c537f9db3fd2e34df6cd9de08af6661fa0bcb815.tar.xz
app/nk: finalize MIDI automation.
-rw-r--r--VERSION2
-rw-r--r--app/synthpod_app.c41
-rw-r--r--app/synthpod_app_private.h14
-rw-r--r--app/synthpod_app_state.c14
-rw-r--r--app/synthpod_app_ui.c50
-rw-r--r--include/synthpod_private.h15
-rw-r--r--plugins/synthpod_common_nk.c119
7 files changed, 177 insertions, 78 deletions
diff --git a/VERSION b/VERSION
index b521b7c7..53e21855 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.1.4917
+0.1.4929
diff --git a/app/synthpod_app.c b/app/synthpod_app.c
index 02429bc6..afbc98d5 100644
--- a/app/synthpod_app.c
+++ b/app/synthpod_app.c
@@ -195,35 +195,29 @@ _sp_app_process_single_run(mod_t *mod, uint32_t nsamples)
if( ( (mauto->channel == -1) || (mauto->channel == channel) )
&& ( (mauto->controller == -1) || (mauto->controller == controller) ) )
{
- float rel = (msg[2] - mauto->min) * mauto->range_1;
- if(rel < 0.f)
- rel = 0.f;
- else if(rel > 1.f)
- rel = 1.f;
+ // linear mapping from MIDI to automation value
+ double f64 = msg[2] * automation->mul + automation->add;
+
+ // clip automation value to destination range
+ if(f64 < automation->c)
+ f64 = automation->c;
+ else if(f64 > automation->d)
+ f64 = automation->d;
port_t *port = &mod->ports[automation->index];
if(port->type == PORT_TYPE_CONTROL)
{
control_port_t *control = &port->control;
- float f32 = rel * control->range + control->min;
- if(control->is_integer)
- f32 = floorf(f32);
-
- if(f32 < control->min)
- f32 = control->min;
- else if(f32 > control->max)
- f32 = control->max;
-
float *buf = PORT_BASE_ALIGNED(port);
- *buf = f32;
+ *buf = control->is_integer
+ ? floor(f64)
+ : f64;
//printf("control automation match: %f %f\n", rel, f32);
}
else if( (port->type == PORT_TYPE_ATOM) && automation->property )
{
- const float f32 = rel * 127.f; //FIXME use correct scaling
-
LV2_Atom_Sequence *control = PORT_BASE_ALIGNED(port);
LV2_Atom_Event *dst = lv2_atom_sequence_end(&control->body, control->atom.size);
LV2_Atom_Forge_Frame obj_frame;
@@ -240,26 +234,23 @@ _sp_app_process_single_run(mod_t *mod, uint32_t nsamples)
{
if(automation->range == app->forge.Bool)
{
- const int32_t i32 = (f32 != 0.f);
- ref = lv2_atom_forge_bool(&app->forge, i32);
+ ref = lv2_atom_forge_bool(&app->forge, f64 != 0.0);
}
else if(automation->range == app->forge.Int)
{
- const int32_t i32 = floorf(f32);
- ref = lv2_atom_forge_int(&app->forge, i32);
+ ref = lv2_atom_forge_int(&app->forge, floor(f64));
}
else if(automation->range == app->forge.Long)
{
- const int64_t i64 = floorf(f32);
- ref = lv2_atom_forge_long(&app->forge, i64);
+ ref = lv2_atom_forge_long(&app->forge, floor(f64));
}
else if(automation->range == app->forge.Float)
{
- ref = lv2_atom_forge_float(&app->forge, f32);
+ ref = lv2_atom_forge_float(&app->forge, f64);
}
else if(automation->range == app->forge.Double)
{
- ref = lv2_atom_forge_double(&app->forge, f32);
+ ref = lv2_atom_forge_double(&app->forge, f64);
}
//FIXME support more types
diff --git a/app/synthpod_app_private.h b/app/synthpod_app_private.h
index d238dc81..46c8c44f 100644
--- a/app/synthpod_app_private.h
+++ b/app/synthpod_app_private.h
@@ -210,16 +210,10 @@ enum _auto_type_t {
struct _midi_auto_t {
int8_t channel;
int8_t controller;
- uint8_t min;
- uint8_t max;
- float range_1;
};
struct _osc_auto_t {
char path [128]; //TODO how big?
- float min;
- float max;
- float span;
};
struct _auto_t {
@@ -228,6 +222,14 @@ struct _auto_t {
LV2_URID property;
LV2_URID range;
+ double a;
+ double b;
+ double c;
+ double d;
+
+ double mul;
+ double add;
+
union {
midi_auto_t midi;
//osc_auto_t osc;
diff --git a/app/synthpod_app_state.c b/app/synthpod_app_state.c
index 70bdc916..12a2e642 100644
--- a/app/synthpod_app_state.c
+++ b/app/synthpod_app_state.c
@@ -1023,11 +1023,17 @@ sp_app_save(sp_app_t *app, LV2_State_Store_Function store,
&& lv2_atom_forge_key(forge, app->regs.midi.controller_number.urid)
&& lv2_atom_forge_int(forge, mauto->controller)
- && lv2_atom_forge_key(forge, app->regs.core.minimum.urid)
- && lv2_atom_forge_int(forge, mauto->min)
+ && lv2_atom_forge_key(forge, app->regs.synthpod.source_min.urid)
+ && lv2_atom_forge_double(forge, automation->a)
- && lv2_atom_forge_key(forge, app->regs.core.maximum.urid)
- && lv2_atom_forge_int(forge, mauto->max);
+ && lv2_atom_forge_key(forge, app->regs.synthpod.source_max.urid)
+ && lv2_atom_forge_double(forge, automation->b)
+
+ && lv2_atom_forge_key(forge, app->regs.synthpod.sink_min.urid)
+ && lv2_atom_forge_double(forge, automation->c)
+
+ && lv2_atom_forge_key(forge, app->regs.synthpod.sink_max.urid)
+ && lv2_atom_forge_double(forge, automation->d);
if(ref)
{
diff --git a/app/synthpod_app_ui.c b/app/synthpod_app_ui.c
index 22edfa57..d596ed9e 100644
--- a/app/synthpod_app_ui.c
+++ b/app/synthpod_app_ui.c
@@ -1215,14 +1215,24 @@ _sp_app_from_ui_patch_get(sp_app_t *app, const LV2_Atom *atom)
ref = lv2_atom_forge_int(&app->forge, mauto->controller);
if(ref)
- ref = lv2_atom_forge_key(&app->forge, app->regs.core.minimum.urid);
+ ref = lv2_atom_forge_key(&app->forge, app->regs.synthpod.source_min.urid);
if(ref)
- ref = lv2_atom_forge_int(&app->forge, mauto->min);
+ ref = lv2_atom_forge_double(&app->forge, automation->a);
if(ref)
- ref = lv2_atom_forge_key(&app->forge, app->regs.core.maximum.urid);
+ ref = lv2_atom_forge_key(&app->forge, app->regs.synthpod.source_max.urid);
if(ref)
- ref = lv2_atom_forge_int(&app->forge, mauto->max);
+ ref = lv2_atom_forge_double(&app->forge, automation->b);
+
+ if(ref)
+ ref = lv2_atom_forge_key(&app->forge, app->regs.synthpod.sink_min.urid);
+ if(ref)
+ ref = lv2_atom_forge_double(&app->forge, automation->c);
+
+ if(ref)
+ ref = lv2_atom_forge_key(&app->forge, app->regs.synthpod.sink_max.urid);
+ if(ref)
+ ref = lv2_atom_forge_double(&app->forge, automation->d);
}
if(ref)
lv2_atom_forge_pop(&app->forge, &frame[2]);
@@ -1850,8 +1860,10 @@ _midi_automation_list_add(sp_app_t *app, const LV2_Atom_Object *obj)
const LV2_Atom_URID *src_range = NULL;
const LV2_Atom_Int *src_channel = NULL;
const LV2_Atom_Int *src_controller = NULL;
- const LV2_Atom_Int *src_min = NULL;
- const LV2_Atom_Int *src_max = NULL;
+ const LV2_Atom_Double *src_min = NULL;
+ const LV2_Atom_Double *src_max = NULL;
+ const LV2_Atom_Double *snk_min = NULL;
+ const LV2_Atom_Double *snk_max = NULL;
lv2_atom_object_get(obj,
app->regs.synthpod.sink_module.urid, &src_module,
@@ -1860,8 +1872,10 @@ _midi_automation_list_add(sp_app_t *app, const LV2_Atom_Object *obj)
app->regs.rdfs.range.urid, &src_range,
app->regs.midi.channel.urid, &src_channel,
app->regs.midi.controller_number.urid, &src_controller,
- app->regs.core.minimum.urid, &src_min,
- app->regs.core.maximum.urid, &src_max,
+ app->regs.synthpod.source_min.urid, &src_min,
+ app->regs.synthpod.source_max.urid, &src_max,
+ app->regs.synthpod.sink_min.urid, &snk_min,
+ app->regs.synthpod.sink_max.urid, &snk_max,
0);
const LV2_URID src_urn = src_module
@@ -1894,15 +1908,21 @@ _midi_automation_list_add(sp_app_t *app, const LV2_Atom_Object *obj)
automation->property = src_prop;
automation->range = src_ran;
+ automation->a = src_min ? src_min->body : 0.0;
+ automation->b = src_max ? src_max->body : 0.0;
+ automation->c = snk_min ? snk_min->body : 0.0;
+ automation->d = snk_max ? snk_max->body : 0.0;
+
+ const double div = automation->b - automation->a;
+ automation->mul = div
+ ? (automation->d - automation->c) / div
+ : 0.0;
+ automation->add = div
+ ? (automation->c*automation->b - automation->a*automation->d) / div
+ : 0.0;
+
automation->midi.channel = src_channel ? src_channel->body : -1;
automation->midi.controller = src_controller ? src_controller->body : -1;
- automation->midi.min = src_min ? src_min->body : 0x0;
- automation->midi.max = src_max ? src_max->body : 0x7f;
-
- const int range = automation->midi.max - automation->midi.min;
- automation->midi.range_1 = range
- ? 1.f / range
- : 0.f;
break;
}
diff --git a/include/synthpod_private.h b/include/synthpod_private.h
index d475edf1..fc1ea85d 100644
--- a/include/synthpod_private.h
+++ b/include/synthpod_private.h
@@ -375,6 +375,11 @@ struct _reg_t {
reg_item_t source_symbol;
reg_item_t sink_module;
reg_item_t sink_symbol;
+
+ reg_item_t source_min;
+ reg_item_t source_max;
+ reg_item_t sink_min;
+ reg_item_t sink_max;
} synthpod;
struct {
@@ -637,6 +642,11 @@ sp_regs_init(reg_t *regs, LilvWorld *world, LV2_URID_Map *map)
_register(&regs->synthpod.sink_module, world, map, SYNTHPOD_PREFIX"sinkModule");
_register(&regs->synthpod.sink_symbol, world, map, SYNTHPOD_PREFIX"sinkSymbol");
+ _register(&regs->synthpod.source_min, world, map, SYNTHPOD_PREFIX"sourceMinimum");
+ _register(&regs->synthpod.source_max, world, map, SYNTHPOD_PREFIX"sourceMaximum");
+ _register(&regs->synthpod.sink_min, world, map, SYNTHPOD_PREFIX"sinkMinimum");
+ _register(&regs->synthpod.sink_max, world, map, SYNTHPOD_PREFIX"sinkMaximum");
+
_register(&regs->midi.Controller, world, map, LV2_MIDI__Controller);
_register(&regs->midi.channel, world, map, LV2_MIDI__channel);
_register(&regs->midi.controller_number, world, map, LV2_MIDI__controllerNumber);
@@ -864,6 +874,11 @@ sp_regs_deinit(reg_t *regs)
_unregister(&regs->synthpod.sink_module);
_unregister(&regs->synthpod.sink_symbol);
+ _unregister(&regs->synthpod.source_min);
+ _unregister(&regs->synthpod.source_max);
+ _unregister(&regs->synthpod.sink_min);
+ _unregister(&regs->synthpod.sink_max);
+
_unregister(&regs->midi.Controller);
_unregister(&regs->midi.channel);
_unregister(&regs->midi.controller_number);
diff --git a/plugins/synthpod_common_nk.c b/plugins/synthpod_common_nk.c
index b63fffbd..b3f4dd5a 100644
--- a/plugins/synthpod_common_nk.c
+++ b/plugins/synthpod_common_nk.c
@@ -118,6 +118,7 @@ union _param_union_t {
int64_t h;
float f;
double d;
+ double u;
struct nk_text_edit editor;
chunk_t chunk;
};
@@ -138,8 +139,8 @@ enum _auto_type_t {
struct _midi_auto_t {
int channel;
int controller;
- int min;
- int max;
+ int a;
+ int b;
};
struct _osc_auto_t {
@@ -150,6 +151,10 @@ struct _osc_auto_t {
struct _auto_t {
auto_type_t type;
+
+ double c;
+ double d;
+
union {
midi_auto_t midi;
osc_auto_t osc;
@@ -912,33 +917,43 @@ _patch_param_automation_internal(plughandle_t *handle, param_t *source_param)
}
static LV2_Atom_Forge_Ref
-_patch_midi_automation_internal(plughandle_t *handle, midi_auto_t *mauto)
+_patch_midi_automation_internal(plughandle_t *handle, auto_t *automation)
{
LV2_Atom_Forge_Ref ref = lv2_atom_forge_key(&handle->forge, handle->regs.midi.channel.urid);
if(ref)
- ref = lv2_atom_forge_int(&handle->forge, mauto->channel);
+ ref = lv2_atom_forge_int(&handle->forge, automation->midi.channel);
if(ref)
ref = lv2_atom_forge_key(&handle->forge, handle->regs.midi.controller_number.urid);
if(ref)
- ref = lv2_atom_forge_int(&handle->forge, mauto->controller);
+ ref = lv2_atom_forge_int(&handle->forge, automation->midi.controller);
+
+ if(ref)
+ ref = lv2_atom_forge_key(&handle->forge, handle->regs.synthpod.source_min.urid);
+ if(ref)
+ ref = lv2_atom_forge_double(&handle->forge, automation->midi.a);
if(ref)
- ref = lv2_atom_forge_key(&handle->forge, handle->regs.core.minimum.urid);
+ ref = lv2_atom_forge_key(&handle->forge, handle->regs.synthpod.source_max.urid);
if(ref)
- ref = lv2_atom_forge_int(&handle->forge, mauto->min);
+ ref = lv2_atom_forge_double(&handle->forge, automation->midi.b);
if(ref)
- ref = lv2_atom_forge_key(&handle->forge, handle->regs.core.maximum.urid);
+ ref = lv2_atom_forge_key(&handle->forge, handle->regs.synthpod.sink_min.urid);
if(ref)
- ref = lv2_atom_forge_int(&handle->forge, mauto->max);
+ ref = lv2_atom_forge_double(&handle->forge, automation->c);
+
+ if(ref)
+ ref = lv2_atom_forge_key(&handle->forge, handle->regs.synthpod.sink_max.urid);
+ if(ref)
+ ref = lv2_atom_forge_double(&handle->forge, automation->d);
return ref;
}
static void
_patch_port_midi_automation_add(plughandle_t *handle, port_t *source_port,
- midi_auto_t *mauto)
+ auto_t *automation)
{
LV2_Atom_Forge_Frame frame [3];
@@ -947,7 +962,7 @@ _patch_port_midi_automation_add(plughandle_t *handle, port_t *source_port,
0, 0, handle->regs.synthpod.automation_list.urid) //TODO subject
&& lv2_atom_forge_object(&handle->forge, &frame[2], 0, handle->regs.midi.Controller.urid)
&& _patch_port_automation_internal(handle, source_port)
- && _patch_midi_automation_internal(handle, mauto) )
+ && _patch_midi_automation_internal(handle, automation) )
{
synthpod_patcher_pop(&handle->forge, frame, 3);
_message_write(handle);
@@ -970,9 +985,28 @@ _patch_port_automation_remove(plughandle_t *handle, port_t *source_port)
}
}
+static inline double
+_param_union_as_double(LV2_Atom_Forge *forge, LV2_URID range, param_union_t *pu)
+{
+ if(range == forge->Bool)
+ return pu->b;
+ else if(range == forge->Int)
+ return pu->i;
+ else if(range == forge->Long)
+ return pu->h;
+ else if(range == forge->Float)
+ return pu->f;
+ else if(range == forge->Double)
+ return pu->d;
+ else if(range == forge->URID)
+ return pu->u;
+
+ return 0.0;
+}
+
static void
_patch_param_midi_automation_add(plughandle_t *handle, param_t *source_param,
- midi_auto_t *mauto)
+ auto_t *automation)
{
LV2_Atom_Forge_Frame frame [3];
@@ -981,7 +1015,7 @@ _patch_param_midi_automation_add(plughandle_t *handle, param_t *source_param,
0, 0, handle->regs.synthpod.automation_list.urid) //TODO subject
&& lv2_atom_forge_object(&handle->forge, &frame[2], 0, handle->regs.midi.Controller.urid)
&& _patch_param_automation_internal(handle, source_param)
- && _patch_midi_automation_internal(handle, mauto) )
+ && _patch_midi_automation_internal(handle, automation) )
{
synthpod_patcher_pop(&handle->forge, frame, 3);
_message_write(handle);
@@ -5095,11 +5129,27 @@ _expose_main_body(plughandle_t *handle, struct nk_context *ctx, float dh, float
port_t *port = handle->port_selector;
param_t *param = handle->param_selector;
+ double c = 0.0;
+ double d = 0.0;
+
auto_t *automation = NULL;
if(port && (port->type == PROPERTY_TYPE_CONTROL) )
+ {
automation = &port->control.automation;
+ control_port_t *control = &port->control;
+ c = control->is_int || control->is_bool
+ ? control->min.i
+ : control->min.f;
+ d = control->is_int || control->is_bool
+ ? control->max.i
+ : control->max.f;
+ }
else if(param)
+ {
automation = &param->automation;
+ c = _param_union_as_double(&handle->forge, param->range, &param->min);
+ d = _param_union_as_double(&handle->forge, param->range, &param->max);
+ }
if(automation)
{
@@ -5119,8 +5169,10 @@ _expose_main_body(plughandle_t *handle, struct nk_context *ctx, float dh, float
// initialize
automation->midi.channel = -1;
automation->midi.controller = -1;
- automation->midi.min = 0x0;
- automation->midi.max = 0x7f;
+ automation->midi.a = 0x0;
+ automation->midi.b = 0x7f;
+ automation->c = c;
+ automation->d = d;
}
else if(automation->type == AUTO_OSC)
{
@@ -5135,12 +5187,16 @@ _expose_main_body(plughandle_t *handle, struct nk_context *ctx, float dh, float
nk_layout_row_dynamic(ctx, dy, 1);
nk_spacing(ctx, 1);
+ const double inc = 1.0; //FIXME
const float ipp = 1.f; //FIXME
- nk_property_int(ctx, "Channel", -1, &automation->midi.channel, 0xf, 1, ipp);
- nk_property_int(ctx, "Controller", -1, &automation->midi.controller, 0x7f, 1, ipp);
- nk_property_int(ctx, "Minimum", 0, &automation->midi.min, 0x7f, 1, ipp);
- nk_property_int(ctx, "Maximum", 0, &automation->midi.max, 0x7f, 1, ipp);
+ nk_property_int(ctx, "MIDI Channel", -1, &automation->midi.channel, 0xf, 1, ipp);
+ nk_property_int(ctx, "MIDI Controller", -1, &automation->midi.controller, 0x7f, 1, ipp);
+ nk_property_int(ctx, "MIDI Minimum", 0, &automation->midi.a, 0x7f, 1, ipp);
+ nk_property_int(ctx, "MIDI Maximum", 0, &automation->midi.b, 0x7f, 1, ipp);
+ nk_spacing(ctx, 1);
+ nk_property_double(ctx, "Target Minimum", c, &automation->c, d, inc, ipp);
+ nk_property_double(ctx, "Target Maximum", c, &automation->d, d, inc, ipp);
}
else if(automation->type == AUTO_OSC)
{
@@ -5160,9 +5216,9 @@ _expose_main_body(plughandle_t *handle, struct nk_context *ctx, float dh, float
else if(automation->type == AUTO_MIDI)
{
if(port)
- _patch_port_midi_automation_add(handle, port, &automation->midi);
+ _patch_port_midi_automation_add(handle, port, automation);
else if(param)
- _patch_param_midi_automation_add(handle, param, &automation->midi);
+ _patch_param_midi_automation_add(handle, param, automation);
}
else if(automation->type == AUTO_OSC)
{
@@ -5610,8 +5666,10 @@ _add_automation(plughandle_t *handle, const LV2_Atom_Object *obj)
const LV2_Atom_URID *src_property = NULL;
const LV2_Atom_Int *midi_channel = NULL;
const LV2_Atom_Int *midi_controller = NULL;
- const LV2_Atom_Int *core_minimum= NULL;
- const LV2_Atom_Int *core_maximum= NULL;
+ const LV2_Atom_Double *src_min = NULL;
+ const LV2_Atom_Double *src_max = NULL;
+ const LV2_Atom_Double *snk_min = NULL;
+ const LV2_Atom_Double *snk_max = NULL;
lv2_atom_object_get(obj,
handle->regs.synthpod.sink_module.urid, &src_module,
@@ -5619,8 +5677,10 @@ _add_automation(plughandle_t *handle, const LV2_Atom_Object *obj)
handle->regs.patch.property.urid, &src_property,
handle->regs.midi.channel.urid, &midi_channel,
handle->regs.midi.controller_number.urid, &midi_controller,
- handle->regs.core.minimum.urid, &core_minimum,
- handle->regs.core.maximum.urid, &core_maximum,
+ handle->regs.synthpod.source_min.urid, &src_min,
+ handle->regs.synthpod.source_max.urid, &src_max,
+ handle->regs.synthpod.sink_min.urid, &snk_min,
+ handle->regs.synthpod.sink_max.urid, &snk_max,
0);
const LV2_URID src_urn = src_module
@@ -5643,6 +5703,8 @@ _add_automation(plughandle_t *handle, const LV2_Atom_Object *obj)
if(src_port && (src_port->type == PROPERTY_TYPE_CONTROL) )
{
automation = &src_port->control.automation;
+
+ control_port_t *control = &src_port->control;
}
}
}
@@ -5665,11 +5727,14 @@ _add_automation(plughandle_t *handle, const LV2_Atom_Object *obj)
{
automation->type = AUTO_MIDI;
+ automation->midi.a = src_min ? src_min->body : 0x0;
+ automation->midi.b = src_max ? src_max->body : 0x7f;
+ automation->c = snk_min ? snk_min->body : 0.0; //FIXME
+ automation->d = snk_max ? snk_max->body : 0.0; //FIXME
+
midi_auto_t *mauto = &automation->midi;
mauto->channel = midi_channel ? midi_channel->body : -1;
mauto->controller = midi_controller ? midi_controller->body : -1;
- mauto->min = core_minimum ? core_minimum->body : 0x0;
- mauto->max = core_maximum ? core_maximum->body : 0x7f;
}
}
//FIXME OSC