8-Channel Spatial Movements

Moves one mono-derived source through a fixed octophonic speaker ring, or applies one of six global amplitude envelopes to an evenly distributed centred source. Spatial gains are generated from source-to-speaker distance, normalized to constant power, and rendered as eight gain-controlled channels.

Author: Shai Cohen Affiliation: Department of Music, Bar-Ilan University, Israel Version: 0.6 (2026) Praat
Contents:

What this does

The script creates eight gain-controlled copies of one working mono source. For the six spatial patterns, a single virtual source follows a 2D trajectory inside an octagonal loudspeaker ring. At each time point, the distance from that source to every speaker determines a Gaussian spatial weight; the eight weights are normalized together before being written to IntensityTiers. For the six global patterns, the source stays at the listener position and all eight channels receive the same global amplitude envelope.

What this is not: there is no VBAP engine, Cube8 layout, keyframe editor, multiple virtual sources, elevation model, air absorption, or physical 1/r distance attenuation in this script. The spatial model is a 2D octagon with one virtual source and Gaussian distance weighting.

Quick start

  1. Select exactly one Sound.
  2. Run 8-Channel_Movements.praat.
  3. Choose a Pattern. The default is Circular rotation.
  4. For a spatial pattern, set Path_radius and Source_focus. Motion_speed is used only by Circular, Figure-8, Random walk, and Spiral.
  5. Choose an Output_format.
  6. Leave Draw_visualization on to inspect the actual path and channel gains.
  7. Click OK.
Useful starting point: Circular rotation, Motion_speed = 1 cycle/s, Path_radius = 0.7, Source_focus = 2, Floor_db = -60 dB, and 8-channel octophonic output.

Speaker geometry

The listener is at the origin and the eight speakers lie on the unit circle. The coordinate system uses y upward/front, x rightward, angle 0° at Front, and increasing angle clockwise.

ChannelLabelAngleRole
1FL315°Front-left diagonal
2FFront
3FR45°Front-right diagonal
4R90°Right
5BR135°Back-right diagonal
6B180°Back
7BL225°Back-left diagonal
8L270°Left
speaker angle a: x = sin(a) y = cos(a) listener: x = 0 y = 0 speaker ring radius = 1

Path_radius is capped at 0.98 so the built-in moving paths remain inside the loudspeaker ring. Custom_x and Custom_y are intentionally not forced inside the ring; an outside position is allowed and reported, although the stereo image cannot localize beyond the array itself.

Patterns

Global envelopes — no spatial movement

Patterns 1–6 hold the virtual source at the listener position. The spatial distribution is therefore even across all eight speakers, while a single envelope scales the complete field.

PatternActive controlsImplementation
Sine waveFrequency_hz, Floor_dbSinusoidal linear-gain envelope between the floor and unity.
Fade inFadein_time, Floor_dbLinear floor-to-unity fade, then unity.
Fade outFloor_dbLinear unity-to-floor fade over the whole file.
Triangle envelopeFloor_dbFloor → unity at mid-file → floor.
ConstantFloor_db onlyNo global attenuation; centred source remains evenly distributed.
Exponential decayExponent, Floor_dbfloor^(u^exponent), normalized to file duration.

Spatial trajectories

PatternTrajectoryMotion_speed?
Linear sweepStraight line from Left to Right at y=0, spanning the complete file.No. Effective sweep rate is 2r / duration.
Circular rotationClockwise circle of radius r, starting at Front.Yes, cycles/s.
Figure-8Gerono lemniscate: x=r·sin(phase), y=(r/2)·sin(2·phase).Yes. The second component runs at 2× the motion frequency.
Random walkMomentum-based deterministic pseudo-random walk reflected at radius r, then linearly interpolated between waypoints.Yes. Waypoint rate = 4× Motion_speed.
SpiralRadius grows linearly from 0 to r while the source rotates clockwise.Yes, cycles/s.
Custom fixed positionStatic source at (Custom_x, Custom_y).No.

Exact trajectory equations

u = t / duration phase = 2π · Motion_speed · t Linear: x = -r + 2r·u y = 0 Circular: x = r·sin(phase) y = r·cos(phase) Figure-8: x = r·sin(phase) y = (r/2)·sin(2·phase) Spiral: r(t) = r·u x = r(t)·sin(phase) y = r(t)·cos(phase) Custom: x = Custom_x y = Custom_y

Spatial gain model

Distance weights

For every control point, squared source-to-speaker distances are calculated. The nearest distance is factored out before evaluating the Gaussian so that very distant or tightly focused positions do not underflow all weights to zero.

d²_i = (x_source - x_i)² + (y_source - y_i)² d²_min = min_i(d²_i) raw weight: w_i = exp[-Source_focus · (d²_i - d²_min)]

Source_focus controls localization width. Higher values concentrate energy more strongly around the nearest speaker or speakers; lower values produce a broader distribution.

Floor and constant-power normalization

Floor_db is converted to a linear bleed floor and applied to the weights before normalization. It is clamped to -120…-6 dB.

floor = 10^(Floor_db / 20) w_i = max(w_i, floor) g_i = w_i / sqrt(Σ w_j²) therefore: Σ g_i² = 1

At the exact centre all speaker distances are equal, so every channel receives 1/sqrt(8), approximately -9.03 dB.

Global-envelope scaling

After the spatial weights are normalized, the selected global envelope is applied:

g_final,i(t) = g_spatial,i(t) · envelope(t) so: Σ g_final,i² = envelope(t)²
Constant power applies to the spatial gain stage. A global Fade, Sine, Triangle, or Exponential envelope intentionally scales the total field. A later shared output gain can also change the absolute overall level while preserving the eight channels' relative balance.

Tier resolution

The channel gains are written into eight IntensityTiers, which interpolate linearly between control points. Number_of_points is therefore a minimum, not always the final count.

fastest component fMax: Figure-8: 2 · Motion_speed Circular: Motion_speed Spiral: Motion_speed Sine: Frequency_hz Random walk: 4 · Motion_speed other modes: 1 / duration required points = ceil(30 · fMax · duration) minimum required count = 50 nPoints = max(Number_of_points, required points) hard cap = 12000

If the requested point count is too small, the script raises it and reports the change. If the 12,000-point cap is reached, the Info window notes that reducing Motion_speed will permit finer temporal representation.

The Random Walk itself is generated from a fixed set of waypoints determined by duration, speed, and seed, so changing Number_of_points does not generate a different walk; it only changes how densely that path is sampled into the tiers.

Parameters

ParameterDefaultActual role
PatternCircular rotationSelects one of 12 global/spatial behaviours.
Motion_speed1.0Cycles/s for Circular, Figure-8, and Spiral; controls random-walk waypoint rate. Not used by the other patterns.
Frequency_hz2.0Frequency of the global Sine envelope only.
Fadein_time1.0 sDuration of the global Fade-in ramp.
Exponent1.0Shape of the normalized Exponential decay.
Path_radius0.7Maximum radius of built-in spatial paths; capped at 0.98.
Source_focus2.0Gaussian distance-weight concentration.
Custom_x / Custom_y0 / 0Static Cartesian source position for Custom only; outside-ring values are allowed.
Floor_db-60 dBBleed floor applied to spatial weights before normalization; clamped to -120…-6 dB.
Scale_peak0.95Target for the shared eight-channel gain stage; values above 1 are clamped to 1.
Number_of_points100Minimum tier point count; automatically raised when the motion needs more resolution.
Random_seed1Changes the deterministic Random Walk path. It does not seed Praat's RNG.
Output_format8-channel octophonicSelects the returned speaker/stem/downmix layout.
Draw_visualizationonDraws the v0.6 process visualization.
Play_resultonPlays the returned object or a temporary stereo monitor for multi-object stem formats.

Output formats

Shared-gain stage

After the eight IntensityTier multiplications, the script measures the largest peak found in any of the eight working channels. One common factor is then applied to all channels:

peakAll = max(peak of Ch1 ... peak of Ch8) sharedGain = Scale_peak / peakAll each channel *= sharedGain

This preserves inter-channel gain relationships. It is a normalization stage and may either attenuate or boost the eight channels. Downmix formats receive an additional final peak normalization after their channel sums are built.

FormatReturned objectsRouting
8 channels — octophonic1 × 8-channelCh1…Ch8 unchanged in speaker order.
4 opposing stereo pairs4 × stereoCh1|Ch5, Ch2|Ch6, Ch3|Ch7, Ch4|Ch8. Each stereo object represents an axis through the listener.
2 quadraphonic groups2 × 4-channelDiagonal group = Ch1,3,5,7; cardinal group = Ch2,4,6,8.
4-channel fold-down1 × 4-channelFL, FR, BR, BL. Diagonal speakers feed directly; each cardinal speaker splits at 1/sqrt(2) to its two neighboring corners.
Stereo fold-down1 × stereoEach octophonic speaker is equal-power panned according to its x coordinate. Left/right is preserved; front/back is necessarily lost.

Exact four-channel fold

FL = Ch1 + 0.7071 · (Ch2 + Ch8) FR = Ch3 + 0.7071 · (Ch2 + Ch4) BR = Ch5 + 0.7071 · (Ch4 + Ch6) BL = Ch7 + 0.7071 · (Ch6 + Ch8)

Stereo preview for stem formats

When the chosen format returns four stereo pairs or two quad groups, Play_result does not play one stem in isolation. The script builds the same geometric stereo fold-down used by the stereo format, peak-normalizes it to Scale_peak, plays it as a temporary monitor, and then deletes the monitor. The actual output stem objects remain selected.

Visualization

The v0.6 figure is generated from the same trajectory and computeGains procedures used by the audio tiers. Its sampling density scales with the fastest motion component, with display-specific caps to keep Picture-window drawing responsive.

TITLE • source, pattern/class, duration, Motion_speed, output format PANEL A — Speaker map and source path • unit-circle octagon and listener • actual trajectory used by the DSP • start marker • speaker dots colored by channel • dot size = channel gain at t = 0 • global-envelope patterns show a centred source and “no spatial movement” PANEL B — Channel gains • all eight gain curves in dB • -9.03 dB centred-source reference • 0 dB unity reference • display is marked when sampling had to be decimated PANEL C — Measured peak gain per channel • dense numerical scan of the same gain engine • horizontal bars give the measured peak in dB • -9.03 dB reference PANEL D — Processed opposing channels • blue = Ch2 Front • orange = Ch6 Back • both are drawn from the eight working channels before output-format cleanup PANEL E — Summary • pattern, source, speed, radius, focus • floor, tier point count and points/cycle • seed • output format, object/channel count and routing
Visualization resolution: the path and gain plots have upper drawing limits even when the audio tiers contain more points. When the displayed gain curves fall below 8 points per fastest cycle, the title explicitly reports that the display is decimated.

Implementation notes