Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linux/ALSA Native MIDI backend #637

Open
wants to merge 9 commits into
base: SDL2
Choose a base branch
from

Conversation

fragglet
Copy link

@fragglet fragglet commented Sep 24, 2024

This (finally!) adds a native MIDI backend for Linux using the ALSA sequencer interface. I've tested this with Chocolate Doom and the Timidity++ ALSA daemon and it works pretty reliably; I haven't gotten around to testing with actual hardware yet. There are still a couple of features missing but it should be complete enough now for people to start using it.

This does not do anything yet, but does set up the necessary build
changes so that we will link against the libasound library.
We don't write any MIDI data to the sequencer yet but this sets up the
basic foundations. For now, the playback thread just exits immediately,
so `playmus` completes successfully.
We try various different ports that are usually the "default"; we need
to provide a mechanism to specify it explicitly but for now this will
do. These are the same "default" ports that DOSbox's ALSA code tries.
This converts all the common MIDI events to the ALSA event types. The
converted events are not yet sent to ALSA.
With this change in place the module actually works! There's more still
to finish but this is actually usable.
The ALSA device we're sending messages to will continue playing them
even if the program quits, and we don't want to leave notes hanging. So
when stopping the current track, send the "notes all off" and "reset all
controllers" messages to every channel, and also send an ALSA reset
event as well for good measure (the Timidity++ daemon seems to respond
to it)
When stopping a song we must wait for the playback thread to terminate.
However, the thread may currently be doing a blocking write of some MIDI
events and we don't actually know how long this may take to complete.

Instead, we can use non-blocking mode and the poll() system call. This
allows us to sleep when the output event buffer is full, but also allows
us to wake it back up when it's time for the song to stop. We accomplish
this by creating a pipe that we close on shutdown.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant