Skip to content

swilcox/rtrax

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rtrax

CI Coverage License: MIT Made with Rust Edition 2021 Platform Type: TUI Audio: libopenmpt Latest release Last commit Code size Top language

A TUI module player for .mod / .xm / .it / .s3m / .mtm (and anything else libopenmpt reads). Per-channel level meters, scrolling pattern view, master spectrum analyzer, file browser. macOS + Linux.

rtrax screenshot

The image above is a placeholder mockup — swap in a real terminal capture by overwriting docs/screenshot.png.

Install

System library — libopenmpt is a runtime dependency, not vendored.

# macOS
brew install libopenmpt

# Debian / Ubuntu
sudo apt install libopenmpt-dev

# Arch
sudo pacman -S libopenmpt

Then build with cargo:

cargo build --release

If the linker can't find libopenmpt, set RTRAX_OPENMPT_LIB_DIR to its location, or make sure pkg-config --libs libopenmpt returns a -L path.

Run

# Launch the TUI; loads a file immediately if given.
cargo run --release -- some_song.xm

# Headless: play a file to the end, no UI.
cargo run --release --example play -- some_song.xm

# Smoke test: just print metadata.
cargo run --release --example load_print -- some_song.xm

Release-mode is meaningful — debug-mode FFT + decode can underrun the audio buffer on modest hardware.

CLI options

rtrax [OPTIONS] [FILES]...
Option Description
[FILES]... One or more module files. Two or more become an inline playlist; n/p navigate within it.
-l, --playlist <FILE> Load an M3U playlist; n/p navigate within it and a saves to it.
--theme <THEME> Override the theme from config (e.g. neon-blue, c64, mono).
--no-config Skip the config file and use built-in defaults.
-h, --help Print help.
-V, --version Print version.

Playlists

Full details: docs/playlists.md

rtrax uses the standard M3U format — plain text, one file path per line, lines starting with # are comments or metadata and are ignored.

Loading a playlist:

# Load from a .m3u file; n/p navigate within it.
rtrax --playlist my-favourites.m3u

# Pass multiple files directly — they become an inline playlist for the session.
rtrax *.xm

Adding songs while playing:

Press a to append the currently-playing file to the active playlist. If no playlist is loaded, the song is saved to the default playlist at:

  • Linux: ~/.local/share/rtrax/playlist.m3u
  • macOS: ~/Library/Application Support/rtrax/playlist.m3u

The file is created automatically (with an #EXTM3U header) if it doesn't exist yet. Pressing a multiple times is safe — each press appends one entry.

Navigation priority:

n and p check the active playlist first. If no playlist is loaded (e.g. you opened a single file), they fall back to the files in the same folder.

Keybindings

Key Action
space Play / pause
s Stop
n / p Next / previous (playlist, then folder)
a Add current song to playlist
/ Seek −5 s / +5 s
[ / ] Volume down / up
/ Focus file browser
Tab Cycle focus
t Cycle theme
b Cycle progress bar style
i Toggle info panel (samples + metadata)
m Show full song message (scrollable)
w Cycle pattern stack (1 / 2 / 4 lanes)
c Toggle compact cells (drops volume + effect)
? Help overlay
q Quit

Override any binding in $XDG_CONFIG_HOME/rtrax/config.toml.

Themes

Select a built-in or custom theme in $XDG_CONFIG_HOME/rtrax/config.toml:

theme = "default"

Built-ins are default, high-contrast, sixteen, neon-blue, neon-green, neon-orange, c64, and mono. Custom themes live in $XDG_CONFIG_HOME/rtrax/themes/<name>.toml and are selected by file stem:

theme = "amber"
# $XDG_CONFIG_HOME/rtrax/themes/amber.toml
extends = "default"

accent = "#ffb454"
note = "#ffe6a3"
instrument = "light-cyan"
volume = "yellow"
effect = "#ff7a90"
current_row_bg = "#302414"

Theme files may override any subset of these color keys: bg, fg, fg_dim, border, border_focus, accent, note, instrument, volume, effect, meter_low, meter_mid, meter_high, and current_row_bg. Values can be #rrggbb, reset, or ratatui ANSI color names such as cyan, dark-gray, and light-magenta. Pressing t cycles built-ins plus any .toml files found in the themes directory. See docs/themes.md for the full theme reference.

Progress bar

The header shows a progress bar between the order/pattern stats and the time display. Four styles are available:

Style Looks like Notes
triangle [━━━━▲────] Single marker over an empty track
blocks ████▌ Smooth fill via eighth-block chars (default)
line ━━━━╸──── Heavy elapsed, light remaining, notch at head
segments ▰▰▰▰▱▱▱▱ Discrete pip segments

Pick one in config, or press b to cycle them at runtime:

progress_bar_style = "blocks"

Architecture

See PLAN.md. In one paragraph: the audio thread owns the openmpt module and the cpal stream. Inside the cpal callback it decodes interleaved f32 stereo, copies a downsampled mono slice into an rtrb ring for the FFT, and updates atomic snapshots of order/row/BPM/VU. The UI thread (~30 fps) reads those atomics, drains the ring for FFT input, and renders a ratatui frame. The cpal callback never allocates, locks (other than try_lock), or logs.

Logs

Logs go to $XDG_CACHE_HOME/rtrax/rtrax.log.YYYY-MM-DD — file-only, never stdout, because that would corrupt ratatui's alternate-screen rendering.

Out of scope

  • Editing / sample manipulation. Playback only.
  • Network features, streaming protocols, web UI.
  • Format conversion (libopenmpt is read-only here).
  • Plugin systems, scripting, custom DSP effects.
  • Windows support — not blocked, but not a v1 goal.

About

TUI MOD/XM/IT/S3M/MTM module player in Rust

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors