Granular Navigation Engine — v1.3 User Guide

Navigate through grains from multiple audio files using an autoencoder‑trained latent space. The Python engine scans a folder, extracts spectral features (batch‑FFT), trains a compact autoencoder, builds a transition score matrix, and generates a path through the grain collection according to a chosen navigation mode. Praat reconstructs the final audio from the original sources.

Author: Shai Cohen Affiliation: Department of Music, Bar‑Ilan University, Israel Version: 1.3 (2026) License: MIT License Repo: GitHub
Contents:

What this does

Granular Navigation Engine treats a folder of sound files as a corpus of grains. All processing – scanning, grain slicing, feature extraction, autoencoder training, and path generation – is handled by a Python script. Praat’s role is limited to folder selection, reading the resulting path CSV, and reconstructing the audio by concatenating grains with crossfade. This clean separation keeps Praat fast and gives Python full control over the neural architecture.

Key idea: The autoencoder learns a 16‑dimensional latent space from 14 spectral features (8 log‑spaced band energies, centroid, spread, flatness, rolloff, ZCR, RMS). A transition score matrix is built from pairwise Euclidean distances in this latent space. The navigation mode then selects a path through the grains: stay in similar regions, seek contrast, or follow a perceptual axis (brighter, darker, noisier, harmonic, denser, sparser). The result is a new granular stream that moves through the acoustic space of the corpus.

Quick start

  1. Place a folder of audio files (.wav, .aif, .aiff, .flac) somewhere on your disk.
  2. In Praat, run GranularNavigationEngine.praat.
  3. In the directory chooser, select your folder.
  4. In the form, choose a Navigation_mode:
    • Similarity, Smooth, Contrast, Brighter, Darker, Noisier, Harmonic, Denser, Sparser
  5. Set Grain_ms (e.g. 150 ms), Path_length (number of grains in output).
  6. Click OK. Python runs (may take a minute for large folders), writes a path CSV, and Praat reconstructs the result as GNE_mode_XXgr.
Quick tip: Start with Similarity to hear grains that are acoustically close. For a dramatic contrast path, use Contrast (jumps between dissimilar regions). For timbral evolution, try Brighter or Darker – the path will follow the spectral centroid axis.
Important: Python dependencies: torch, numpy, soundfile. The autoencoder training uses PyTorch; a CUDA‑capable GPU is not required (CPU is fine). The script uses batch‑FFT feature extraction – all grains from a file are processed simultaneously, making it fast even for large folders.

The nine navigation modes

ModeDescriptionTransition logic
similarity Stay in acoustically similar regions. Minimise Euclidean distance in latent space from current grain.
smooth Minimise feature‑space distance (raw features, not latent). Minimise distance in the 14‑dim feature space.
contrast Jump to regions far from the recent past. Maximise distance from the mean of the last few grains.
brighter Progressively increase spectral centroid. Follow direction vector derived from centroid → latent space.
darker Progressively decrease spectral centroid. Follow direction vector derived from centroid ← latent space.
noisier Increase zero‑crossing rate (ZCR). Follow direction vector derived from ZCR → latent space.
harmonic Decrease spectral flatness (become more tonal). Follow direction vector derived from flatness ← latent space.
denser Increase RMS (louder grains). Follow direction vector derived from RMS → latent space.
sparser Decrease RMS (quieter grains). Follow direction vector derived from RMS ← latent space.

For directional modes (brighter … sparser), the engine solves a least‑squares problem to find a vector in latent space that best predicts the target feature. The path then maximises the projection onto that vector, blended with the raw transition score.

Pipeline — six stages

Stage 1 – Folder scan + batch‑FFT feature extraction (Python)
For each file: slice into grains (50% overlap), apply Hanning window to all grains simultaneously, compute 14 features (8 log‑spaced bands, centroid, spread, flatness, rolloff, ZCR, RMS).
Stage 2 – Normalisation (median / IQR, robust to outliers).
Stage 3 – Train autoencoder (16‑dim latent, 80 epochs by default).
Stage 4 – PCA projection to 2‑D (for visualisation).
Stage 5 – Build transition scores (1 / (1 + Euclidean distance) in latent space).
Stage 6 – Navigate path according to selected mode, write CSV.
Praat reconstruction – read CSV, extract grains from original files, concatenate with crossfade.

Feature set (14 dimensions)

Autoencoder architecture & training

Encoder

Input (14) → Linear(64) → BatchNorm → LeakyReLU(0.1) → Linear(32) → LeakyReLU → Linear(16)

Decoder

Latent (16) → Linear(32) → LeakyReLU → Linear(64) → LeakyReLU → Linear(14)

Training: Adam (lr=1e‑3, weight decay 1e‑5), CosineAnnealingLR, batch size 32. Default 80 epochs (can be changed by editing the Praat script – epochs = 80 near the top).

Latent space: 16‑dimensional. After training, the encoder maps each grain to a point in this space. The transition score between grains i and j is 1 / (1 + ||z_i – z_j||) – similarity in the learned manifold.

Visualization (Praat picture)

When Draw_visualization = 1, the script draws a multi‑panel plot:

Tip: The scatter plot reveals the structure the autoencoder learned. Grains from the same file often cluster together. The path shows how the navigation mode traverses this space.

FAQ / troubleshooting

“Python not found” or missing packages

Install: pip install torch numpy soundfile. On Windows, ensure Python is in PATH (the script tries python, py, python3).

No grains assembled / output silent

Check the Info window: if “Grains assembled” is 0, the CSV may have contained filenames that don’t match the actual files (case‑sensitive on Linux). Ensure all files are in the selected folder and have supported extensions (.wav, .aif, .aiff, .flac). Also verify that Grain_ms is not too short for your files (minimum 25 ms).

Path length shorter than requested

The engine cannot repeat grains (each grain is used at most once). If the total number of grains is less than Path_length, the path will stop when all grains are exhausted. Increase the corpus size or reduce path length.

Autoencoder training is slow on large folders

For folders with thousands of grains, training may take a minute or two. Reduce epochs (edit the Praat script) or increase grain_ms to reduce the total grain count. The batch‑FFT extraction is already optimised – it’s the PyTorch training that dominates.

Transition scores in CSV

The path CSV includes a transition_score column (0–1) derived from latent similarity. The “next_grain” column gives the index (1‑based) of the following grain – useful for debugging.

Modifying the autoencoder

The architecture is defined in granular_navigation_engine.py. You can change LATENT_DIM (currently 16) or the hidden layer sizes, but note that PCA projection to 2‑D assumes latent dim ≥ 2.

Command‑line usage of granular_navigation_engine.py

The Python engine can be run independently (batch processing):

python granular_navigation_engine.py --folder /path/ --path_out path.csv --stats stats.txt --mode similarity --grain_ms 150 --path_length 60 --epochs 80 --seed 42