Low-latency TUI MIDI drum sampler for electronic drum kits on Linux, macOS, and Windows.
Connect your e-drums (Alesis Nitro Max, Roland, Yamaha, etc.) via USB and trigger custom audio samples with sub-6ms latency. No DAW, no configuration files — just drop WAV files into a folder and play.
- Sub-6ms latency — lock-free audio pipeline with zero allocations on the audio thread, pre-decoded samples held in RAM, and a lock-free SPSC ring buffer between MIDI and audio threads
- Simple sample mapping — name WAV files by MIDI note number (
36.wavfor kick,38.wavfor snare) and drop them into a folder - Velocity layers —
38_v1.wav,38_v2.wavfor dynamic expression across the velocity range - Round-robin —
38_v1_rr1.wav,38_v1_rr2.wavto cycle through variations and avoid the machine-gun effect - Hot-reload — edit samples while playing, changes load automatically with zero downtime
- Built-in Kit Store — press
sto browse and download kits from GitHub repositories, grouped by repo with progress tracking. Add your own repos withr - On-the-fly kit switching — press
kto browse and switch kits instantly, no restart needed - On-the-fly device switching — press
ato switch audio output devices andmto switch MIDI inputs without restarting - Note mappings — built-in General MIDI and Alesis Nitro Max presets, per-kit
mapping.tomlsupport, user-created mappings, and live note renaming - Library directory management — browse, add, and remove extra kit and mapping directories on-the-fly (
d), persisted across restarts - Settings persistence — selected kit, audio device, MIDI input, and extra directories are remembered between sessions
- Hi-hat choke groups — closing the hi-hat pedal chokes open hi-hat samples with a natural fade-out
- Cymbal grab choke — polyphonic aftertouch silences cymbals for realistic muting
- Live pad visualization — TUI grid shows hits with velocity-mapped green flash intensity
- Hit log — scrolling log of recent hits with note names, numbers, and velocity bars
- Stderr capture — ALSA/PipeWire noise captured and viewable in a log popup (
l), keeping the TUI clean - Interactive setup — guided picker for kit, audio device, and MIDI port if not specified via CLI flags
- CLI-first — all options available as flags for scripting and quick launch (
drumkit play --kit ./my-kit --port 0 --device 2)
brew tap backmeupplz/drumkit
brew install drumkit
sudo add-apt-repository ppa:borodutch/drumkit
sudo apt install drumkit
yay -S drumkit
Download the latest drumkit-windows-x86_64.zip from Releases, extract it, and run it from the terminal:
# Navigate to the folder where you extracted the zip
cd C:\Users\YourName\Downloads\drumkit-windows-x86_64
# Run drumkit
.\drumkit.exe playTo make drumkit available from anywhere, add the folder to your PATH:
- Press Win + R, type
sysdm.cpl, press Enter - Go to Advanced → Environment Variables
- Under User variables, select Path, click Edit
- Click New and add the folder path (e.g.
C:\Users\YourName\Programs\drumkit) - Click OK, then restart your terminal
Now you can run drumkit play from any directory.
git clone https://github.com/backmeupplz/drumkit.git
cd drumkit
cargo install --path .
- Rust 1.75+
- Linux: ALSA development libraries:
sudo pacman -S alsa-lib(Arch) orsudo apt install libasound2-dev(Debian/Ubuntu) - macOS: No additional dependencies — CoreAudio and CoreMIDI are provided by the system
- Windows: No additional dependencies — WASAPI and Windows MIDI are provided by the system
Sample kits are available from the built-in Kit Store — press s during the setup flow or in play mode to browse and download kits from the drumkit-kits repository. Downloaded kits are saved to ~/.local/share/drumkit/kits/.
You can also add custom kit repositories — press r inside the Kit Store to manage repos. See Creating a Kit Repository for details.
# 1. See what MIDI devices are connected
drumkit devices
# 2. Monitor MIDI input — hit pads to see note numbers
drumkit monitor --port 0
# 3. Play! Interactive setup picks kit, audio, and MIDI for you
drumkit play
# 4. Or skip setup entirely with flags
drumkit play --kit ~/.local/share/drumkit/kits/My-Kit --port 0 --device 2
# 5. Add extra sample library folders
drumkit play --kits-dir /path/to/samples --kits-dir /another/path| Key | Action |
|---|---|
k |
Kit picker — browse and switch between discovered kits (s inside to open store) |
s |
Kit Store — browse and download kits from configured repositories (r to manage repos) |
n |
Mapping picker — switch note name mappings (General MIDI, Alesis, user-created, or kit-bundled) |
r |
Rename note — rename the most recently hit pad (creates a user mapping if editing a built-in) |
d |
Directory manager — browse kit and mapping directories, add new ones (a/A), or remove user-added ones (Del) |
a |
Audio device picker — switch audio output device |
m |
MIDI input picker — switch MIDI input port |
l |
Log viewer — view captured stderr (ALSA/PipeWire noise) and kit summary |
q |
Quit |
All selections (kit, audio device, MIDI input) are saved to ~/.config/drumkit/settings.toml and restored on next launch.
drumkit searches for kits in these directories:
$XDG_DATA_HOME/drumkit/kits/(usually~/.local/share/drumkit/kits/)- Any directories added via
--kits-diror theddirectory manager
Each subdirectory containing audio files is a kit:
~/.local/share/drumkit/kits/
├── My-Rock-Kit/
│ ├── 36.wav # Kick — single sample
│ ├── 38_v1_rr1.wav # Snare — soft, variation 1
│ ├── 38_v1_rr2.wav # Snare — soft, variation 2
│ ├── 38_v2_rr1.wav # Snare — hard, variation 1
│ ├── 38_v2_rr2.wav # Snare — hard, variation 2
│ ├── 42.wav # Closed hi-hat
│ ├── 46.wav # Open hi-hat
│ ├── 49.wav # Crash
│ └── mapping.toml # Optional kit-specific note names
└── Electronic-Kit/
└── ...
Adding a new kit is instant — create a folder, drop in audio files, and press k to see it. Editing samples while playing triggers an automatic hot-reload with zero downtime.
Supported audio formats: WAV, FLAC, OGG, MP3.
{midi_note}[_v{velocity_layer}][_rr{round_robin}].wav
| Pattern | Meaning |
|---|---|
36.wav |
Single sample for MIDI note 36 (kick) |
38_rr1.wav, 38_rr2.wav |
Round-robin only (cycles through variations) |
38_v1.wav, 38_v2.wav |
Velocity layers only (v1=soft, v2=hard) |
38_v1_rr1.wav |
Both velocity layers and round-robin |
Mappings give human-readable names to MIDI note numbers and define choke groups. drumkit resolves mappings in this order:
- Kit-bundled — if the kit folder contains a
mapping.toml, it's loaded automatically when you switch to that kit - User-selected — press
nto pick from available mappings (built-in presets, user-created, kit-bundled) - Default — General MIDI drum names
Built-in presets: General MIDI, Alesis Nitro Max.
Creating a mapping: press r after hitting a pad to rename it. If the current mapping is built-in, a user copy is created automatically. User mappings are saved to $XDG_DATA_HOME/drumkit/mappings/ (usually ~/.local/share/drumkit/mappings/).
Kit-bundled mapping: add a mapping.toml to your kit folder:
name = "My Kit"
[notes]
36 = "Kick"
38 = "Snare"
42 = "Closed Hi-Hat"
46 = "Open Hi-Hat"
[chokes]
42 = [46] # closing hi-hat chokes the open hi-hat
44 = [46] # pedal hi-hat also chokes open hi-hatExtra mapping directories: press d then A to add directories containing .toml mapping files. These are persisted in settings and appear in the n picker.
| Note | Drum |
|---|---|
| 36 | Kick |
| 38 | Snare (head) |
| 40 | Snare (rim) |
| 42 | Closed Hi-Hat |
| 44 | Pedal Hi-Hat |
| 46 | Open Hi-Hat |
| 48 | Hi-Mid Tom |
| 45 | Low Tom |
| 43 | High Floor Tom |
| 41 | Low Floor Tom |
| 49 | Crash 1 |
| 57 | Crash 2 |
| 51 | Ride |
Anyone can create a GitHub repository that works as a kit source for drumkit's Kit Store. The repo just needs to follow a simple folder structure:
your-drumkit-kits/
├── My-Rock-Kit/
│ ├── 36.wav
│ ├── 38_v1_rr1.wav
│ ├── 38_v1_rr2.wav
│ ├── 42.wav
│ ├── 46.wav
│ └── mapping.toml # optional
├── Electronic-Kit/
│ ├── 36.wav
│ ├── 38.wav
│ └── ...
└── README.md # optional, ignored by drumkit
Requirements:
- Each top-level directory is treated as a kit
- Kits contain audio files following the naming convention (
{note}[_v{layer}][_rr{robin}].wav) - Files at the repo root (like
README.md) are ignored - The repo must have a
mainbranch - Supported formats: WAV, FLAC, OGG, MP3
Adding your repo to drumkit:
- Press
sto open the Kit Store - Press
rto open the repo manager - Press
aand enter your repo inowner/repoformat (e.g.myuser/my-drumkit-kits) - Press
Escto go back — your kits will appear in the store alongside the default ones
Repos are persisted in ~/.config/drumkit/settings.toml and scanned every time you open the Kit Store.
[MIDI Thread] → lock-free ring buffer → [Audio Thread (RT)] → speakers
↑
[Filesystem Watcher] → [Main Thread / TUI] → sample reload
- MIDI input via
midir(ALSA/JACK on Linux, CoreMIDI on macOS, Windows MIDI on Windows) - Audio output via
cpal(ALSA/PipeWire on Linux, CoreAudio on macOS, WASAPI on Windows) - Lock-free SPSC ring buffer between threads (
rtrb) - Samples pre-decoded to f32 PCM in RAM
- Zero allocations on the audio thread
ArcSwapfor lock-free kit hot-swapping- Filesystem watching via
notifyfor automatic hot-reload
For the best experience on Arch Linux with PipeWire:
mkdir -p ~/.config/pipewire/pipewire.conf.d
cat > ~/.config/pipewire/pipewire.conf.d/low-latency.conf << 'EOF'
context.properties = {
default.clock.rate = 48000
default.clock.quantum = 64
default.clock.min-quantum = 32
}
EOF
systemctl --user restart pipewireThis brings PipeWire's buffer down to ~1.3ms. Combined with drumkit's lock-free pipeline, total pad-to-sound latency is typically under 6ms.
git clone https://github.com/backmeupplz/drumkit.git
cd drumkit
# Build in debug mode
cargo build
# Run directly
cargo run -- play
# Run tests
cargo test
# Build optimized release binary
cargo build --releaseThe codebase is a single Rust crate:
| Module | Purpose |
|---|---|
main.rs |
CLI parsing, resource wiring |
tui/ |
Terminal UI, popups, key handling, rendering |
audio.rs |
Audio output stream, voice mixing |
midi.rs |
MIDI input, callback routing |
kit.rs |
Kit loading, velocity/round-robin grouping |
download.rs |
Kit Store — GitHub API fetching and kit downloading |
mapping.rs |
Note name mappings, choke groups, TOML parsing |
settings.rs |
Persisted user settings (kit, devices, directories) |
setup.rs |
Interactive setup flow |
sample.rs |
Multi-format audio decoding (WAV, FLAC, OGG, MP3) |
stderr.rs |
Stderr capture for clean TUI |
MIT
