home-lab/modules/sound/troubleshoot-voice-distortion.sh
Geir Okkenhaug Jerstad bc3d199cca fix: prevent troubleshoot script from exiting abruptly
- Change from 'set -euo pipefail' to 'set -uo pipefail' to avoid early exits
- Add proper error handling for all commands that might fail
- Wrap pw-dump, jq, and pw-cli commands with availability checks
- Add null checks and error suppression where appropriate
- Ensure script completes with success message
- Fix RNNoise filter detection and removal logic
- The script should now run completely without abrupt termination
2025-06-18 21:53:55 +02:00

322 lines
11 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
# Use safer error handling - don't exit on all errors
set -uo 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 command -v pw-dump >/dev/null 2>&1 && command -v jq >/dev/null 2>&1; then
if pw-dump 2>/dev/null | jq -r '.[] | select(.info.props."node.name" == "rnnoise_source")' 2>/dev/null | grep -q "rnnoise" 2>/dev/null; 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
else
warning "Cannot check RNNoise filter status (pw-dump or jq not available)"
fi
# Check for high CPU usage
if command -v pw-top >/dev/null 2>&1; then
highlight "Checking PipeWire performance (5 seconds)..."
if timeout 5 pw-top --batch-mode 2>/dev/null | tail -10 2>/dev/null; then
info "Performance check completed"
else
warning "Could not check performance - pw-top failed"
fi
else
info "pw-top not available for performance checking"
fi
# Check input levels
if command -v wpctl >/dev/null 2>&1; then
echo ""
echo "Current microphone volume levels:"
if wpctl get-volume @DEFAULT_AUDIO_SOURCE@ 2>/dev/null; then
info "Volume check completed"
else
warning "Could not get volume info - no default audio source?"
fi
else
warning "wpctl not available for volume checking"
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 command -v pw-dump >/dev/null 2>&1 && command -v jq >/dev/null 2>&1 && command -v pw-cli >/dev/null 2>&1; then
# Find and remove RNNoise filter nodes
FILTER_IDS=$(pw-dump 2>/dev/null | jq -r '.[] | select(.info.props."node.name" == "rnnoise_source") | .id' 2>/dev/null || echo "")
if [ -n "$FILTER_IDS" ]; then
echo "$FILTER_IDS" | while read -r id; do
if [ -n "$id" ]; then
echo "Removing filter node $id"
pw-cli destroy "$id" 2>/dev/null || warning "Could not remove filter $id"
fi
done
success "RNNoise filter removal attempted"
else
info "No RNNoise filter found to remove"
fi
echo "Try speaking now. If distortion is gone, use EasyEffects for noise suppression instead."
else
warning "Required tools not available (pw-dump, jq, pw-cli)"
echo "Try manually: systemctl --user restart pipewire"
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..."
if command -v pw-dump >/dev/null 2>&1 && command -v jq >/dev/null 2>&1; then
FILTER_IDS=$(pw-dump 2>/dev/null | jq -r '.[] | select(.info.props."node.name" == "rnnoise_source") | .id' 2>/dev/null || echo "")
if [ -n "$FILTER_IDS" ]; then
echo "$FILTER_IDS" | while read -r id; do
if [ -n "$id" ]; then
pw-cli destroy "$id" 2>/dev/null || true
fi
done
fi
fi
# Step 2: Reset audio settings
echo "2/6: Resetting audio settings..."
pw-metadata -n settings 0 clock.force-quantum 0 2>/dev/null || true
pw-metadata -n settings 0 clock.force-rate 0 2>/dev/null || true
# Step 3: Set conservative volume
echo "3/6: Setting conservative microphone gain..."
wpctl set-volume @DEFAULT_AUDIO_SOURCE@ 60% 2>/dev/null || warning "Could not set volume"
# Step 4: Restart services
echo "4/6: Restarting audio services..."
systemctl --user restart pipewire pipewire-pulse wireplumber 2>/dev/null || warning "Could not restart services"
# 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"
echo ""
echo "✅ Script completed successfully!"
exit 0