tuxrecord2/README.md
2026-10-15 03:34:39 +02:00

234 lines
7.5 KiB
Markdown

# 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 <dir>` | Output directory (default: current directory) |
| `-d, --duration <secs>` | Stop automatically after `<secs>` seconds |
| `-p, --prefix <prefix>` | Filename prefix instead of `tuxrecord2` |
| `-D, --device <device>` | ALSA capture device (default: `default`; `pipewire` on PipeWire systems) |
| `-f, --format <fmt>` | 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 `<prefix>__<timestamp>.<ext>` where `<ext>` 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 `<prefix>__<timestamp>.<ext>` naming and can be stopped with `q` or
**Ctrl+C**. The default setting can be restored later with
`pactl set-default-source <your-input-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