Real time microphone noise cancellation on Linux
This article will focus on configuring the Noise cancelling plugin with PipeWire and creating a Virtual Source to use as an input for any application, even web-based applications like Discord or Steam.
Prerequisites:
- PipeWire
- Arch Linux based Distro
1. Plugin Installation
sudo pacman -S noise-suppression-for-voice
2. Create Filter chain for PipeWire
A filter chain provides the capability to insert an arbitrary graph of LADSPA (Linux Audio Developer’s Simple Plugin API) and built-in plugins in front of a sink or a source to create a new Virtual filtered sink/source.
2.1 Create a configuration directory to store filter chain configuration files.
mkdir -p ~/.config/pipewire/
2.2 Create a filter chain file with the name “input-filter-chain.conf”.
You can use any name you prefer, but make sure to use it throughout the configuration.
nano ~/.config/pipewire/input-filter-chain.conf
Paste the following content to the above file.
# Noise canceling source # # start with pipewire -c filter-chain/input-filter-chain.conf # context.properties = { log.level = 0 } context.spa-libs = { audio.convert.* = audioconvert/libspa-audioconvert support.* = support/libspa-support } context.modules = [ { name = libpipewire-module-rtkit args = { #nice.level = -11 #rt.prio = 88 #rt.time.soft = 200000 #rt.time.hard = 200000 } flags = [ ifexists nofail ] } { name = libpipewire-module-protocol-native } { name = libpipewire-module-client-node } { name = libpipewire-module-adapter } { name = libpipewire-module-filter-chain args = { node.name = "rnnoise_source" node.description = "Noise Canceling source" media.name = "Noise Canceling source" filter.graph = { nodes = [ { type = ladspa name = rnnoise plugin = /usr/lib/ladspa/librnnoise_ladspa.so label = noise_suppressor_stereo control = { "VAD Threshold (%)" 50.0 } } ] } capture.props = { node.passive = true } playback.props = { media.class = Audio/Source } } } ]
3. Persist the configuration
To load this filter chain to the PipeWire, we need to create a systemd service. The service we will be making as a systemd user instance and it will start at the first login. The systemd user instance is a per-user process and not per-session.
3.1 Create the systemd user configuration directory if it does not exist.
mkdir -p ~/.config/systemd/user/
3.2 Create a new systemd unit file.
nano ~/.config/systemd/user/pipewire-input-filter-chain.service
Make sure to replace the <username> with your account username.
[Unit] Description=PipeWire Input Filter Chain After=pipewire.service BindsTo=pipewire.service [Service] ExecStart=/usr/bin/pipewire -c /home/<username>/.config/pipewire/input-filter-chain.conf Type=simple Restart=on-failure [Install] WantedBy=pipewire.service
3.3 Reload systemd user unit files.
systemctl --user daemon-reload
3.4 Enable the created systemd service.
systemctl --user enable pipewire-input-filter-chain.service
Logout and log back in and check the sound control panel on your DE and you will see a new input source with the name “Noise cancelling source”.
4. Finally select the new audio source on applications.