aboutsummaryrefslogtreecommitdiffhomepage
path: root/backends/midi.c
diff options
context:
space:
mode:
Diffstat (limited to 'backends/midi.c')
-rw-r--r--backends/midi.c143
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