Design and test DSP filters (highpass, lowpass, bandpass, notch) for WaveCap-SDR...
This skill helps design, test, and visualize digital filters for the WaveCap-SDR DSP pipeline.
Use this skill when:
The skill provides an interactive filter design tool that:
Determine what you need:
Use the provided script to interactively design filters:
PYTHONPATH=backend backend/.venv/bin/python .claude/skills/dsp-filter-designer/filter_designer.py \
--type lowpass \
--cutoff 15000 \
--sample-rate 48000 \
--order 5
Parameters:
--type: Filter type (lowpass, highpass, bandpass, notch)--cutoff: Cutoff frequency in Hz (or low,high for bandpass/notch)--sample-rate: Sample rate in Hz (default: 48000)--order: Filter order 1-10 (default: 5)--filter-design: butterworth, chebyshev1, chebyshev2, elliptic (default: butterworth)--ripple: Passband ripple in dB for Chebyshev/Elliptic (default: 0.5)--output: Save plots to file instead of displaying--export-code: Generate Python code for wavecapsdr/dsp/filters.pyThe script outputs:
Frequency Response:
Phase Response:
Impulse Response:
Filter Coefficients:
Test the filter with actual audio:
# Generate test code that applies filter to a signal
PYTHONPATH=backend backend/.venv/bin/python .claude/skills/dsp-filter-designer/filter_designer.py \
--type lowpass \
--cutoff 15000 \
--sample-rate 48000 \
--order 5 \
--export-code
This generates code like:
from scipy.signal import butter, lfilter
def apply_lowpass_filter(signal, sample_rate=48000):
"""Apply 15000 Hz lowpass filter (5th order Butterworth)"""
nyquist = sample_rate / 2
cutoff_norm = 15000 / nyquist
b, a = butter(5, cutoff_norm, btype='low', analog=False)
return lfilter(b, a, signal)
Add the filter to backend/wavecapsdr/dsp/filters.py:
def lowpass_filter(signal: np.ndarray, cutoff_hz: float, sample_rate: int, order: int = 5) -> np.ndarray:
"""Apply Butterworth lowpass filter"""
from scipy.signal import butter, lfilter
nyquist = sample_rate / 2
cutoff_norm = cutoff_hz / nyquist
b, a = butter(order, cutoff_norm, btype='low', analog=False)
return lfilter(b, a, signal)
Then use in demodulation pipeline (e.g., wavecapsdr/dsp/fm.py):
# After demodulation, apply de-emphasis filter
audio = lowpass_filter(audio, cutoff_hz=15000, sample_rate=audio_rate)
# 15 kHz lowpass for FM broadcast de-emphasis
.claude/skills/dsp-filter-designer/filter_designer.py \
--type lowpass --cutoff 15000 --order 5
# 300-3000 Hz bandpass for SSB voice
.claude/skills/dsp-filter-designer/filter_designer.py \
--type bandpass --cutoff 300,3000 --order 4
# 20 Hz highpass to remove DC offset
.claude/skills/dsp-filter-designer/filter_designer.py \
--type highpass --cutoff 20 --order 2
# 60 Hz notch to remove AC hum
.claude/skills/dsp-filter-designer/filter_designer.py \
--type notch --cutoff 60 --order 4
Filter Order:
Filter Type:
Analog vs Digital:
Filter Implementation: WaveCap-SDR uses scipy.signal IIR filters (Infinite Impulse Response):
from scipy.signal import butter, lfilter
# Design filter (returns coefficients)
b, a = butter(N=order, Wn=cutoff_normalized, btype='low')
# Apply filter (stateless, per-chunk processing)
filtered = lfilter(b, a, signal)
Stateful Filtering: For streaming applications, maintain filter state between chunks:
from scipy.signal import lfilter_zi
# Initialize state
zi = lfilter_zi(b, a) * signal[0]
# Apply filter with state
filtered, zi = lfilter(b, a, signal, zi=zi)
Frequency Normalization:
SKILL.md: This file - instructions for using the skillfilter_designer.py: Interactive filter design and visualization toolmatplotlib for visualization (interactive plots)