SPEAR Par-Text-Frame Format Parser — Partial-Tracking Additive Synthesis
Parses SPEAR's "par-text-frame-format" text export (or analyses a selected Sound via spectral peak-picking) and resynthesises the partials via an additive sine-bank engine with extensive creative controls: transpose, inharmonicity, brightness tilt, frequency shift, harmonic selection, time stretch, reverse, freeze, and more.
What this does
This script implements a partial-tracking additive synthesis engine with two input modes. It can parse SPEAR's "par-text-frame-format" text export, or analyse a selected Sound via spectral peak-picking. The partials are resynthesised as a sine-bank with extensive creative controls: transpose, inharmonicity exponent, frequency shift, brightness tilt, amplitude gate, band filtering, harmonic selection (all/odd/even), time stretch, reverse, and frame freezing. The result is a new Sound that preserves the original's spectral evolution with dramatic transformations.
Key Features:
- Two input sources — SPEAR text file OR analyse selected Sound via spectral peak-picking
- 12 Creative Presets — Faithful, OctaveUp, OctaveDown, GlassBells, HollowClarinet, FrozenDrone, SlowMotion, Reversed, DarkPad, Shimmer, Inharmonic, LowBand
- Frequency transformations — transpose ratio, inharmonicity exponent, frequency shift (Hz)
- Amplitude transformations — brightness tilt (dB/octave), amplitude gate, master scale
- Selection — all partials, odd index only, even index only
- Time manipulations — time stretch, reverse, freeze on a specific frame
- Visualisation — partial trajectories (frequency vs. time, colour-coded by amplitude), resynthesised waveform
Quick start
- Choose Input source: SPEAR text file (provide path) OR "Selected Sound (analyse)" (select a Sound in Praat).
- If analysing a Sound, set Analysis_max_freq, Analysis_hop_s, Analysis_threshold.
- Choose a preset from the dropdown (12 options).
- Or select "Custom" and adjust individual parameters: Transpose_ratio, Inharmonicity_exponent, Frequency_shift_Hz, Brightness_tilt, etc.
- Set Max_partials_per_frame (64 default).
- Enable Build_partials_table to export a Table of Real with partial data.
- Click OK — script parses/analyses, transforms, resynthesises, outputs
spear_resynth.
12 Presets
| Preset | Transpose | Inharm | Shift (Hz) | Brightness | Gate | Band High | Harmonic | Stretch | Reverse | Freeze | Character |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Faithful | 1.0 | 1.0 | 0 | 0.0 | 0.0 | 20000 | all | 1.0 | no | — | Clean, faithful resynthesis. |
| OctaveUp | 2.0 | 1.0 | 0 | 0.0 | 0.0 | 20000 | all | 1.0 | no | — | Up one octave (bright). |
| OctaveDown | 0.5 | 1.0 | 0 | 0.0 | 0.0 | 20000 | all | 1.0 | no | — | Down one octave (dark). |
| GlassBells | 1.0 | 1.3 | 0 | 0.4 | 0.0 | 20000 | all | 1.0 | no | — | Inharmonic, bell-like. |
| HollowClarinet | 1.0 | 1.0 | 0 | 0.0 | 0.01 | 20000 | odd | 1.0 | no | — | Odd harmonics only, clarinet-like. |
| FrozenDrone | 1.0 | 1.0 | 0 | 0.0 | 0.0 | 20000 | all | 2.0 | no | middle | Stretched + frozen — drone. |
| SlowMotion | 1.0 | 1.0 | 0 | 0.0 | 0.0 | 20000 | all | 3.0 | no | — | 3× time stretch — slow. |
| Reversed | 1.0 | 1.0 | 0 | 0.0 | 0.0 | 20000 | all | 1.5 | yes | — | Reverse + 1.5× stretch. |
| DarkPad | 0.5 | 1.0 | 0 | -0.5 | 0.0 | 20000 | all | 2.0 | no | — | Dark, low, stretched. |
| Shimmer | 2.0 | 1.0 | 0 | 0.6 | 0.02 | 20000 | all | 1.0 | no | — | Bright + gate — shimmering. |
| Inharmonic | 1.0 | 1.15 | 30 | 0.0 | 0.0 | 20000 | all | 1.0 | no | — | Inharmonic + 30 Hz shift. |
| LowBand | 1.0 | 1.0 | 0 | 0.0 | 0.0 | 1500 | all | 1.0 | no | — | Low-pass — only below 1500 Hz. |
SPEAR "par-text-frame-format" File Format
par-text-frame-format
point-type index frequency amplitude
partials-count 36
frame-count 450
frame-data
0.000000 36 1 449.21 0.0001 2 898.41 0.0001 ...
0.005000 36 1 448.12 0.0002 2 896.24 0.0002 ...
...
Header:
- Line 1:
par-text-frame-format(magic string) - Line 2:
point-type index frequency amplitude(column labels; may include "phase") - Line 3:
partials-count <N>(max partials per frame) - Line 4:
frame-count <M>(number of frames) - Line 5:
frame-data(data marker)
<time> <count> <index freq amp> <index freq amp> ...
Each partial group:
index frequency amplitude [phase]
analysis_hop_s step), converts to a Matrix, then performs local maxima peak-picking per time column. The amplitude is taken as sqrt(power) and the frequency from the bin centre. This is a simple partial tracker — not as sophisticated as SPEAR, but sufficient for many creative applications.
Creative Controls — Partial Manipulation
Frequency transformations
- Transpose_ratio — multiply all partial frequencies (e.g., 2.0 = octave up).
- Inharmonicity_exponent — stretch partials non-linearly: f ← 1000 × (f/1000)^β. β=1.0 = harmonic, β>1 = stretched (bell-like).
- Frequency_shift_Hz — constant shift in Hz (e.g., +30 Hz for slight detuning).
Amplitude transformations
- Brightness_tilt — spectral slope: amp ← amp × (f/1000)^tilt. Negative = dark, positive = bright.
- Amplitude_gate — fraction of peak amplitude below which partials are removed.
- Amplitude_scale — master gain multiplier.
- Band_low/High_Hz — frequency bandpass filter.
Selection & time
- Harmonic_selection — all partials, odd index only, even index only.
- Time_stretch — stretch/compress the output duration (modifies frame mapping).
- Reverse — play frames in reverse order.
- Freeze_on_frame — repeat a single frame throughout the output (set frame number, or 0=off).
Resynthesis equation
For each output frame and each selected partial:
f' = (f × transpose) × (f/1000)^(β-1) + shift (frequency transformation)
a' = a × scale × (f'/1000)^tilt (amplitude transformation)
y(t) = Σ a' × sin(2π f' t) (sine-bank sum)
Each frame is windowed with a Hann (50% overlap) and overlap-added.
Only the max_partials_per_frame loudest partials are kept.
Applications
Classic spectral modelling / resynthesis
Use case: Analyse a sound with SPEAR or the built-in peak-picker, then resynthesise with creative transformations.
Settings: Faithful preset for clean resynthesis. Use the partial trajectories visualisation to understand the sound's spectral structure.
Inharmonic / bell transformations
Use case: Turn harmonic sounds (voice, strings) into bell-like, metallic textures.
Settings: GlassBells preset (β=1.3, brightness=0.4). The inharmonic exponent stretches partials non-linearly, creating inharmonic spectra.
Clarinet / odd-harmonic emulation
Use case: Select only odd harmonics to emulate clarinet-like timbre.
Settings: HollowClarinet preset (odd-only, amplitude gate=0.01). The output has the characteristic hollow sound of a clarinet.
Time-stretch / freeze / reverse
Use case: Create drones, reversed textures, or frozen moments.
Settings: FrozenDrone (2× stretch + freeze on middle frame), Reversed (1.5× stretch + reverse), SlowMotion (3× stretch).
Brightness / spectral shaping
Use case: Adjust the spectral balance without affecting pitch.
Settings: DarkPad (negative tilt, 0.5× transpose, 2× stretch) for dark ambient textures; Shimmer (positive tilt, 2× transpose, gate) for bright, crystalline sounds.
Workflow: Voice → Glass Bells
Source: Singing voice.
Settings: GlassBells preset (β=1.3, brightness=0.4).
Result: The voice becomes bell-like — inharmonic partials create a shimmering, metallic timbre. The original pitch contour is preserved, but the harmonic structure is stretched.
Workflow: Instrument → Frozen drone
Source: Piano recording.
Settings: FrozenDrone preset (2× stretch, freeze on middle frame).
Result: The piano is stretched to twice its duration, then frozen on the middle frame — a sustained drone that holds the spectral snapshot indefinitely.
Workflow: Sound analysis → Spear-style resynthesis
Source: Any Sound in Praat.
Settings: Input source = Selected Sound (analyse), hop=0.01, threshold=0.05, preset=Custom, transpose=1.0.
Result: The script analyses the sound into partials (peak-picking) and resynthesises it. This is a lightweight alternative to SPEAR for quick spectral transformations.
• SPEAR file not parsing: Ensure the file is a valid par-text-frame-format text export. Check the header lines match exactly. The script expects "point-type index frequency amplitude" (or similar with phase).
• Sound analysis mode produces no partials: Increase Analysis_max_freq or lower Analysis_threshold. If the sound is very quiet, normalise it first.
• Output has clicks at frame boundaries: The script uses Hann windows with 50% overlap, which should prevent clicks. If clicks persist, increase the hop or check for phase discontinuities (the script uses sine phases starting at 0 per frame).
• Partial trajectories visualisation is slow: The script limits visualisation to 40,000 points. For long sounds, reduce max_partials_per_frame or turn off Draw_visualization for faster processing.
• Time_stretch values > 1 produce frame repeats: The script maps output frames to source frames using floor((oFrame - 1) / ts) + 1, which repeats frames. This is intentional for time-stretching.
Visualisation: Partial trajectories
- Title — preset name, frame count, duration, number of partials drawn.
- Partial trajectories — x = time, y = frequency (Hz), colour = amplitude (blue = quiet, red = loud). Each dot is one partial at one frame. This is the signature spectral-modelling view.
- Resynthesised waveform — the output Sound's waveform.
- Summary panel — frame count, duration, max partials per frame, transpose, inharmonicity, brightness, stretch, gate.
- Colour legend — quiet → loud amplitude ramp.