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.

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

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.

What is SPEAR? SPEAR (Sinusoidal Partial Editing Analysis and Resynthesis) is a classic application for sinusoidal modelling, developed by Michael Klingbeil. It analyses audio into time-varying partials (frequency, amplitude, phase) and exports them in a text format. This script reads that format and resynthesises the partials into a Sound, with the ability to manipulate the partials before resynthesis — effectively a spectral editing and transformation tool.

Key Features:

Resynthesis efficiency: For each frame, the loudest partials are summed as windowed sines (Hann, 50% overlap) and overlap-added into a master Sound. This keeps the cost to one Formula pass per frame (hundreds), not one per partial (tens of thousands), so it stays tractable in pure Praat.

Quick start

  1. Choose Input source: SPEAR text file (provide path) OR "Selected Sound (analyse)" (select a Sound in Praat).
  2. If analysing a Sound, set Analysis_max_freq, Analysis_hop_s, Analysis_threshold.
  3. Choose a preset from the dropdown (12 options).
  4. Or select "Custom" and adjust individual parameters: Transpose_ratio, Inharmonicity_exponent, Frequency_shift_Hz, Brightness_tilt, etc.
  5. Set Max_partials_per_frame (64 default).
  6. Enable Build_partials_table to export a Table of Real with partial data.
  7. Click OK — script parses/analyses, transforms, resynthesises, outputs spear_resynth.
Quick tip: Start with Faithful preset for a clean resynthesis. OctaveUp/Down for simple pitch shifting. GlassBells for inharmonic, bell-like textures (β=1.3). HollowClarinet selects only odd harmonics. FrozenDrone time-stretches 2× and freezes on the middle frame. Enable Draw_visualization to see partial trajectories — a classic spectral-modelling view.
Important: SPEAR text files must follow the "par-text-frame-format" exactly. The script expects the header lines and then frame data. For the Sound analysis mode, the script uses a Spectrogram → Matrix → local maxima peak-picking. The analysis threshold is relative to the peak amplitude in each frame (higher threshold = fewer partials). The output is band-limited to 8 kHz (due to the 16 kHz internal processing) — the visualization draws up to 6 kHz for clarity.

12 Presets

PresetTransposeInharmShift (Hz)BrightnessGateBand HighHarmonicStretchReverseFreezeCharacter
Faithful1.01.000.00.020000all1.0noClean, faithful resynthesis.
OctaveUp2.01.000.00.020000all1.0noUp one octave (bright).
OctaveDown0.51.000.00.020000all1.0noDown one octave (dark).
GlassBells1.01.300.40.020000all1.0noInharmonic, bell-like.
HollowClarinet1.01.000.00.0120000odd1.0noOdd harmonics only, clarinet-like.
FrozenDrone1.01.000.00.020000all2.0nomiddleStretched + frozen — drone.
SlowMotion1.01.000.00.020000all3.0no3× time stretch — slow.
Reversed1.01.000.00.020000all1.5yesReverse + 1.5× stretch.
DarkPad0.51.00-0.50.020000all2.0noDark, low, stretched.
Shimmer2.01.000.60.0220000all1.0noBright + gate — shimmering.
Inharmonic1.01.15300.00.020000all1.0noInharmonic + 30 Hz shift.
LowBand1.01.000.00.01500all1.0noLow-pass — only below 1500 Hz.

SPEAR "par-text-frame-format" File Format

File structure (example):
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)
Data lines: <time> <count> <index freq amp> <index freq amp> ...
Each partial group: index frequency amplitude [phase]
Sound analysis mode: If you don't have a SPEAR file, the script can analyse a selected Sound directly. It converts to mono, generates a spectrogram (with 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.

Partial trajectories visualisation: The script captures up to 40,000 partials (loudest per frame) and draws them as coloured dots: x = time, y = frequency, colour = amplitude (blue = quiet, red = loud). This is the classic spectral-modelling view — you can see how the partials evolve over time and how the transformations affect them.

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.

Troubleshooting:
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

When Draw_visualization is enabled, the script generates:
  • 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.
The partial trajectories show how the spectral content evolves over time and how the transformations change the partial frequencies and amplitudes.