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.
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.
Key Features:
- 6 Presets — Standard Mosaic, Deep Drone Mutation, Micro-Glitch Cloud, Extreme Warping, Sparse Rested Field, Custom
- Void Sieve — probes feature space, finds low-density regions, spaced by minimum distance (
void_spacing) - Grain mutation — pitch-shifts to match void's target F0, scales RMS to match void's target amplitude
- Octave folding — maps target pitch into selected vocal register (Bass/Tenor/Alto/Soprano/Full Range)
- Length jitter — randomises grain duration for natural variation
- Rest probability — inserts silent gaps (articulation/spacing control)
- Source variety — penalises reuse of recent corpus grains
- Visualisation — waveform, spectrogram, and "matter map" (corpus vs. voids in 2D space)
Quick start
- Prepare a corpus folder containing audio files (WAV, FLAC, AIFF, MP3) — the more varied, the richer the voids.
- In Praat, run
VoidMosaic.praat. - Enter the corpus folder path (or leave blank for a chooser dialog).
- Choose a preset (Standard Mosaic, Deep Drone Mutation, Micro-Glitch Cloud, Extreme Warping, Sparse Rested Field, or Custom).
- Adjust parameters: Target Duration, Grain Duration, Overlap, Jitter, Max Stretch (semitones), Rest Probability, Void Spacing, Source Variety, Vocal Register.
- Click OK — Python engine analyses corpus, finds voids, mutates grains, synthesises output.
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
| Preset | Duration (s) | Grain (ms) | Overlap (%) | Jitter (%) | Max Shift (st) | Rest Prob | Void Spacing | Variety | Character |
|---|---|---|---|---|---|---|---|---|---|
| Standard Mosaic | 10 | 250 | 50 | 10 | 24 | 0.0 | 2.0 | 1.0 | Balanced, general-purpose |
| Deep Drone Mutation | 30 | 800 | 75 | 5 | 36 | 0.0 | 1.5 | 0.6 | Ambient, sustained, smooth |
| Micro-Glitch Cloud | 5 | 50 | 15 | 40 | 12 | 0.1 | 2.5 | 1.0 | Fast, granular, stuttering |
| Extreme Warping | 15 | 150 | 50 | 25 | 60 | 0.0 | 3.0 | 1.0 | Wild pitch shifts, dramatic |
| Sparse Rested Field | 20 | 400 | 40 | 30 | 24 | 0.35 | 2.5 | 1.0 | Punctuated, 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.
Mutation Pipeline — Filling the Voids
- Source selection: Find the nearest corpus grain to the void in feature space (with recency penalty to diversify sources).
- Pitch mutation:
shift_st = 12 × log₂(target_f0 / source_f0)clamped to ±max_shift. Applylibrosa.effects.pitch_shift. - 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).
- Amplitude scaling:
scaler = target_rms / current_rms, clamped to [0.1, 5.0]. - Overlap-add: Place mutated grain with Hanning window, accumulate into output buffer.
- Normalisation: Divide by accumulated window sum, peak-normalise to 0.95.
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.
• 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)
- 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.