fix(pipewire): denoising through configPackages, desktop gets steam and bitwig
The RNNoise config was deployed to /etc/xdg/pipewire, which PipeWire never reads: it resolves $PIPEWIRE_CONFIG_DIR, then the home config, then its compiled-in /etc/pipewire, and knows nothing of XDG_CONFIG_DIRS. An installed system therefore had no denoising while carrying the file. It now goes through services.pipewire.configPackages, with the LADSPA plugin substituted to its store path since LADSPA_PATH has no /usr here. Alongside, on the desktop host only: steam via its module (which also turns on 32-bit graphics), bitwig-studio, and rtkit so a DAW can ask for realtime scheduling at all.
This commit is contained in:
@@ -1,5 +1,63 @@
|
||||
# Decisions
|
||||
|
||||
## 2026-08-20 – Input denoising was deployed to a path PipeWire never reads
|
||||
|
||||
- **Who**: Dominik, ClaudeCode
|
||||
- **Why**: The Arch machine runs RNNoise input denoising, and the config for it
|
||||
lives in the shared tree as
|
||||
`defaults/xdg/pipewire/pipewire.conf.d/99-input-denoising.conf`. It was in
|
||||
`modules/desktop.nix` too, in the generic sweep to `/etc/xdg/` — and inert
|
||||
there. PipeWire resolves its config directory from `$PIPEWIRE_CONFIG_DIR`,
|
||||
then `$XDG_CONFIG_HOME/pipewire` or `$HOME/.config/pipewire`, then the
|
||||
compiled-in `/etc/pipewire`; `XDG_CONFIG_DIRS` appears nowhere in
|
||||
`src/pipewire/conf.c`. On Arch the file works because `post-install.sh` seeds
|
||||
it into the home directory. Same class as the swaylock config on 2026-08-18: a
|
||||
file installed to a plausible path that the program does not read.
|
||||
- **Tradeoffs**: (1) **Which option** — the module accepts both
|
||||
`services.pipewire.extraConfig.pipewire.<name>` (Nix attributes, rendered to
|
||||
JSON) and `services.pipewire.configPackages` (a package carrying
|
||||
`share/pipewire/pipewire.conf.d/*.conf`); both end up in the same merged
|
||||
directory (`pipewire.nix:59-75`). The NixOS wiki uses `extraConfig` for its
|
||||
examples, which are written by hand and have no file behind them. Taking that
|
||||
route here would mean translating the shared file into Nix and maintaining the
|
||||
VAD values in two places, so `configPackages` was chosen — which is also what
|
||||
the module's own option documentation shows for a conf.d file
|
||||
(`pipewire.nix:258-279`). (2) **The plugin path** — the file names the plugin
|
||||
as `librnnoise_ladspa`, resolved through `LADSPA_PATH`, which is
|
||||
`/usr/lib/ladspa` on Arch and does not exist here. There is no LADSPA
|
||||
counterpart to `services.pipewire.extraLv2Packages`, so the absolute store
|
||||
path is substituted into the file, the same treatment the wallpaper paths get.
|
||||
- **How**: `denoisingConfig` via `runCommand` + `substitute`, handed to
|
||||
`services.pipewire.configPackages`. The `xdg/pipewire/` entry in
|
||||
`environment.etc` is removed rather than kept for layout parity — after the
|
||||
swaylock case, an inert copy is a liability. Verified by building the package:
|
||||
the conf.d file is there, the plugin line points at
|
||||
`rnnoise-plugin-1.10/lib/ladspa/librnnoise_ladspa.so`, and that file exists.
|
||||
- **Note**: the filter chain shows up as a separate "Noise Canceling source"
|
||||
input. It does not replace the raw microphone; applications have to select it.
|
||||
|
||||
## 2026-08-20 – Steam, Bitwig and rtkit belong to the desktop alone
|
||||
|
||||
- **Who**: Dominik, ClaudeCode
|
||||
- **Why**: Both programs are wanted on the desktop and on no other machine, so
|
||||
they go into `hosts/desktop/default.nix` rather than the shared module every
|
||||
host imports.
|
||||
- **Tradeoffs**: (1) **Steam** — `pkgs.steam` in `systemPackages` is the wrong
|
||||
handle: the module wraps the binary in an FHS environment and turns on
|
||||
`hardware.graphics.enable32Bit` itself (`nixos/modules/programs/steam.nix:215-218`),
|
||||
which the bare package would leave off. (2) **Bitwig** — the `bitwig-studio`
|
||||
attribute currently resolves to `bitwig-studio6-6.0.11`; `bitwig-studio5`
|
||||
(5.3.13) exists as a separate attribute if a downgrade is ever needed.
|
||||
Dominik chose 6. (3) **Realtime** — `security.rtkit.enable` was off. The
|
||||
rlimits the PipeWire module installs (`rtprio` 95, `nice` -19, `memlock`)
|
||||
apply to members of the `pipewire` group, and the account is in
|
||||
`networkmanager wheel video input plugdev docker` only, so a DAW had no path
|
||||
to realtime scheduling at all. Enabled on this host, where the DAW is.
|
||||
- **How**: `programs.steam.enable`, `security.rtkit.enable` and
|
||||
`environment.systemPackages = [ pkgs.bitwig-studio ]` in the host file.
|
||||
Verified by evaluating both hosts: on `desktop` all three are set and 32-bit
|
||||
graphics came along; on `thinkpad` Steam and rtkit stay `false`.
|
||||
|
||||
## 2026-08-20 – The browser is LibreWolf from nixpkgs, not a self-packaged Waterfox
|
||||
|
||||
- **Who**: Dominik, ClaudeCode
|
||||
|
||||
@@ -109,6 +109,20 @@
|
||||
# the shared module sets it unconditionally.
|
||||
services.fwupd.enable = lib.mkForce false;
|
||||
|
||||
# --- Applications, this machine only ---
|
||||
#
|
||||
# Steam comes as a module rather than a package: it wraps the binary in an FHS
|
||||
# environment and turns on 32-bit graphics for the drivers, which the package
|
||||
# alone would not do.
|
||||
programs.steam.enable = true;
|
||||
|
||||
# Lets audio applications ask for realtime scheduling, which Bitwig does. The
|
||||
# rlimits the PipeWire module sets (rtprio 95, memlock) apply to members of
|
||||
# the pipewire group only, and this account is not one.
|
||||
security.rtkit.enable = true;
|
||||
|
||||
environment.systemPackages = [ pkgs.bitwig-studio ];
|
||||
|
||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
|
||||
|
||||
+28
-2
@@ -36,6 +36,24 @@ let
|
||||
--replace-fail /usr/share/moonarch/wallpaper-blur.jpg ${wallpaperBlur}
|
||||
'';
|
||||
|
||||
# PipeWire searches $PIPEWIRE_CONFIG_DIR, then $XDG_CONFIG_HOME/pipewire, then
|
||||
# its compiled-in /etc/pipewire — never /etc/xdg (verified in PipeWire's
|
||||
# src/pipewire/conf.c). The shared file therefore cannot be deployed the way
|
||||
# the other XDG configs are; it goes through the module's configPackages,
|
||||
# which is what its own option documentation shows for a conf.d file.
|
||||
#
|
||||
# The file names the plugin as `librnnoise_ladspa`, resolved through
|
||||
# LADSPA_PATH — /usr/lib/ladspa on Arch, nothing here. Substituted to the
|
||||
# store path, like the wallpaper paths above. LADSPA has no counterpart to
|
||||
# services.pipewire.extraLv2Packages, so the path belongs in the file.
|
||||
denoisingConfig = pkgs.runCommand "moonarch-pipewire-denoising" { } ''
|
||||
mkdir -p "$out/share/pipewire/pipewire.conf.d"
|
||||
substitute ${xdg}/pipewire/pipewire.conf.d/99-input-denoising.conf \
|
||||
"$out/share/pipewire/pipewire.conf.d/99-input-denoising.conf" \
|
||||
--replace-fail "plugin = librnnoise_ladspa" \
|
||||
"plugin = ${pkgs.rnnoise-plugin}/lib/ladspa/librnnoise_ladspa.so"
|
||||
'';
|
||||
|
||||
# zsh/newuser runs its setup wizard on every interactive login for as long as
|
||||
# the user has none of .zshenv, .zprofile, .zshrc or .zlogin — the whole
|
||||
# configuration living in /etc/zshrc does not count. Seeded below to stop
|
||||
@@ -74,8 +92,9 @@ in
|
||||
"xdg/qt6ct/qt6ct.conf".source = "${xdg}/qt6ct/qt6ct.conf";
|
||||
"xdg/gtk-3.0/settings.ini".source = "${xdg}/gtk-3.0/settings.ini";
|
||||
"xdg/gtk-4.0/settings.ini".source = "${xdg}/gtk-4.0/settings.ini";
|
||||
"xdg/pipewire/pipewire.conf.d/99-input-denoising.conf".source =
|
||||
"${xdg}/pipewire/pipewire.conf.d/99-input-denoising.conf";
|
||||
# No xdg/pipewire/ entry: PipeWire does not read /etc/xdg, so the file was
|
||||
# deployed and inert. It goes through services.pipewire.configPackages
|
||||
# below instead.
|
||||
# Kept for layout parity with the Arch package; waypaper itself only reads
|
||||
# the copy in the home directory, seeded below.
|
||||
"xdg/waypaper/config.ini".source = waypaperConfig;
|
||||
@@ -202,6 +221,13 @@ in
|
||||
openmoji-color
|
||||
];
|
||||
|
||||
# --- Audio ---
|
||||
#
|
||||
# RNNoise input denoising, from the shared config. The filter chain appears as
|
||||
# a separate "Noise Canceling source" input; it does not replace the raw
|
||||
# microphone, so applications have to select it.
|
||||
services.pipewire.configPackages = [ denoisingConfig ];
|
||||
|
||||
# --- Printing ---
|
||||
#
|
||||
# Driverless only, and no printer is declared here. Asked over IPP, the
|
||||
|
||||
Reference in New Issue
Block a user