
- 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
285 lines
9.1 KiB
Bash
Executable file
285 lines
9.1 KiB
Bash
Executable file
#!/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"
|