Add ALSA RawMidi backend
@dagargo Here's a new issue to follow up on our discussion on pull request #60.
We can use ctypes or CFFI to call functions in the rawmidi C API. The PortMidi backend uses ctypes. I find CFFI easier to use (especially if you need to use structs) but it adds a dependency.
I suggest we start with a simple prototype that opens an output device and allows you to send messages. If this works we can look at reception.
It looks like the input device needs to be opened in blocking or nonblocking mode which doesn't fit the Mido API very well. If RawMidi supports callbacks we can use the queue trick from the RtMidi backend.
I think we should call the module mido.backends.alsa_rawmidi.
Some documentation on RawMidi:
- http://www.alsa-project.org/alsa-doc/alsa-lib/rawmidi.html
- https://ccrma.stanford.edu/~craig/articles/linuxmidi/
- https://ccrma.stanford.edu/~craig/articles/linuxmidi/alsa-1.0/
This is a long time issue but people are still struggling with this in some scenarios.
I dicover recently that it is possible to resize the MIDI ringbuffer like this, which will allow any device to send more than 4096 data bytes of SysEx without being corrupted.
root@host:/# echo "65536" > /sys/module/snd_seq_midi/parameters/output_buffer_size
The issue is that only root can do so and this should be performed every time we need to use Mido.
Adding this is a more permanent solution.
$ cat /etc/modprobe.d/local.conf
options snd_seq_midi output_buffer_size=65536
We must just keep in mind that this workaround is needed because all Mido backends use the MIDI Sequencer API, which is not intended for SysEx. For this, the RawMidi API should be used.
Probably we should close this issue. In case you still consider this will be useful, the RawMidi ALSA API bindings for Python are the way to go.