Sympathetic Resonance — v1.0 User Guide
Virtual string physical model. Discovers the latent pitch collection embedded in a source sound, builds a bank of virtual resonant strings tuned to that discovered scale, and excites them with the source. The result is the sympathetic resonance aura: a glowing image of the sound as if it had excited a giant metallic, glassy, wooden, or airy resonant body.
What this does
Sympathetic Resonance creates the sound of a source audio signal exciting a bank of virtual resonant strings. Unlike reverb or simple filtering, this is a physical model: each string is a second-order digital resonator with a specific pitch, decay time, and bandwidth. The source signal excites all strings simultaneously, and the energy spreads between adjacent strings via sympathetic coupling (modelled as Gaussian blur across the frequency axis).
Quick start
- In Praat, select exactly one Sound object (mono or stereo – stereo will be downmixed to mono for analysis).
- Run script… →
SympatheticResonance.praat. - Choose a Preset:
- Piano Frame, Metal Plate, Harp Body, Glass Chamber, Wood Box, Shimmer Cloud
- For custom mode (preset = Custom), set:
- Character – Metallic, Glassy, Wooden, Airy
- N_strings – number of resonators (4–96)
- Decay_s – decay time in seconds (0.1–60 s)
- Coupling – amount of sympathetic energy spread (0–2)
- Wet_dry – 0 = 100 % resonance, 1 = 100 % dry original
- Click OK. Praat exports WAV, runs Python physical model, and imports the result as
SR_originalname_preset(orSR_originalname_characterfor Custom).
numpy, soundfile, scipy, librosa. The engine uses a true Constant‑Q Transform (CQT) for pitch discovery – librosa is required for optimal results.
The rendering is done in the frequency domain (FFT) and is efficient even for hundreds of resonators.
The 6 presets (+ Custom)
| Preset | Character | Strings | Decay (s) | Coupling | Description |
|---|---|---|---|---|---|
| Piano Frame | Metallic | 48 | 8.0 | 0.35 | Rich, bell‑like resonance with moderate decay. |
| Metal Plate | Metallic | 64 | 14.0 | 0.50 | Long, shimmering metallic plate – like a giant gong. |
| Harp Body | Airy | 32 | 4.0 | 0.20 | Light, airy resonance – harpsichord‑like body. |
| Glass Chamber | Glassy | 64 | 20.0 | 0.60 | Very long, glassy, ethereal – a hall of glass strings. |
| Wood Box | Wooden | 24 | 1.8 | 0.40 | Short, warm, woody resonance – like a small soundbox. |
| Shimmer Cloud | Airy | 56 | 9.0 | 0.70 | Dense, airy cloud with strong coupling – washes of resonance. |
Each preset also sets internal character parameters: brightness, shelf_freq_hz, inharmonicity, n_harmonics, harm_rolloff, and src_tilt_db_oct.
Physical model – how it works
Digital resonator (second‑order IIR)
y[n] = 2·r·cos(ω)·y[n‑1] – r²·y[n‑2] + gain·x[n]
- r (pole radius) determines both frequency selectivity and temporal decay. For a target -60 dB decay in T seconds:
r = exp( –6.908 / (T·sr) ). - ω = 2π·freq / sr – the resonant frequency.
- gain compensates for the resonator’s peak gain and applies source spectral tilt correction.
Pitch discovery
- Constant‑Q Transform (CQT) with 24 bins per octave (quarter‑tone resolution) from ~61 Hz to Nyquist.
- Time‑average the CQT magnitude to get a salience profile.
- Detect prominent peaks, cluster within 2 bins, compute centroid frequencies weighted by salience.
- Select the N most salient pitches; if fewer than requested, fill by geometric interpolation and octave extension.
Resonator bank construction
- Each discovered fundamental is expanded into a harmonic series (up to 20 partials, depending on character).
- Harmonic amplitudes follow
1 / k^harm_rolloff(e.g., rolloff 0.5 for metallic, 1.4 for wooden). - Inharmonicity (for metallic) stretches partial frequencies:
f = f0·k·√(1 + β·k²). - Pole radius r for each partial is derived from the global decay, scaled for higher partials (faster decay).
- Bandwidth (r_bw) limits the sharpness of the resonance.
- Gain is compensated for the IIR peak and for source spectral tilt (speech has ~6 dB/octave rolloff).
Excitation & sympathetic coupling
- All resonators are excited in parallel using FFT‑domain multiplication (not sequential sosfilt).
- Each resonator’s frequency response H_i(ω) is computed analytically; Gaussian blur across the resonator axis models sympathetic coupling (energy spread between adjacent strings).
- Pan gains (equal‑power stereo) are assigned to each resonator using a sinusoidal warp to break monotonic left/right bias.
- A shelf EQ (brightness control) is applied in the frequency domain.
- Output is IFFT of (input FFT × summed coupled responses).
Pipeline — six stages
Stage 2 – CQT analysis – compute Constant‑Q Transform (librosa) for log‑frequency representation.
Stage 3 – Spectral flatness – measure tonality vs. noise (used to modulate decay, bandwidth, coupling).
Stage 4 – Pitch discovery – peak detection + clustering + interpolation → fundamental frequencies.
Stage 5 – Build resonator bank – expand to harmonics, compute IIR coefficients, pan gains.
Stage 6 – FFT rendering – frequency‑domain excitation, coupling, shelf EQ, IFFT → stereo output.
Character‑dependent parameters
| Character | Brightness (dB) | Inharmonicity | Harmonics | Rolloff | Tilt (dB/oct) |
|---|---|---|---|---|---|
| +16 | 8e‑5 | 20 | 0.5 | 7.0 | |
| Glassy | +20 | 0.0 | 24 | 0.4 | 8.0 |
| Wooden | -3 | 0.0 | 6 | 1.4 | 3.0 |
| Airy | +10 | 0.0 | 16 | 0.6 | 6.0 |
Parameters & defaults
Custom parameters (when Preset = Custom)
| Parameter | Range | Default | Description |
|---|---|---|---|
| Character | Metallic / Glassy / Wooden / Airy | Metallic | Sets brightness, inharmonicity, harmonic count, rolloff, and source tilt compensation. |
| N_strings | 4–96 | 32 | Number of virtual strings (after harmonic expansion and subsampling). |
| Decay_s | 0.1–60 s | 5.0 | Global decay time (‑60 dB point). Higher partials decay faster. |
| Coupling | 0–2 | 0.30 | Strength of sympathetic coupling between adjacent strings (blur in frequency‑response domain). |
| Wet_dry | 0–1 | 0.0 | 0 = 100 % wet resonance, 1 = 100 % dry original. In between mixes. |
Output
| Parameter | Default | Description |
|---|---|---|
| Draw_visualization | yes | Show waveforms, string bank plot, spectrogram, and summary in Praat picture. |
| Play_result | yes | Auto‑play after processing. |
Visualization (Praat picture)
When Draw_visualization = 1, the script draws:
- Original waveform (grey).
- Resonance waveform (teal).
- Resonant string bank – a vertical bar plot on a logarithmic frequency axis (20 Hz–20 kHz). Each bar represents one virtual string; bar height = gain (after normalisation), bar colour varies by character (gold for metallic, blue for glassy, brown for wooden, purple for airy). Frequency reference ticks at 100 Hz, 1 kHz, 10 kHz.
- Resonance spectrogram (0–6 kHz).
- Summary panel with source name, preset, character, string count, decay, coupling, wet/dry, spectral flatness, and a list of the top discovered pitches.
FAQ / troubleshooting
Install: pip install numpy soundfile scipy librosa. On Windows, the script uses python.
Check the string count in the Info window. If n_strings is 0, pitch discovery may have failed – possibly because the source is very short or has no clear spectral peaks. Try a longer source, or increase the number of discovered pitches by raising N_strings (the engine will fill with interpolated pitches).
The model includes source tilt compensation (src_tilt_db_oct) to boost high frequencies relative to low ones, compensating for speech’s natural rolloff. If your source is already bright, you may need to reduce brightness in the character preset (edit the Python script) or lower src_tilt_db_oct.
Librosa’s CQT may fail on very short files or certain sample rates. The engine falls back to a simple STFT‑based log‑spectrum, which is less precise but still works. For best results, ensure librosa is installed and use longer source files (≥2 s).
The frequency‑domain renderer is efficient even for hundreds of resonators. For a 10‑second file with 64 resonators, processing takes about 1–2 seconds on a modern CPU.
The file temp_sr_resonances.csv contains the frequency and normalised gain of every resonator. It is used for the string bank visualisation and can be inspected for further analysis.