aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2017-06-05 16:37:02 +0200
committercbdev <cb@cbcdn.com>2017-06-05 16:37:02 +0200
commited55916e772264dc8278fc8c96d4139aec31e89e (patch)
tree9c003bc1e41aceb9a0af3a664785dcd76c03b8f6
parentc47b0765a8605b9afcc6205a6d2396ccbe3d5e05 (diff)
downloadmidimonster-ed55916e772264dc8278fc8c96d4139aec31e89e.tar.gz
midimonster-ed55916e772264dc8278fc8c96d4139aec31e89e.tar.bz2
midimonster-ed55916e772264dc8278fc8c96d4139aec31e89e.zip
Backend channel spec parsing
-rw-r--r--artnet.c9
-rw-r--r--midi.c61
-rw-r--r--midimonster.c13
-rw-r--r--monster.cfg3
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