aboutsummaryrefslogtreecommitdiffhomepage
path: root/backends
diff options
context:
space:
mode:
Diffstat (limited to 'backends')
-rw-r--r--backends/midi.c40
-rw-r--r--backends/midi.md23
2 files changed, 54 insertions, 9 deletions
diff --git a/backends/midi.c b/backends/midi.c
index ad7f6fe..2999e6b 100644
--- a/backends/midi.c
+++ b/backends/midi.c
@@ -24,6 +24,9 @@ enum /*_midi_channel_type*/ {
none = 0,
note,
cc,
+ pressure,
+ aftertouch,
+ pitchbend,
nrpn,
sysmsg
};
@@ -174,6 +177,16 @@ static channel* midi_channel(instance* instance, char* spec){
ident.fields.type = nrpn;
channel += 4;
}
+ else if(!strncmp(channel, "pressure", 8)){
+ ident.fields.type = pressure;
+ channel += 8;
+ }
+ else if(!strncmp(channel, "pitch", 8)){
+ ident.fields.type = pitchbend;
+ }
+ else if(!strncmp(channel, "aftertouch", 10)){
+ ident.fields.type = aftertouch;
+ }
}
ident.fields.control = strtoul(channel, NULL, 10);
@@ -209,6 +222,16 @@ static int midi_set(instance* inst, size_t num, channel** c, channel_value* v){
case cc:
snd_seq_ev_set_controller(&ev, ident.fields.channel, ident.fields.control, v[u].normalised * 127.0);
break;
+ case pressure:
+ snd_seq_ev_set_keypress(&ev, ident.fields.channel, ident.fields.control, v[u].normalised * 127.0);
+
+ break;
+ case pitchbend:
+ snd_seq_ev_set_pitchbend(&ev, ident.fields.channel, (v[u].normalised * 16383.0) - 8192);
+ break;
+ 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;
@@ -239,13 +262,28 @@ static int midi_handle(size_t num, managed_fd* fds){
switch(ev->type){
case SND_SEQ_EVENT_NOTEON:
case SND_SEQ_EVENT_NOTEOFF:
- case SND_SEQ_EVENT_KEYPRESS:
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;
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;
+ 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;
+ 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;
+ break;
case SND_SEQ_EVENT_CONTROLLER:
ident.fields.type = cc;
ident.fields.channel = ev->data.control.channel;
diff --git a/backends/midi.md b/backends/midi.md
index 7d3e847..315edfe 100644
--- a/backends/midi.md
+++ b/backends/midi.md
@@ -22,25 +22,32 @@ Each instance also provides a virtual port, so MIDI devices can also be connecte
#### Channel specification
-The MIDI backend supports multiple channel types
+The MIDI backend supports mapping different MIDI events to MIDIMonster channels. The currently supported event types are
* `cc` - Control Changes
* `note` - Note On/Off messages
+* `pressure` - Note pressure/aftertouch messages
+* `aftertouch` - Channel-wide aftertouch messages
+* `pitch` - Channel pitchbend messages
* `nrpn` - NRPNs (not yet implemented)
-A channel is specified using the syntax `channel<channel>.<type><index>`. The shorthand `ch` may be used instead
-of `channel`.
+A MIDIMonster channel is specified using the syntax `channel<channel>.<type><index>`. The shorthand `ch` may be
+used instead of the word `channel` (Note that `channel` here refers to the MIDI channel number).
The earlier syntax of `<type><channel>.<index>` is officially deprecated but still supported for compatability
reasons. This support may be removed at some future time.
-Channels range from `0` to `15`. Each channel consists of 128 notes (numbered `0` through `127`) and 128 CC's
-(numbered likewise), a channel pressure control (also called 'channel aftertouch') and a pitch control.
-Each Note also has an additional pressure value associated with it.
+The `pitch` and `aftertouch` events are channel-wide, thus they can be specified as `channel<channel>.<type>`.
+
+MIDI channels range from `0` to `15`. Each MIDI channel consists of 128 notes (numbered `0` through `127`), which
+additionally each have a pressure control, 128 CC's (numbered likewise), a channel pressure control (also called
+'channel aftertouch') and a pitch control which may all be mapped to individual MIDIMonster channels.
Example mappings:
```
midi1.ch0.note9 > midi2.channel1.cc4
-midi1.channel15.cc1 > midi1.channel0.note0
+midi1.channel15.pressure1 > midi1.channel0.note0
+midi1.aftertouch > midi2.cc0
+midi1.pitch > midi2.pitch
```
#### Known bugs / problems
@@ -51,4 +58,4 @@ a configuration option at a later time.
NRPNs are not yet fully implemented, though rudimentary support is in the codebase.
To see which events your MIDI devices output, ALSA provides the `aseqdump` utility. You can
-list all incoming events using `aseqdump -p <portname>`. \ No newline at end of file
+list all incoming events using `aseqdump -p <portname>`.