Skip to content

Linux/ALSA Native MIDI backend #637

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

Closed
wants to merge 9 commits into 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.
@sezero
Copy link
Contributor

sezero commented Mar 12, 2025

This was somehow missed and #595 was merged...

@fragglet: Can we pick bits from here into presently existing one? If yes, rebase?

CC: @slouken, @icculus

@sezero
Copy link
Contributor

sezero commented Mar 12, 2025

This was somehow missed and #595 was merged...

@fragglet: Can we pick bits from here into presently existing one? If yes, rebase?

CC: @slouken, @icculus

And I missed that this is agaignst SDL2 branch, which I believe that we want to leave alone?

Adapting things from this one to SDL3_mixer (main branch) would be best, I guess?

@slouken
Copy link
Collaborator

slouken commented Mar 12, 2025

Yes, this should go in SDL3, not SDL2.

@fragglet
Copy link
Author

I'm fine with us going with the #595 route instead. Just really happy to see SDL_mixer get a Linux midi backend at last!

If there is anything from my implementation that look like it's missing from the one that got merged, please let me know and I can adapt it.

@fragglet fragglet closed this Mar 12, 2025
@sezero
Copy link
Contributor

sezero commented Mar 12, 2025

I'm fine with us going with the #595 route instead. Just really happy to see SDL_mixer get a Linux midi backend at last!

If there is anything from my implementation that look like it's missing from the one that got merged, please let me know and I can adapt it.

CC @tatokis

@tatokis
Copy link
Contributor

tatokis commented Mar 16, 2025

I don't immediately see anything missing. One thing I am unsure about is Sysex handling, as I don't think my implementation passes them through. I'll look into it shortly.

@sezero
Copy link
Contributor

sezero commented Mar 16, 2025

I don't immediately see anything missing. One thing I am unsure about is Sysex handling, as I don't think my implementation passes them through. I'll look into it shortly.

Great, thanks

@fragglet
Copy link
Author

I don't immediately see anything missing. One thing I am unsure about is Sysex handling, as I don't think my implementation passes them through. I'll look into it shortly.

I have a personal interest in making sure sysex messages are handled properly (one of my original motivations was to be able to hook up synths like the Roland sc55) so if you don't have the time to look into it please say and I can take it off your hands

@tatokis
Copy link
Contributor

tatokis commented Mar 17, 2025

I have a personal interest in making sure sysex messages are handled properly (one of my original motivations was to be able to hook up synths like the Roland sc55) so if you don't have the time to look into it please say and I can take it off your hands

Please have a look at #679 and let me know if it works.

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.

4 participants