Spectral Permutation — User Guide
Rearranges a selected sound region in the short-time Fourier domain across time blocks, frequency bands, or magnitude/phase structure, then resynthesizes the transformed region as one or more new Praat Sounds.
What this does
Spectral Permutation analyzes a user-defined time region with a Hann-windowed short-time Fourier transform (STFT), rearranges selected parts of that time-frequency representation, and reconstructs the result with inverse STFT overlap-add. The transformation can act globally in time, independently across frequency bands, across the frequency axis itself, across both axes, or on magnitude while leaving the original phase trajectory in place.
time axis is intentionally retained as a reference mode, but it is not uniquely spectral. Reordering contiguous STFT frame blocks across the whole spectrum reconstructs essentially the same time segments in a new order. The genuinely spectral behavior appears when frequency bands receive different operations or when magnitude and phase are separated: band_time, freq, time_freq, and mag_phase.
Key features:
- Five transformation axes — time, per-band time, frequency, combined time+frequency, and magnitude over continuous phase.
- Six presets + Custom — every preset fixes all parameters that determine the sound, including window, hop and seed.
- Perceptual band layouts — linear, logarithmic, mel, Bark and ERB spacing.
- Band decorrelation — controls how many bands receive independent time-block orders.
- Optional phase continuation — Laroche–Dolson-style peak-region phase locking at relocated block boundaries.
- Multiple variants — up to 16 differently seeded outputs rendered in one Python process.
- Multichannel-safe processing — every input channel is processed with the same permutation configuration and retained in the output.
- Diagnostic visualization — before/after spectrograms, an explicit permutation map, and a numerical summary.
Quick start
- In Praat, select exactly one Sound.
- Run
SpectralPermute.praat. - Set Start_time and End_time.
End_time = 0means the end of the Sound. - Choose a preset. Band shuffle is the default and the clearest introduction to the genuinely spectral behavior.
- Set Num_variants to 1 for a single result, or higher to audition multiple random-seed variants.
- Leave Draw_visualization enabled to see what was actually permuted.
- Enable Show_advanced only when you want to inspect or edit the preset parameters. Choosing Custom opens this dialog automatically.
- Click OK. The first result can be played automatically with Play_result.
numpy, scipy and soundfile. Install with pip install numpy scipy soundfile. The advanced dialog requires Praat 6.3 or newer. On Praat 7.0+, the script requests trust before writing and deleting temporary files.
Presets
Presets are complete configurations rather than partial suggestions. Each one sets the axis, blocks, bands, spacing, decorrelation, ordering, seed, STFT window, hop, phase mode and edge fade. If Show_advanced is enabled, the advanced dialog opens already filled with those values so they can be inspected or edited.
| Preset | Axis | Blocks / bands | Spacing | Order / decorrelation | STFT / phase | Character |
|---|---|---|---|---|---|---|
| Band shuffle | band_time | 6 / 12 | Bark | random, 1.0 | 46.4 ms, hop 512, lock | Reference spectral permutation: each band can follow its own shuffled time order. |
| Gentle drift | band_time | 4 / 8 | ERB | rotate, 0.4 | 92.9 ms, hop 1024, lock | Broader, slower spectral displacement with only partial band independence. |
| Spectral smear | band_time | 12 / 24 | ERB | random, 1.0 | 46.4 ms, hop 256, lock | Dense, fine-grained temporal scrambling distributed across many bands. |
| Timbre transplant | freq | blocks unused / 8 | Log | reverse bands | 46.4 ms, hop 512, destination phase | Moves magnitude content between frequency regions while time stays in place. |
| Phase mosaic | mag_phase | 8 / 12 | Bark | random, 1.0 | 46.4 ms, hop 512, original phase | Reorders spectral magnitude blocks while retaining the source phase trajectory. |
| Retrograde (reference) | time | 4 / 1 | — | reverse | 46.4 ms, hop 512, lock | Whole-spectrum block reversal; useful as a time-domain reference. |
| Custom | Starts from Band shuffle values and forces the advanced dialog open. No hidden Custom-specific processing is applied. | |||||
Five permutation axes
1. time — global time-block permutation
The entire spectrum uses one common order. Each destination time block receives the corresponding complete STFT block from another source position.
What you hear: segment reordering, rotation or reversal with STFT/Hann joins. Because all frequencies move together, this is effectively a time-domain block splice and is included as a reference rather than as the tool's uniquely spectral operation.
Forced behavior: one band; decorrelation = 0.
2. band_time — independent time order by frequency band
The spectrum is divided into bands and each band receives a time-block order. Low frequencies can therefore come from one source block while mid and high frequencies come from different blocks at the same output moment.
What makes it spectral: the source's original synchronization across frequency is broken. The result cannot in general be reproduced by cutting and rearranging the waveform in time.
Decorrelation: at 0, every band shares the master order; at 1, every band receives its own variant order. Intermediate values are the probability that a band receives an independent order.
3. freq — frequency-band permutation, time fixed
Frequency bands are reassigned to new spectral locations without reordering time. If source and destination bands contain different numbers of FFT bins, the magnitude envelope of the source band is linearly resampled onto the destination band's bin grid.
The destination bins retain their own original phase. This avoids copying a source band's phase pattern into a different frequency range.
Important: Num_blocks is unused on this axis. Decorrelation does not determine the band order, and Phase_mode is not applied; the operator explicitly uses destination phase.
4. time_freq — both axes at once
Each destination frequency band receives content from another source band, and its time blocks can also be reordered. Cross-band magnitude content is resampled to fit the destination band's width.
Custom ordering has two parts: Custom_order controls time blocks and Custom_band_order controls source-to-destination frequency-band mapping.
This is the most radical mode because both spectral location and temporal placement can change simultaneously.
5. mag_phase — permuted magnitude, continuous original phase
Magnitude blocks are reordered within the frequency bands, but the phase at every destination time-frequency bin remains the phase that was originally there.
Consequence: magnitude structure moves over an unchanged phase trajectory. This is not equivalent to moving complex STFT blocks and is not available as a simple waveform splice.
Important: Phase_mode is not used on this axis because the original phase is already retained explicitly.
random_shuffle, independent bands receive independent seeded shuffles. For reverse and custom_order, independent band variants are cyclic rotations of the master order; for rotate, each independent band uses a different rotation amount. The seed makes random configurations reproducible.
How the processing works
The internal pipeline is deliberately conservative at the boundaries of the chosen region:
- Export: Praat writes the selected Sound to a temporary 32-bit floating-point WAV.
- Context extension: Python includes up to one FFT window of real source audio before and after the requested region.
- STFT: each channel is analyzed with a Hann window and the requested hop.
- Interior selection: only STFT frames whose entire analysis window lies inside the requested region are eligible for permutation. Boundary-support frames remain in place.
- Equal blocks: eligible time frames are divided into equal-length blocks. Any remainder stays unpermuted as a tail and is reported.
- Permutation: the chosen axis determines which time blocks, frequency bands, magnitudes and/or phases are reassigned.
- Inverse STFT: the modified spectrum is reconstructed by Hann overlap-add.
- Trim: the context is removed so the output contains only the requested region.
- Edge taper: an optional quarter-sine fade is applied at the beginning and end of the resulting clip.
- Import: Praat reads the 32-bit floating-point result(s) back into the Object List.
Advanced parameters
The main form is intentionally compact. Show_advanced opens a second dialog pre-filled by the chosen preset. Custom always opens it.
| Parameter | Effective range / options | Meaning |
|---|---|---|
| Axis | time / band_time / freq / time_freq / mag_phase | Selects the spectral permutation operator described above. |
| Num_blocks | 2–64 | Number of equal time blocks. Unused on freq. |
| Num_bands | 1–64 | Frequency-band count. Forced to 1 on time; at least 2 on freq and time_freq. |
| Band_spacing | linear / log / mel / bark / erb | Places the frequency-band boundaries. Perceptual scales allocate bands non-uniformly across Hz. |
| Decorrelation | 0–1 | Probability that a band receives its own time order instead of the shared master order. Forced to 0 on time; not a sonic control on freq. |
| Ordering | reverse / rotate / random_shuffle / custom_order | Constructs the time order, and on frequency-bearing modes also determines the default band permutation strategy. |
| Custom_order | Permutation of 1…Num_blocks | Exact 1-based time-block order. Required only when custom_order is selected and the axis uses time blocks. |
| Custom_band_order | Permutation of 1…Num_bands | Exact 1-based source-band order for freq and time_freq when Custom ordering is selected. |
| Seed | 0 or greater | Reproducible seed for random permutations. Each additional variant uses Seed + variant index. |
| Window_ms | positive; snapped to 256–16384 samples | Requested STFT window duration. The actual FFT size is the nearest allowed power of two. |
| Hop_size | minimum 32 samples; must be < FFT size | STFT frame spacing. If it is too large, the script replaces it with one quarter of the FFT size. |
| Phase_mode | off / lock | Controls boundary phase continuation where complex time blocks are moved. It is not used by freq or mag_phase. |
| Edge_fade_ms | 0–200 ms | Quarter-sine taper applied only to the beginning and end of the output clip. |
Main-form controls
| Parameter | Default | Description |
|---|---|---|
| Start_time | 0.0 s | Beginning of the region. |
| End_time | 0.0 s | 0 means the end of the Sound. |
| Preset | Band shuffle | Selects a complete sound configuration. |
| Num_variants | 1 | 1–16 outputs. Additional variants use successive seeds. |
| Show_advanced | off | Open the detailed parameter dialog after the preset has been applied. |
| Draw_visualization | on | Draw source/result spectrograms, permutation map and summary. |
| Play_result | on | Play the first result after processing. |
Phase, joins and boundaries
Phase mode: off
Moved complex STFT blocks keep their original complex values. Hann-window overlap-add handles the joins, with no additional phase correction.
Phase mode: lock
At each relocated block boundary, the engine predicts the nominal phase advance of each FFT bin from the previously placed frame. Instead of correcting every bin independently, it detects spectral peaks and applies each peak's correction to its surrounding region of influence. The same per-bin rotation is then applied across the incoming block, so the block's internal evolution is not time-warped.
Edge fade
Edge_fade_ms is not a crossfade back into the rest of the original Sound, because the script does not output that surrounding material. It is a short quarter-sine taper at the two clip boundaries to avoid beginning or ending on an arbitrary non-zero sample.
Visualization and report
With Draw_visualization enabled, Praat draws four coordinated panels. The spectrogram display is capped at 10 kHz for readability when the source Nyquist frequency is higher.
| Panel | What it shows | How to read it |
|---|---|---|
| A. Source region | Original region spectrogram with band and block guides. | Reference for the material before permutation. |
| B. Permuted result | Output spectrogram with the same guides. | Shows where spectral energy moved in time and/or frequency. |
| C. Permutation map | Explicit mapping used by the engine. | On time-bearing axes, each cell gives the source block placed at a destination block for that band. On freq, each row gives the source band assigned to that destination band. |
| D. Summary | Preset, axis, ordering, phase, window/hop, usable frames, block/tail counts, independent bands, seed, seam metric and output peak. | Use this panel and the Info window to reproduce a result you want to keep. |
band_time, time_freq or mag_phase, rows that differ show that frequency bands are following different source-block histories. That row-to-row disagreement is the visible signature of the spectral reorganization.
The Info window also reports the master order, the frequency-band order when relevant, each band's individual time order, frequency limits, interior-frame count, leftover tail frames, maximum sample step and output peak.
Applications
Fragment a gesture without cutting it into broadband slices
Use Band shuffle or Spectral smear. Different parts of the spectrum can draw from different temporal blocks, so a single gesture becomes internally asynchronous rather than merely chopped into reordered waveform segments.
Move timbral regions while preserving temporal phase behavior
Use Timbre transplant. Frequency-band magnitude content is reassigned across the spectrum while destination phase is retained. Log, Bark or ERB spacing can make the transplantation more perceptually structured than equal-Hz bands.
Separate spectral envelope from phase trajectory
Use Phase mosaic. The magnitude history is permuted while the original phase trajectory remains at each destination bin, producing a transformation that is conceptually distinct from moving complete complex STFT blocks.
Create families of related results
Increase Num_variants with a random preset or Custom random shuffle. The engine renders successive seeds in one run, returning _permspec_v1, _permspec_v2, and so on for direct audition and selection.
Compare temporal and spectral permutation directly
Use Retrograde (reference) as the broadband time-block condition, then compare it with the same region under band_time or time_freq. This isolates the perceptual effect of ungluing frequency bands from one common temporal order.
Troubleshooting
numpy, scipy and soundfile are installed. The script checks these before exporting the processing run.
Custom_order must contain each 1-based block index exactly once. On freq and time_freq, Custom_band_order must likewise contain each band index exactly once. Spaces are allowed in the Praat sentence field; they are stripped before validation.
freq axis holds time fixed and uses the entire eligible frame range, so no time-block grid participates in the sound transformation.
freq the destination phase is explicitly preserved, and on mag_phase the original phase trajectory is explicitly retained, so the phase-lock option is not part of those operators. On ordinary steady material, Hann overlap-add can also make off and lock sound similar.