From ed55916e772264dc8278fc8c96d4139aec31e89e Mon Sep 17 00:00:00 2001 From: cbdev Date: Mon, 5 Jun 2017 16:37:02 +0200 Subject: Backend channel spec parsing --- midi.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) (limited to 'midi.c') diff --git a/midi.c b/midi.c index 0d51d38..3cd8507 100644 --- a/midi.c +++ b/midi.c @@ -5,6 +5,18 @@ #define BACKEND_NAME "midi" static snd_seq_t* sequencer = NULL; +/* + * TODO + * Optionally send note-off messages + */ + +enum /*_midi_channel_type*/ { + none = 0, + note, + cc, + sysmsg +}; + int midi_init(){ backend midi = { .name = BACKEND_NAME, @@ -68,8 +80,53 @@ static int midi_configure_instance(instance* instance, char* option, char* value } static channel* midi_channel(instance* instance, char* spec){ - fprintf(stderr, "Parsing MIDI channelspec %s\n", spec); - //TODO + union { + struct { + uint8_t pad[5]; + uint8_t type; + uint8_t channel; + uint8_t control; + } fields; + uint64_t label; + } ident = { + .label = 0 + }; + + char* channel; + + if(!strncmp(spec, "cc", 2)){ + ident.fields.type = cc; + channel = spec + 2; + } + else if(!strncmp(spec, "note", 4)){ + ident.fields.type = note; + channel = spec + 4; + } + else{ + fprintf(stderr, "Unknown MIDI channel specification %s\n", spec); + return NULL; + } + + ident.fields.channel = strtoul(channel, &channel, 10); + + //FIXME test this + if(ident.fields.channel > 16){ + fprintf(stderr, "Channel out of range in channel spec %s\n", spec); + return NULL; + } + + if(*channel != '.'){ + fprintf(stderr, "Need MIDI channel specification of form channel.control, had %s\n", spec); + return NULL; + } + channel++; + + ident.fields.control = strtoul(channel, NULL, 10); + + if(ident.label){ + return mm_channel(instance, ident.label); + } + return NULL; } -- cgit v1.2.3