3D Audio Room Simulator with Distance-Based Panning — User Guide

Moves a mono source along a bounded 3D trajectory inside a rectangular room and projects the result to two-channel loudspeaker stereo using either a shared room response or position-dependent image-source responses.

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

What this does

3D Audio Room Simulator places a stationary listener at the centre of a rectangular room and moves the source along one of eight trajectories. The source is divided into overlapping time blocks. Each block is spatialized at the corresponding trajectory position, room-processed, and accumulated into a stereo output.

What is “3D” here?

The source position has x, y, and z coordinates, and all three coordinates affect distance and the room/image-source geometry. The output, however, is ordinary two-channel loudspeaker stereo. There is no HRTF, head model, binaural rendering, or explicit elevation cue. Vertical movement can change distance, delay, level, and reflection geometry, but height is not encoded as a binaural elevation percept.

The two room modes are deliberately different:

Quick start

  1. Select exactly one Sound in Praat.
  2. Run 3D Audio Room Simulator with Distance-Based Panning.praat.
  3. Choose a room preset or Custom.
  4. Choose one of the eight movement trajectories and set Movement_radius and Num_positions.
  5. Choose Shared room IR or Per-position image-source IR.
  6. For the per-position model, choose whether the complete response is shifted by physical propagation delay d/c.
  7. Set Ir_padding, Crossfade_time, and DBAP or equal-power stereo panning.
Processing behaviour: the script always draws its visualization and always plays the completed result. There are no separate Draw_visualization or Play_result controls in v0.6.1.

Geometry and movement

Coordinate convention

Listener = (0, 0, 0), at the room centre x = left (-) / right (+) — spans Room_length y = back (-) / front (+) — spans Room_width z = down (-) / up (+) — spans Room_height

The same convention is used by the trajectory generator, panning equations, image-source geometry, and visualization.

Movement trajectories

MovementImplemented path
CircularHorizontal circle: x=r cos(a), y=r sin(a).
Front to BackOne-way sweep on y, from +r (front) to -r (back).
Left to RightOne-way sweep on x, from -r to +r.
SpiralThree-turn horizontal spiral whose radius grows from 0 to r.
Up and DownVertical sinusoid on z, reaching ±r.
Random walkDeterministic two-axis wander. It contains no random draw and therefore needs no seed.
Figure-8Gerono lemniscate: x=r sin(a), y=(r/2) sin(2a).
Diagonal sweepOne-way diagonal with x=y, normalized so the corner distance reaches r.

Radius enforcement

Movement_radius means the maximum source-listener distance for the selected trajectory. The script computes a trajectory-specific admissible radius from the room dimensions and clamps the requested radius to 95% of that limit when necessary. The Info window reports any clamp.

Room model

Sabine RT60 and wall reflection

V = length × width × height S = 2 × (length×width + length×height + width×height) RT60 = 0.161 × V / (alpha × S + 0.001) alpha is an energy absorption coefficient. Pressure reflection coefficient: |R| = sqrt(1 - alpha)

Custom absorption is clamped to 0.01–1.0. Computed RT60 is then clamped to 0.05–5.0 s.

Critical distance

d_crit = 0.057 × sqrt(V / RT60) minimum d_crit = 0.15 m

In the per-position model, this value calibrates the diffuse-tail energy against the direct field. The calibration is specifically direct versus diffuse tail; early reflections add additional non-direct energy.

Shared room IR

The shared mode builds one mono IR at the room centre. It contains a direct tap, first- and second-order axial reflections, and a deterministic diffuse tail. Each moving source segment is first attenuated by the softened amplitude law:

gain_distance = 1 / (1 + distance)

The segment is then convolved with that same room IR and projected into stereo using the source position. In this mode, movement does not change reflection times or reflection directions.

Per-position image-source IR

What is the image-source model here?

For each source position, the script creates separate left and right IRs. The direct sound and axial image sources of orders 1 and 2 are placed according to the rectangular-room image-source geometry. Reflection amplitude is |R|^order / distance, and each image source receives its own DBAP or equal-power stereo gains before its tap is written.

The direct amplitude follows 1/d, with source-listener distance floored at 0.3 m to avoid an unbounded gain when a trajectory passes through the listener.

Diffuse tail

The diffuse component uses two deterministic, decorrelated hash-noise sequences for left and right. Its envelope is:

exp(-6.9 t / RT60) × (1 - exp(-3 t / t_mix)), where t_mix = max(RT60/8, 0.005 s)

The tail amplitude is calibrated from the closed-form energy of that complete envelope so that the diffuse field matches the direct field at d_crit. Because the early field is additional, d_crit is not the crossover between direct sound and the total reverberant response.

Propagation delay

With Propagation_delay enabled in the per-position model, the entire response for each segment — direct sound, early reflections, and diffuse tail — is shifted by d/c with c = 343 m/s. This keeps the response causal at each source position. The shared-IR mode does not use this per-position propagation delay.

IR padding

Ir_padding adds time after the RT60-based diffuse decay when sizing the IR. It does not change the RT60 itself.

Stereo panning

Speaker geometry

The listener is at the origin. The stereo speakers lie on the x axis. Their nominal positions are ±1 m, but each is clamped to 90% of the room half-length so the speakers remain inside narrow rooms.

DBAP

dL = distance from source/image to left speaker dR = distance from source/image to right speaker wL = 1 / dL^2 wR = 1 / dR^2 gL = sqrt(wL / (wL + wR)) gR = sqrt(wR / (wL + wR))

The gains satisfy gL² + gR² = 1. With the square-root normalization, the underlying amplitude rolloff is approximately 1/d, or about 6 dB per doubling of distance. This is stereo distance-based amplitude panning; it should not be confused with binaural localization.

Equal-power alternative

With DBAP off, the script maps the source/image x coordinate into the room's left-right span and applies ordinary equal-power stereo:

p = clamp(x / half_room_length, -1, +1) a = (p + 1) × pi / 4 gL = cos(a) gR = sin(a)

Segment rendering

The source is divided into Num_positions equally spaced hops:

block_duration = source_duration / Num_positions segment_duration = block_duration + Crossfade_time

Adjacent source segments overlap by exactly Crossfade_time. Linear fade-out/fade-in windows are used so the overlap reconstructs continuously when Crossfade_time ≤ block_duration. The script stops with an explicit error if the requested crossfade is longer than one hop.

Each windowed segment is processed at one trajectory position and written to its corresponding output time. In per-position mode, optional propagation delay is added to that write position. The stereo buffers are finally combined and peak-scaled to 0.99.

Room presets

PresetLength × Width × HeightAbsorption
CustomForm valuesForm value, clamped to 0.01–1.0
Small Studio4 × 3 × 2.5 m0.60
Living Room6 × 5 × 3 m0.40
Concert Hall20 × 15 × 8 m0.15
Cathedral40 × 25 × 15 m0.08
Bathroom2.5 × 2 × 2.5 m0.05
Anechoic Chamber5 × 5 × 3 m0.99
Club/Bar15 × 10 × 3.5 m0.25

RT60 is calculated from these values at run time rather than stored as a preset constant, and is limited to the 0.05–5.0 s range.

Parameters

ParameterDefaultBehaviour
PresetCustomCustom plus seven room presets.
Custom_length8.0 mLeft-right room dimension; used only for Custom.
Custom_width6.0 mBack-front room dimension; used only for Custom.
Custom_height3.0 mDown-up room dimension; used only for Custom.
Custom_absorption0.3Energy absorption coefficient; clamped to 0.01–1.0.
MovementCircularEight trajectories listed above.
Movement_radius2.5 mRequested maximum distance from listener; may be reduced to keep the complete path inside the room.
Num_positions16Number of source positions/time blocks; enforced minimum is 2.
Ir_modelPer-position image-source IRShared room IR or position-dependent stereo image-source responses.
Propagation_delayonPer-position mode only: shifts the entire response by source distance / 343.
Ir_padding0.3 sExtra IR duration after the RT60-based decay.
Crossfade_time0.1 sOverlap between adjacent source blocks; must not exceed source_duration / Num_positions.
Use_dbaponDBAP if on; x-based equal-power stereo if off.

Visualization

The visualization is always drawn in v0.6.1 and is a direct process view rather than an explanatory diagram.

The top-view path is blue at its start and red at its end; the sampled position markers use the same progression.

Output and limits

Interpretation: the tool uses physically motivated room and propagation relationships, but its output is a creative stereo room simulator rather than a validated binaural or architectural-acoustics renderer.