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.

Author: Shai Cohen Affiliation: Department of Music, Bar-Ilan University, Israel Praat front end: v2.2 (2026) Python engine: v2.0 License: MIT License Category: Spectral transformation / experimental composition
Contents:

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.

The most important distinction: the 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:

Output scope: the script returns only the selected region, not a full-length copy of the source with the region replaced. If you analyze 2.0–5.0 s, the output Sound is approximately 3.0 s long.

Quick start

  1. In Praat, select exactly one Sound.
  2. Run SpectralPermute.praat.
  3. Set Start_time and End_time. End_time = 0 means the end of the Sound.
  4. Choose a preset. Band shuffle is the default and the clearest introduction to the genuinely spectral behavior.
  5. Set Num_variants to 1 for a single result, or higher to audition multiple random-seed variants.
  6. Leave Draw_visualization enabled to see what was actually permuted.
  7. Enable Show_advanced only when you want to inspect or edit the preset parameters. Choosing Custom opens this dialog automatically.
  8. Click OK. The first result can be played automatically with Play_result.
Recommended first comparison: run the same short region once with Retrograde (reference) and once with Band shuffle. Retrograde moves the whole spectrum together; Band shuffle lets frequency bands follow different temporal orders. The contrast makes the purpose of the tool immediately audible.
Requirements: Python with 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.

PresetAxisBlocks / bandsSpacingOrder / decorrelationSTFT / phaseCharacter
Band shuffleband_time6 / 12Barkrandom, 1.046.4 ms, hop 512, lockReference spectral permutation: each band can follow its own shuffled time order.
Gentle driftband_time4 / 8ERBrotate, 0.492.9 ms, hop 1024, lockBroader, slower spectral displacement with only partial band independence.
Spectral smearband_time12 / 24ERBrandom, 1.046.4 ms, hop 256, lockDense, fine-grained temporal scrambling distributed across many bands.
Timbre transplantfreqblocks unused / 8Logreverse bands46.4 ms, hop 512, destination phaseMoves magnitude content between frequency regions while time stays in place.
Phase mosaicmag_phase8 / 12Barkrandom, 1.046.4 ms, hop 512, original phaseReorders spectral magnitude blocks while retaining the source phase trajectory.
Retrograde (reference)time4 / 1reverse46.4 ms, hop 512, lockWhole-spectrum block reversal; useful as a time-domain reference.
CustomStarts from Band shuffle values and forces the advanced dialog open. No hidden Custom-specific processing is applied.
Window values are requests in milliseconds. The script converts them to samples and snaps the FFT size to the nearest power of two between 256 and 16384 samples. Therefore the exact effective window in milliseconds depends on the Sound's sampling rate and is reported after processing.

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.

About decorrelation and deterministic orders: for 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:

  1. Export: Praat writes the selected Sound to a temporary 32-bit floating-point WAV.
  2. Context extension: Python includes up to one FFT window of real source audio before and after the requested region.
  3. STFT: each channel is analyzed with a Hann window and the requested hop.
  4. Interior selection: only STFT frames whose entire analysis window lies inside the requested region are eligible for permutation. Boundary-support frames remain in place.
  5. Equal blocks: eligible time frames are divided into equal-length blocks. Any remainder stays unpermuted as a tail and is reported.
  6. Permutation: the chosen axis determines which time blocks, frequency bands, magnitudes and/or phases are reassigned.
  7. Inverse STFT: the modified spectrum is reconstructed by Hann overlap-add.
  8. Trim: the context is removed so the output contains only the requested region.
  9. Edge taper: an optional quarter-sine fade is applied at the beginning and end of the resulting clip.
  10. Import: Praat reads the 32-bit floating-point result(s) back into the Object List.
Why the context matters: moving STFT frames created at a zero-padded region boundary can move the analysis-window fade into the middle of the sound. Keeping real context and permuting only fully interior frames prevents those artificial boundary ramps from travelling with a block.

Advanced parameters

The main form is intentionally compact. Show_advanced opens a second dialog pre-filled by the chosen preset. Custom always opens it.

ParameterEffective range / optionsMeaning
Axistime / band_time / freq / time_freq / mag_phaseSelects the spectral permutation operator described above.
Num_blocks2–64Number of equal time blocks. Unused on freq.
Num_bands1–64Frequency-band count. Forced to 1 on time; at least 2 on freq and time_freq.
Band_spacinglinear / log / mel / bark / erbPlaces the frequency-band boundaries. Perceptual scales allocate bands non-uniformly across Hz.
Decorrelation0–1Probability 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.
Orderingreverse / rotate / random_shuffle / custom_orderConstructs the time order, and on frequency-bearing modes also determines the default band permutation strategy.
Custom_orderPermutation of 1…Num_blocksExact 1-based time-block order. Required only when custom_order is selected and the axis uses time blocks.
Custom_band_orderPermutation of 1…Num_bandsExact 1-based source-band order for freq and time_freq when Custom ordering is selected.
Seed0 or greaterReproducible seed for random permutations. Each additional variant uses Seed + variant index.
Window_mspositive; snapped to 256–16384 samplesRequested STFT window duration. The actual FFT size is the nearest allowed power of two.
Hop_sizeminimum 32 samples; must be < FFT sizeSTFT frame spacing. If it is too large, the script replaces it with one quarter of the FFT size.
Phase_modeoff / lockControls boundary phase continuation where complex time blocks are moved. It is not used by freq or mag_phase.
Edge_fade_ms0–200 msQuarter-sine taper applied only to the beginning and end of the output clip.

Main-form controls

ParameterDefaultDescription
Start_time0.0 sBeginning of the region.
End_time0.0 s0 means the end of the Sound.
PresetBand shuffleSelects a complete sound configuration.
Num_variants11–16 outputs. Additional variants use successive seeds.
Show_advancedoffOpen the detailed parameter dialog after the preset has been applied.
Draw_visualizationonDraw source/result spectrograms, permutation map and summary.
Play_resultonPlay 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.

This is a heuristic continuity treatment, not a guarantee of perfect reconstruction after arbitrary permutation. The report therefore measures the largest sample-to-sample step in the source region and the result rather than claiming that a fixed number of seams were “corrected.”

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.

PanelWhat it showsHow to read it
A. Source regionOriginal region spectrogram with band and block guides.Reference for the material before permutation.
B. Permuted resultOutput spectrogram with the same guides.Shows where spectral energy moved in time and/or frequency.
C. Permutation mapExplicit 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. SummaryPreset, 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.
The permutation map is the key diagnostic. In 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

Python engine failed / no output: verify that Python is discoverable and that numpy, scipy and soundfile are installed. The script checks these before exporting the processing run.
Selected region is unchanged: the region may be shorter than the STFT window, or it may contain too few fully interior STFT frames for the requested number of blocks. Use a longer region, smaller Window_ms, smaller Hop_size, or fewer blocks. The engine reports the reason rather than forcing an invalid permutation.
Custom order error: 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.
Changing Num_blocks does nothing on freq: this is intentional. The freq axis holds time fixed and uses the entire eligible frame range, so no time-block grid participates in the sound transformation.
Phase lock seems to do nothing: on 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.