MIDIplex is a utility for volume-aware distributing a polyphonic MIDI stream into multiple output streams. The output streams are guaranteed to be monophonic. Output streams are allocated to a note in proportion to that note's velocity, relative to the velocity of other notes being played.
Music is often polyphonic, i.e., at times, there are multiple notes playing simultaneously. However, some synthesizers are monophonic, i.e., they can only voice one sound at a time. MIDIplex consumes a MIDI stream and automagically distributes it across a set number of output channels in such a way that it is guaranteed that no output will be expected to play two notes or more notes simultaneously. You can use MIDIplex to render a polyphonic MIDI across a given number of monophonic synthesizers, be it a choir of musical floppy disks, or (as I am) across a lab of computers with beep
installed.
For a visual depiction of how MIDIplex distributes notes, watch this demonstration video, in which events from an input keyboard (top) are distributed across three output channels.
MIDIplex integrates with the Advanced Linux Sound Architecture. MIDIplex therefore is only supported on systems running Linux.
USAGE:
midiplex [OPTIONS] <OUTPUT MODE>
OPTIONS:
-i, --input-pool-size <I> sets the ALSA input pool size
-m, --max-allocation <N> sets the maximum number of outputs allocated to any note
OUTPUT MODES:
alsa ALSA output mode
udp UDP output mode
MIDIplex consumes input as a virtual ALSA MIDI device named ‘midiplex’ with a writable port named ‘input’. You can verify that MIDIplex is running with aconnect
:
$ aconnect -l
client 0: 'System' [type=kernel]
0 'Timer '
1 'Announce '
client 14: 'Midi Through' [type=kernel]
0 'Midi Through Port-0'
client 128: 'midiplex' [type=user,pid=6496]
0 'input
MIDIplex supports two output modes. For most users, the ALSA output mode offers the most flexibility.
In the ALSA output mode, midiplex creates a specified list of readable ports to which it distributes notes. You can then patch those notes to other MIDI devices using the aconnect
utility from alsa-utils
, or a visual connection manager such as patchage.
USAGE:
midiplex alsa [OPTIONS] <NAMES>...
OPTIONS:
-o, --output-pool-size <O> sets output pool size
ARGS:
<NAMES>... space-delimited names of output ports
$ midiplex alsa melete mneme aoide & aconnect -l
[1] 10337
client 0: 'System' [type=kernel]
0 'Timer '
1 'Announce '
client 14: 'Midi Through' [type=kernel]
0 'Midi Through Port-0'
client 128: 'midiplex' [type=user,pid=10337]
0 'input '
1 'melete '
2 'mneme '
3 'aoide '
The ALSA output mode is resource-intensive. For 𝘯 outputs, each input note on and off event must be copied 𝘯 times. If those 𝘯 output ports are then patched to 𝘯 synthesizers, that entails additional copying of the event. These issues can be somewhat assuaged with --input-pool-size
and --output-pool-size
, but for large values of 𝘯, intensive pieces may nonetheless cause MIDIplex to terminate with ENOSPC
.
For cases where ALSA output mode is unsuitable, MIDIplex can write its output directly to a UDP socket. Note on and off events are encoded as three-byte datagrams, as described by the MIDI specification. You can receive these messages using a utility such as MIDInet or qmidinet.
USAGE:
midiplex udp [HOSTS]...
ARGS:
<HOSTS>... space-delimited socket addresses
Assuming three reachable hosts, melete, mneme and aoide:
$ midiplex udp melete:8336 mneme:8336 aoide:8336 & aconnect -l
[1] 13114
client 0: 'System' [type=kernel]
0 'Timer '
1 'Announce '
client 14: 'Midi Through' [type=kernel]
0 'Midi Through Port-0'
client 128: 'midiplex' [type=user,pid=13114]
0 'input '