Skip to content
dsp-filter-designer logo

DSP Filter Designer for WaveCap-SDR

dsp-filter-designer

Design and test DSP filters (highpass, lowpass, bandpass, notch) for WaveCap-SDR. Use when adding filters to demodulation pipeline, debugging filter response, or tuning cutoff frequencies and rolloff characteristics.

SKILL.md

Full skill instructions

DSP Filter Designer for WaveCap-SDR

This skill helps design, test, and visualize digital filters for the WaveCap-SDR DSP pipeline.

When to Use This Skill

Use this skill when:

  • Designing new filters for demodulation pipelines (FM, AM, SSB)
  • Testing filter parameters (cutoff frequencies, order, rolloff)
  • Debugging filter response issues (not cutting enough, too much ripple)
  • Visualizing frequency and phase response of existing filters
  • Optimizing filter performance vs computational cost
  • Adding notch filters to remove interference

How It Works

The skill provides an interactive filter design tool that:

  1. Designs filters using scipy.signal (Butterworth, Chebyshev, Elliptic)
  2. Visualizes response - frequency response, phase response, impulse response
  3. Tests performance - applies filter to test signals to verify behavior
  4. Exports code - generates Python code ready for wavecapsdr/​dsp/​filters.py

Usage Instructions

Step 1: Identify Filter Requirements

Determine what you need:

  • Filter type: highpass, lowpass, bandpass, notch
  • Cutoff frequency: Where filter should start attenuating
  • Sample rate: Audio sample rate (typically 48000 Hz)
  • Filter order: Higher = steeper rolloff but more CPU
  • Passband ripple: Acceptable variation in passband (dB)

Step 2: Run the Filter Designer

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.py

Step 3: Interpret Results

The script outputs:

Frequency Response:

  • Shows magnitude response in dB vs frequency
  • Verify cutoff is where expected (-3 dB point)
  • Check stopband attenuation is sufficient
  • Look for passband ripple

Phase Response:

  • Shows phase shift vs frequency
  • Linear phase = no distortion (difficult to achieve with IIR)
  • Non-linear phase can cause audio artifacts

Impulse Response:

  • Shows filter's time-domain behavior
  • Long impulse response = more "ringing"
  • Short impulse response = faster transient response

Filter Coefficients:

  • Prints b (numerator) and a (denominator) coefficients
  • These can be used directly with scipy.signal.lfilter()

Step 4: Test with Real Signals

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)

Step 5: Integrate into WaveCap-SDR

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)

Common Filter Use Cases

1. FM De-emphasis Filter

# 15 kHz lowpass for FM broadcast de-emphasis
.claude/​skills/​dsp-filter-designer/​filter_designer.py \
  --type lowpass --cutoff 15000 --order 5

2. SSB Audio Bandpass

# 300-3000 Hz bandpass for SSB voice
.claude/​skills/​dsp-filter-designer/​filter_designer.py \
  --type bandpass --cutoff 300,3000 --order 4

3. DC Blocking Highpass

# 20 Hz highpass to remove DC offset
.claude/​skills/​dsp-filter-designer/​filter_designer.py \
  --type highpass --cutoff 20 --order 2

4. Notch Filter for Interference

# 60 Hz notch to remove AC hum
.claude/​skills/​dsp-filter-designer/​filter_designer.py \
  --type notch --cutoff 60 --order 4

Filter Design Trade-offs

Filter Order:

  • Higher order = steeper rolloff, better frequency selectivity
  • Higher order = more CPU, potential instability, longer transients
  • Typical: 4-6 for audio, 2-3 for computational efficiency

Filter Type:

  • Butterworth: Maximally flat passband, gentle rolloff (most common)
  • Chebyshev Type I: Steeper rolloff, passband ripple
  • Chebyshev Type II: Steeper rolloff, stopband ripple
  • Elliptic: Steepest rolloff, both passband and stopband ripple

Analog vs Digital:

  • All filters in WaveCap-SDR are digital (discrete-time)
  • Design in normalized frequency (0 to 1, where 1 = Nyquist)
  • Nyquist frequency = sample_rate / 2

Technical Details

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:

  • Cutoff frequencies are normalized to Nyquist (sample_rate / 2)
  • Example: 15 kHz cutoff at 48 kHz sample rate → 15000 / 24000 = 0.625

Files in This Skill

  • SKILL.md: This file - instructions for using the skill
  • filter_designer.py: Interactive filter design and visualization tool

Notes

  • Always test filters with real audio before deployment
  • Check for numerical instability (very high orders can be unstable)
  • Consider FIR filters for linear phase requirements (not yet implemented)
  • Profile CPU usage when adding filters to real-time pipeline
  • Use matplotlib for visualization (interactive plots)

More DevOps & CI/CD skills

Project scaffolding, deployment configuration, and CI/CD setup for Google ADK agents.

6K 472.6K
View

Set up tracing, logging, and monitoring for deployed ADK agents across Cloud Trace, BigQuery, and third-party platforms.

6K 472.6K
View

Enterprise Azure infrastructure architect generating Bicep or Terraform from workload descriptions.

1.5K 454.3K
View
azure-kubernetes logo
DevOps & CI/CD

azure-kubernetes

Plan and configure production-ready Azure Kubernetes Service clusters with Day-0 and Day-1 best practices.

1.5K 447.1K
View

Raw mechanical interfaces fusing Swiss typographic print with military terminal aesthetics. Rigid grids, extreme type scale contrast, utilitarian color, analog degradation effects. For data-heavy dashboards, portfolios, or editorial sites that need to feel like declassified blueprints.

92.7K 354.9K
View
just-scrape logo
DevOps & CI/CD

just-scrape

Web search, scraping, extraction, crawling, and monitoring via ScrapeGraph AI CLI.

69 245K
View

Skill for working with Firebase Hosting (Classic). Use this when you want to deploy static web apps, Single Page Apps (SPAs), or simple microservices. Do NOT use for Firebase App Hosting.

462 159.7K
View

Deploy and manage web apps with Firebase App Hosting. Use this skill when deploying Next.js/Angular apps with backends.

462 159.1K
View
deploy-to-vercel logo
DevOps & CI/CD

deploy-to-vercel

Deploy applications and websites to Vercel. Use when the user requests deployment actions like "deploy my app", "deploy and give me the link", "push this live", or "create a preview deployment".

31.9K 146.6K
View
programmatic-seo logo
DevOps & CI/CD

programmatic-seo

Build SEO-optimized pages at scale using templates, data, and proven playbook patterns.

53.3K 140.1K
View

Design and build isolated, reusable Convex backend components with clear boundaries and app-facing wrappers.

63 123.5K
View

Deploy and manage projects on Vercel using token-based authentication. Use when working with Vercel CLI using access tokens rather than interactive login — e.g. "deploy to vercel", "set up vercel", "add environment variables to vercel".

31.9K 116.1K
View

Coding & apps AI tools

Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View
I
Coding & apps

Imagica

Build a no-code AI app in minutes.

Freemium
View
E
Coding & apps

Emergent.sh

An IDE for code migration from legacy to modern frameworks through coding agents.

Freemium
View
Wonder Dynamics logo
Coding & apps

Wonder Dynamics

Automate CGI animation in live-action scenes

Paid
View
M
Coding & apps

Mixo

Launch a website in seconds with AI.

Paid
View
AI Code Convert logo
Coding & apps

AI Code Convert

Streamline Your Coding Experience with AI Code Helper

Free
View