Skip to content

Comments

Add Nix flake for out-of-the-box NixOS support#16

Open
zitongcharliedeng wants to merge 13 commits intoflipcoder:mainfrom
zitongcharliedeng:nix-support
Open

Add Nix flake for out-of-the-box NixOS support#16
zitongcharliedeng wants to merge 13 commits intoflipcoder:mainfrom
zitongcharliedeng:nix-support

Conversation

@zitongcharliedeng
Copy link

@zitongcharliedeng zitongcharliedeng commented Feb 13, 2026

Summary

I made this to run midimech easily on my NixOS machines at home. Single command, zero manual setup:

nix run github:zitongcharliedeng/midimech/nix-support

This sets up everything automatically — Python environment, all dependencies, and a virtual MIDI cable (equivalent to loopMIDI on Windows). Been using this daily on two NixOS machines over the past few days with no issues.

What's included

  • flake.nix — Self-contained Nix package. Builds all Python deps from PyPI (rtmidi2, launchpad-py, musicpy, mido-fix), compiles the native MIDI virtual cable, and bundles everything into a single midimech command. Includes desktop entry with icon for GNOME/KDE.

  • midimech-vport.c — Tiny C program that creates an ALSA sequencer virtual MIDI port named "midimech". Equivalent to loopMIDI on Windows. Started automatically when you run midimech. Any synth (SurgeXT, etc.) subscribes to this port to receive MIDI.

  • NixOS module — System-wide install via services.midimech.enable = true. Installs desktop entry with icon and blacklists snd_seq_dummy to remove the "Midi Through Port-0" phantom device.

Bug fix included

Wrapped launchpad detection (src/core.py) in try/except — launchpad_py's Check()/Open() calls throw RtMidiError on Linux ALSA when the requested port index doesn't exist (on Windows WinMM it returns False gracefully). This crashed midimech on any Linux system without a Launchpad connected.

Tested

Smoke tested and used daily on NixOS unstable (x86_64-linux) with PipeWire + ALSA, LinnStrument → midimech → SurgeXT. Full MIDI chain working, LEDs working, no crash without Launchpad connected.

🤖 Generated with Claude Code

zitongcharliedeng and others added 3 commits February 13, 2026 11:42
- flake.nix: self-contained Nix package with all Python deps
  (rtmidi2, launchpad-py, musicpy, mido-fix) and native MIDI
  virtual cable (midimech-vport)
- midimech-vport.c: native C ALSA sequencer virtual MIDI cable,
  equivalent to loopMIDI on Windows
- midimech-launch.py: launcher that starts vport + midimech
- NixOS module with snd_seq_dummy blacklist for clean MIDI ports
- Fix launchpad_py crash on Linux ALSA when no Launchpad connected

Usage:
  nix run github:zitongcharliedeng/midimech#midimech

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The launcher is trivial shell glue (start vport, sleep, exec midimech).
Convention: flake handles its own wrappers in installPhase.

Repo now has only flake.nix, flake.lock, and midimech-vport.c as
nix-related files. midimech-vport.c is real Linux source code, not
nix plumbing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@zitongcharliedeng
Copy link
Author

Known limitation: extra "RtMidi" ports visible on Linux

On Linux ALSA, each rtmidi2.MidiIn() / MidiOut() instance creates a globally visible ALSA sequencer client. This means synths like SurgeXT will see 2-3 "RtMidi" entries alongside the actual "midimech" port. On Windows WinMM, these internal connections are invisible — this is a fundamental difference in how ALSA exposes MIDI clients vs how WinMM handles them.

This is an rtmidi2/ALSA behavior, not something we can fix at the midimech level without replacing rtmidi2 with direct ALSA sequencer bindings. Functionally harmless — users just need to select the "midimech" port and ignore the RtMidi entries.

@zitongcharliedeng
Copy link
Author

Note: audio glitches at very low ALSA buffer sizes

At buffer sizes below 128 samples (2.9ms), audio through ALSA/PipeWire can become distorted and glitchy under heavy polyphony. This is an ALSA + PipeWire scheduling limitation, not a midimech issue — the same behavior occurs with any MIDI source at those buffer sizes on Linux. 128 samples / 44100 Hz (2.9ms) is a solid sweet spot for low latency without artifacts.

zitongcharliedeng and others added 8 commits February 13, 2026 12:20
Installs midimech.desktop and icon so desktop environments
can show midimech in their application menu.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Without this, GNOME shows a generic gear icon in alt-tab and
the taskbar because it can't associate the pygame/SDL2 window
with the desktop entry.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Documents nix run, nix profile install, and NixOS module
usage with the recommended virtual MIDI cable setup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Removed misleading claim that nix profile install creates
desktop entries. Only the NixOS module provides full desktop
integration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The virtual MIDI cable is always started with midimech.
No need for a separate binary without it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Virtual cable starts by default (recommended). Pass --no-vport
to skip it for users who manage MIDI routing themselves.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The flake is NixOS-only. The vport IS the point — it's the
loopMIDI equivalent. Users who don't want it run midimech.py
directly, same as on Windows/Mac.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Version was incorrectly set to 0.1.0-chromatic-quantize
despite nix-support being based on main. Set SDL hints for
icon matching on both Wayland and X11 backends.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@zitongcharliedeng
Copy link
Author

zitongcharliedeng commented Feb 13, 2026

Okay the icon seems to be working in alt-tab Wayland GNOME too now.

midimech-wayland-icon

zitongcharliedeng and others added 2 commits February 14, 2026 15:37
The Python launcher (removed in b4a648e) set cwd= to the midimech
directory. The inlined shell launcher did not, so scales.yaml and
settings.ini were not found when launched from a .desktop file.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
GNOME desktop launches don't inherit NixOS shell environment.
Without ALSA_CONFIG_PATH, rtmidi2 can't find alsa.conf, fails to
create a sequencer client, and pygame segfaults on MIDI init.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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