diff options
author | Hanspeter Portner <dev@open-music-kontrollers.ch> | 2017-05-09 21:11:26 +0200 |
---|---|---|
committer | Hanspeter Portner <dev@open-music-kontrollers.ch> | 2017-05-09 21:11:26 +0200 |
commit | c537f9db3fd2e34df6cd9de08af6661fa0bcb815 (patch) | |
tree | cd60b1650dfd09d3cdf09c65b4a5ec2d6c613373 | |
parent | 641076534cbe9ea02093e071b8b958787e13af84 (diff) | |
download | synthpod-c537f9db3fd2e34df6cd9de08af6661fa0bcb815.tar.xz |
app/nk: finalize MIDI automation.
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | app/synthpod_app.c | 41 | ||||
-rw-r--r-- | app/synthpod_app_private.h | 14 | ||||
-rw-r--r-- | app/synthpod_app_state.c | 14 | ||||
-rw-r--r-- | app/synthpod_app_ui.c | 50 | ||||
-rw-r--r-- | include/synthpod_private.h | 15 | ||||
-rw-r--r-- | plugins/synthpod_common_nk.c | 119 |
7 files changed, 177 insertions, 78 deletions
@@ -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(®s->synthpod.sink_module, world, map, SYNTHPOD_PREFIX"sinkModule"); _register(®s->synthpod.sink_symbol, world, map, SYNTHPOD_PREFIX"sinkSymbol"); + _register(®s->synthpod.source_min, world, map, SYNTHPOD_PREFIX"sourceMinimum"); + _register(®s->synthpod.source_max, world, map, SYNTHPOD_PREFIX"sourceMaximum"); + _register(®s->synthpod.sink_min, world, map, SYNTHPOD_PREFIX"sinkMinimum"); + _register(®s->synthpod.sink_max, world, map, SYNTHPOD_PREFIX"sinkMaximum"); + _register(®s->midi.Controller, world, map, LV2_MIDI__Controller); _register(®s->midi.channel, world, map, LV2_MIDI__channel); _register(®s->midi.controller_number, world, map, LV2_MIDI__controllerNumber); @@ -864,6 +874,11 @@ sp_regs_deinit(reg_t *regs) _unregister(®s->synthpod.sink_module); _unregister(®s->synthpod.sink_symbol); + _unregister(®s->synthpod.source_min); + _unregister(®s->synthpod.source_max); + _unregister(®s->synthpod.sink_min); + _unregister(®s->synthpod.sink_max); + _unregister(®s->midi.Controller); _unregister(®s->midi.channel); _unregister(®s->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 = ¶m->automation; + c = _param_union_as_double(&handle->forge, param->range, ¶m->min); + d = _param_union_as_double(&handle->forge, param->range, ¶m->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 |