# tuxrecord2 Record audio to WAV, FLAC or MP3 files on **Linux** using **ALSA** as the recording source. `tuxrecord2` is the **Rust** port of `tuxrecord`, the Linux port of the former macOS-only **macrecord** tool. The original port was written in C99; this rewrite keeps the same command-line interface and behaviour but is implemented in Rust on top of the safe [alsa](https://crates.io/crates/alsa) bindings and a small amount of `libc` for terminal, polling and signal handling. FLAC and MP3 output is encoded in real time through small FFI shims over the system `libFLAC` and `libmp3lame` libraries. It builds with **Cargo**. macrecord was created by my good friend Armin. You can find his code here: [https://codeberg.org/armin/macrecord](https://codeberg.org/armin/macrecord) ## Requirements - Rust toolchain (Cargo) — 1.77 or newer (uses C string literals) - ALSA development headers and `pkg-config` (`libasound2-dev` on Debian/Ubuntu, `alsa-lib-devel` on Fedora, `alsa-lib` on Arch) - FLAC and LAME (MP3) development headers and `pkg-config`, used for the bundled real-time encoders (`libflac-dev` and `libmp3lame-dev` on Debian/Ubuntu, `flac-devel` and `lame-devel` on Fedora, `flac` and `lame` on Arch). They are only needed to build; at run time the shared `libFLAC` / `libmp3lame` libraries are used. ## Usage ```bash # Record until q or Ctrl+C tuxrecord2 # Record for N seconds tuxrecord2 -d 30 tuxrecord2 --duration 30 # Specify output directory tuxrecord2 -o /path/to/dir tuxrecord2 --output /path/to/dir # Use a custom filename prefix tuxrecord2 -p myrec tuxrecord2 --prefix myrec # Use a specific ALSA capture device tuxrecord2 -D hw:1,0 tuxrecord2 --device hw:1,0 # Encode to FLAC (lossless) or MP3 (lossy) in real time tuxrecord2 -f flac tuxrecord2 --format mp3 # Record from PipeWire (the PipeWire sound server) tuxrecord2 -D pipewire ``` ## Options | Option | Description | | ----------------------- | -------------------------------------------------------- | | `-o, --output ` | Output directory (default: current directory) | | `-d, --duration ` | Stop automatically after `` seconds | | `-p, --prefix ` | Filename prefix instead of `tuxrecord2` | | `-D, --device ` | ALSA capture device (default: `default`; `pipewire` on PipeWire systems) | | `-f, --format ` | Output format: `wav`, `flac` or `mp3` (default: `wav`) | | `-h, --help` | Show help | Run `arecord -l` to list available ALSA capture devices. On systems with PipeWire, list the PipeWire source nodes with `pactl list short sources` or `wpctl status` (see "Recording from PipeWire" below). ## Controls - **q** - Stop recording and save the file - **Ctrl+C** - Stop recording and save the file The file is written as `__.` where `` is `wav`, `flac` or `mp3` depending on `-f/--format` (default prefix `tuxrecord2`). The VU meter shows the input level of the left and right channels in real time when stderr is a terminal. ## Output formats Audio is captured once and handed to the selected encoder as it arrives, so FLAC and MP3 are produced **in real time** — no intermediate WAV file is written and no second conversion pass runs afterwards. - **wav** (default) — uncompressed 16-bit little-endian PCM in a RIFF/WAVE container. - **flac** — lossless compression via libFLAC (streaming, default compression level 5). - **mp3** — lossy compression via LAME at a constant 192 kbit/s, quality 2. `wav` and `flac` preserve the captured stream exactly; `mp3` is lossy. The classic 4 GiB RIFF limit applies to `wav` only (the program stops cleanly before exceeding it); `flac` and `mp3` have no such limit. ## Recording system audio The default ALSA capture device (`default`) is usually the microphone. To record **system audio** (everything playing on the machine), route playback through the ALSA loopback driver `snd-aloop` and capture from the other side of the loop. ```bash # 1. Load the loopback module (once per boot) sudo modprobe snd-aloop # 2. Play audio on the "playback" side of the loop aplay -D hw:Loopback,0 song.wav # 3. In another terminal, record from the paired "capture" side tuxrecord2 -D hw:Loopback,1 ``` Audio written to `hw:Loopback,0` (playback) is heard on `hw:Loopback,1` (capture): the two subdevices form a loop and the samples pass straight through. Point your players at `hw:Loopback,0` (default sink) and record from `hw:Loopback,1` to capture the system mix. Subdevice pairing depends on the kernel version; if one direction is silent, try recording from `hw:Loopback,0` while playing to `hw:Loopback,1`. ## Recording from PipeWire On modern distributions (Fedora 34+, Ubuntu 22.04+, Arch Linux) the **PipeWire** sound server takes over audio handling. PipeWire ships an ALSA compatibility plugin (`pipewire-alsa`) that exposes the server as a normal ALSA capture device named `pipewire`, so `tuxrecord2` can record from it with no extra setup: ```bash # Record from PipeWire's default source (usually the microphone) tuxrecord2 -D pipewire # Record a fixed duration tuxrecord2 -D pipewire -d 10 ``` ### What "pipewire" records The pipewire-alsa plugin routes capture to PipeWire's **default source**: ```bash # Show the current default source pactl get-default-source # or: wpctl status # List all available PipeWire sources wpctl status pactl list short sources ``` ### Recording system audio (what you hear) To capture everything that is currently playing (system audio), point the default source at the **monitor** of the default sink. This is the PipeWire equivalent of the ALSA loopback approach above but needs no kernel module: ```bash # 1. Find the monitor of the default sink pactl set-default-source "$(pactl get-default-sink).monitor" # 2. Record it with tuxrecord2 tuxrecord2 -D pipewire ``` The `.monitor` source carries exactly what the sink is playing, so anything your players output ends up in the recorded file. Every capture follows the same `__.` naming and can be stopped with `q` or **Ctrl+C**. The default setting can be restored later with `pactl set-default-source `. ### Troubleshooting - **"cannot open ALSA capture device 'pipewire'"** — the `pipewire-alsa` plugin is missing. Install it (e.g. `pipewire-alsa` on Debian/Ubuntu/Arch, `pipewire-alsa` on Fedora), or the PipeWire server is not running (`systemctl --user status pipewire`). In that case fall back to a regular ALSA device with `tuxrecord2 -D hw:0,0`. - Recording from a specific device or virtual node instead of the default source is possible by setting the default source first (see `pactl` / `wpctl` output) or by creating a loopback with `pw-loopback` and recording that node. ## Build ```bash make # or directly: # cargo build --release ``` The resulting binary is `target/release/tuxrecord2`. You can also install it straight from the source tree: ```bash cargo install --path . ``` Install (installs to `$(PREFIX)/bin`, default `/usr/local/bin`): ```bash sudo make install # or: sudo cp target/release/tuxrecord2 /usr/local/bin/tuxrecord2 ``` Install to a custom prefix: ```bash make install PREFIX=~/.local ``` Uninstall: ```bash sudo make uninstall ``` ## Development ```bash make debug # cargo build make test # cargo test make fmt # cargo fmt make lint # cargo clippy -- -D warnings ``` ## License Apache License 2.0 — see the LICENSE file for details. Copyright 2026 Johannes Findeisen