# headroom Automatic loudness and per-app volume control for PipeWire, in Rust. Headroom puts a per-application audio safety net between noisy sources (browsers, voice chat, random video) and your speakers, while leaving the things you *don't* want compressed (music players, games, DAWs) untouched. - **Hard −0.1 dBTP ceiling on the processed route**, with proper inter-sample-peak handling, enforced inline so the contract holds regardless of control-plane state. Streams routed `bypass` ride the real sink directly and are not in scope of the contract — that's the trade-off that makes the per-app exclusion useful. - **Per-app exclusion** with profile-driven rules. - **Layer A per-app level control** (peak + RMS detector → smoothed `channelVolumes` writes) for taming individual streams without touching the bus path. Zero added signal-path latency; safe to use on bypass-routed streams. - **Single binary** daemon + CLI, controlled over a Unix-domain socket with a documented JSON wire protocol (see [`IPC.md`](IPC.md)). - **First-party Rust crate** (`headroom-client`) for programmatic use; third-party clients (Qt panels, status bars, …) target the wire protocol directly. - **Live profile reload** — edit a TOML file in `$XDG_CONFIG_HOME/headroom/profiles/` and the daemon picks up changes within ~500 ms; the audio thread doesn't glitch. See [`PLAN.md`](PLAN.md) for the full design and roadmap. ## Status Alpha. The signal chain (AGC, compressor, two-tier limiter, Layer A per-app), the routing engine (explicit-link enforcement, sink hotplug, sticky default sink), the IPC server with topic subscriptions, the `headroom monitor` TUI, and live profile reload all work end-to-end. Packaging exposes a systemd user unit and Nix modules. What's missing is real-world soak time on multi-rate / Bluetooth setups and other distros' init systems. ## Installing ### Nix (flake) This repo is a flake; the daemon plus its systemd user unit and the canonical profiles are exposed as a package. ```sh nix run github:atagen/headroom -- daemon # one-shot run nix profile install github:atagen/headroom # add to $PATH ``` For **Home Manager**, add the flake as an input and enable the module: ```nix { inputs.headroom.url = "github:atagen/headroom"; # In your Home Manager configuration: imports = [ inputs.headroom.homeModules.default ]; services.headroom.enable = true; } ``` The module symlinks the shipped profiles into `$XDG_CONFIG_HOME/headroom/profiles/`, drops the systemd user unit into the user's services dir, and the unit starts after PipeWire and WirePlumber come up. `services.headroom.extraProfiles` lets you add your own. For **NixOS** (system-wide binary install + systemd-user discovery): ```nix { inputs.headroom.url = "github:atagen/headroom"; # In your NixOS configuration: imports = [ inputs.headroom.nixosModules.default ]; programs.headroom.enable = true; } ``` Then any user can `systemctl --user enable --now headroom`. ### Other distros (manual) ```sh cargo install --path crates/headroom-cli # or: cargo build --release # Profiles mkdir -p ~/.config/headroom/profiles cp profiles/*.toml ~/.config/headroom/profiles/ # systemd user unit (edit the ExecStart path to point at your binary) install -Dm644 contrib/systemd/headroom.service \ ~/.config/systemd/user/headroom.service sed -i "s|@bindir@|$(dirname "$(command -v headroom)")|" \ ~/.config/systemd/user/headroom.service systemctl --user daemon-reload systemctl --user enable --now headroom ``` ## Usage Once the daemon is running: ```sh headroom status # JSON snapshot — sinks, streams, active profile headroom profile list # available profiles headroom profile use night # activate one headroom monitor # full-screen TUI (bus gauges + per-stream) headroom monitor --json meters # line-delimited JSON, for scripting headroom route set firefox processed headroom set compressor.threshold_db -28 headroom bypass on # kill switch — straight to the real sink ``` See `headroom --help` for the full surface. ## Building ```sh nix develop # toolchain + pipewire dev libs + helpers cargo build # iterate cargo test --workspace nix build # final packaged headroom binary ``` ## License GPL-3.0-or-later for the daemon and CLI. `headroom-dsp` and `headroom-ipc` are MPL-2.0 so they can be reused by non-GPL plugin hosts and clients.