Vector Synthesis — User Guide

Geometric sound generation: creates evolving timbres by interpolating between four oscillators along mathematical 2D paths, producing complex harmonic motion.

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

What this does

This script implements vector synthesis — a geometric approach to sound generation where timbre evolves by moving through a 2D space defined by four corner oscillators. A "vector" (point) travels along a mathematical path (circle, ellipse, Lissajous, spiral, etc.), and at each moment, the output sound is a bilinear interpolation between the four oscillator waveforms based on the vector's X,Y coordinates. This creates continuously changing harmonic spectra that follow geometric patterns.

Key Features:

What is vector synthesis? Originally popularized by synths like the Korg Wavestation and Yamaha SY series, vector synthesis places different waveforms at the corners of a 2D coordinate system. A joystick or automated path controls a "vector" that moves through this space, blending the waveforms in real time. This creates evolving timbres that change harmonically in ways that are musically intuitive (geometric) rather than purely mathematical (additive) or static (sample‑based). The script implements this concept algorithmically with mathematical path generation.

Technical Implementation: (1) Generate four oscillators: Create sawtooth, square, triangle, and sine waves at the target frequency. (2) Generate vector path: Create X and Y coordinate signals that follow the selected mathematical path over time. (3) Bilinear interpolation: At each sample, compute output = (1‑X)(1‑Y)×saw + X(1‑Y)×square + (1‑X)Y×triangle + X×Y×sine. (4) Melody mode: Concatenate multiple notes with the same path behavior. (5) Visualization: Draw the 2D vector space with oscillator corners and animated path.

Quick start

  1. In Praat, ensure no Sound objects are selected (or any selection will be ignored).
  2. Run script…vector_synthesis.praat.
  3. For quick demo, check Melody_demo to hear an 8‑note bassline.
  4. Otherwise, choose a Path_type (start with "Circle" or "Lissajous (3:2)").
  5. Set Path_speed (0.1–2.0 Hz typical; cycles per second).
  6. Adjust Duration_s and Frequency_Hz for single‑note mode.
  7. Enable Draw_visualization and Show_trail for animated path.
  8. Click OK — the vector‑synthesized sound appears as "VectorSynth" or "VectorSynth_Melody".
Quick tip: Start with Melody_demo checked to hear how different paths sound over a musical sequence. Use Circle path for smooth, periodic timbre evolution. Try Lissajous (3:2) for complex, non‑repeating patterns. Set Path_speed = 0.5 for slow evolution, or 2.0+ for rapid timbre changes. Enable Show_trail for beautiful gradient visualization of the path history. The script generates sound from scratch — no input audio required.
Important: This script generates new audio — it does not process existing sounds. For melody mode, the bassline is fixed (E2‑G2‑A2‑C3‑A2‑G2‑E2‑D2). Path_speed controls cycles per second of the vector motion; higher values create faster timbre changes. Very high frequencies (>1000 Hz) with fast paths may cause aliasing. Visualization can be CPU‑intensive for long durations; disable for faster rendering. The output is normalized to ‑0.95 dBFS. All oscillators are band‑limited but may still have harmonic aliasing at high frequencies.

Vector Synthesis Theory

The Vector Space Concept

2D Coordinate System

The synthesis space is defined as a unit square:

X ∈ [0, 1] (horizontal axis) Y ∈ [0, 1] (vertical axis) Corners: (0,0) = Northwest = Sawtooth oscillator (1,0) = Northeast = Square oscillator (0,1) = Southwest = Triangle oscillator (1,1) = Southeast = Sine oscillator At any point (X,Y) within the square, the output is a blend of all four oscillators.

🧭 The Vector Path

The "vector" is a point (X(t), Y(t)) that moves through the space over time.

Its trajectory is defined by mathematical functions:

  • Circle: X = 0.5 + 0.4×cos(2π×speed×t), Y = 0.5 + 0.4×sin(2π×speed×t)
  • Lissajous: X = 0.5 + 0.4×sin(3×2π×speed×t), Y = 0.5 + 0.4×sin(2×2π×speed×t)
  • Spiral: Radius decreases/increases over time while rotating

As the vector moves, it passes through different regions, emphasizing different oscillators.

Bilinear Interpolation

Four‑Corner Blending

For any point (X,Y), the output is computed as:

Output = (1‑X)(1‑Y)×Saw + X(1‑Y)×Square + (1‑X)Y×Triangle + X×Y×Sine Where: Saw = sawtooth waveform at current time Square = square waveform at current time Triangle = triangle waveform at current time Sine = sine waveform at current time X, Y ∈ [0,1] (normalized coordinates) Properties: • At corners: 100% of that oscillator, 0% others • At center (0.5,0.5): 25% of each oscillator • Linear variation along edges • Smooth quadratic variation in interior

Why Bilinear?

Advantages over simpler blending:

Oscillator Generation

Waveform Formulas

📊 Four Classic Waveforms

Sawtooth (band‑limited):

Formula: 2 × (phase − floor(phase + 0.5))

Where: phase = frequency × time

Harmonics: All integer harmonics, amplitude ~1/n


Square (50% duty cycle):

Formula: if phase mod 1 < 0.5 then 1 else −1 fi

Harmonics: Odd harmonics only, amplitude ~1/n


Triangle:

Formula: 4 × abs((phase mod 1) − 0.5) − 1

Harmonics: Odd harmonics, amplitude ~1/n² (softer)


Sine:

Formula: sin(2π × frequency × time)

Harmonics: Only fundamental (pure tone)

Phase Calculation

All oscillators share the same frequency but different waveforms:

phase(t) = frequency × t (continuous, not wrapped) For periodic waveforms, we use: phase_mod = phase(t) mod 1 (fractional part) This ensures all oscillators remain phase‑locked, avoiding phasing issues when blended.

Path Mathematics

Parametric Equations

Each path type is defined by parametric equations X(θ), Y(θ):

θ = 2π × speed × t (angle parameter) Circle: X(θ) = 0.5 + 0.4 × cos(θ) Y(θ) = 0.5 + 0.4 × sin(θ) Lissajous (3:2): X(θ) = 0.5 + 0.4 × sin(3θ) Y(θ) = 0.5 + 0.4 × sin(2θ) Figure‑8 (Lemniscate): X(θ) = 0.5 + 0.4 × sin(θ) Y(θ) = 0.5 + 0.4 × sin(2θ) # Actually sin(4π×speed×t) Spiral In: r(θ) = 0.45 × (1 − t/duration) X(θ) = 0.5 + r(θ) × cos(θ) Y(θ) = 0.5 + r(θ) × sin(θ)

Time Scaling

The path speed controls how fast θ advances:

θ(t) = 2π × speed × t Where: speed = Path_speed (cycles per second) t = time in seconds Example: speed = 0.5, duration = 6 s Total cycles = 0.5 × 6 = 3 complete path cycles After 1 second: θ = 2π × 0.5 × 1 = π radians (180°)

Processing Pipeline

STEP 1 – PARAMETER SETUP: If melody_demo: generate 8 notes (E2‑G2‑A2‑C3‑A2‑G2‑E2‑D2) Else: single note at frequency_Hz for duration_s STEP 2 – PER‑NOTE GENERATION: For each note frequency f, duration d: a) Generate four oscillators (saw, square, triangle, sine) at frequency f b) Generate X(t) and Y(t) signals based on path_type and speed c) Bilinear interpolation: output = (1‑X)(1‑Y)×saw + X(1‑Y)×square + (1‑X)Y×triangle + X×Y×sine d) Apply fade‑in/out (5 ms / 10 ms) STEP 3 – MELODY CONCATENATION (if demo): Concatenate all note sounds Name result "VectorSynth_Melody" STEP 4 – NORMALIZATION: Scale peak to 0.95 (‑0.95 dBFS) STEP 5 – VISUALIZATION (if enabled): Draw 2D vector space with oscillator corners Animate path with gradient trail (if show_trail) Mark start point (green) STEP 6 – PLAYBACK (if enabled): Play resulting sound

Path Types

12 Mathematical Paths

PathX(t) FormulaY(t) FormulaCharacter
Circle0.5 + 0.4×cos(θ)0.5 + 0.4×sin(θ)Smooth, periodic, equal time in all quadrants
Ellipse0.5 + 0.45×cos(θ)0.5 + 0.3×sin(θ)Stretched horizontally, more saw‑square motion
Lissajous (3:2)0.5 + 0.4×sin(3θ)0.5 + 0.4×sin(2θ)Complex, non‑repeating pattern (3:2 ratio)
Figure‑80.5 + 0.4×sin(θ)0.5 + 0.4×sin(4π×speed×t)Symmetrical infinity symbol, crosses center twice
Spiral In0.5 + 0.45×(1‑t/d)×cos(θ)0.5 + 0.45×(1‑t/d)×sin(θ)Starts at edges, converges to center
Spiral Out0.5 + 0.45×(t/d)×cos(θ)0.5 + 0.45×(t/d)×sin(θ)Starts at center, expands to edges
Square PathCorner switchingCorner switchingJumps between corners, abrupt timbre changes
Star0.5 + 0.4×r×cos(θ)0.5 + 0.4×r×sin(θ)5‑pointed star pattern, rhythmic emphasis
Infinity Loop0.5 + 0.35×cos(θ)/(1+sin²(θ))0.5 + 0.35×sin(θ)cos(θ)/(1+sin²(θ))True lemniscate (∞ symbol), mathematical
Butterfly0.5 + 0.35×sin(θ)×scale0.5 + 0.35×cos(θ)×scaleComplex butterfly curve, detailed pattern
Rose Curve0.5 + 0.4×cos(5θ)×cos(θ)0.5 + 0.4×cos(5θ)×sin(θ)5‑petaled rose, symmetric petals
Chaotic Attractor0.5 + 0.3×sin(θ)×cos(3.7θ)0.5 + 0.3×cos(θ)×sin(2.3θ)Pseudo‑chaotic, never repeats exactly

🔄 Path Deep Dive: Circle

Characteristics: Perfectly smooth, periodic motion. Equal time spent near each oscillator. Creates predictable, cyclic timbre evolution.

Musical use: Slow speeds (0.1–0.3 Hz) for gradual timbre sweeps; fast speeds (1–2 Hz) for rhythmic animation.

Visual pattern: Perfect circle centered at (0.5,0.5) with radius 0.4.

🎭 Path Deep Dive: Lissajous (3:2)

Characteristics: 3:2 frequency ratio creates complex, non‑repeating pattern (quasi‑periodic). Never exactly retraces itself within reasonable time spans.

Musical use: Evolving pads, soundscapes, or effects where repetition is undesirable. Sounds "alive" and unpredictable.

Visual pattern: Classic Lissajous figure with 3 lobes horizontally, 2 vertically.

🌀 Path Deep Dive: Spiral In

Characteristics: Starts at outer edges (strong oscillator character), spirals inward toward center (balanced blend). Creates "focusing" or "convergence" effect.

Musical use: Build‑ups, transitions, or sounds that start with strong identity and evolve into complex blends.

Visual pattern: Spiral that tightens toward center over time.

Path Selection Guide

🎯 Choosing the Right Path

For smooth, musical evolution: Circle, Ellipse, Rose Curve

For complex, non‑repeating textures: Lissajous, Chaotic Attractor, Butterfly

For dramatic structural changes: Spiral In/Out, Square Path

For symmetrical patterns: Figure‑8, Infinity Loop, Star

For mathematical curiosity: All paths — each has unique parametric equations

Oscillator Types

The Four Corner Oscillators

OscillatorCornerWaveformHarmonic SpectrumSonic Character
SawtoothNorthwest (0,0)Ramp waveAll harmonics: 1, 1/2, 1/3, 1/4, ...Bright, rich, "analog synth"
SquareNortheast (1,0)50% pulseOdd harmonics: 1, 1/3, 1/5, 1/7, ...Hollow, woody, "video game"
TriangleSouthwest (0,1)Linear slopeOdd harmonics: 1, 1/9, 1/25, ... (1/n²)Mellow, soft, "flutey"
SineSoutheast (1,1)Pure toneFundamental onlyPure, simple, "tuning fork"

Harmonic Blending Behavior

Spectral Evolution

As the vector moves, the harmonic spectrum evolves:

From Sawtooth to Square: Even harmonics decrease, odd harmonics emphasized.
From Sawtooth to Triangle: All harmonics soften, higher harmonics attenuated more.
From Square to Sine: Odd harmonics decrease, approaching pure tone.
Through center (0.5,0.5): All four oscillators equally mixed = complex, evolving spectrum.

Example path: Circle at 0.5 Hz:
• Passes near Saw (bright) → Square (hollow) → Triangle (mellow) → Sine (pure) → back
• Creates continuous timbre cycle every 2 seconds

Phase Coherence

All oscillators are phase‑locked:

Shared phase: φ = 2π × frequency × t Sawtooth: 2 × (φ/2π − floor(φ/2π + 0.5)) Square: if (φ/2π mod 1) < 0.5 then 1 else −1 Triangle: 4 × abs((φ/2π mod 1) − 0.5) − 1 Sine: sin(φ) Because they share phase φ, blending is coherent — no phasing/comb‑filter effects.

Oscillator Placement Rationale

🗺️ The Sonic Map

Horizontal axis (X): Brightness

Left (X=0): Sawtooth/Triangle (complex spectra)

Right (X=1): Square/Sine (simpler spectra)


Vertical axis (Y): Harmonic Density

Top (Y=0): Sawtooth/Square (many harmonics)

Bottom (Y=1): Triangle/Sine (fewer harmonics)


Thus:

NW (0,0): Sawtooth = bright + dense (maximum complexity)

NE (1,0): Square = simple + dense (odd‑harmonic richness)

SW (0,1): Triangle = bright + sparse (mellow complexity)

SE (1,1): Sine = simple + sparse (minimum complexity)

Parameters & Controls

Mode Parameters

ParameterTypeDefaultDescription
Melody_demoboolean0If checked, generates 8‑note bass melody (E2‑G2‑A2‑C3‑A2‑G2‑E2‑D2) instead of single note

Vector Path Parameters

ParameterTypeDefaultDescription
Path_typeoptionCircleMathematical path: Circle, Ellipse, Lissajous, Figure‑8, Spiral In/Out, Square, Star, Infinity, Butterfly, Rose, Chaotic
Path_speedpositive0.5Speed of vector motion in cycles per second (0.05–5.0 typical)

Single Note Parameters

ParameterTypeDefaultDescription
Duration_spositive6.0Duration of single note in seconds (0.1–30.0)
Frequency_Hzpositive110Fundamental frequency in Hz (20–2000 typical)

Visualization Parameters

ParameterTypeDefaultDescription
Draw_visualizationboolean1Draw vector space and animated path after generation
Show_trailboolean1Show gradient color trail effect (blue→red over time)
Play_resultboolean1Play the generated sound automatically
Parameter Ranges & Tips:
  • Path_speed: 0.05–5.0 Hz. Below 0.1 = very slow evolution; above 2.0 = rapid changes.
  • Duration_s: 0.1–30.0 s. Short durations (<1 s) may not complete full path cycles.
  • Frequency_Hz: 20–2000 Hz. Lower frequencies (<100 Hz) highlight harmonic evolution; higher frequencies (>1000 Hz) may alias.
  • Melody demo: Fixed bassline in E minor. Each note is 0.5 s except C3 (0.7 s) and D2 (0.9 s).
  • Show_trail: Creates beautiful gradient visualization but uses more CPU. Disable for faster rendering.

Applications

Evolving Pad Synthesis

Use case: Create rich, continuously changing pads for ambient, electronic, or film music.

Technique: Use Lissajous (3:2) or Chaotic Attractor path with slow speed (0.1–0.3 Hz), low frequency (50–150 Hz), long duration (10–20 s).

Example: A 12‑second pad at 82 Hz (E2) with Lissajous path at 0.2 Hz creates a never‑repeating, evolving bed.

Sound Design & Effects

Use case: Generate unique sweeps, transitions, or animated textures for sound design.

Technique: Use Spiral In/Out for build‑ups/releases; Square Path for rhythmic gating; Butterfly for complex movements.

Workflow:

Algorithmic Composition

Use case: Create harmonically evolving sequences for generative music.

Technique: Use melody mode with different paths for each note, or script multiple calls with parameter variations.

Advantages:

Educational Demonstrations

Use case: Teach concepts of harmonics, waveforms, interpolation, and parametric equations.

Technique: Start with simple paths (Circle), show visualization, then demonstrate how X,Y coordinates blend waveforms.

Example: Compare Circle (smooth) vs Square Path (abrupt) to illustrate interpolation vs switching.

Practical Workflow Examples

🎹 Animated Synth Lead

Goal: Create a lead sound that evolves during sustained notes.

Settings:

  • Path_type: Rose Curve
  • Path_speed: 0.8 Hz (moderate evolution)
  • Frequency_Hz: 440 Hz (A4)
  • Duration_s: 2.0 s
  • Melody_demo: No (single note)

Result: A lead tone that cycles through five distinct timbral "petals" during each note hold.

🌌 Ambient Soundscape

Goal: Generate 30 seconds of evolving ambient texture.

Settings:

  • Path_type: Chaotic Attractor
  • Path_speed: 0.15 Hz (very slow)
  • Frequency_Hz: 65.41 Hz (C2)
  • Duration_s: 30.0 s
  • Post‑process: Add reverb in DAW

Result: A slowly shifting, never‑repeating drone suitable for film backgrounds or meditation music.

🎮 Video Game Sound Effects

Goal: Create retro‑style power‑up or transformation sounds.

Settings:

  • Path_type: Spiral Out
  • Path_speed: 1.5 Hz (fast)
  • Frequency_Hz: 220 Hz (A3) rising to 440 Hz (modulate via script)
  • Duration_s: 1.2 s
  • Square Path for "digital" effects

Result: Animated synth effects with clear harmonic evolution, reminiscent of 80s/90s game audio.

Advanced Techniques

Parameter automation via scripting:
  • Evolving speed: Create multiple sounds with increasing Path_speed, concatenate for acceleration effect.
  • Frequency sweeps: Modify the script to change frequency_Hz during note generation.
  • Path morphing: Generate with one path, then another, crossfade between them.
  • Multi‑layer textures: Run script multiple times with different frequencies (harmonic series), mix results.
Creative parameter combinations:
  • Extreme slow: Path_speed = 0.05, Duration_s = 60 s = 3 cycles in one minute (glacial evolution).
  • Audio rate modulation: Path_speed = 20 Hz (into audio range) creates complex sidebands.
  • Infrasound: Frequency_Hz = 20 Hz (bottom of hearing) emphasizes timbre over pitch.
  • Micro‑sound: Duration_s = 0.05 s with fast path = granular‑like events.

Troubleshooting Common Issues

Problem: Aliasing/noise at high frequencies
Cause: Sawtooth/square waves have infinite harmonics; at high fundamental frequencies, harmonics exceed Nyquist.
Solution: Use lower frequencies (<1000 Hz); the script uses band‑limited formulas but not perfect.
Problem: Path doesn't complete cycles
Cause: Duration too short relative to Path_speed.
Solution: Ensure duration × speed ≥ 1 for at least one full cycle. Example: speed=0.5 needs duration≥2 s for one cycle.
Problem: Visualization slow or crashes
Cause: Long duration with Show_trail enabled creates many drawing operations.
Solution: Disable Show_trail for durations >10 s; reduce Draw_visualization quality by modifying steps in procedure.
Problem: Melody demo sounds "choppy"
Cause: Path resets at each note boundary (each note starts at path beginning).
Solution: Modify script to continue path phase across notes, or use single‑note mode with manually created melodies.

Technical Deep Dive

Visualization Algorithm

Animated Path Drawing

The visualization draws 800 line segments to approximate the path:

1. Grid: Light gray dotted lines at 0.2 intervals
2. Boundary: Black square (0,0)–(1,1)
3. Corner markers: Colored circles with white centers and labels
4. Path: 800 segments connecting calculated points
5. Trail effect: Gradient from blue (past) to red (present)
6. Start marker: Green circle at beginning of path

With Show_trail: Each segment colored by its position in time (i/steps)
Without Show_trail: All segments red (0.9,0.1,0.3)

Coordinate Calculation

The getPathCoords procedure computes X,Y for any time t:

procedure getPathCoords: .t, .dur .phase = path_speed * .t # cycles completed # Different equations for each path_type$ if path_type$ = "Circle" .x = 0.5 + 0.4 * cos(2 * pi * .phase) .y = 0.5 + 0.4 * sin(2 * pi * .phase) elsif path_type$ = "Spiral In" .progress = .t / .dur .x = 0.5 + 0.45 * (1 - .progress) * cos(2 * pi * .phase) .y = 0.5 + 0.45 * (1 - .progress) * sin(2 * pi * .phase) # ... etc for all 12 path types endif endproc

Optimization Strategies

Efficient Oscillator Generation

Praat's Formula is vectorized — entire sounds created with one expression:

# Sawtooth (band‑limited via folding) Create Sound from formula: "OscA", 1, 0, duration, sampling_rate, "2 * (x * freq - floor(x * freq + 0.5))" # Square (50% duty cycle) Create Sound from formula: "OscB", 1, 0, duration, sampling_rate, "if x * freq mod 1 < 0.5 then 1 else -1 fi" These evaluate the formula for all samples at once, much faster than sample‑by‑sample loops.

Memory Management

Objects are removed immediately after use:

After bilinear interpolation: removeObject: "Sound OscA", "Sound OscB", "Sound OscC", "Sound OscD" removeObject: "Sound VectorX", "Sound VectorY" This keeps Praat's object list clean and conserves memory, especially important for melody mode with 8 notes × 6 objects = 48 temporary objects.

Mathematical Foundations

Bilinear Interpolation Derivation

Given four corner values A,B,C,D at (0,0), (1,0), (0,1), (1,1):

First interpolate horizontally along top edge (Y=0): top = (1‑X)×A + X×B First interpolate horizontally along bottom edge (Y=1): bottom = (1‑X)×C + X×D Then interpolate vertically between top and bottom: result = (1‑Y)×top + Y×bottom Expanded: result = (1‑X)(1‑Y)×A + X(1‑Y)×B + (1‑X)Y×C + X×Y×D This matches the formula used in the script.

Path Equation Special Cases

Lissajous figures: General form: X(t) = A×sin(a×ωt + φ) Y(t) = B×sin(b×ωt + ψ) Where a/b is rational ⇒ periodic; irrational ⇒ non‑repeating. Script uses a=3, b=2 ⇒ periodic but complex pattern. Rose curves: Polar form r = cos(kθ) X = r×cos(θ), Y = r×sin(θ) Script uses k=5 ⇒ 5 petals if k odd, 10 petals if k even. Butterfly curve: Polar form from Temple Fay (1989): r = e^cos(θ) − 2×cos(4θ) + sin^5(θ/12) Script uses simplified version.