Arranger — User Guide
A visual multi-clip arrangement and stereo-mixing bridge for Praat AudioTools: selected Sounds are exported to a Python/Tkinter timeline where they can be repositioned, balanced, faded, auditioned, and rendered back into Praat as a new stereo Sound.
What this does
Arranger turns a set of selected Praat Sound objects into movable clips on a visual timeline. Each selected Sound becomes one clip. You can change its start time, lane, gain, stereo balance, fade-in, and fade-out, then render the complete arrangement into a stereo WAV that is automatically imported back into Praat.
Praat ↔ Python workflow
Praat front end
Arranger.praat:
- collects the selected Sounds and their metadata;
- finds the highest sample rate in the selection;
- resamples temporary copies when necessary;
- exports one temporary WAV per clip;
- writes a JSON manifest containing clip names, durations, channels, sample rate, default lane, and default start time;
- launches the Python GUI synchronously;
- imports the rendered stereo WAV when Render completes;
- removes the temporary files.
Python GUI / renderer
arranger.py:
- draws the timeline and one lane per selected clip;
- handles drag movement and fade handles;
- opens the gain/pan editor on right-click;
- provides zoom, Reset, Audition, Stop, Cancel, and Render;
- mixes all clips into a two-channel floating-point buffer;
- writes the final result as 16-bit stereo PCM WAV;
- writes a completion JSON file for Praat.
Requirements
Required
- Python 3
tkinter— required for the graphical arranger window
The Praat front end explicitly tests whether Python can import tkinter before launching the arranger.
Optional
| Package | Role | If missing |
|---|---|---|
numpy | Fast vectorized mixing and PCM decode/write path. | Final Render still works through the pure-Python standard-library fallback. |
sounddevice | Non-blocking Audition playback. | Audition is unavailable; final Render still works. |
For Audition:
pip install numpy sounddevice
Python discovery
The Praat front end uses python on Windows and python3 on Linux/Unix. On macOS it first checks several common Homebrew/framework paths before falling back to python3.
The Python arranger is searched in this order:
Quick start
- Select one or more Sound objects in Praat.
- Run
Arranger.praat. - The Python Arranger window opens with one clip per selected Sound.
- Drag clips horizontally to change their start times.
- Drag vertically to another lane if that helps organize the layout.
- Drag the yellow handles to set fade-in and fade-out.
- Right-click a clip to edit gain and pan.
- Use Audition to preview when
numpyandsounddeviceare available. - Click Render to create the stereo result and return it to Praat.
Timeline & lanes
Initial layout
Every selected Sound starts at:
The first selected Sound is placed on lane 1, the second on lane 2, and so on. The number of lanes equals the number of selected clips.
Initial project span
The manifest's initial project_duration is the sum of all selected source durations. This value establishes a generous initial GUI timeline width; it is not the duration of the default arrangement, because all default clips begin at time 0.
Dynamic extension
If a clip is moved beyond the initial span, the timeline expands automatically to include its new end time.
Zoom
| Setting | Value |
|---|---|
| Default zoom | 80 pixels/second |
| Minimum | 10 pixels/second |
| Maximum | 400 pixels/second |
Horizontal and vertical scrollbars allow long timelines and large clip selections to remain usable.
Moving clips
Left-drag a clip body to move it:
- horizontal movement changes start time;
- vertical movement changes its lane.
Start time is clamped at 0 seconds. Negative placement is not supported.
The clip duration itself does not change when it is moved. Arranger has no trim, cut, time-stretch, slip-edit, or source-offset control in v1.5.
Reset All
Reset All restores every clip to the original manifest state:
Gain & pan
Right-click a clip to open its gain/pan popup. On platforms where standard right-click differs, middle-click or Ctrl-click is also bound to the same action.
Gain
| Range | Step | DSP law |
|---|---|---|
| −24 to +24 dB | 0.5 dB | gainLinear = 10^(gainDB / 20) |
Pan is stereo balance
In v1.5, pan is deliberately a balance control, not an equal-power mono panner:
Therefore a stereo clip at center and 0 dB gain remains at unity on both channels. It is not attenuated by −3 dB at center.
| Pan value | Result |
|---|---|
| −1 | Left retained, right reduced to zero. |
| 0 | Both channels retained at unity. |
| +1 | Right retained, left reduced to zero. |
The GUI changes pan in 0.05 steps.
Fade handles
Each clip has a yellow handle at its left and right edge. Dragging these handles changes fade duration without trimming the clip.
Fade-in
The amplitude envelope rises linearly from exactly 0 to exactly 1 across the requested fade samples.
Fade-out
The amplitude envelope falls linearly from exactly 1 to exactly 0 across the requested fade samples.
The GUI prevents the two fade handles from consuming the entire clip: each fade is limited so that at least about 10 ms remains outside the combined requested fades.
Audition & Stop
Audition calls the same internal _compute_mix() routine used by final Render. It therefore previews the same placement, gain, pan, fades, overlap summation, duration, and peak-safety rule as the final mix.
Audition requires both numpy and sounddevice. Playback is non-blocking, so the GUI remains interactive.
Stop calls sounddevice.stop().
Render path
When Render is clicked, Arranger:
- stops any active Audition;
- computes the complete stereo mix;
- writes the result as 16-bit stereo PCM WAV;
- writes a completion JSON containing result path, duration, channel count and clip count;
- closes the GUI;
- returns control to Praat.
Praat reads the WAV into a new Sound and then deletes the temporary WAV, manifest, clip exports, completion JSON, and error file.
Sample rate & channel handling
Unified project sample rate
Praat determines:
Any selected Sound at a lower sample rate is copied and resampled to that rate with Praat precision 50 before export. The user's original objects remain untouched.
Mono
A mono clip is duplicated internally:
Pan then behaves as a normal left/right balance on those duplicate channels.
Stereo
Channels 1 and 2 are used as L and R. At 0 dB / center / no fades, they enter the mix without the previous center-pan attenuation.
More than two channels
Supported PCM input widths in the Python renderer
The decoder handles 8-, 16-, 24-, and 32-bit integer PCM WAV data. Praat's temporary exports are normally the standard WAV format produced by Save as WAV file.
Output format
The renderer always writes:
Mixing & peak safety
All clips are summed sample-by-sample into the same stereo buses. Lane position has no effect on mixing.
Overlap
Timeline overlap is ordinary additive mixing. Arranger does not automatically duck, crossfade, compress, or normalize overlapping clips.
Final peak safety
After all clips have been summed, the renderer checks the largest absolute sample across both channels:
This is an attenuate-only safety stage, not target normalization. A mix whose peak is 0.60 stays at 0.60; a mix whose peak is 1.20 is attenuated so its new peak is 0.98.
Output duration
The renderer allocates a buffer long enough for the latest placed clip, plus temporary safety headroom. The delivered audio is then trimmed to the last sample actually written by any clip.
The placement extent is preserved even if a clip ends in digital silence or its fade reaches zero at the end.
Praat output
After the rendered WAV is imported, Praat names the Sound from the number of clips and the actual rendered duration:
Examples:
arrangement_3clips_8.4s arrangement_7clips_21.0s
The output is selected and automatically played at the end of the Praat script.
The Info window reports:
- number of clips;
- sum of selected source durations;
- target sample rate;
- how many clips were resampled;
- Python executable and arranger path;
- actual output duration;
- output channel count;
- sample rate;
- RMS level;
- a warning if the output is effectively silent.
Limits & important distinctions
No trimming or source-offset editing
A clip always represents its complete exported Sound. v1.5 provides placement, gain, pan and fades, but no source-in/source-out trim handles.
No time stretching or pitch shifting
Moving a clip changes only its timeline position. Its playback rate and duration are unchanged.
No track processing
Lanes have no independent mute, solo, gain, pan, effects, bus routing, or output assignment.
No project save / reopen
Reset can restore the defaults during the active session, but GUI edits are not serialized as a persistent arrangement project.
Maximum two source channels per clip
Multichannel WAV decoding is safe, but only channels 1 and 2 are used in the stereo renderer.
Audition is optional; Render is not
sounddevice and numpy are needed for Audition. NumPy is only an optimization for final Render; a standard-library mixer remains available.
Gain can create clipping before final safety scaling
Positive per-clip gain and overlapping clips can raise the floating mix above ±1. Arranger does not distort or hard-clip that floating buffer; it applies the final global attenuation when the peak exceeds 1.0, then quantizes the safe mix to 16-bit PCM.
Errors return to Praat
The Python process writes a traceback to the temporary error file on failure. Praat prints that traceback in the Info window before stopping, rather than treating a crash as a normal Cancel.