pwtune

Measure any speaker with any microphone, then build and install a PipeWire EQ profile from the result.

brew trust --tap jakobhviid/tapbrew install jakobhviid/tap/pwtune

Install Read the README

Linux, x86_64 and arm64 · needs PipeWire · MIT licensed

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