Initial commit.
This commit is contained in:
commit
d0a20cd562
7 changed files with 1160 additions and 0 deletions
199
README.md
Normal file
199
README.md
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
# tuxrecord2
|
||||
|
||||
Record audio to a WAV file 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. 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)
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Record until q or Ctrl+C
|
||||
tuxrecord2
|
||||
|
||||
# Record for N seconds
|
||||
tuxrecord2 -d 30
|
||||
|
||||
# Specify output directory
|
||||
tuxrecord2 -o /path/to/dir
|
||||
|
||||
# Use a custom filename prefix
|
||||
tuxrecord2 -p myrec
|
||||
|
||||
# Use a specific ALSA capture device
|
||||
tuxrecord2 -D hw:1,0
|
||||
|
||||
# Record from PipeWire (the PipeWire sound server)
|
||||
tuxrecord2 -D pipewire
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
| Option | Description |
|
||||
| -------------- | -------------------------------------------------------- |
|
||||
| `-o <dir>` | Output directory (default: current directory) |
|
||||
| `-d <secs>` | Stop automatically after `<secs>` seconds |
|
||||
| `-p <prefix>` | Filename prefix instead of `tuxrecord2` |
|
||||
| `-D <device>` | ALSA capture device (default: `default`; `pipewire` on PipeWire systems) |
|
||||
| `-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>.wav` (default prefix
|
||||
`tuxrecord2`). The VU meter shows the input level of the left and right channels
|
||||
in real time when stderr is a terminal.
|
||||
|
||||
## 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 WAV file. Every capture follows the same
|
||||
`<prefix>__<timestamp>.wav` 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue