A comprehensive, modular Digital Signal Processing (DSP) toolkit developed in Python. This project simulates an audio engineering environment ("Wave Form Labs") to synthesize retro 8-bit audio, perform spectral noise reduction, and design stable vintage filters using Fourier and Laplace transforms.
It is designed with an educational tone, bridging the gap between theoretical math (continuous-time signals) and practical implementation (discrete-time processing).
Requirement: Python >= 3.11
The toolkit relies on PyAudio for real-time streaming, which requires the PortAudio C library.
macOS:
brew install portaudioLinux (Debian/Ubuntu):
sudo apt-get update
sudo apt-get install portaudio19-dev python3-pyaudioWindows:
No system dependencies required. pip install pyaudio typically provides pre-compiled binaries.
git clone https://github.com/armansadeghpoor/Audio-Signal-Processor.git
cd Audio-Signal-Processor
python -m venv .venv
# Activate the virtual environment
# On macOS/Linux:
source .venv/bin/activate
# On Windows:
# .venv\Scripts\activate
# Install the package in editable mode with development dependencies
pip install -e ".[dev]"Run the offline demonstrations:
python scripts/phase1_demo.py
python scripts/phase2_demo.py
python scripts/phase3_demo.pyRun the Real-Time Microphone Filter:
python scripts/realtime_stream.pyLaunch the Interactive GUI:
python gui/app.py(Check the assets/audio/ directory for generated audio files and assets/images/ for analytical plots).
The repository has been refactored into a modern Python package to separate the core DSP math from executable scripts and the user interface.
graph LR
A[Audio Input] --> B[audio_signal_processor]
B -->|Synthesis| C[DSP Modules]
B -->|Filters| C
B -->|Noise Reduction| C
C --> D[Audio Output]
audio_signal_processor/: The core DSP library.synthesis.py: Fourier-series square-wave synthesizer & melody sequencer.noise_reduction.py: Threshold-based spectral noise detection & IIR notch filtering.filters.py: 2nd-order RLC filter design (continuous & discrete).audio_io.py: Safe WAV I/O with soft-clipping & peak normalization.
scripts/: Executable demos and the real-time audio stream.gui/: InteractiveTkinterapplication for the vintage filter.tests/: Comprehensivepytestsuite ensuring algorithmic correctness and edge-case handling.assets/: Output directory for generated.wavfiles and educational.pngplots.
- Fourier Series & Gibbs Phenomenon (Synthesis)
- Fast Fourier Transform (FFT) (Spectral Analysis)
- IIR Notch Filtering (Zero-phase distortion noise reduction)
- Laplace Transform & Pole-Zero Maps (Analog filter stability)
- Bilinear Transform & Prewarping (Analog-to-digital mapping)
- Digital Gain Staging & Soft-Clipping (Real-time saturation)
You can use the core DSP library directly in your own projects:
import numpy as np
from scipy.signal import lfilter
from audio_signal_processor.filters import design_vintage_resonant_filter
# Design a prewarped discrete resonant filter
fs = 44100
b, a = design_vintage_resonant_filter(
natural_freq=1000.0,
damping_ratio=0.1,
fs=fs,
prewarp=True
)
# Apply to your audio array
dummy_audio = np.random.randn(fs)
filtered_audio = lfilter(b, a, dummy_audio)Synthesizes square waves from pure sinusoidal harmonics to recreate classic 8-bit video game melodies.
- Fourier Synthesis: A square wave is mathematically modeled using the Continuous-Time Fourier Series (CTFS) by summing odd harmonics of sine waves. To prevent digital aliasing, harmonics that exceed the Nyquist limit (sample_rate / 2) are automatically discarded.
-
Gibbs Phenomenon: Approximating a discontinuous square wave with a finite number of harmonics (
$N$ ) leads to ringing artifacts at the edges. The demo visually analyzes this behavior, comparing$N=5$ and$N=100$ .
Demonstrates spectral analysis and selective filtering to remove a high-frequency tonal noise spike from a corrupted audio file.
- Spectral Analysis: Uses the real-valued Fast Fourier Transform (
rfft) to convert the time-domain signal into the frequency domain. It employs a statistical threshold (median + N*std) to robustly detect the dominant noise spike. - IIR Notch Filter: Once the noise frequency is found, an Infinite Impulse Response (IIR) notch filter is applied using
scipy.signal.iirnotchandfiltfilt. This provides a sharp, zero-phase distortion cut exactly at the target frequency, removing the tone while leaving the rest of the spectrum intact.
Designs a 2nd-order RLC low-pass filter to add resonant "warmth" to digital audio signals.
-
Natural Frequency vs. Cutoff Frequency: In a high-Q (resonant) system, such as our filter with a damping ratio of
$\zeta=0.1$ , the Natural Frequency ($\omega_n$ ) is the resonant peak where the gain heavily amplifies the signal (approx.$5\times$ or$14\text{ dB}$ ). This is mathematically distinct from the standard$-3\text{ dB}$ cutoff frequency. Because of this resonance, soft-clipping (tanh) is critical to prevent harsh digital clipping. -
Pole-Zero Stability: The system's stability is analyzed via its poles in the s-plane. As long as all poles reside in the Left Half-Plane (LHP), the system is stable. Pushing poles to the Right Half-Plane (RHP) via negative damping (
$\zeta < 0$ ) causes the step-response to explode into instability. -
Continuous to Discrete Time: The theoretical continuous-time transfer function
$H(s)$ is converted into a discrete-time digital filter$H(z)$ using the bilinear (Tustin) transform, enabling sample-by-sample processing for real-time applications.
- Sparse Tonal Noise Suppression: The audio detective is a surgical tool designed strictly for eliminating constant, tonal noise spikes (like a 60Hz hum or a high-frequency sine whine) via spectral peak detection. It does not perform broad-spectrum noise reduction, vocal isolation, and cannot magically restore heavily corrupted or non-stationary noise.
- Synthesizer Polyphony: The Fourier synthesizer is an educational demonstration of additive synthesis. It intentionally produces simple, monophonic, 8-bit layered sounds and is not a professional multi-timbral polyphonic instrument.
- Real-Time Latency: The real-time stream buffers audio in blocks. Latency is fundamentally dependent on the chunk size (e.g., a 1024-sample chunk introduces ~23ms of base latency at 44.1kHz). Smaller chunks reduce latency but increase CPU overhead.