What this does
This script implements a spectral band equalizer with precise frequency control that operates directly in the frequency domain via FFT spectral multiplication. It provides 9 curated presets for common audio processing tasks (telephone effect, radio simulation, bass boost, etc.) along with fully customizable parametric EQ controls. The system uses raised-cosine (Hann) shaped frequency responses for smooth transitions, supports both boost/cut EQ operations and bandpass/lowpass/highpass filtering modes, and includes visual feedback of the exact filter response being applied.
Key Features:
- 9 Curated Presets — Common audio effects and corrective EQ settings
- 4 Operating Modes — Band boost/cut, bandpass, lowpass, highpass
- Spectral Processing — Frequency-domain multiplication for precision
- Raised-Cosine Shapes — Smooth Hann-windowed frequency responses
- Visual Response Plot — Real-time display of filter magnitude response
- Parametric Control — Center frequency, bandwidth, gain with fine resolution
- Automatic Gain Management — Peak normalization to prevent clipping
Why Spectral EQ vs. Time-Domain Filtering? Traditional time-domain filters (FIR/IIR) are efficient but have limitations for precise, arbitrary frequency responses. Spectral EQ using FFT multiplication offers: (1) Arbitrary shapes: Can create any frequency response, not just standard filter types. (2) Precise control: Exact center frequency and bandwidth specification. (3) Smooth transitions: Raised-cosine shaping prevents ringing artifacts. (4) Visual feedback: Direct correlation between parameters and frequency response. (5) No phase distortion: Linear-phase operation (though with FFT delay). The implementation uses: (1) FFT analysis: Convert time-domain signal to frequency spectrum. (2) Spectral multiplication: Apply computed gain at each frequency bin. (3) Inverse FFT: Return to time domain. (4) Overlap considerations: Uses rectangular window for whole-file processing (no overlap-add needed for static filters). This approach is ideal for mastering and precise spectral shaping where exact frequency control matters more than real-time efficiency.
Technical Implementation: (1) Preset selection: Maps to predefined center, bandwidth, gain, and mode parameters. (2) Parameter validation: Checks Nyquist limits, ensures frequency ranges are valid. (3) Response calculation: Computes raised-cosine shaped gain curve based on parameters. (4) Visualization: Plots magnitude response in dB with grid and parameter annotations. (5) FFT processing: Whole-file FFT transform to frequency domain. (6) Spectral multiplication: Applies computed gain to each frequency bin via Praat Formula. (7) Inverse transform: Returns to time domain with proper cropping. (8) Gain management: Applies peak normalization to prevent clipping. The complete process maintains high precision and provides immediate visual and auditory feedback.
Quick start
- In Praat, select exactly one Sound object (mono or stereo).
- Run script… →
spectral_band_eq.praat.
- Choose a Preset (start with "Telephone" or "Sub Bass Boost" for immediate results).
- For custom EQ: Set Center_frequency_(Hz) (e.g., 1000 Hz for midrange).
- Set Bandwidth_(Hz): Narrow (100-200 Hz) for precise adjustment, wide (1000+ Hz) for broad shaping.
- Set Gain_(dB): Positive for boost, negative for cut, -100 for complete removal (filter mode).
- Enable Draw_response to visualize the filter shape (recommended).
- Enable Play_result to hear processed audio immediately.
- Click OK — FFT processing, spectral multiplication, and visualization will run.
- Examine the frequency response plot to understand exactly what was applied.
- Adjust parameters and re-run for fine-tuning (presets provide good starting points).
Quick tip: Start with presets to understand common EQ applications. The visual response plot is essential for understanding what the EQ is doing — always enable it. For subtle adjustments, use ±3-6 dB gain with moderate bandwidth (300-500 Hz). For dramatic effects, use ±12 dB or more with wider bandwidths. The three filter modes (bandpass, lowpass, highpass) activate automatically with gain = -100 dB. Processing stages: (1) Whole-file FFT (fast for short files, slower for long ones), (2) Frequency-bin gain application, (3) Inverse FFT, (4) Peak normalization. For best results, use clean recordings and apply EQ purposefully (e.g., fix problematic frequencies or enhance desired characteristics). The raised-cosine shape ensures smooth transitions without ringing artifacts.
Important: NYQUIST LIMIT: All frequencies must be below Nyquist (sample_rate/2). PROCESSING TIME: Whole-file FFT can be slow for very long files (>30 seconds). FREQUENCY RESOLUTION: Limited by FFT length (whole file), very narrow bandwidths may not be perfectly realized. GAIN LIMITS: Very high boosts (>12 dB) may cause distortion even with peak normalization. FILTER MODES: Bandpass/lowpass/highpass modes use -100 dB gain (effective removal). PHASE CONSIDERATIONS: FFT processing introduces linear phase delay (not audible but present). STEREO PROCESSING: Same EQ applied to both channels (linked stereo). REAL-TIME USE: Not suitable for live processing due to whole-file FFT. PRESET OVERRIDE: Selecting a preset overrides custom parameters. BANDWIDTH INTERPRETATION: Bandwidth is the total width between -6 dB points for bell curves, transition width for filters.
Spectral EQ Theory
Frequency-Domain Equalization
🎛️ Spectral Multiplication Principles
Core operation: Multiply frequency spectrum by desired gain curve
Mathematical basis: Convolution in time domain = multiplication in frequency domain
FFT implementation: Discrete Fourier Transform of entire signal
Gain curve: User-defined frequency response applied bin-by-bin
Phase preservation: Linear phase (constant delay) characteristic
Mathematical Foundation
# SPECTRAL EQ MATHEMATICS
# 1. FOURIER TRANSFORM RELATIONSHIP
# Time-domain filtering: y(t) = h(t) * x(t) (convolution)
# Frequency-domain equivalent: Y(ω) = H(ω) × X(ω) (multiplication)
# Discrete implementation:
# X[k] = FFT{x[n]} (N-point FFT)
# H[k] = desired gain at frequency bin k
# Y[k] = X[k] × H[k]
# y[n] = IFFT{Y[k]}
# 2. FREQUENCY BIN MAPPING
# For N-point FFT (Praat uses next power of 2):
# Frequency of bin k: f_k = k × f_s / N
# Where f_s = sampling frequency, k = 0 to N/2 (DC to Nyquist)
# 3. GAIN CURVE CONSTRUCTION
# User parameters: center_fc, bandwidth, gain_dB
# Linear gain: G_linear = 10^(gain_dB / 20)
# For each frequency f:
# Normalized distance from center: d = |f - center_fc| / (bandwidth/2)
# Raised-cosine (Hann) shape: w(d) = 0.5 × (1 + cos(π × d))
# 4. FOUR OPERATING MODES:
# MODE 1: BELL CURVE (BOOST/CUT)
IF gain_dB ≥ 0: # Boost
H(f) = 1 + w(d) × (G_linear - 1)
ELSE: # Cut
H(f) = 1 - w(d) × (1 - G_linear)
# MODE 2: BANDPASS FILTER (gain_dB = -100)
IF f < (center_fc - bandwidth/2) OR f > (center_fc + bandwidth/2):
H(f) = 0 # Complete attenuation outside band
ELSE:
# Raised-cosine window within band
H(f) = 0.5 × (1 + cos(π × (f - center_fc) / (bandwidth/2)))
# MODE 3: LOWPASS FILTER
IF f < (center_fc - bandwidth/2):
H(f) = 1 # Full pass
ELSIF f > (center_fc + bandwidth/2):
H(f) = 0 # Complete attenuation
ELSE:
# Transition region
normalized = (f - (center_fc - bandwidth/2)) / bandwidth
H(f) = 0.5 × (1 + cos(π × normalized))
# MODE 4: HIGHPASS FILTER
IF f > (center_fc + bandwidth/2):
H(f) = 1 # Full pass
ELSIF f < (center_fc - bandwidth/2):
H(f) = 0 # Complete attenuation
ELSE:
# Transition region (inverted)
normalized = ((center_fc + bandwidth/2) - f) / bandwidth
H(f) = 0.5 × (1 + cos(π × normalized))
# 5. SPECTRAL MULTIPLICATION
# Complex spectrum: X[k] = |X[k]| × e^(j·φ[k])
# Gain application: Y[k] = H(f_k) × X[k]
# Magnitude scaled: |Y[k]| = H(f_k) × |X[k]|
# Phase preserved: ∠Y[k] = ∠X[k] (linear phase)
# 6. WHOLE-FILE PROCESSING ADVANTAGES
# - No edge effects (implicit circular convolution)
# - Perfect frequency resolution for static filters
# - Exact realization of desired frequency response
# - No time-domain aliasing
# 7. PRACTICAL CONSIDERATIONS
# FFT size = next power of 2 ≥ N_samples
# Frequency resolution = f_s / N_FFT
# Very narrow bandwidths may need longer files for accurate realization
# Gain curves are sampled at FFT bin frequencies
Raised-Cosine (Hann) Windowing
📐 Smooth Transition Shape
Function: w(x) = 0.5 × (1 + cos(π × x)) for -1 ≤ x ≤ 1
Properties: Smooth, continuous first derivative, goes to 0 at edges
EQ application: Creates gentle bell curves without sharp edges
Filter application: Provides gradual rolloff without ringing
Alternative names: Hann window, raised cosine, cosine squared
EQ Presets & Common Applications
9 Curated Preset Configurations
📞 Telephone Effect (300-3400 Hz)
Center: 1850 Hz, Bandwidth: 3100 Hz, Gain: -100 dB (bandpass)
Effect: Classic telephone bandpass, removes lows and highs
Use: Vintage sound, radio dramas, communication effects
Technical: Approximates POTS telephone bandwidth
📻 AM Radio Simulation (500-4500 Hz)
Center: 2500 Hz, Bandwidth: 4000 Hz, Gain: -100 dB (bandpass)
Effect: AM radio characteristic bandwidth
Use: Vintage radio effect, lo-fi aesthetics, broadcast simulation
Technical: Wider than telephone but still band-limited
🔊 Sub Bass Boost (+6dB < 100 Hz)
Center: 50 Hz, Bandwidth: 100 Hz, Gain: +6 dB
Effect: Enhances ultra-low frequencies
Use: Electronic music, film sound, subwoofer enhancement
Technical: Focused on infrasonic and sub-bass region
🎤 Presence Boost (+4dB 2-5 kHz)
Center: 3500 Hz, Bandwidth: 3000 Hz, Gain: +4 dB
Effect: Adds clarity and articulation
Use: Vocal enhancement, instrument clarity, podcast processing
Technical: Speech intelligibility and presence range
🗑️ Mud Cut (-6dB 200-500 Hz)
Center: 350 Hz, Bandwidth: 300 Hz, Gain: -6 dB
Effect: Reduces muddy, boxy frequencies
Use: Mix cleanup, vocal de-mudding, instrument clarity
Technical: Targets common buildup region in small rooms
💨 Air Boost (+3dB > 10 kHz)
Center: 14000 Hz, Bandwidth: 8000 Hz, Gain: +3 dB
Effect: Adds brightness and airiness
Use: Mastering, vocal sheen, hi-hat enhancement
Technical: Ultra-high frequency sparkle
🎸 Mid Scoop (-8dB 1-3 kHz)
Center: 2000 Hz, Bandwidth: 2000 Hz, Gain: -8 dB
Effect: Classic guitar/bass "scooped" sound
Use: Rock guitar, metal tones, aggressive sound shaping
Technical: Reduces harsh midrange for bass/treble emphasis
🔇 Low Pass (< 2 kHz)
Center: 1000 Hz, Bandwidth: 2000 Hz, Gain: -100 dB (lowpass)
Effect: Removes high frequencies
Use: Distant sound, underwater effect, LPF simulation
Technical: Gentle rolloff starting around 1 kHz
🔊 High Pass (> 500 Hz)
Center: 1000 Hz, Bandwidth: 2000 Hz, Gain: -100 dB (highpass)
Effect: Removes low frequencies
Use: Rumble removal, vocal isolation, HPF simulation
Technical: Gentle rolloff removing below ~500 Hz
Preset Parameter Summary
| Preset | Center (Hz) | Bandwidth (Hz) | Gain (dB) | Mode | Frequency Range |
| Telephone | 1850 | 3100 | -100 | Bandpass | 300-3400 Hz |
| AM Radio | 2500 | 4000 | -100 | Bandpass | 500-4500 Hz |
| Sub Bass Boost | 50 | 100 | +6 | Bell Boost | 0-100 Hz |
| Presence Boost | 3500 | 3000 | +4 | Bell Boost | 2000-5000 Hz |
| Mud Cut | 350 | 300 | -6 | Bell Cut | 200-500 Hz |
| Air Boost | 14000 | 8000 | +3 | Bell Boost | 10000-18000 Hz |
| Mid Scoop | 2000 | 2000 | -8 | Bell Cut | 1000-3000 Hz |
| Low Pass | 1000 | 2000 | -100 | Lowpass | < 2000 Hz pass |
| High Pass | 1000 | 2000 | -100 | Highpass | > 500 Hz pass |
Frequency Response Design
Visual Response Plot
📊 Real-Time Filter Visualization
Axes: Frequency (Hz) vs. Gain (dB), -24 to +12 dB range
Grid: 6 dB vertical lines, 1-5 kHz horizontal lines depending on Nyquist
Reference: 0 dB line shown for comparison
Annotations: Center frequency and bandwidth marked with vertical lines
Title: Indicates mode (boost/cut/filter) and key parameters
Response Plot Implementation
# FREQUENCY RESPONSE VISUALIZATION
# 1. PLOT SETUP
# X-axis: 0 to Nyquist frequency (f_s/2)
# Y-axis: -24 dB to +12 dB (covers most practical EQ ranges)
# Grid: Light gray lines for orientation
# 2. RESPONSE CALCULATION
# Sample response at 300 points across frequency range
step = nyquist / 300
plotFreq = step
WHILE plotFreq <= nyquist:
# Determine gain at this frequency based on mode
IF isPassFilter = 1: # Bandpass
IF plotFreq < lowFreq OR plotFreq > highFreq:
responseDB = -24 # Effective -∞ dB
ELSE:
# Raised cosine inside band
phase = pi * (plotFreq - center_frequency) / (bandwidth / 2)
response = 0.5 * (1 + cos(phase))
responseDB = 20 * log10(response)
ELSIF isPassFilter = 2: # Lowpass
IF plotFreq < lowFreq:
responseDB = 0
ELSIF plotFreq > highFreq:
responseDB = -24
ELSE:
phase = pi * (plotFreq - lowFreq) / bandwidth
response = 0.5 * (1 + cos(phase))
responseDB = 20 * log10(response)
ELSIF isPassFilter = 3: # Highpass
IF plotFreq > highFreq:
responseDB = 0
ELSIF plotFreq < lowFreq:
responseDB = -24
ELSE:
phase = pi * (highFreq - plotFreq) / bandwidth
response = 0.5 * (1 + cos(phase))
responseDB = 20 * log10(response)
ELSE: # Bell curve (boost/cut)
IF plotFreq < lowFreq OR plotFreq > highFreq:
responseDB = 0
ELSE:
# Raised cosine shape
phase = pi * (plotFreq - center_frequency) / (bandwidth / 2)
boostAmount = 0.5 * (1 + cos(phase))
IF gain >= 0: # Boost
response = 1 + boostAmount * (linearGain - 1)
ELSE: # Cut
response = 1 - boostAmount * (1 - linearGain)
responseDB = 20 * log10(response)
# Clamp to plot range
responseDB = max(-24, min(12, responseDB))
# Draw line segment
Draw line: prevX, prevDB, plotFreq, responseDB
prevX = plotFreq
prevDB = responseDB
plotFreq = plotFreq + step
# 3. REFERENCE LINES
# Center frequency: Vertical dotted line
# Band edges: Vertical lines at lowFreq and highFreq
# 0 dB line: Horizontal gray line for reference
# 4. AUTOMATIC GRID ADAPTATION
IF nyquist > 15000:
gridStep = 5000 # 5 kHz grid for high sample rates
ELSIF nyquist > 8000:
gridStep = 2000 # 2 kHz grid for 44.1/48 kHz
ELSE:
gridStep = 1000 # 1 kHz grid for lower rates
# 5. TITLE AND ANNOTATIONS
# Title indicates mode and key parameters
# Bottom annotation shows exact center frequency and bandwidth
# All text automatically sized and positioned
# 6. VISUAL INTERPRETATION
# Steep slopes: Narrow bandwidth or sharp filter
# Gentle slopes: Wide bandwidth or gradual filter
# Above 0 dB: Boost region
# Below 0 dB: Cut or filter region
# Flat at 0 dB: Unaffected frequencies
Response Shape Characteristics
📐 Raised-Cosine Bell Curve Properties
Symmetry: Perfectly symmetric around center frequency
Smoothness: Continuous first derivative, no sharp corners
Edge behavior: Goes smoothly to 0 at bandwidth edges
Bandwidth definition: -6 dB points at ±bandwidth/2 from center
Mathematical purity: Simple trigonometric implementation
Spectral Processing Implementation
Whole-File FFT Processing
🔬 Frequency-Domain Multiplication
FFT size: Next power of 2 ≥ sample count (Praat automatic)
Frequency resolution: Δf = sample_rate / N_FFT Hz per bin
Complex spectrum: Magnitude and phase for each frequency bin
Gain application: Multiply magnitude by gain curve, preserve phase
Inverse FFT: Return to time domain with proper cropping
Spectral Processing Algorithm
# SPECTRAL PROCESSING ALGORITHM
# 1. FFT TRANSFORM
selectObject: originalSound
spectrumObj = To Spectrum: "yes"
# Praat automatically chooses optimal FFT size
# Result: complex spectrum with N/2+1 frequency bins
# 2. FREQUENCY BIN CALCULATION
# For each bin k (0 to N/2):
# frequency_k = k × sample_rate / N_FFT
# 3. GAIN APPLICATION (PRAAT FORMULA)
# Build formula string based on parameters
lowStr$ = fixed$(lowFreq, 2)
highStr$ = fixed$(highFreq, 2)
centerStr$ = fixed$(center_frequency, 2)
halfBW$ = fixed$(bandwidth / 2, 2)
# Example: Bell curve boost
IF gain >= 0:
gainMinusOne$ = fixed$(linearG