Skip to content

Mesh v0.9.3

Choose a tag to compare

@github-actions github-actions released this 21 Feb 11:57
· 589 commits to main since this release

Installation

Linux (.deb)

Download the .deb package for your system:

  • mesh-player — Performance mode (4-deck stem player)
  • mesh-cue — Editing mode (waveform editor, analysis, stem separation)
  • mesh-cue-cuda — Editing mode with NVIDIA GPU acceleration
sudo dpkg -i mesh-player_*.deb mesh-cue_*.deb
# Install dependencies if needed:
sudo apt-get install -f

Requirements: PipeWire (Ubuntu 22.04+, Fedora 34+) or JACK2, glibc 2.35+

Windows (.zip)

Extract the zip and run the .exe directly. No installation required.
GPU acceleration via DirectML (any DirectX 12 GPU).

NixOS / Nix

Run directly (x86_64-linux):

nix run github:dataO1/Mesh#mesh-player
nix run github:dataO1/Mesh#mesh-cue

aarch64-linux (Orange Pi 5 / embedded): A pre-built binary cache is published to GitHub Pages with every release. Configure the cache and update:

# /etc/nix/nix.conf (or flake nixConfig)
extra-substituters = https://datao1.github.io/Mesh/
extra-trusted-public-keys = mesh-embedded:vLo1l3Abp0Uzcn21wR3oXvmZxZb1Z1rbk+ggTOIGmeQ=

# Update an embedded device
nixos-rebuild switch --flake github:dataO1/Mesh#mesh-embedded --no-write-lock-file

ML models are downloaded automatically on first use.


[0.9.3]

Fixed

  • USB: device label resolution — USB sticks were showing kernel device names
    (e.g. "/dev/sda") instead of human-readable names. On Linux, now resolves the
    filesystem label from /dev/disk/by-label/, falling back to the hardware model
    name from sysfs (e.g. "STORE N GO"), then /dev/sdX as last resort. macOS and
    Windows are unaffected (sysinfo already returns proper volume labels there).

  • Embedded: ES8388 audio init — mesh-audio-init service was failing on every
    boot because the Headphone mixer control is a switch, not a volume. Replaced
    the single broken amixer command with a proper init script that enables the
    headphone amplifier path (hp switch on), sets PCM and output volumes, disables
    3D spatial processing, and ensures left/right mixer paths are enabled.

  • Embedded: ALSA device aliases — mesh_cue and mesh_master PCM aliases
    used type hw (raw hardware access), which rejected mono audio and any format
    the ES8388 doesn't natively accept. Changed to type plug with nested
    slave.pcm for automatic format, channel, and sample rate conversion.

  • Embedded: PipeWire low-latency config — Added PipeWire clock configuration
    with 256-sample quantum at 48kHz (5.33ms per period), min 64, max 1024. Without
    this, PipeWire defaulted to 1024 samples (21.3ms).

  • Embedded: WirePlumber device rules — Split the combined ES8388/PCM5102A
    match into separate rules with per-device priorities. Reduced api.alsa.headroom
    from 256 to 0 (I2S codecs use DMA, not USB batch transfer, so headroom adds
    unnecessary latency). PCM5102A gets higher priority.driver so it becomes the
    graph clock source when connected.

  • Embedded: JACK audio routing via pw-link — PipeWire JACK clients with
    node.always-process=true (set by the JACK layer) remain on Dummy-Driver
    unless explicit port links exist to a real ALSA sink. target.object,
    PIPEWIRE_NODE, and priority.driver all proved insufficient — they are
    routing hints that don't force driver assignment. The kiosk wrapper now starts
    mesh-player via pw-jack in the background, waits for its JACK ports to
    register, then creates pw-link connections from master_left/master_right
    to the ES8388's playback_FL/playback_FR. This reliably moves mesh-player
    off Dummy-Driver onto the ES8388 graph driver.

  • Embedded: WirePlumber config via environment.etc — The NixOS
    services.pipewire.wireplumber.extraConfig option silently fails to create
    config files on NixOS 24.11 (/etc/wireplumber/ was empty). Switched to
    environment.etc for direct file creation with WirePlumber 0.5 SPA-JSON
    format, ensuring ALSA tuning rules (session.suspend-timeout-seconds,
    api.alsa.period-size, priority.driver) are actually deployed.

  • CI: Windows cross-compilation bindgen — signalsmith-stretch bindgen
    failed with stdbool.h not found after Phase 4's unset BINDGEN_EXTRA_CLANG_ARGS.
    bindgen auto-injects --target=x86_64-pc-windows-gnu which makes clang lose
    its resource directory. Now re-exports BINDGEN_EXTRA_CLANG_ARGS with just
    the clang include path (no MinGW sysroot) immediately after the unset.

  • Embedded: mesh-player logging — Process substitution (> >(systemd-cat ...))
    doesn't survive through pw-jack's exec chain, so all mesh-player log output
    was silently lost. Replaced with a named FIFO pipe to systemd-cat, making
    logs available via journalctl -t mesh-player. Also sets RUST_LOG=info by
    default (overridable via systemctl set-environment).

Added

  • MIDI: Master BPM slider control — The master BPM slider is now controllable
    via MIDI. GlobalAction::SetBpm was stubbed out; it now routes through the
    full pipeline: range_for_action("global.bpm") maps CC 0-127 to 60-200 BPM,
    the mapping engine converts to SetBpm, and the app handler calls
    set_global_bpm_with_engine(). The MIDI learn wizard includes a "Move the
    BPM slider" step at the end of the Browser phase across all layout variants.
  • Embedded: Default config files — Ship midi.yaml, slicer-presets.yaml,
    and theme.yaml to /home/mesh/Music/mesh-collection/ via systemd tmpfiles
    C (copy-if-not-exists) rules, so the Orange Pi boots with working defaults
    while preserving any user modifications on subsequent updates.
  • Embedded: PAM audio limits — @audio group gets unlimited memlock,
    rtprio 99, and nice -19 for real-time audio scheduling.
  • Embedded: RT kernel tuning — Added threadirqs kernel parameter (threads
    all IRQ handlers for priority control) and vm.swappiness=10 (keeps audio
    buffers in RAM).

Changed

  • CI: Split native deps cache from Rust build cache — Essentia, FFmpeg, and
    TagLib (pinned C/C++ libraries that never change) now have a separate GitHub
    Actions cache keyed on the build script hash instead of Cargo.lock. Previously,
    any Rust dependency update invalidated the entire cache, forcing 10-60 minute
    rebuilds of unchanged native libraries. The stable deps cache persists across
    Cargo.lock changes, saving significant CI time on every release.
  • CI: Regenerated binary cache signing key — Replaced the cache signing key
    pair and fixed the narinfo signing pipeline. nix copy and nix store sign
    are now separate steps with key format validation and post-sign verification
    to prevent silent signing failures.