diff options
Diffstat (limited to 'backends/midi.c')
-rw-r--r-- | backends/midi.c | 143 |
1 files changed, 57 insertions, 86 deletions
diff --git a/backends/midi.c b/backends/midi.c index 11d759d..1f0f2d5 100644 --- a/backends/midi.c +++ b/backends/midi.c @@ -13,9 +13,7 @@ enum /*_midi_channel_type*/ { cc, pressure, aftertouch, - pitchbend, - nrpn, - sysmsg + pitchbend }; static struct { @@ -69,19 +67,14 @@ static int midi_configure(char* option, char* value){ return 1; } -static instance* midi_instance(){ - instance* inst = mm_instance(); - if(!inst){ - return NULL; - } - +static int midi_instance(instance* inst){ inst->impl = calloc(1, sizeof(midi_instance_data)); if(!inst->impl){ LOG("Failed to allocate memory"); - return NULL; + return 1; } - return inst; + return 0; } static int midi_configure_instance(instance* inst, char* option, char* value){ @@ -116,39 +109,22 @@ static channel* midi_channel(instance* inst, char* spec, uint8_t flags){ .label = 0 }; - //support deprecated syntax for a transition period... - uint8_t old_syntax = 0; - char* channel; - + char* channel = NULL; if(!strncmp(spec, "ch", 2)){ channel = spec + 2; if(!strncmp(spec, "channel", 7)){ channel = spec + 7; } } - else if(!strncmp(spec, "cc", 2)){ - ident.fields.type = cc; - channel = spec + 2; - old_syntax = 1; - } - else if(!strncmp(spec, "note", 4)){ - ident.fields.type = note; - channel = spec + 4; - old_syntax = 1; - } - else if(!strncmp(spec, "nrpn", 4)){ - ident.fields.type = nrpn; - channel = spec + 4; - old_syntax = 1; - } - else{ - LOGPF("Unknown control type in %s", spec); + + if(!channel){ + LOGPF("Invalid channel specification %s", spec); return NULL; } ident.fields.channel = strtoul(channel, &channel, 10); if(ident.fields.channel > 15){ - LOGPF("Channel out of range in spec %s", spec); + LOGPF("MIDI channel out of range in spec %s", spec); return NULL; } @@ -159,33 +135,27 @@ static channel* midi_channel(instance* inst, char* spec, uint8_t flags){ //skip the period channel++; - if(!old_syntax){ - if(!strncmp(channel, "cc", 2)){ - ident.fields.type = cc; - channel += 2; - } - else if(!strncmp(channel, "note", 4)){ - ident.fields.type = note; - channel += 4; - } - else if(!strncmp(channel, "nrpn", 4)){ - ident.fields.type = nrpn; - channel += 4; - } - else if(!strncmp(channel, "pressure", 8)){ - ident.fields.type = pressure; - channel += 8; - } - else if(!strncmp(channel, "pitch", 5)){ - ident.fields.type = pitchbend; - } - else if(!strncmp(channel, "aftertouch", 10)){ - ident.fields.type = aftertouch; - } - else{ - LOGPF("Unknown control type in %s", spec); - return NULL; - } + if(!strncmp(channel, "cc", 2)){ + ident.fields.type = cc; + channel += 2; + } + else if(!strncmp(channel, "note", 4)){ + ident.fields.type = note; + channel += 4; + } + else if(!strncmp(channel, "pressure", 8)){ + ident.fields.type = pressure; + channel += 8; + } + else if(!strncmp(channel, "pitch", 5)){ + ident.fields.type = pitchbend; + } + else if(!strncmp(channel, "aftertouch", 10)){ + ident.fields.type = aftertouch; + } + else{ + LOGPF("Unknown control type in %s", spec); + return NULL; } ident.fields.control = strtoul(channel, NULL, 10); @@ -229,9 +199,6 @@ static int midi_set(instance* inst, size_t num, channel** c, channel_value* v){ case aftertouch: snd_seq_ev_set_chanpress(&ev, ident.fields.channel, v[u].normalised * 127.0); break; - case nrpn: - //FIXME set to nrpn output - break; } snd_seq_event_output(sequencer, &ev); @@ -241,6 +208,24 @@ static int midi_set(instance* inst, size_t num, channel** c, channel_value* v){ return 0; } +static char* midi_type_name(uint8_t type){ + switch(type){ + case none: + return "none"; + case note: + return "note"; + case cc: + return "cc"; + case pressure: + return "pressure"; + case aftertouch: + return "aftertouch"; + case pitchbend: + return "pitch"; + } + return "unknown"; +} + static int midi_handle(size_t num, managed_fd* fds){ snd_seq_event_t* ev = NULL; instance* inst = NULL; @@ -258,59 +243,45 @@ static int midi_handle(size_t num, managed_fd* fds){ while(snd_seq_event_input(sequencer, &ev) > 0){ event_type = NULL; ident.label = 0; + + ident.fields.channel = ev->data.note.channel; + ident.fields.control = ev->data.note.note; + val.normalised = (double) ev->data.note.velocity / 127.0; + switch(ev->type){ case SND_SEQ_EVENT_NOTEON: case SND_SEQ_EVENT_NOTEOFF: case SND_SEQ_EVENT_NOTE: ident.fields.type = note; - ident.fields.channel = ev->data.note.channel; - ident.fields.control = ev->data.note.note; - val.normalised = (double)ev->data.note.velocity / 127.0; if(ev->type == SND_SEQ_EVENT_NOTEOFF){ val.normalised = 0; } - event_type = "note"; break; case SND_SEQ_EVENT_KEYPRESS: ident.fields.type = pressure; - ident.fields.channel = ev->data.note.channel; - ident.fields.control = ev->data.note.note; - val.normalised = (double)ev->data.note.velocity / 127.0; - event_type = "pressure"; break; case SND_SEQ_EVENT_CHANPRESS: ident.fields.type = aftertouch; ident.fields.channel = ev->data.control.channel; - val.normalised = (double)ev->data.control.value / 127.0; - event_type = "aftertouch"; + val.normalised = (double) ev->data.control.value / 127.0; break; case SND_SEQ_EVENT_PITCHBEND: ident.fields.type = pitchbend; ident.fields.channel = ev->data.control.channel; - val.normalised = ((double)ev->data.control.value + 8192) / 16383.0; - event_type = "pitch"; + val.normalised = ((double) ev->data.control.value + 8192) / 16383.0; break; case SND_SEQ_EVENT_CONTROLLER: ident.fields.type = cc; ident.fields.channel = ev->data.control.channel; ident.fields.control = ev->data.control.param; - val.raw.u64 = ev->data.control.value; - val.normalised = (double)ev->data.control.value / 127.0; - event_type = "cc"; - break; - case SND_SEQ_EVENT_CONTROL14: - case SND_SEQ_EVENT_NONREGPARAM: - case SND_SEQ_EVENT_REGPARAM: - //FIXME value calculation - ident.fields.type = nrpn; - ident.fields.channel = ev->data.control.channel; - ident.fields.control = ev->data.control.param; + val.normalised = (double) ev->data.control.value / 127.0; break; default: LOG("Ignored event of unsupported type"); continue; } + event_type = midi_type_name(ident.fields.type); inst = mm_instance_find(BACKEND_NAME, ev->dest.port); if(!inst){ //FIXME might want to return failure |