From af0c0ab5c8fdf09df3b120a584e934c1f5614e0c Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Sun, 27 Nov 2011 10:56:40 -0300 Subject: [PATCH] midi2osc: added channel wildcard and overriding the value --- midi2osc/README | 6 +++++- midi2osc/midi2osc.c | 45 ++++++++++++++++++++++++++++++--------------- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/midi2osc/README b/midi2osc/README index 2415c36..d39373e 100644 --- a/midi2osc/README +++ b/midi2osc/README @@ -22,7 +22,7 @@ To use it with the Milkymist One, midi2osc can also remap MIDI controls. The syntax is -c[.]=c[.] +c[][.]=c[.[=]] where is a channel number and is the optional control number. For example, @@ -32,3 +32,7 @@ number. For example, would map the joysticks and two faders of a Faderfox LV3 to the controls 1 through 6 on channel 0, and send the OSC messages to a host called "m1". + +If is given, that value will be assigned for any control +message that matches the input pattern, irrespective of the input +value. diff --git a/midi2osc/midi2osc.c b/midi2osc/midi2osc.c index 5beeff2..ddbff47 100644 --- a/midi2osc/midi2osc.c +++ b/midi2osc/midi2osc.c @@ -27,11 +27,13 @@ static int debug = 0; static struct map { int chan_in, ctrl_in; int chan_out, ctrl_out; + int value; struct map *next; } *mappings = NULL; -static void add(int chan_in, int ctrl_in, int chan_out, int ctrl_out) +static void add(int chan_in, int ctrl_in, int chan_out, int ctrl_out, + int value) { struct map *new; @@ -40,6 +42,7 @@ static void add(int chan_in, int ctrl_in, int chan_out, int ctrl_out) new->ctrl_in = ctrl_in; new->chan_out = chan_out; new->ctrl_out = ctrl_out; + new->value = value; new->next = mappings; mappings = new; } @@ -47,17 +50,22 @@ static void add(int chan_in, int ctrl_in, int chan_out, int ctrl_out) static void add_mapping(const char *s) { - unsigned chan_in, ctrl_in, chan_out, ctrl_out; + unsigned chan_in, ctrl_in, chan_out, ctrl_out, value; - if (sscanf(s, "c%u.%u=c%u.%u", + if (sscanf(s, "c%u.%u=c%u.%u=%u", + &chan_in, &ctrl_in, &chan_out, &ctrl_out, &value) == 5) + add(chan_in, ctrl_in, chan_out, ctrl_out, value); + else if (sscanf(s, "c%u.%u=c%u.%u", &chan_in, &ctrl_in, &chan_out, &ctrl_out) == 4) - add(chan_in, ctrl_in, chan_out, ctrl_out); + add(chan_in, ctrl_in, chan_out, ctrl_out, -1); else if (sscanf(s, "c%u.%u=c%u", &chan_in, &ctrl_in, &chan_out) == 3) - add(chan_in, ctrl_in, chan_out, -1); + add(chan_in, ctrl_in, chan_out, -1, -1); else if (sscanf(s, "c%u=c%u.%u", &chan_in, &chan_out, &ctrl_out) == 3) - add(chan_in, -1, chan_out, ctrl_out); + add(chan_in, -1, chan_out, ctrl_out, -1); + else if (sscanf(s, "c.%u=c%u.%u", &ctrl_in, &chan_out, &ctrl_out) == 3) + add(-1, ctrl_in, chan_out, ctrl_out, -1); else if (sscanf(s, "c%u=c%u", &chan_in, &chan_out) == 2) - add(chan_in, -1, chan_out, -1); + add(chan_in, -1, chan_out, -1, -1); else { fprintf(stderr, "unrecognized mapping syntax\n"); exit(1); @@ -65,7 +73,7 @@ static void add_mapping(const char *s) } -static void map(uint8_t *chan, uint8_t *ctrl) +static void map(uint8_t *chan, uint8_t *ctrl, uint8_t *value) { const struct map *m; @@ -76,6 +84,8 @@ static void map(uint8_t *chan, uint8_t *ctrl) *chan = m->chan_out; if (m->ctrl_out != -1) *ctrl = m->ctrl_out; + if (m->value != -1) + *value = m->value; return; } } @@ -85,7 +95,7 @@ static void forward(snd_seq_t *midi, lo_address osc) { snd_seq_event_t *ev; uint8_t msg[4] = { 0, }; - uint8_t chan, ctrl; + uint8_t chan, ctrl, value; while (snd_seq_event_input(midi, &ev)) { switch (ev->type) { @@ -97,15 +107,17 @@ static void forward(snd_seq_t *midi, lo_address osc) case SND_SEQ_EVENT_CONTROLLER: chan = ev->data.control.channel; ctrl = ev->data.control.param; - map(&chan, &ctrl); - msg[3] = ev->data.control.value; + value = ev->data.control.value; + map(&chan, &ctrl, &value); if (debug) - fprintf(stderr, "c%u.%u(%u) -> c%u.%u\n", + fprintf(stderr, "c%u.%u=%u -> c%u.%u=%u\n", ev->data.control.channel, - ev->data.control.param, msg[3], - chan, ctrl); + ev->data.control.param, + ev->data.control.value, + chan, ctrl, value); msg[1] = 0xb0 | chan; msg[2] = ctrl; + msg[3] = value; break; case SND_SEQ_EVENT_PITCHBEND: msg[1] = 0xe0 | ev->data.control.channel; @@ -114,6 +126,8 @@ static void forward(snd_seq_t *midi, lo_address osc) break; default: /* Flickernoise currently doesn't support any others */ + if (debug) + fprintf(stderr, "unrecognized MIDI event\n"); snd_seq_free_event(ev); continue; } @@ -128,7 +142,8 @@ static void usage(const char *name) { fprintf(stderr, "usage: %s hostname [-d] [mapping ...] [port]\n\n" -" mappings are of the form c[.]=c[.]\n\n" +" mappings are of the form\n" +" c[][.]=c[.[=]]\n\n" " -d debug mode: print all MIDI messages\n", name); exit(1);