What it does
pwtune works on the .conf files in the folder you run it in, like a linter
or formatter. A profile's state is its filename: desk.draft.conf is a draft you can edit,
desk.calibrated.conf is frozen, and promote is the rename between them. The
generated EQ is a starting point: trust the low and low-mid bands, and use your ears above about 1–2 kHz.
Measure what a speaker does
pwtune measure plays a logarithmic sine sweep out a speaker, records it back through a mic
and prints the frequency response. It averages --iterations passes (3 by default) and
changes nothing.
A starting EQ, written for you
pwtune create desk measures, designs a parametric EQ toward a target curve and writes
./desk.draft.conf. --class, from laptop to
fullrange, declares how low the speaker may be pushed and adds a 4th-order high-pass at
that corner.
Profiles that follow the device
Each profile is a PipeWire filter-chain config that creates a virtual sink. Its
target-match pattern is matched at install time against each sink, including a
monitor's EDID name, so one profile follows the device across machines.
Made for scripts and agents
Every verb takes a name and flags that answer its prompts, so the whole lifecycle can run
non-interactively. --quiet and NO_COLOR=1 keep the output clean, and
pwtune --llm prints the whole guide.
A first look
list changes nothing. It shows one line per profile in the current folder:
● when its speaker is connected right now, then its tags: draft or calibrated, installed,
active output.
$ cd ~/audio/profiles
$ pwtune list
● desk Desk speakers [calibrated · installed · active output]
○ tv Living-room TV [draft]
Install
Homebrew, on Linux
For x86_64 and arm64. On x86_64 it pours a prebuilt binary, so no compiler is needed. The tap is trusted once first, as Homebrew 6 and later ask.
brew trust --tap jakobhviid/tapbrew install jakobhviid/tap/pwtune
Or one line, without Homebrew
No compiler and no root: downloads the prebuilt binary for your architecture to
~/.local/bin (set PWTUNE_BIN_DIR to choose another folder).
curl -fsSL https://raw.githubusercontent.com/jakobhviid/pwtune/main/install.sh | sh
Or build from source
Needs Rust. The binary lands in ./target/release/pwtune.
cargo build --release
It needs PipeWire
pwtune uses PipeWire's pactl, paplay and parecord; PipeWire is the
default audio server on most modern distros. Nothing else is needed: the sweep, the analysis and the EQ
design are built into the binary.
Documentation
- README: every command, the speaker classes and how profiles work
- WORKFLOWS.md: end-to-end recipes, and the flags that drive each command without prompts
- pipewire-speaker-profiles: ready-made profiles for specific devices
- Releases