Latent Void Mosaic — Negative-Space Corpus Synthesis

Finds deep acoustic voids, then forces real corpus grains to mutate (via algorithmic pitch-shifting and scaling) to fill those voids.

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

What this does

This script implements negative-space corpus synthesis — it searches a corpus of audio files for "deep acoustic voids" (regions of feature space with low density), then forces real corpus grains to mutate (via algorithmic pitch-shifting and RMS scaling) to fill those voids. The result is a mosaic that sounds like it's made from the corpus, but occupies timbral regions that were originally empty.

What is a "void"? The script extracts a 6-dimensional feature vector (RMS, centroid, flatness, rolloff, ZCR, pitch) from every grain in the corpus. It then randomly probes the feature space and identifies points that are far from any corpus grain — these are the "voids". By mutating corpus grains to match the target features of these voids, the output synthesis fills the empty spaces of the corpus's timbral distribution.

Key Features:

Quick start

  1. Prepare a corpus folder containing audio files (WAV, FLAC, AIFF, MP3) — the more varied, the richer the voids.
  2. In Praat, run VoidMosaic.praat.
  3. Enter the corpus folder path (or leave blank for a chooser dialog).
  4. Choose a preset (Standard Mosaic, Deep Drone Mutation, Micro-Glitch Cloud, Extreme Warping, Sparse Rested Field, or Custom).
  5. Adjust parameters: Target Duration, Grain Duration, Overlap, Jitter, Max Stretch (semitones), Rest Probability, Void Spacing, Source Variety, Vocal Register.
  6. Click OK — Python engine analyses corpus, finds voids, mutates grains, synthesises output.
Quick tip: Use Standard Mosaic for a balanced, 10-second output. Deep Drone Mutation (30s, long grains) for ambient textures. Micro-Glitch Cloud (5s, 50 ms grains) for rapid, stuttering effects. Extreme Warping allows up to 60 semitones of pitch-shift — wild timbral transformations. Sparse Rested Field includes 35% rests for punctuated, articulate texture.
Important: Python dependencies required: pip install numpy scipy soundfile librosa. The engine extracts 6 features per grain; the void search is computationally intensive but scales with corpus size. If your corpus is very large (>10,000 grains), consider using a faster machine or smaller corpus. The output is automatically imported as Mutated_Bestiary Sound object.

6 Presets

PresetDuration (s)Grain (ms)Overlap (%)Jitter (%)Max Shift (st)Rest ProbVoid SpacingVarietyCharacter
Standard Mosaic102505010240.02.01.0Balanced, general-purpose
Deep Drone Mutation30800755360.01.50.6Ambient, sustained, smooth
Micro-Glitch Cloud5501540120.12.51.0Fast, granular, stuttering
Extreme Warping151505025600.03.01.0Wild pitch shifts, dramatic
Sparse Rested Field204004030240.352.51.0Punctuated, articulate, rests

Void Sieve — Finding the Negative Space

Feature space (6 dimensions)

  • RMS — amplitude (loudness)
  • Spectral centroid — brightness
  • Spectral flatness — tonal vs. noise-like
  • Spectral rolloff — frequency below which 85% of energy lies
  • ZCR — zero-crossing rate (noisiness)
  • Pitch (F0) — median fundamental frequency

Each grain from the corpus is projected into this 6D space and z-score normalised.

Void detection

1. Probe the feature space with 40,000 random points within the corpus bounds.
2. For each probe, compute distance to the nearest corpus grain.
3. Sort probes by distance (far = void).
4. Greedily select voids, enforcing minimum distance (void_spacing) between selected voids.

Why "void" instead of "target distribution"? Traditional corpus mosaicking tries to match a target distribution (e.g., from a reference sound). The Void Mosaic instead generates a target by looking for regions of the corpus's own feature space that are under-represented. It then forces grains to mutate into those voids — filling the gaps in the corpus's timbral landscape. The result is a "bestiary" of sounds that could have existed but didn't.

Mutation Pipeline — Filling the Voids

For each selected void:
  1. Source selection: Find the nearest corpus grain to the void in feature space (with recency penalty to diversify sources).
  2. Pitch mutation: shift_st = 12 × log₂(target_f0 / source_f0) clamped to ±max_shift. Apply librosa.effects.pitch_shift.
  3. Octave folding: If target_f0 is outside the selected register, fold it by octaves until it fits (Bass: 82–330 Hz, Tenor: 131–523 Hz, Alto: 175–698 Hz, Soprano: 262–1047 Hz, Full Range: 50–2000 Hz).
  4. Amplitude scaling: scaler = target_rms / current_rms, clamped to [0.1, 5.0].
  5. Overlap-add: Place mutated grain with Hanning window, accumulate into output buffer.
  6. Normalisation: Divide by accumulated window sum, peak-normalise to 0.95.
Source variety (reuse penalty): When source_variety > 0, the engine adds a penalty to recently used corpus grains, encouraging the algorithm to spread across the corpus instead of leaning on a handful of boundary grains. Higher variety = more diverse source material, less repetition.

Applications

Generative ambient / drone music

Use case: Create long, evolving textures from a small corpus.

Settings: Deep Drone Mutation preset (30s, 800 ms grains, 75% overlap). The voids drive the synthesis into the empty regions of the corpus, producing sustained, morphing textures.

Glitch / stutter effects

Use case: Transform any corpus into a rapid-fire, granular stutter.

Settings: Micro-Glitch Cloud preset (5s, 50 ms grains, 15% overlap, 40% jitter, 10% rests). The output is a dense cloud of tiny, shifting fragments.

Extreme timbral mutation

Use case: Push corpus grains far beyond their original timbral range.

Settings: Extreme Warping preset (60 semitones max shift, 25% jitter). Grain pitch-shifts are so extreme they become nearly unrecognisable — a "bestiary" of impossible sounds.

Composition with rests / articulation

Use case: Create a punctuated, rhythmic texture with silences between events.

Settings: Sparse Rested Field preset (35% rest probability, 30% jitter). The output has natural articulation — like a "breathing" mosaic.

Workflow: Field recording corpus → Deep Drone Mutation

Corpus: 20 field recordings (birds, water, wind, traffic).
Settings: Deep Drone Mutation, Tenor register (131–523 Hz).
Result: 30 seconds of ambient drone that sounds like a choir of birds and wind — but with sustained pitches that never existed in the original recordings.

Workflow: Drum loop corpus → Micro-Glitch Cloud

Corpus: 10 drum loops (various genres).
Settings: Micro-Glitch Cloud (50 ms grains, 40% jitter, 10% rests).
Result: A 5-second rapid-fire glitch texture — all the transients of drums, but recombined into a stuttering cloud of tiny hits.

Workflow: Voice corpus → Extreme Warping

Corpus: 5 minutes of spoken word (multiple speakers).
Settings: Extreme Warping (60 semitones max shift, Full Range register).
Result: Voices pitch-shifted up to 5 octaves — from sub-bass growls to piercing squeaks. The voids drive the synthesis into places no human voice naturally goes.

Troubleshooting:
No output / silent: Check that the corpus folder contains audio files and that they are long enough for the grain size. Increase grain_duration_ms if corpus files are short.
Output is repetitive: Decrease source_variety (or set to 0) to allow reuse. Increase void_spacing to find more distinct voids.
Pitch shifts too extreme: Reduce Max_Stretch_Semitones. Use a narrower Vocal_Register to fold target pitches into a more natural range.
Processing is slow: Reduce corpus size (number of files), or reduce grain resolution (increase grain_duration_ms). Use smaller target duration.
Rests not appearing: Increase rest_probability (0.35–0.5 for noticeable gaps). Ensure output duration is long enough for rests to be audible.

Visualisation (8-wide canvas)

When Draw_visualization is enabled, the script generates:
  • Title — preset name, target duration, grain size, max stretch
  • Waveform — the mutated output (purple curve)
  • Spectrogram — 0–5000 Hz, shows the timbral distribution of the mosaic
  • Matter Map — 2D projection (centroid vs rolloff) showing grey dots = corpus grains, purple dots = selected voids. Visualises the negative-space mapping.
  • Engine Trace — computation time, number of grains mutated, corpus files used, audio length.
The matter map is the key visual: it shows where the voids are relative to the corpus distribution. Voids far from corpus clusters represent "deep" acoustic gaps.