Spatial Trajectory Painter — Drawable Panning

Convert a Sound to mono, draw a curve directly on the waveform using a PitchTier editor, and pan the mono signal across N output channels (4/6/8/12/16) by equal-power gains that follow that curve. Two mapping modes: Relative (stretch the drawn range to the full array) or Absolute (fixed height-to-channel mapping).

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

What this does

This script implements a drawable spatial panning effect. It converts a Sound to mono, then lets you draw a movement curve directly on the waveform using a PitchTier editor. The mono signal is panned across N output channels (4, 6, 8, 12, or 16) by equal-power gains (cos/sin crossfade) that follow that curve. The result is a multichannel Sound where the source moves through space according to your drawn trajectory.

Two-phase workflow: The script runs in two phases. Phase 1 creates a mono copy and opens an editor with an empty PitchTier curve on top of the waveform. You draw the movement by clicking and pressing Ctrl-T (Cmd-T on Mac) to drop points. Phase 2 reads the drawn curve, pans the mono signal across the selected number of channels using equal-power gains, and produces the multichannel output. The original source Sound is never modified.

Key Features:

Power diagnostic: The visualisation includes a "power gain" metric — the sum of squared gains across all channels at each control frame. For equal-power panning, this should be near 1.0 at all times. The summary bar shows mean, min, and max power gain across the movement, helping you verify that the panning is smooth and constant-loudness.

Quick start

  1. Select exactly one Sound object in Praat.
  2. Run script…Spatial_Trajectory_Painter.praat.
  3. A mono copy is created and an editor opens showing the waveform with an empty PitchTier curve ("movement") on top.
  4. Draw the movement:
    • Click at the desired time/height inside the CURVE panel (not the waveform panel) to position the cursor.
    • Press Ctrl-T (Windows/Linux) or Cmd-T (Mac) to drop a point.
    • Repeat to draw the movement. Drag existing points to reshape.
    • One point is enough for a fixed, static pan position.
  5. Close the editor and return to the Objects window.
  6. Select both the mono Sound (name ends in "_mono") and the "movement" PitchTier.
  7. Run the script again — the N-channel panned Sound is created. The mono Sound and movement PitchTier are removed, leaving only the final multichannel result.
Quick tip: Use Relative mapping mode for convenience — whatever range you draw is stretched to cover the full channel array. A flat curve sits in the middle. Use Absolute mode for precise, repeatable control: Base=100, Step=100 means 100 Hz → channel 1, 200 Hz → channel 2, etc. Ring topology wraps around: going past the last channel brings you back toward channel 1.
Important: Phase 1 and Phase 2 are separate runs of the same script. In Phase 1, you draw the curve. In Phase 2, you select both the mono Sound and the "movement" PitchTier, then run the script again. The script detects which phase you're in based on your selection. If you want to redraw and try again, re-run Phase 1 from the original source Sound.

Two-Phase Workflow

Phase 1 Draw the curve

  1. Select 1 Sound → Run script.
  2. A mono copy is created: original_mono.
  3. A PitchTier named movement is created.
  4. Editor opens showing waveform + empty curve.
  5. Draw: click in curve panel → Ctrl-T to add points.
  6. Close editor, return to Objects window.

Phase 2 Generate panning

  1. Select mono Sound + "movement" PitchTier.
  2. Run script again.
  3. Script samples the curve at control_rate Hz.
  4. Maps each sample to a channel position via mapping mode + topology.
  5. Creates equal-power gain envelopes per channel.
  6. Multiplies mono signal by each gain envelope.
  7. Combines channels into multichannel Sound.
  8. Mono Sound and movement PitchTier are removed.
Why two phases? The drawing interface (PitchTier editor) is interactive and requires the user to manipulate points. By separating drawing from processing, you can take your time shaping the movement, experiment with different curves, and re-run Phase 2 multiple times with the same curve (or different settings) without redrawing. The original source Sound remains untouched throughout.

Mapping Modes — How Height Becomes Channel Position

Relative (default)

The min and max of whatever you drew are stretched to fill the whole channel array (channel 1 ... last channel).

Convenience: Draw anything, it always uses the full array. A flat curve sits in the middle of the array.

Use when: You want the movement to always span the full spatial field, regardless of the absolute values drawn.

posNorm = (value - minDrawn) / (maxDrawn - minDrawn)
channel = 1 + posNorm × (n_ch - 1)

Absolute

Fixed scale: channel_position = (drawn_value - Base_value) / Step_value + 1

Precision: With Base=100, Step=100: 100 Hz → channel 1, 200 Hz → channel 2, etc.

Use when: You need precise, repeatable control over which channels are addressed, or motion confined to a few channels. A flat curve stays exactly where you drew it.

channel = (value - Base_value) / Step_value + 1
Absolute mode example: If you draw a flat curve at 150 Hz with Base=100, Step=100, the channel position is (150 - 100) / 100 + 1 = 1.5 — halfway between channel 1 and channel 2. Draw at 300 Hz → (300 - 100) / 100 + 1 = 3.0 → channel 3 exactly. This is useful for mapping known frequency ranges to specific speaker positions.

Topologies — Channel Arrangement

Line (clamp at ends)

Position is clamped to [channel 1 ... channel N]. The movement travels along a linear array of speakers.

Visualisation: Speakers shown in a horizontal row.

Use when: You have a linear speaker array (e.g., horizontal line of speakers).

Ring (wrap around)

Position wraps around a full loop: going past the last channel brings you back toward channel 1.

Visualisation: Speakers arranged in a circle around a central "Listener" marker.

Use when: You have speakers arranged in a circle (e.g., 8-channel surround, ambisonics).

Ring topology distance calculation:
For each output channel c and current position p:
  • chanWrapped = p - N × floor((p - 1) / N)
  • rawdist = |chanWrapped - c|
  • dist = min(rawdist, N - rawdist) (wrap-around distance)
  • gain = cos(dist × π/2) (equal-power panning between adjacent channels)

Applications

Multichannel panning for spatial audio

Use case: Pan a mono sound across 8 or 16 channels for immersive audio installations or surround sound.

Settings: Ring topology, Relative mapping, 8 or 16 channels. Draw a circular movement for a rotating source.

Fixed position panning

Use case: Place a mono sound at a specific speaker position in a multichannel array.

Settings: Absolute mapping, Base=0, Step=1. Draw a flat curve at the desired channel position.

Dynamic spatial trajectories for electroacoustic composition

Use case: Compose a piece where the source moves through space according to a drawn shape — accelerating, decelerating, circling.

Settings: Relative mapping, Ring topology. Draw complex trajectories with multiple points and curves.

Source separation / stem isolation

Use case: Use the panning as a creative effect — different parts of the sound are routed to different speakers based on the drawn curve.

Settings: Line topology, Relative mapping. The drawn curve acts as a "spatial filter" for the sound.

Workflow: Voice → 8-channel surround rotation

Source: Spoken word or vocal recording.
Settings: 8 channels, Ring topology, Relative mapping.
Curve: Draw a sine wave over the duration — the voice rotates around the listener.
Result: The voice moves in a circle through 8 speakers, creating an immersive surround effect.

Workflow: Drum loop → Static speaker placement

Source: Drum loop.
Settings: 4 channels, Line topology, Absolute mapping (Base=0, Step=1).
Curve: Draw a flat curve at 2.5 — the drum loop is placed between channel 2 and channel 3.
Result: The drum loop is panned to a specific position in a 4-channel array.

Workflow: Synth pad → Complex spatial trajectory

Source: Synth pad (long, sustained).
Settings: 12 channels, Ring topology, Relative mapping, control_rate=200 Hz.
Curve: Draw a complex, multi-point trajectory — fast zigzags, slow glides, circular loops.
Result: The synth pad moves through 12 speakers with intricate, drawn spatial motion.

Troubleshooting:
Phase 1: Editor opens but no curve panel: The PitchTier editor shows two panels — the waveform (lower) and the curve (upper). Click in the upper (curve) panel to position the cursor before pressing Ctrl-T.
Phase 2: "Select both objects" error: You must select both the mono Sound and the "movement" PitchTier. Ctrl-click (or shift-click) to select multiple objects.
Output has clicks / discontinuities: The control_rate determines how finely the curve is sampled. Higher rates (200–500 Hz) capture rapid movements better. The gain envelopes are interpolated linearly between control points.
Power gain not constant: Equal-power panning uses cos/sin crossfade. If the trajectory moves too fast between non-adjacent channels, the sum of squared gains may dip. The power diagnostic in the visualisation shows this — increase control_rate if needed.
Visualisation labels are crowded: For 12/16 channels, the script automatically reduces font size and speaker dot size. For very dense arrays, the visualisation may still be busy — consider using fewer channels for clearer visual feedback.

Visualisation (8-wide canvas)

When Draw_visualization is enabled, the script generates:
  • Movement trajectory — channel position over time (blue line). For Ring topology, wrap points are marked with "wrap" labels.
  • Speaker array map — speakers arranged according to topology (Line: horizontal row; Ring: circle). Dot size = active time percentage.
  • Channel utilisation — bar chart showing percentage of time each channel is active.
  • Per-channel gain heatmap — colour intensity = gain over time for each channel.
  • Power diagnostic — mean/min/max sum of squared gains (should be ≈1.0 for equal-power panning).
The speaker array map and heatmap are particularly useful for verifying that the movement reaches all intended channels and that the equal-power panning is consistent.
```