Skip to content

Instantly share code, notes, and snippets.

@aminnez
Created November 6, 2025 14:15
Show Gist options
  • Select an option

  • Save aminnez/54fb4e404e4806398d82ca29f9cc7641 to your computer and use it in GitHub Desktop.

Select an option

Save aminnez/54fb4e404e4806398d82ca29f9cc7641 to your computer and use it in GitHub Desktop.
DeepFilterNet Installation Script for Linux (PipeWire)

DeepFilterNet Installation Script for PipeWire

This script installs the DeepFilterNet LADSPA plugin system-wide in Linux (Like Ubuntu) and configures it as a virtual microphone with noise cancellation in PipeWire.

Usage:

  1. Download the appropriate library for your architecture from this repo:

https://github.com/Rikorose/DeepFilterNet/releases

  1. Download the gist and run it.
chmod +x ./install-deepfilter.sh

./install-deepfilter.sh [path-to-libdeep_filter_ladspa.so]

3.In your system’s Sound settings: Choose “DeepFilter Microphone” for system-wide input.

#!/bin/bash
################################################################################
# DeepFilterNet Installation Script for PipeWire
#
# This script installs DeepFilterNet LADSPA plugin system-wide and configures
# it as a virtual microphone with noise cancellation in PipeWire.
#
# Usage: bash install-deepfilter.sh [path-to-libdeep_filter_ladspa.so]
#
# If no path is provided, the script will look for the .so file in:
# - Current directory
# - ~/Downloads
# - Common download locations
#
# Author: Amin Nezampour
# Date: 2025-11-06
################################################################################
set -euo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Configuration
LADSPA_INSTALL_PATH="$HOME/.ladspa/libdeep_filter_ladspa.so"
PIPEWIRE_CONFIG_DIR="$HOME/.config/pipewire/filter-chain.conf.d"
PIPEWIRE_CONFIG_FILE="$PIPEWIRE_CONFIG_DIR/50-deepfilter-mic.conf"
################################################################################
# Helper Functions
################################################################################
print_header() {
echo -e "${BLUE}=================================================================================${NC}"
echo -e "${BLUE}$1${NC}"
echo -e "${BLUE}=================================================================================${NC}"
}
print_success() {
echo -e "${GREEN}✓ $1${NC}"
}
print_error() {
echo -e "${RED}✗ $1${NC}"
}
print_info() {
echo -e "${YELLOW}ℹ $1${NC}"
}
print_step() {
echo -e "\n${BLUE}→ $1${NC}"
}
exit_error() {
print_error "$1"
exit 1
}
################################################################################
# Requirement Checks
################################################################################
check_requirements() {
print_step "Checking system requirements..."
if [[ "$OSTYPE" != "linux-gnu"* ]]; then
exit_error "This script only works on Linux"
fi
print_success "Running on Linux"
if command -v pactl >/dev/null 2>&1; then
if ! pactl info 2>/dev/null | grep -qi "pipewire"; then
exit_error "PipeWire does not appear to be the active audio server. 'pactl info' did not report PipeWire. Please install/configure PipeWire so it's the active audio server:
- Debian/Ubuntu: sudo apt install pipewire pipewire-pulse wireplumber
- Fedora: sudo dnf install pipewire pipewire-pulseaudio wireplumber
- Arch: sudo pacman -S pipewire pipewire-pulse wireplumber"
fi
else
if ! command -v wpctl >/dev/null 2>&1; then
exit_error "Neither 'pactl' nor 'wpctl' were found. Please install PipeWire and its clients:
- Debian/Ubuntu: sudo apt install pipewire pipewire-pulse wireplumber
- Fedora: sudo dnf install pipewire pipewire-pulseaudio wireplumber
- Arch: sudo pacman -S pipewire pipewire-pulse wireplumber"
fi
fi
print_success "PipeWire is installed"
if ! systemctl --user is-active --quiet pipewire; then
print_info "PipeWire is not running. Attempting to start it..."
systemctl --user start pipewire pipewire-pulse wireplumber || \
exit_error "Could not start PipeWire services"
fi
print_success "PipeWire is running"
print_step "Checking for PipeWire filter-chain module..."
if command -v shopt >/dev/null 2>&1; then
shopt -s nullglob globstar || true
fi
local candidates=(
/usr/lib/**/libpipewire-module-filter-chain.so
/usr/lib64/**/libpipewire-module-filter-chain.so
/lib/**/libpipewire-module-filter-chain.so
/usr/lib/*/pipewire-*/libpipewire-module-filter-chain.so
/usr/lib64/*/pipewire-*/libpipewire-module-filter-chain.so
)
local found=""
for f in "${candidates[@]}"; do
if [[ -f "$f" ]]; then
found="$f"
break
fi
done
if [[ -z "$found" ]] && command -v ldconfig >/dev/null 2>&1; then
found=$(ldconfig -p 2>/dev/null | awk '/libpipewire-module-filter-chain.so/ {print $NF; exit}') || true
fi
if [[ -z "$found" ]]; then
exit_error "PipeWire filter-chain module not found. Install pipewire-plugins (or the package that provides libpipewire-module-filter-chain.so) and try again:
- Debian/Ubuntu: sudo apt install pipewire-plugins
- Fedora: sudo dnf install pipewire-plugins
- Arch: sudo pacman -S pipewire"
fi
print_success "PipeWire filter-chain module found: $found"
}
################################################################################
# Find and Validate .so File
################################################################################
find_libdeep_filter() {
local provided_path="$1"
if [[ -n "$provided_path" && -f "$provided_path" ]]; then
echo "$provided_path"
return 0
fi
local search_paths=(
"."
"$HOME/Downloads"
"$HOME/Downloads/libdeep_filter_ladspa*"
"/tmp/libdeep_filter_ladspa*"
)
for path in "${search_paths[@]}"; do
if [[ -f "$path" ]]; then
echo "$path"
return 0
fi
for file in $path; do
if [[ -f "$file" ]]; then
echo "$file"
return 0
fi
done
done
return 1
}
validate_so_file() {
local so_file="$1"
if [[ ! -f "$so_file" ]]; then
exit_error "File not found: $so_file"
fi
if ! file "$so_file" | grep -q "ELF.*x86-64"; then
exit_error "Invalid or incompatible binary: $so_file (expected x86-64 ELF)"
fi
print_success "Validated .so file: $so_file"
print_step "Checking library dependencies..."
if ldd "$so_file" | grep -q "not found"; then
print_error "Missing dependencies detected:"
ldd "$so_file" | grep "not found"
exit_error "Please install missing libraries and try again"
fi
print_success "All dependencies are available"
}
################################################################################
# Installation
################################################################################
install_ladspa_plugin() {
local so_file="$1"
print_step "Installing DeepFilter LADSPA plugin to user directory..."
if [[ ! -d "$HOME/.ladspa" ]]; then
print_info "Creating $HOME/.ladspa directory..."
mkdir -p "$HOME/.ladspa"
fi
print_info "Copying $so_file to $LADSPA_INSTALL_PATH..."
install -Dm644 "$so_file" "$LADSPA_INSTALL_PATH" || \
exit_error "Failed to install LADSPA plugin to $LADSPA_INSTALL_PATH"
print_success "LADSPA plugin installed to $LADSPA_INSTALL_PATH"
if [[ -f "$LADSPA_INSTALL_PATH" ]]; then
print_success "Installation verified: $LADSPA_INSTALL_PATH"
else
exit_error "Installation verification failed"
fi
}
################################################################################
# PipeWire Configuration
################################################################################
create_pipewire_config() {
print_step "Creating PipeWire filter-chain configuration..."
mkdir -p "$PIPEWIRE_CONFIG_DIR" || \
exit_error "Failed to create config directory: $PIPEWIRE_CONFIG_DIR"
cat > "$PIPEWIRE_CONFIG_FILE" << EOF
# DeepFilterNet Noise Canceling Microphone
#
# This configuration creates a virtual microphone source that applies
# real-time noise cancellation to your physical microphone input.
#
# The DeepFilter LADSPA plugin processes audio in mono, removing background noise
# with an attenuation limit of 100 dB (maximum noise suppression).
context.modules = [
{ name = libpipewire-module-filter-chain
args = {
node.description = "DeepFilter Microphone"
media.name = "DeepFilter Microphone"
# Define the audio processing filter graph
filter.graph = {
nodes = [
{
type = ladspa
name = "DeepFilter Mono"
plugin = $LADSPA_INSTALL_PATH
label = deep_filter_mono
control = {
# Attenuation Limit in dB:
# 100 = maximum noise suppression (default)
# 24-18 = medium noise reduction
# 12-6 = light noise reduction
"Attenuation Limit (dB)" 100
}
}
]
}
# Audio configuration
audio.rate = 48000
audio.channels = 1
audio.position = [ MONO ]
# Capture properties: listen to the default system microphone
capture.props = {
node.name = "deep_filter_mic_input"
node.passive = true
# Optional: specify a particular microphone if auto-connect fails
# node.target = "alsa_input.pci-0000_00_1f.3.analog-stereo"
}
# Playback properties: expose as a new virtual microphone to applications
playback.props = {
node.name = "deep_filter_mic_output"
media.class = Audio/Source
node.autoconnect = true
}
}
}
]
EOF
if [[ -f "$PIPEWIRE_CONFIG_FILE" ]]; then
print_success "PipeWire configuration created: $PIPEWIRE_CONFIG_FILE"
else
exit_error "Failed to create PipeWire configuration"
fi
}
################################################################################
# PipeWire Restart
################################################################################
restart_pipewire() {
print_step "Restarting PipeWire to load the configuration..."
systemctl --user daemon-reload || \
exit_error "Failed to reload systemd user daemon"
systemctl --user restart wireplumber pipewire pipewire-pulse || \
exit_error "Failed to restart PipeWire services"
print_success "PipeWire restarted"
print_info "Waiting for services to initialize (3 seconds)..."
sleep 3
}
################################################################################
# Verification
################################################################################
verify_installation() {
print_step "Verifying DeepFilter Microphone installation..."
if [[ ! -f "$LADSPA_INSTALL_PATH" ]]; then
print_error "LADSPA plugin not found at: $LADSPA_INSTALL_PATH"
return 1
fi
print_success "LADSPA plugin exists"
if [[ ! -f "$PIPEWIRE_CONFIG_FILE" ]]; then
print_error "PipeWire config not found at: $PIPEWIRE_CONFIG_FILE"
return 1
fi
print_success "PipeWire configuration exists"
print_step "Checking if DeepFilter Microphone is available..."
if wpctl status 2>/dev/null | grep -q "DeepFilter Microphone"; then
print_success "DeepFilter Microphone is available in PipeWire"
echo -e "\n${BLUE}Available audio sources:${NC}"
wpctl status 2>/dev/null | sed -n '/Sources:/,/Source endpoints:/p' | head -20
return 0
else
print_error "DeepFilter Microphone not found in PipeWire"
print_info "Check PipeWire logs for errors:"
print_info " journalctl --user -u pipewire -n 50"
print_info " journalctl --user -u wireplumber -n 50"
return 1
fi
}
################################################################################
# Usage Instructions
################################################################################
print_usage_instructions() {
print_header "DeepFilter Installation Complete!"
cat << EOF
The DeepFilter Microphone is now installed and available on your system.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
HOW TO USE:
1. Set as Default Microphone (Optional):
$ wpctl set-default <SOURCE_ID>
Find the SOURCE_ID from:
$ wpctl status
2. Use in Applications:
- Video conferencing (Zoom, Discord, Teams, etc.): Select "DeepFilter Microphone"
- Sound settings: Choose "DeepFilter Microphone" as the input device
- Command line recording:
$ pw-cat --record --target "DeepFilter Microphone" output.wav
3. Test the Configuration:
$ pw-cat --record --target "DeepFilter Microphone" /tmp/dfn-test.wav
$ pw-cat --playback /tmp/dfn-test.wav
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
CONFIGURATION:
Plugin Location:
$LADSPA_INSTALL_PATH
PipeWire Configuration:
$PIPEWIRE_CONFIG_FILE
To Adjust Noise Attenuation (in the config file):
"Attenuation Limit (dB)" 100 (100 = max suppression, default)
"Attenuation Limit (dB)" 24 (medium reduction)
"Attenuation Limit (dB)" 12 (light reduction)
After editing the config, restart PipeWire:
$ systemctl --user restart wireplumber pipewire pipewire-pulse
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
TROUBLESHOOTING:
1. DeepFilter Microphone Not Appearing:
$ journalctl --user -u pipewire -n 50
$ journalctl --user -u wireplumber -n 50
2. Silent or No Audio:
- Check if the real microphone is working:
$ pw-cat --record /tmp/test.wav
- Ensure PipeWire routes correctly:
$ pw-cli ls Node | grep -i deepfilter
3. If You Need to Specify Your Microphone:
Edit the config file and uncomment/modify the capture node.target property.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
EOF
}
################################################################################
# Main Execution
################################################################################
main() {
print_header "DeepFilterNet Installation for PipeWire"
SO_FILE="${1:-}"
check_requirements
print_step "Locating DeepFilter LADSPA plugin..."
if SO_FILE=$(find_libdeep_filter "$SO_FILE"); then
print_success "Found: $SO_FILE"
else
exit_error "Could not find libdeep_filter_ladspa.so
Please provide the path as an argument:
bash $0 /path/to/libdeep_filter_ladspa.so
Or place it in one of these locations:
- Current directory
- $HOME/Downloads
- /tmp"
fi
validate_so_file "$SO_FILE"
install_ladspa_plugin "$SO_FILE"
create_pipewire_config
restart_pipewire
if verify_installation; then
print_usage_instructions
print_success "Installation completed successfully!"
exit 0
else
print_error "Installation completed but verification failed"
print_info "Please check the logs and try restarting PipeWire manually:
systemctl --user restart wireplumber pipewire pipewire-pulse"
exit 1
fi
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment