aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHanspeter Portner <dev@open-music-kontrollers.ch>2017-05-07 21:12:08 +0200
committerHanspeter Portner <dev@open-music-kontrollers.ch>2017-05-07 21:12:08 +0200
commitee75edc7c175023f4de6aac921352536d189e772 (patch)
tree3da1eb56fb3f27b18004935cacea1208c2e56337
parent2fc3370f547a44b651b1c8de1e158d051e5fbcdd (diff)
downloadsynthpod-ee75edc7c175023f4de6aac921352536d189e772.tar.xz
app/nk: prototype parameter automations.
* only atom:Int supported for testing.
-rw-r--r--VERSION2
-rw-r--r--app/synthpod_app.c93
-rw-r--r--app/synthpod_app_mod.c3
-rw-r--r--app/synthpod_app_private.h9
-rw-r--r--app/synthpod_app_state.c69
-rw-r--r--app/synthpod_app_ui.c210
6 files changed, 179 insertions, 207 deletions
diff --git a/VERSION b/VERSION
index 31d13e5e..69fb3b4b 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.1.4913
+0.1.4915
diff --git a/app/synthpod_app.c b/app/synthpod_app.c
index a32ba69d..5c5dda4e 100644
--- a/app/synthpod_app.c
+++ b/app/synthpod_app.c
@@ -162,8 +162,8 @@ _sp_app_process_single_run(mod_t *mod, uint32_t nsamples)
// apply automation if any
{
const unsigned p = mod->num_ports - 1;
- port_t *port = &mod->ports[p];
- const LV2_Atom_Sequence *seq = PORT_BASE_ALIGNED(port);
+ port_t *auto_port = &mod->ports[p];
+ const LV2_Atom_Sequence *seq = PORT_BASE_ALIGNED(auto_port);
LV2_ATOM_SEQUENCE_FOREACH(seq, ev)
{
@@ -182,48 +182,10 @@ _sp_app_process_single_run(mod_t *mod, uint32_t nsamples)
const uint8_t channel = msg[0] & 0x0f;
const uint8_t controller = msg[1];
- //FIXME use per-module flag whether it actually has any automations
- for(unsigned d = 0; d<mod->num_ports - 1; d++) // - automation port
- {
- port_t *dst = &mod->ports[d];
-
- if(dst->type != PORT_TYPE_CONTROL)
- continue; // skip non-control ports
-
- control_port_t *control = &dst->control;
- if(control->automation.type != AUTO_TYPE_MIDI)
- continue; // skip non-midi automation
-
- midi_auto_t *mauto = &control->automation.midi;
-
- 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;
-
- 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(dst);
- *buf = f32;
- //printf("automation match: %f %f\n", rel, f32);
- }
- }
-
- // iterate over parameters
+ // iterate over automations
for(unsigned i = 0; i < MAX_AUTOMATIONS; i++)
{
- auto_t *automation = &mod->param_automations[i];
+ auto_t *automation = &mod->automations[i];
if(automation->type != AUTO_TYPE_MIDI)
continue;
@@ -239,10 +201,49 @@ _sp_app_process_single_run(mod_t *mod, uint32_t nsamples)
else if(rel > 1.f)
rel = 1.f;
- float f32 = rel * 127.f; //FIXME
- printf("automation match: %f %f\n", rel, f32);
-
- //FIXME append patch:Set to patch:Message ports
+ 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;
+
+ //printf("control automation match: %f %f\n", rel, f32);
+ }
+ else if( (port->type == PORT_TYPE_ATOM) && automation->property )
+ {
+ const int32_t i32 = floorf(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;
+
+ lv2_atom_forge_set_buffer(&app->forge, (uint8_t *)dst, PORT_SIZE(port) - control->atom.size - sizeof(LV2_Atom));
+
+ if( lv2_atom_forge_frame_time(&app->forge, nsamples - 1)
+ && lv2_atom_forge_object(&app->forge, &obj_frame, 0, app->regs.patch.set.urid)
+ && lv2_atom_forge_key(&app->forge, app->regs.patch.property.urid)
+ && lv2_atom_forge_urid(&app->forge, automation->property)
+ && lv2_atom_forge_key(&app->forge, app->regs.patch.value.urid)
+ && lv2_atom_forge_int(&app->forge, i32) ) //FIXME use correct type
+ {
+ lv2_atom_forge_pop(&app->forge, &obj_frame);
+
+ control->atom.size += sizeof(LV2_Atom_Event) + dst->body.size;
+ }
+
+ //printf("parameter automation match: %f %f\n", rel, f32);
+ }
}
}
}
diff --git a/app/synthpod_app_mod.c b/app/synthpod_app_mod.c
index 59791371..d07f8cae 100644
--- a/app/synthpod_app_mod.c
+++ b/app/synthpod_app_mod.c
@@ -801,9 +801,6 @@ _sp_app_mod_add(sp_app_t *app, const char *uri, LV2_URID urn)
lilv_node_free(dflt_node);
lilv_node_free(min_node);
lilv_node_free(max_node);
-
- //FIXME this is just temporary
- control->automation.type = AUTO_TYPE_NONE;
}
else if(lilv_port_is_a(plug, port, app->regs.port.atom.node))
{
diff --git a/app/synthpod_app_private.h b/app/synthpod_app_private.h
index 8bb80b0b..087daed2 100644
--- a/app/synthpod_app_private.h
+++ b/app/synthpod_app_private.h
@@ -224,11 +224,12 @@ struct _osc_auto_t {
struct _auto_t {
auto_type_t type;
- bool learning;
+ uint32_t index;
LV2_URID property;
+
union {
midi_auto_t midi;
- osc_auto_t osc;
+ //osc_auto_t osc;
};
};
@@ -315,7 +316,7 @@ struct _mod_t {
float y;
} pos;
- auto_t param_automations [MAX_AUTOMATIONS];
+ auto_t automations [MAX_AUTOMATIONS];
};
struct _port_driver_t {
@@ -363,8 +364,6 @@ struct _control_port_t {
float stash;
bool stashing;
atomic_flag lock;
-
- auto_t automation;
};
struct _audio_port_t {
diff --git a/app/synthpod_app_state.c b/app/synthpod_app_state.c
index 9f94164f..75d0cd96 100644
--- a/app/synthpod_app_state.c
+++ b/app/synthpod_app_state.c
@@ -1001,44 +1001,55 @@ sp_app_save(sp_app_t *app, LV2_State_Store_Function store,
{
mod_t *mod = app->mods[m];
- for(unsigned p=0; p<mod->num_ports; p++)
+ for(unsigned i = 0; i < MAX_AUTOMATIONS; i++)
{
- port_t *port = &mod->ports[p];
+ auto_t *automation = &mod->automations[i];
+ port_t *port = &mod->ports[automation->index];
- // serialize port automations
- if(port->type == PORT_TYPE_CONTROL)
+ if(automation->type == AUTO_TYPE_MIDI)
{
- auto_t *automation = &port->control.automation;
+ midi_auto_t *mauto = &automation->midi;
- if(automation->type == AUTO_TYPE_MIDI)
+ LV2_Atom_Forge_Frame auto_frame;
+ if( ref
+ && lv2_atom_forge_object(forge, &auto_frame, 0, app->regs.midi.Controller.urid) )
{
- midi_auto_t *mauto = &automation->midi;
+ ref = lv2_atom_forge_key(forge, app->regs.synthpod.sink_module.urid)
+ && lv2_atom_forge_urid(forge, mod->urn)
- LV2_Atom_Forge_Frame auto_frame;
- if( ref
- && lv2_atom_forge_object(forge, &auto_frame, 0, app->regs.midi.Controller.urid) )
- {
- ref = lv2_atom_forge_key(forge, app->regs.synthpod.sink_module.urid)
- && lv2_atom_forge_urid(forge, port->mod->urn)
- && lv2_atom_forge_key(forge, app->regs.synthpod.sink_symbol.urid)
- && lv2_atom_forge_string(forge, port->symbol, strlen(port->symbol))
- && lv2_atom_forge_key(forge, app->regs.midi.channel.urid)
- && lv2_atom_forge_int(forge, mauto->channel)
- && 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.core.maximum.urid)
- && lv2_atom_forge_int(forge, mauto->max);
+ && lv2_atom_forge_key(forge, app->regs.midi.channel.urid)
+ && lv2_atom_forge_int(forge, mauto->channel)
- if(ref)
- lv2_atom_forge_pop(forge, &auto_frame);
+ && 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.core.maximum.urid)
+ && lv2_atom_forge_int(forge, mauto->max);
+
+ if(ref)
+ {
+ if(automation->property)
+ {
+ ref = lv2_atom_forge_key(forge, app->regs.patch.property.urid)
+ && lv2_atom_forge_urid(forge, automation->property);
+ }
+ else
+ {
+ ref = lv2_atom_forge_key(forge, app->regs.synthpod.sink_symbol.urid)
+ && lv2_atom_forge_string(forge, port->symbol, strlen(port->symbol));
+ }
}
+
+ if(ref)
+ lv2_atom_forge_pop(forge, &auto_frame);
}
- else if(automation->type == AUTO_TYPE_OSC)
- {
- //FIXME write me
- }
+ }
+ else if(automation->type == AUTO_TYPE_OSC)
+ {
+ //FIXME
}
}
}
diff --git a/app/synthpod_app_ui.c b/app/synthpod_app_ui.c
index fbca7c7d..3eb4157e 100644
--- a/app/synthpod_app_ui.c
+++ b/app/synthpod_app_ui.c
@@ -1168,66 +1168,10 @@ _sp_app_from_ui_patch_get(sp_app_t *app, const LV2_Atom *atom)
{
mod_t *mod = app->mods[m];
- for(unsigned p = 0; p < mod->num_ports; p++)
- {
- port_t *port = &mod->ports[p];
-
- if(port->type != PORT_TYPE_CONTROL)
- continue;
-
- auto_t *automation = &port->control.automation;
- if(automation->type == AUTO_TYPE_NONE)
- continue;
-
- if(automation->type == AUTO_TYPE_MIDI)
- {
- midi_auto_t *mauto = &automation->midi;
-
- if(ref)
- ref = lv2_atom_forge_object(&app->forge, &frame[2], 0, app->regs.midi.Controller.urid);
- {
- if(ref)
- ref = lv2_atom_forge_key(&app->forge, app->regs.synthpod.sink_module.urid);
- if(ref)
- ref = lv2_atom_forge_urid(&app->forge, mod->urn);
-
- if(ref)
- ref = lv2_atom_forge_key(&app->forge, app->regs.synthpod.sink_symbol.urid);
- if(ref)
- ref = lv2_atom_forge_string(&app->forge, port->symbol, strlen(port->symbol));
-
- if(ref)
- ref = lv2_atom_forge_key(&app->forge, app->regs.midi.channel.urid);
- if(ref)
- ref = lv2_atom_forge_int(&app->forge, mauto->channel);
-
- if(ref)
- ref = lv2_atom_forge_key(&app->forge, app->regs.midi.controller_number.urid);
- if(ref)
- ref = lv2_atom_forge_int(&app->forge, mauto->controller);
-
- if(ref)
- ref = lv2_atom_forge_key(&app->forge, app->regs.core.minimum.urid);
- if(ref)
- ref = lv2_atom_forge_int(&app->forge, mauto->min);
-
- if(ref)
- ref = lv2_atom_forge_key(&app->forge, app->regs.core.maximum.urid);
- if(ref)
- ref = lv2_atom_forge_int(&app->forge, mauto->max);
- }
- if(ref)
- lv2_atom_forge_pop(&app->forge, &frame[2]);
- }
- else if(automation->type == AUTO_TYPE_OSC)
- {
- //FIXME
- }
- }
-
for(unsigned i = 0; i < MAX_AUTOMATIONS; i++)
{
- auto_t *automation = &mod->param_automations[i];
+ auto_t *automation = &mod->automations[i];
+ port_t *port = &mod->ports[automation->index];
if(automation->type == AUTO_TYPE_MIDI)
{
@@ -1241,10 +1185,20 @@ _sp_app_from_ui_patch_get(sp_app_t *app, const LV2_Atom *atom)
if(ref)
ref = lv2_atom_forge_urid(&app->forge, mod->urn);
- if(ref)
- ref = lv2_atom_forge_key(&app->forge, app->regs.patch.property.urid);
- if(ref)
- ref = lv2_atom_forge_urid(&app->forge, automation->property);
+ if(automation->property)
+ {
+ if(ref)
+ ref = lv2_atom_forge_key(&app->forge, app->regs.patch.property.urid);
+ if(ref)
+ ref = lv2_atom_forge_urid(&app->forge, automation->property);
+ }
+ else
+ {
+ if(ref)
+ ref = lv2_atom_forge_key(&app->forge, app->regs.synthpod.sink_symbol.urid);
+ if(ref)
+ ref = lv2_atom_forge_string(&app->forge, port->symbol, strlen(port->symbol));
+ }
if(ref)
ref = lv2_atom_forge_key(&app->forge, app->regs.midi.channel.urid);
@@ -1810,6 +1764,47 @@ _notification_list_add(sp_app_t *app, const LV2_Atom_Object *obj)
}
__realtime static void
+_automation_list_rem_internal(port_t *port, LV2_URID prop)
+{
+ mod_t *mod = port->mod;
+
+ for(unsigned i = 0; i < MAX_AUTOMATIONS; i++)
+ {
+ auto_t *automation = &mod->automations[i];
+
+ if(automation->type == AUTO_TYPE_NONE)
+ continue; // ignore
+
+ if(!prop && (automation->index == port->index))
+ automation->type = AUTO_TYPE_NONE; // invalidate
+ else if(prop && (automation->property == prop) )
+ automation->type = AUTO_TYPE_NONE; // invalidate
+ }
+}
+
+__realtime static port_t *
+_automation_port_find(mod_t *mod, const char *src_sym, LV2_URID src_prop)
+{
+ for(unsigned p = 0; p < mod->num_ports; p++)
+ {
+ port_t *port = &mod->ports[p];
+
+ if(src_sym)
+ {
+ if( (port->type == PORT_TYPE_CONTROL) && !strcmp(port->symbol, src_sym) )
+ return port;
+ }
+ else if(src_prop)
+ {
+ if( (port->type == PORT_TYPE_ATOM) && port->atom.patchable)
+ return port;
+ }
+ }
+
+ return NULL;
+}
+
+__realtime static void
_automation_list_rem(sp_app_t *app, const LV2_Atom_Object *obj)
{
//printf("got patch:remove for automationList:\n");
@@ -1831,38 +1826,15 @@ _automation_list_rem(sp_app_t *app, const LV2_Atom_Object *obj)
const LV2_URID src_prop = src_property
? src_property->body : 0;
- auto_t *automation = NULL;
-
- if(src_urn && src_sym)
- {
- port_t *src_port = _port_find_by_symbol(app, src_urn, src_sym);
-
- if(src_port->type == PORT_TYPE_CONTROL)
- {
- automation = &src_port->control.automation;
- }
- }
- else if(src_urn && src_prop)
+ mod_t *mod = _mod_find_by_urn(app, src_urn);
+ if(mod)
{
- mod_t *mod = _mod_find_by_urn(app, src_urn);
-
- if(mod)
+ port_t *port = _automation_port_find(mod, src_sym, src_prop);
+ if(port)
{
- for(unsigned i = 0; i < MAX_AUTOMATIONS; i++)
- {
- if(mod->param_automations[i].type == AUTO_TYPE_NONE)
- continue; // search empty slot
-
- if(mod->param_automations[i].property == src_prop)
- automation = &mod->param_automations[i];
- }
+ _automation_list_rem_internal(port, src_prop);
}
}
-
- if(automation)
- {
- automation->type = AUTO_TYPE_NONE;
- }
}
__realtime static void
@@ -1893,48 +1865,40 @@ _midi_automation_list_add(sp_app_t *app, const LV2_Atom_Object *obj)
const LV2_URID src_prop = src_property
? src_property->body : 0;
- auto_t *automation = NULL;
-
- if(src_urn && src_sym)
- {
- port_t *src_port = _port_find_by_symbol(app, src_urn, src_sym);
-
- if(src_port && (src_port->type == PORT_TYPE_CONTROL) )
- {
- automation = &src_port->control.automation;
- }
- }
- else if(src_urn && src_prop)
+ mod_t *mod = _mod_find_by_urn(app, src_urn);
+ if(mod)
{
- mod_t *mod = _mod_find_by_urn(app, src_urn);
-
- if(mod)
+ port_t *port = _automation_port_find(mod, src_sym, src_prop);
+ if(port)
{
+ _automation_list_rem_internal(port, src_prop); // remove any previously registered automation
+
for(unsigned i = 0; i < MAX_AUTOMATIONS; i++)
{
- if(mod->param_automations[i].type != AUTO_TYPE_NONE)
+ auto_t *automation = &mod->automations[i];
+
+ if(automation->type != AUTO_TYPE_NONE)
continue; // search empty slot
- automation = &mod->param_automations[i];
+ // fill slot
+ automation->type = AUTO_TYPE_MIDI;
+ automation->index = port->index;
+ automation->property = src_prop;
+
+ 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;
}
}
}
-
- if(automation)
- {
- automation->type = AUTO_TYPE_MIDI;
- automation->property = src_prop;
-
- 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;
- }
}
__realtime void