Harmonic Remover — v1.0 User Guide
Selectively removes the fundamental frequency and/or chosen overtones from a sound. Uses pitch tracking and a bandpass subtraction method (Hann‑windowed frames, 75 % overlap) to isolate and subtract harmonic content, leaving the residual (noise, breath, or remaining partials). Ideal for spectral sculpting, debuzzing, noise extraction, and educational demonstrations.
What this does
Harmonic Remover extracts the pitched (harmonic) content from a sound and subtracts it, leaving the residual (noise, breath, or remaining partials). The algorithm:
- Detects the fundamental frequency (F0) per frame using Praat’s pitch tracker.
- For each voiced frame, isolates each harmonic (fundamental and/or selected overtones) using a Hann bandpass filter that captures the full spectral spread (including vibrato).
- Subtracts the isolated harmonic bands from the original frame.
- Reconstructs the output via overlap‑add (75 % overlap, exact COLA normalisation).
Quick start
- In Praat, select exactly one Sound object (mono or stereo – stereo will be downmixed to mono for processing).
- Run script… →
Harmonic_Remover.praat. - Choose a Preset:
- Remove Fundamental, Remove Odd Harmonics, Remove Even Harmonics, Remove All Overtones (keep F0 only), Remove F0 + All Overtones (noise/breath only), Remove High Harmonics (warm/mellow)
- For custom mode (preset = Custom), adjust parameters as desired:
- Removal_mode – Fundamental only / Selected overtone numbers / All overtones (keep fundamental) / Fundamental + all overtones.
- Overtone_numbers – comma‑separated list (e.g.,
2,4,6) for selected mode. - Pitch_floor / Pitch_ceiling – range for F0 detection.
- Number_of_harmonics – up to 20 partials considered.
- Analysis_window_ms – frame length (20–200 ms).
- Notch_bandwidth_Hz – half‑width of the bandpass filter around each harmonic (± value).
- Min_amplitude_dB – skip frames below this RMS (avoid amplifying noise).
- Wet_dry_percent – blend between processed (wet) and original (dry).
- Click OK. The script analyses pitch, processes frames, and creates a new Sound object named
originalname_harmonicRemoved_preset.
The 6 presets (+ Custom)
Method: bandpass subtraction
- Pitch detection –
To Pitchwith user‑defined floor/ceiling. - Framing – Hann window, 75 % overlap (
hop = win/4). COLA property: sum of windows = 2.0 at every point. - For each voiced frame:
- For each harmonic to be removed (fundamental and/or selected overtones):
- Isolate the harmonic using
Filter (pass Hann band)with centre =hn × F0, width =2 × notch_bandwidth_Hz. - Subtract the isolated band from the frame.
- Unvoiced or low‑amplitude frames pass through unmodified (preserves noise).
- Overlap‑add – after OLA, divide by 2.0 for exact unity gain.
- Wet/dry mix – blend with original.
Hann bandpass filter is implemented with Praat’s built‑in Filter (pass Hann band), which uses a smooth, zero‑phase filter (no ringing). The transition width is set to notch_bandwidth_Hz / 2 to ensure the filter captures the full harmonic spread while not interfering with neighbouring partials.
📐 COLA normalisation
For a Hann window with 75 % overlap (hop = win/4), the sum of overlapping windows is exactly 2.0 at every sample. After OLA, the output is divided by 2.0 to restore unity gain. This is more accurate than peak‑based normalisation and preserves the original amplitude of non‑processed frames.
Parameters & defaults
Removal mode
| Parameter | Options | Description |
|---|---|---|
| Removal_mode | Fundamental only / Selected overtone numbers / All overtones (keep fundamental) / Fundamental + all overtones | Which harmonic components to subtract. |
| Overtone_numbers | comma‑separated integers | Used only in “Selected overtone numbers” mode. Example: 2,4,6 removes the 2nd, 4th, and 6th partials. |
Pitch detection
| Parameter | Range | Default | Description |
|---|---|---|---|
| Pitch_floor | ≥ 50 Hz | 75 Hz | Lowest expected fundamental frequency. |
| Pitch_ceiling | ≤ 2000 Hz | 600 Hz | Highest expected fundamental frequency. |
| Number_of_harmonics | 1–20 | 8 | How many partials to consider (for mode “All overtones” and “F0+all”). |
Spectral removal
| Parameter | Range | Default | Description |
|---|---|---|---|
| Analysis_window_ms | 20–200 ms | 60 ms | STFT frame length. Larger = better frequency resolution, poorer time resolution. |
| Notch_bandwidth_Hz | 5–200 Hz | 60 Hz | Half‑width of the bandpass filter around each harmonic. Larger = more aggressive removal (captures vibrato). |
Threshold & output
| Parameter | Range | Default | Description |
|---|---|---|---|
| Min_amplitude_dB | -∞ … 0 | -50 dB | Frames below this RMS level are not processed (avoid amplifying noise). |
| Wet_dry_percent | 0–100 | 100 | 100 = fully processed; 0 = fully original. |
| Scale_peak | 0–1 | 0.95 | Normalise output peak to this value. |
| Draw_visualization | yes/no | yes | Show 5‑panel visualisation. |
| Play_result | yes/no | yes | Auto‑play after processing. |
Visualization (5‑panel Praat picture)
When Draw_visualization = 1, the script draws:
- Input and output waveforms – side‑by‑side.
- Original and processed spectrograms (0–5 kHz).
- Notch shape diagram – a frequency‑domain view showing which harmonics are removed (red shaded bands with “×”) and which are kept (green markers with numbers). The diagram is drawn at the median fundamental frequency of the source.
- Summary panel – mode, number of harmonics, notch bandwidth, window, median F0, voiced frames, wet/dry, processing time.
FAQ / troubleshooting
Adjust Pitch_floor and Pitch_ceiling to match your source. For speech, 75–600 Hz is typical; for bass instruments, lower the floor to 40 Hz; for high soprano voices, raise the ceiling to 800 Hz. The script prints the median F0 in the Info window – if it’s 0, no pitch was found.
The OLA normalisation (division by 2.0) ensures perfect reconstruction for unprocessed frames. If clicks appear, try reducing Notch_bandwidth_Hz (sharper filters) or increasing Analysis_window_ms (smoother spectral transitions). Also ensure Min_amplitude_dB is not set too high – low‑amplitude frames are passed through unmodified, which can cause discontinuities if they are adjacent to heavily processed frames. A small wet/dry mix (e.g., 80 %) can smooth transitions.
The bandpass filter width is centred on the instantaneous F0 per frame. If vibrato is very wide, increase Notch_bandwidth_Hz to capture the full frequency sweep. For very fast pitch changes (e.g., glissandi), consider using a smaller analysis window (20–30 ms) to better track the trajectory.
Zeroing FFT bins introduces severe ringing artefacts (pre‑echo/post‑echo) because the abrupt truncation in the frequency domain creates a sinc‑shaped impulse response. The bandpass subtraction method uses a smooth, zero‑phase filter, preserving the time‑domain envelope of the harmonic while removing its energy. It also naturally handles vibrato and pitch variation within the frame.
For a 10‑second sound at 44.1 kHz, analysis_window_ms = 60 gives about 665 frames. If removing 12 harmonics per frame, that’s ~8000 bandpass filter calls. Each filter is implemented in Praat’s C‑level code, so it’s reasonably fast (10–30 seconds). The progress indicator updates every 50 frames.