mirror of
https://github.com/zephrynis/nix-flake.git
synced 2026-08-18 05:55:53 +00:00
noise-suppression: RNNoise virtual mic via PipeWire, enable on host
App-independent mic denoising as a PipeWire filter-chain exposing a "Noise Canceling source" — replaces Discord's unusable Krisp and works in every app. Imported into the nixos-pc host. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
../../modules/nvidia.nix
|
../../modules/nvidia.nix
|
||||||
../../modules/gaming.nix
|
../../modules/gaming.nix
|
||||||
../../modules/tailscale.nix
|
../../modules/tailscale.nix
|
||||||
|
../../modules/noise-suppression.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
networking.hostName = "nixos-pc";
|
networking.hostName = "nixos-pc";
|
||||||
|
|||||||
74
modules/noise-suppression.nix
Normal file
74
modules/noise-suppression.nix
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
# App-independent microphone noise suppression via PipeWire + RNNoise.
|
||||||
|
#
|
||||||
|
# Replaces Discord's Krisp (which can't be enabled on current nixpkgs Discord:
|
||||||
|
# the binary is patchelf'd, and even after bypassing Krisp's signature check the
|
||||||
|
# newer "THz SDK" stage fails with KRISP_INIT_ERROR_GLOBAL_INIT). Instead we run
|
||||||
|
# RNNoise as a PipeWire filter-chain that exposes a cleaned virtual microphone.
|
||||||
|
#
|
||||||
|
# This works in EVERY app (Discord, browser, OBS, games), survives Discord
|
||||||
|
# updates, and touches no DRM. In each app's input settings, pick the source
|
||||||
|
# named "Noise Canceling source" instead of the raw mic.
|
||||||
|
|
||||||
|
{
|
||||||
|
# LADSPA plugin providing noise_suppressor_mono/stereo (werman RNNoise).
|
||||||
|
environment.systemPackages = [ pkgs.rnnoise-plugin ];
|
||||||
|
|
||||||
|
services.pipewire.extraConfig.pipewire."99-input-denoising" = {
|
||||||
|
"context.modules" = [
|
||||||
|
{
|
||||||
|
name = "libpipewire-module-filter-chain";
|
||||||
|
args = {
|
||||||
|
"node.description" = "Noise Canceling source";
|
||||||
|
"media.name" = "Noise Canceling source";
|
||||||
|
"filter.graph" = {
|
||||||
|
nodes = [
|
||||||
|
{
|
||||||
|
type = "ladspa";
|
||||||
|
name = "rnnoise";
|
||||||
|
plugin = "${pkgs.rnnoise-plugin}/lib/ladspa/librnnoise_ladspa.so";
|
||||||
|
label = "noise_suppressor_mono";
|
||||||
|
control = {
|
||||||
|
# Higher threshold = more aggressive gating of non-voice.
|
||||||
|
# 50% is a balanced starting point; raise toward 90–95 if a
|
||||||
|
# noisy background still leaks through, lower if speech clips.
|
||||||
|
"VAD Threshold (%)" = 50.0;
|
||||||
|
"VAD Grace Period (ms)" = 200.0;
|
||||||
|
"Retroactive VAD Grace (ms)" = 0.0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
# Makeup gain baked into the graph so the source volume is
|
||||||
|
# reproducible instead of living only in WirePlumber's runtime
|
||||||
|
# state. Mult = 1.53 matches the 153% level set in the mixer.
|
||||||
|
type = "builtin";
|
||||||
|
name = "gain";
|
||||||
|
label = "linear";
|
||||||
|
control = {
|
||||||
|
"Mult" = 1.53;
|
||||||
|
"Add" = 0.0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
links = [
|
||||||
|
{ output = "rnnoise:Output"; input = "gain:In"; }
|
||||||
|
];
|
||||||
|
};
|
||||||
|
# The virtual mic apps select. media.class = Audio/Source makes it
|
||||||
|
# appear as a capture device throughout the desktop.
|
||||||
|
"capture.props" = {
|
||||||
|
"node.name" = "capture.rnnoise_source";
|
||||||
|
"node.passive" = true;
|
||||||
|
"audio.rate" = 48000;
|
||||||
|
};
|
||||||
|
"playback.props" = {
|
||||||
|
"node.name" = "rnnoise_source";
|
||||||
|
"media.class" = "Audio/Source";
|
||||||
|
"audio.rate" = 48000;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user