Harmonic Comb — User Guide

Recursive inharmonic comb morph with a sample-by-sample beta trajectory, weighted resonant teeth, random phase modulation, and true dry/effect mixing.

Author: Shai Cohen Affiliation: Department of Music, Bar-Ilan University, Israel Version: 0.5.1 (2026) License: MIT License Repo: https://github.com/ShaiCohen-ops/Praat-plugin_AudioTools
Contents:

What this does

Harmonic Comb is a time-varying stack of recursive comb resonators. A randomly chosen fundamental delay anchors a set of teeth whose delays follow fundamental / h^β. The exponent β moves linearly from Beta_start to Beta_end over the sound, so the resonant spacing can move from harmonic to compressed or stretched/inharmonic structures.

The harmonic index h = 1 is fixed at the fundamental delay because 1^β = 1. Higher teeth are weighted by 1/h² and receive independent random phases in the cosine modulation.

Quick start

  1. Select exactly one Sound.
  2. Run Harmonic_Comb.praat.
  3. Choose a preset, or Custom.
  4. Use Beta_start and Beta_end to define the spectral-spacing trajectory.
  5. Set Wet_dry_percent; 0 = dry, 100 = comb-resonance contribution only.
  6. Run the script. The result is named original_comb_Preset.

Presets

PresetHarmonicsFundamental delay rangeβ start → endModulation period
Subtle Comb430–80 samples1.00 → 1.051200 samples
Medium Comb720–100 samples1.00 → 1.301000 samples
Heavy Comb1115–120 samples0.85 → 1.50850 samples
Extreme Comb1610–150 samples0.70 → 2.00700 samples

Parameters

ParameterDefaultBehavior
Number_of_harmonics7Number of recursive comb teeth.
Fundamental_delay_min_samp20Lower bound for the randomly selected fundamental delay.
Fundamental_delay_max_samp100Upper bound. The two bounds are rounded, clamped to at least 2 samples, and reordered if necessary.
Beta_start1.0Initial spacing exponent. β=1 is harmonic; β<1 compresses; β>1 stretches.
Beta_end1.3Final exponent; β is linearly interpolated sample-by-sample.
Modulation_period1000 samplesPeriod parameter in the cosine term. Harmonic h uses h/period cycles per sample plus a random phase.
Wet_dry_percent50Clamped to 0–100.
Scale_peak0.95Final attenuate-only peak ceiling; quiet signals are not boosted.

Comb engine

β(col) = Beta_start + (Beta_end - Beta_start) × (col-1)/(ncol-1) delay_h(col) = round(fundamental_delay / h^β(col)) weight_h = 1/h² if delay_h ≥ 2 and col > delay_h: self += weight_h × self[col-delay_h] × cos(randomPhase_h + 2π × col × h / Modulation_period)

The delayed read is from self, so each tooth is a feedback/recursive comb, not a feed-forward tap. Teeth whose current delay falls below 2 samples are treated as inactive to avoid zero/one-sample self-gain behavior.

The chosen fundamental delay is random on every run unless the minimum and maximum bounds are equal. Every tooth also receives a random phase. There is no exposed random seed, so repeated runs with identical form values need not be identical.

Wet/Dry semantics

The internal processed buffer contains the dry signal plus comb resonance. The final mixer explicitly subtracts the embedded dry component, so the public control behaves as advertised:

output = dry × (1 - wet) + (processed - dry) × wet

Output and visualization

The visualization contains the original waveform, result waveform, a 1/h² weight chart, and paired start/end delay bars for each comb tooth. Those delay bars show the endpoints of the β morph; the actual delay changes continuously across the sound.