Skip to content

v0.8.0

Choose a tag to compare

@mdwn mdwn released this 26 Feb 18:03
· 152 commits to main since this release
9f6dfce

Added

MIDI-triggered sample playback has been added. Samples can be configured globally or per-song
with the following features:

  • Velocity handling: Configurable velocity sensitivity with optional fixed velocity override
  • Note Off behavior: Samples can play to completion, stop immediately, or fade out on Note Off
  • Retrigger behavior: Polyphonic mode allows layering, cut mode stops previous instances
  • Voice limits: Global and per-sample voice limits with oldest-voice stealing
  • Output routing: Samples can be routed to specific output channels via track mappings
  • In-memory preloading: Samples are decoded and cached in memory for low-latency playback

Sample triggering uses a fixed-latency scheduling system that ensures consistent trigger-to-audio
latency with zero jitter. At 256 sample buffer size (44.1kHz), latency is approximately 11.6ms
(~5.8ms scheduled delay + ~5.8ms output buffer). Cut transitions are sample-accurate - old
samples stop at exactly the same sample the new one starts, eliminating gaps.

The audio engine has been refactored for lower latency and stability:

Audio is now fully optional. mtrack can run as a pure MIDI or DMX player without any
audio device configured. This enables dedicated lighting-only or MIDI-only nodes.

A warning is displayed when playing songs that have tracks that are not configured to
be output in the current player configuration. This will not cause an error, but will be
logged so that it's easier to diagnose a misconfiguration.

Hardware profiles allow multiple complete host configurations in a single config file:

  • Unified profiles (profiles): Define complete per-host configurations in a single list.
    Each profile specifies audio (optional), MIDI (optional), and DMX (optional) for one host.
    All three subsystems are optional — a profile can define any combination (e.g. MIDI-only,
    DMX-only, audio + MIDI, etc.). Subsystem presence in profile = required, absence = skipped.

  • Hostname filtering: Each profile can optionally specify a hostname constraint so that
    different hosts sharing the same config file use different devices and channel mappings.
    Set the MTRACK_HOSTNAME environment variable to override the system hostname.

  • Per-host optionality: All subsystems (audio, MIDI, DMX) can be required on some hosts
    (present in profile) and optional on others (absent from profile), enabling flexible
    multi-host setups such as dedicated lighting-only or MIDI-only nodes.

  • External profiles directory (profiles_dir): Load profiles from individual YAML files in a
    directory instead of (or in addition to) defining them inline. Each file defines one profile.
    Files are sorted by filename for deterministic ordering. Directory profiles are prepended
    before inline profiles, making them useful for host-specific configs with inline fallbacks.

  • Backwards compatible: Existing configs using audio:, midi:, dmx:, and track_mappings:
    are automatically normalized into a single profile at startup.

  • Direct callback mode: The CPAL callback now calls the mixer directly, eliminating the
    intermediate ring buffer. This follows the pattern used by professional audio systems
    (ASIO, CoreAudio, JACK) for lowest possible latency.

  • Lock-free voice cancellation using atomic flags

  • Channel-based source addition to decouple sample engine from mixer locks

  • Inline cleanup of finished sources during mixing (simpler, no separate cleanup pass)

  • Bounded source channel (capacity 64) to prevent unbounded memory growth

  • Precomputed channel mappings at sample load time (no allocations during trigger)

  • Song playback is buffered to reduce buffer underrun.

  • Audio stress test (examples/audio_stress): A standalone stress test binary for
    verifying real-time audio performance against real hardware. Sweeps buffer sizes, sample
    rates, and formats; ramps source counts; and churns source creation/destruction. Reports
    pass/fail based on callback budget headroom. Useful for validating hardware configurations
    before live use.

Changed

  • cpal 0.15.3 to 0.17.1: Updated for improved ALSA handling. (Breaking) Device names
    may have changed. Run mtrack devices to check.
  • Symphonia replaces hound: Supports flac, ogg, vorbis, mp3, alac, aac, and anything
    else Symphonia supports, not just wav.
  • Security: mtrack now supports running as a dedicated mtrack user instead of root
    via systemd, with updated service definitions and documentation.
  • Error handling: Improved error reporting and panic aversion across the player, DMX
    engine, sample loader, and playlist handling.
  • Lighting cleanup: A pass of cleanup on the lighting system, improving code quality
    across the effect engine, parser, timeline, and layering.

Fixed

  • Stop during playback: Fixed a bug where stopping too fast after playing could produce
    a hang. This is unlikely to have happened in a live scenario.
  • Clean device shutdown: The CPAL output stream now shuts down promptly when the device
    is dropped, fixing a bug where the stream thread would block indefinitely on join.
  • Lighting bug fixes: Fixed bugs in the lighting system discovered during cleanup.