| name | audio-quality-checker |
| description | Analyze the WaveCap-SDR audio stream to assess tuning quality, detect silence, noise, proper audio, or distortion. Use when checking if SDR channels are properly configured or debugging audio issues. |
Audio Quality Checker for WaveCap-SDR
This skill helps analyze the audio stream from WaveCap-SDR channels to determine if they are properly tuned and producing usable audio.
When to Use This Skill
Use this skill when:
- User asks to check if an SDR channel is "well tuned" or working properly
- User wants to verify audio quality or detect issues
- User asks if they're getting "real sound" vs "just noise" vs "nothing"
- Debugging why audio playback isn't working as expected
- Validating SDR configuration changes
How It Works
The skill captures a sample of the audio stream and analyzes it to detect:
- Silence - No signal, near-zero amplitude (broken/stopped channel)
- Noise - Random signal with no structure (poor tuning, no carrier)
- Proper Audio - Structured signal with meaningful content (well-tuned FM station)
- Clipping/Distortion - Signal hitting limits (gain too high, overmodulation)
Usage Instructions
Step 1: Identify the Server and Channel
First, determine:
- Server port (default: 8087, check
backend/config/wavecapsdr.yamlor environment variables) - Channel ID to test (e.g., "ch1", "ch2", etc.)
- Server bind address (default: 127.0.0.1)
You can find active channels by checking:
curl http://127.0.0.1:8087/api/v1/captures | jq '.[] | .channels'
Step 2: Capture Audio Sample
Use the provided analyze_audio_stream.py script to capture and analyze:
PYTHONPATH=backend backend/.venv/bin/python .claude/skills/audio-quality-checker/analyze_audio_stream.py \
--port 8087 \
--channel ch1 \
--duration 3
Parameters:
--port: Server port (default: 8087)--channel: Channel ID to test (default: ch1)--duration: Seconds of audio to capture (default: 3)--host: Server host (default: 127.0.0.1)--format: Audio format, pcm16 or f32 (default: pcm16)
Step 3: Interpret Results
The script outputs a detailed analysis including:
Signal Level Metrics:
- RMS Level (dB): Overall signal strength (-inf = silence, -20 to 0 dB = good)
- Peak Level (dB): Maximum amplitude (near 0 dB may indicate clipping)
- Crest Factor: Peak-to-RMS ratio (high = dynamic, low = compressed/noise)
Spectral Analysis:
- Spectral Flatness: How "flat" the spectrum is (high = noise-like, low = tonal)
- Spectral Centroid: "Center of mass" of the spectrum in Hz
- Zero Crossing Rate: How often signal crosses zero (higher for noise/high-freq content)
Signal Classification: The script will classify the signal as:
- SILENCE: RMS < -60 dB
- NOISE: High spectral flatness (> 0.7) and low RMS
- CLIPPED: Peak level > -0.5 dB
- GOOD AUDIO: Structured signal with moderate levels
Step 4: Recommendations
Based on the results:
If SILENCE detected:
- Check if channel is started:
curl -X POST http://127.0.0.1:8087/api/v1/channels/{chan_id}/start - Verify capture is running
- Check SDR device connection
If NOISE detected:
- Adjust channel frequency (offset_hz) - may not be tuned to a station
- Check antenna connection
- Try different frequencies known to have active broadcasts
- Verify modulation mode matches the signal (wbfm, nbfm, am, ssb, p25, dmr supported)
If CLIPPED detected:
- Reduce SDR gain settings
- Check for overmodulation from the broadcaster
- Adjust RF gain in device configuration
If GOOD AUDIO:
- Channel is properly tuned and working correctly
- Can fine-tune squelch_db if needed to reduce noise during silent periods
Example Workflow
# 1. Check what channels exist
curl http://127.0.0.1:8087/api/v1/captures | jq
# 2. Start a channel if needed
curl -X POST http://127.0.0.1:8087/api/v1/channels/ch1/start
# 3. Analyze the audio quality
PYTHONPATH=backend backend/.venv/bin/python .claude/skills/audio-quality-checker/analyze_audio_stream.py \
--channel ch1 --duration 3
# 4. If noise detected, try adjusting frequency
# (Update channel configuration and restart)
Technical Details
Audio Stream Format:
- Endpoint:
GET /api/v1/stream/channels/{chan_id}.pcm?format=pcm16 - Sample Rate: 48000 Hz (default, configurable)
- Channels: Mono (1 channel)
- Format: 16-bit signed little-endian PCM
- Streaming: Continuous, no headers
Analysis Metrics:
RMS Level:
20 * log10(sqrt(mean(signal^2)))- Measures average signal power
- Typical good audio: -20 to -6 dB
Spectral Flatness: Geometric mean / Arithmetic mean of power spectrum
- Near 1.0 = white noise (flat spectrum)
- Near 0.0 = tonal (structured frequencies)
Zero Crossing Rate: Count of sign changes / total samples
- High ZCR = noisy or high-frequency content
- Low ZCR = low-frequency or tonal content
Crest Factor: Peak / RMS
- High (>4) = dynamic audio (speech, music)
- Low (<3) = compressed or noise-like
Files in This Skill
SKILL.md: This file - instructions for using the skillanalyze_audio_stream.py: Python script to capture and analyze audiorequirements.txt: Python dependencies (numpy, scipy, requests)
Notes
- The skill uses the Python environment at
backend/.venv - Ensure the WaveCap-SDR server is running before analysis
- For best results, capture at least 2-3 seconds of audio
- The analysis is statistical and works best with steady signals
- Some transient issues may not be detected in short samples