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 --- artnet.c | 9 ++++++--- midi.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- midimonster.c | 13 +++++++++++++ monster.cfg | 3 ++- 4 files changed, 80 insertions(+), 6 deletions(-) diff --git a/artnet.c b/artnet.c index 1fe8fb2..2684d46 100644 --- a/artnet.c +++ b/artnet.c @@ -80,9 +80,12 @@ static int artnet_configure_instance(instance* instance, char* option, char* val } static channel* artnet_channel(instance* instance, char* spec){ - fprintf(stderr, "Parsing ArtNet channelspec %s\n", spec); - //TODO - return NULL; + unsigned channel = strtoul(spec, NULL, 10); + if(channel > 512 || channel < 1){ + fprintf(stderr, "Invalid ArtNet channel %s\n", spec); + return NULL; + } + return mm_channel(instance, channel); } static int artnet_set(size_t num, channel* c, channel_value* v){ 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; } diff --git a/midimonster.c b/midimonster.c index aeaf04d..367ca6f 100644 --- a/midimonster.c +++ b/midimonster.c @@ -50,6 +50,16 @@ int mm_map_channel(channel* from, channel* to){ return 0; } +void map_free(){ + size_t u; + for(u = 0; u < mappings; u++){ + free(map[u].to); + } + free(map); + mappings = 0; + map = NULL; +} + int usage(char* fn){ fprintf(stderr, "MIDIMonster v0.1\n"); fprintf(stderr, "Usage:\n"); @@ -75,7 +85,9 @@ int main(int argc, char** argv){ if(config_read(cfg_file)){ fprintf(stderr, "Failed to read configuration file %s\n", cfg_file); backends_stop(); + channels_free(); instances_free(); + map_free(); return usage(argv[0]); } @@ -93,6 +105,7 @@ bail: backends_stop(); channels_free(); instances_free(); + map_free(); return rv; } diff --git a/monster.cfg b/monster.cfg index b638e56..eb65a07 100644 --- a/monster.cfg +++ b/monster.cfg @@ -28,5 +28,6 @@ output = true net = 0 [map] -net1.231 = lc1.cc5 +net1.231 = foo.1 +net1.255 = lc1.cc1.1 ;net1.231 = osc.f/channel5/ toggle=127 -- cgit v1.2.3