home-lab/modules/sound/troubleshoot-voice-distortion.sh
Geir Okkenhaug Jerstad 406acb3daf fix: improve voice quality and add distortion troubleshooting
- Fix RNNoise configuration: use mono instead of stereo, increase VAD threshold to 95%
- Adjust quantum settings: increase min-quantum to 64 for stability
- Add comprehensive voice distortion troubleshoot script
- Create optional disable-auto-rnnoise.nix for problematic setups
- The automatic RNNoise filter can cause artifacts, script helps diagnose and fix
2025-06-18 21:46:31 +02:00

285 lines
9.1 KiB
Bash
Executable file
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# Voice Distortion Troubleshoot Script
# This script helps diagnose and fix voice distortion issues in PipeWire
set -euo pipefail
echo "🎤 Voice Distortion Troubleshoot Tool"
echo "===================================="
echo ""
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
success() {
echo -e "${GREEN}$1${NC}"
}
warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
error() {
echo -e "${RED}$1${NC}"
}
info() {
echo -e "${BLUE} $1${NC}"
}
highlight() {
echo -e "${CYAN}🔧 $1${NC}"
}
echo "Let's diagnose your voice distortion issue step by step..."
echo ""
# 1. Check current audio settings
echo "1. Current Audio Configuration"
echo "=============================="
if command -v wpctl >/dev/null 2>&1; then
echo "Default devices:"
wpctl status | head -20
echo ""
# Get default source
DEFAULT_SOURCE=$(wpctl inspect @DEFAULT_AUDIO_SOURCE@ 2>/dev/null | grep "node.name" | head -1 | sed 's/.*"\(.*\)".*/\1/' || echo "unknown")
info "Current default source: $DEFAULT_SOURCE"
# Check sample rate
CURRENT_RATE=$(pw-metadata -n settings | grep "clock.rate" | awk '{print $3}' || echo "unknown")
info "Current sample rate: $CURRENT_RATE Hz"
# Check buffer size
CURRENT_QUANTUM=$(pw-metadata -n settings | grep "clock.quantum" | awk '{print $3}' || echo "unknown")
info "Current buffer size: $CURRENT_QUANTUM samples"
else
error "wpctl not available"
fi
echo ""
# 2. Check for common distortion causes
echo "2. Distortion Diagnosis"
echo "======================"
# Check if using RNNoise filter
if pw-dump 2>/dev/null | jq -r '.[] | select(.info.props."node.name" == "rnnoise_source")' | grep -q "rnnoise"; then
warning "You're using the RNNoise filter chain - this might be causing distortion"
echo " The automatic filter chain can sometimes cause artifacts"
else
info "Not using automatic RNNoise filter"
fi
# Check for high CPU usage
if command -v pw-top >/dev/null 2>&1; then
highlight "Checking PipeWire performance (5 seconds)..."
timeout 5 pw-top --batch-mode 2>/dev/null | tail -10 || warning "Could not check performance"
fi
# Check input levels
if command -v wpctl >/dev/null 2>&1; then
echo ""
echo "Current microphone volume levels:"
wpctl get-volume @DEFAULT_AUDIO_SOURCE@ || warning "Could not get volume info"
fi
echo ""
# 3. Quick fixes
echo "3. Quick Fixes to Try"
echo "===================="
echo ""
echo "Choose a solution to try:"
echo ""
echo "A) Disable automatic RNNoise filter (recommended first step)"
echo "B) Lower microphone input gain"
echo "C) Reduce buffer size for lower latency"
echo "D) Use EasyEffects instead of filter chain"
echo "E) Reset to safe audio settings"
echo "F) Test different sample rates"
echo "G) Monitor audio in real-time"
echo "H) All of the above (comprehensive fix)"
echo ""
read -p "Enter your choice (A-H): " choice
case $choice in
A|a)
echo ""
highlight "Disabling automatic RNNoise filter..."
if pw-dump 2>/dev/null | jq -r '.[] | select(.info.props."node.name" == "rnnoise_source") | .id' | while read id; do
echo "Removing filter node $id"
pw-cli destroy "$id" 2>/dev/null || warning "Could not remove filter $id"
done; then
success "RNNoise filter disabled"
echo "Try speaking now. If distortion is gone, use EasyEffects for noise suppression instead."
else
warning "Could not disable RNNoise filter automatically"
fi
;;
B|b)
echo ""
highlight "Lowering microphone input gain to 50%..."
wpctl set-volume @DEFAULT_AUDIO_SOURCE@ 50%
success "Microphone gain reduced to 50%"
echo "Test your voice now. Adjust further if needed with: wpctl set-volume @DEFAULT_AUDIO_SOURCE@ X%"
;;
C|c)
echo ""
highlight "Setting lower buffer size for reduced latency..."
pw-metadata -n settings 0 clock.force-quantum 512
success "Buffer size set to 512 samples"
echo "This should reduce latency but may increase CPU usage"
;;
D|d)
echo ""
highlight "Launching EasyEffects for manual noise suppression..."
if command -v easyeffects >/dev/null 2>&1; then
easyeffects &
success "EasyEffects launched"
echo ""
echo "In EasyEffects:"
echo "1. Go to 'Input' tab"
echo "2. Add 'RNNoise' effect"
echo "3. Set 'VAD Threshold' to 95% (very conservative)"
echo "4. Set 'Wet' signal to 50-70% (not 100%)"
echo "5. Disable any other aggressive processing"
else
error "EasyEffects not available"
fi
;;
E|e)
echo ""
highlight "Resetting to safe audio settings..."
# Reset quantum
pw-metadata -n settings 0 clock.force-quantum 0
# Reset rate
pw-metadata -n settings 0 clock.force-rate 0
# Set reasonable volume
wpctl set-volume @DEFAULT_AUDIO_SOURCE@ 70%
# Restart audio services
systemctl --user restart pipewire pipewire-pulse wireplumber
success "Audio settings reset to defaults"
echo "Wait 5 seconds for services to restart, then test your voice"
;;
F|f)
echo ""
highlight "Testing different sample rates..."
echo "Current rate: $(pw-metadata -n settings | grep clock.rate | awk '{print $3}' || echo 'default')"
echo ""
echo "Trying 44100 Hz..."
pw-metadata -n settings 0 clock.force-rate 44100
sleep 2
echo "Test your voice now. Press Enter to continue..."
read
echo "Trying 48000 Hz..."
pw-metadata -n settings 0 clock.force-rate 48000
sleep 2
echo "Test your voice now. Press Enter to continue..."
read
echo "Back to automatic rate..."
pw-metadata -n settings 0 clock.force-rate 0
success "Rate testing complete"
;;
G|g)
echo ""
highlight "Starting real-time audio monitoring..."
echo "Press Ctrl+C to stop monitoring"
echo ""
if command -v pw-top >/dev/null 2>&1; then
pw-top
else
echo "Monitoring with wpctl status (updating every 2 seconds):"
while true; do
clear
echo "=== PipeWire Status ==="
wpctl status
echo ""
echo "=== Microphone Volume ==="
wpctl get-volume @DEFAULT_AUDIO_SOURCE@
echo ""
echo "Press Ctrl+C to stop"
sleep 2
done
fi
;;
H|h)
echo ""
highlight "Running comprehensive fix..."
# Step 1: Disable RNNoise filter
echo "1/6: Disabling automatic RNNoise filter..."
pw-dump 2>/dev/null | jq -r '.[] | select(.info.props."node.name" == "rnnoise_source") | .id' | while read id; do
pw-cli destroy "$id" 2>/dev/null || true
done
# Step 2: Reset audio settings
echo "2/6: Resetting audio settings..."
pw-metadata -n settings 0 clock.force-quantum 0
pw-metadata -n settings 0 clock.force-rate 0
# Step 3: Set conservative volume
echo "3/6: Setting conservative microphone gain..."
wpctl set-volume @DEFAULT_AUDIO_SOURCE@ 60%
# Step 4: Restart services
echo "4/6: Restarting audio services..."
systemctl --user restart pipewire pipewire-pulse wireplumber
# Step 5: Wait for restart
echo "5/6: Waiting for services to stabilize..."
sleep 5
# Step 6: Launch EasyEffects
echo "6/6: Launching EasyEffects for manual control..."
if command -v easyeffects >/dev/null 2>&1; then
easyeffects &
success "Comprehensive fix applied!"
echo ""
echo "Next steps:"
echo "1. Test your voice without any effects first"
echo "2. In EasyEffects, gradually add noise suppression:"
echo " - Start with RNNoise at 50% wet signal"
echo " - Use VAD threshold of 95% or higher"
echo " - Avoid aggressive compression or EQ"
echo "3. If still distorted, try lowering input gain further"
else
warning "EasyEffects not available for manual control"
fi
;;
*)
error "Invalid choice"
;;
esac
echo ""
echo "🎯 Additional Tips to Prevent Distortion:"
echo "========================================="
echo ""
echo "• Keep microphone gain below 80% to avoid clipping"
echo "• Use RNNoise conservatively (50-70% wet signal, not 100%)"
echo "• Check for background applications using audio"
echo "• Ensure your microphone hardware supports 48kHz"
echo "• Consider using a better quality microphone"
echo "• Avoid stacking multiple noise reduction effects"
echo ""
echo "Run this script again anytime with: troubleshoot-voice-distortion"