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).
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.
Key Features:
- 5 Channel Configurations — 4, 6, 8, 12, or 16 output channels
- 2 Topologies — Line (clamp at ends) or Ring (wrap around)
- 2 Mapping Modes — Relative (stretch drawn curve to full array) or Absolute (fixed height-to-channel mapping)
- Equal-power panning — cos/sin crossfade ensures constant perceived loudness
- Interactive drawing — click to add points, drag to reshape
- Visualisation — movement trajectory, speaker array map, channel utilisation, gain heatmap, power diagnostic
Quick start
- Select exactly one Sound object in Praat.
- Run script… →
Spatial_Trajectory_Painter.praat. - A mono copy is created and an editor opens showing the waveform with an empty PitchTier curve ("movement") on top.
- 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.
- Close the editor and return to the Objects window.
- Select both the mono Sound (name ends in "_mono") and the "movement" PitchTier.
- 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.
Two-Phase Workflow
Phase 1 Draw the curve
- Select 1 Sound → Run script.
- A mono copy is created:
original_mono. - A PitchTier named
movementis created. - Editor opens showing waveform + empty curve.
- Draw: click in curve panel → Ctrl-T to add points.
- Close editor, return to Objects window.
Phase 2 Generate panning
- Select mono Sound + "movement" PitchTier.
- Run script again.
- Script samples the curve at
control_rateHz. - Maps each sample to a channel position via mapping mode + topology.
- Creates equal-power gain envelopes per channel.
- Multiplies mono signal by each gain envelope.
- Combines channels into multichannel Sound.
- Mono Sound and movement PitchTier are removed.
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.
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.
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).
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.
• 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)
- 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).