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

native_midi: Add support for native MIDI on Linux #595

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Commits on Jun 19, 2024

  1. native_midi: Add support for native MIDI on Linux

    This adds support for native MIDI on Linux using the ALSA sequencer API.
    
    Playback is performed by spawning a thread which processes SMF events,
    converts them to ALSA SEQ ones, and forwards them to a synth client.
    
    To ensure responsiveness (and not cause applications to freeze), the
    sequencer API is used in nonblock mode. When an event is added to a
    queue, it is first sent to a userspace buffer, which is eventually
    flushed to a kernel buffer and then sent to the destination. This means
    that events are processed in chunks until the buffer is filled which
    then gets drained, and not in realtime.
    
    A socketpair is set up for the main thread to control the playback
    thread, which uses poll() to wait until IO can be performed on the
    sequencer or a command can be received from the main thread.
    
    The playback thread reports its status by writing to an atomic enum.
    
    Two new hints are introduced:
    - SDL_NATIVE_MUSIC_ALLOW_PAUSE
    - SDL_NATIVE_MUSIC_NO_CONNECT_PORTS
    
    Pausing is implemented by stopping the queue and setting the volume to 0
    with a GM SysEx Master Volume message. Since at the time of writing none
    of the most common use cases support it (FluidSynth, Emu10k1 WaveTable,
    Linux OPL3 MIDI Synth), pausing is disabled by default as it is
    preferred to have music playing instead of listening to hanging notes.
    
    The hint SDL_NATIVE_MUSIC_ALLOW_PAUSE was added so that a user with a
    compatible MIDI device can simply set the environment variable
    SDL_NATIVE_MUSIC_ALLOW_PAUSE=1 to enable pausing.
    
    The implementation outputs events to any client subscribed to its port.
    When the hint SDL_NATIVE_MUSIC_NO_CONNECT_PORTS is set, it does not
    attempt to automatically connect the port to a client. This might be
    desired if the end user uses an external patchbay application.
    
    Otherwise, it first checks for the environment variable
    ALSA_OUTPUT_PORTS, and if successfully parsed and the client is found,
    the output port is connected to it automatically. This env var is used
    by aplaymidi. If it could not be parsed, or it is not set, then the
    first MIDI synth client is preferred. If one is not found, then the
    application connects its port to any available client as a last resort.
    tatokis committed Jun 19, 2024
    Configuration menu
    Copy the full SHA
    2133c27 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    867fdb5 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    d7f5641 View commit details
    Browse the repository at this point in the history