Stochastic Time Folding — User Guide

Probabilistic temporal mangling: iteratively averages samples with randomly-offset neighbors based on adaptive probability thresholds, creating glitchy, stuttering, time-smeared textures through stochastic sample-level processing.

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

What this does

This script implements stochastic time folding — a destructive audio mangling technique that "folds" time by averaging each sample with temporally distant samples selected at random offsets. Process operates iteratively (default 6 passes): for each iteration, (1) Generate probability mask (random 0-1 per sample), (2) If mask < threshold: fold sample = average with forward-offset sample + backward-offset sample (temporal averaging), (3) Else: apply random amplitude variation (0.7-1.2×), (4) Adapt threshold (drifts each iteration). Result: glitchy stutters, temporal smearing, buffer-like artifacts, rhythmic disruption, sample-level chaos. "Folding" = bringing distant time points together (like folding paper). Stochastic = probabilistic, not deterministic. Each run creates different result due to randomness.

Key Features:

What is time folding? Concept from granular/microsound techniques and glitch aesthetics. Traditional delay: fixed temporal offset, predictable echoes. Time folding: variable temporal mixing, creates unpredictable temporal structures. Similar to: (1) Buffer shuffling: Reordering audio chunks (but this operates at sample level). (2) Time stretching artifacts: Pitch shifting creates temporal discontinuities. (3) Granular synthesis: Micro-time manipulations. (4) Digital glitching: Data corruption aesthetics (Oval, Alva Noto). This script: algorithmic approach to temporal chaos. Each iteration increasingly destroys temporal coherence. Creates: stutters (repeated samples), smearing (averaged neighbors), discontinuities (random amplitude jumps), buffer-like artifacts (read from wrong positions). Musical applications: glitch music, IDM, experimental electronica, sound design.

Technical Implementation: (1) Copy input sound (non-destructive), (2) Iteration loop (fold_iterations times, default 6): Update adaptive threshold: threshold += random(variation_min, variation_max), constrain to limits (0.1-0.9), Calculate fold distance: samples / random(distance_min, distance_max), Generate probability mask: random(0,1) per sample, Apply conditional formula: IF mask < threshold: output = (current + forward_offset + backward_offset) / divisor, ELSE: output = current × random_amplitude(0.7-1.2). (3) Normalize to scale_peak 0.96. Key insight: Stochastic gating means some samples folded, others not → creates irregular, glitchy texture. Adaptive threshold means folding probability changes over iterations → evolving character. Random distances means temporal offsets unpredictable → chaotic rather than rhythmic. Averaging three samples (current + future + past) → smooths some samples while leaving others intact → mix of coherence and chaos.

Quick start

  1. In Praat, select exactly one Sound object.
  2. Run script…Stochastic_Time_Folding.praat.
  3. Choose Preset: Default (balanced), Gentle Folds, Aggressive Folds, Micro Glitch, or Custom.
  4. If Custom: adjust fold_iterations (6), initial_adaptive_threshold (0.5), threshold variations, fold distances, amplitude ranges, divisors.
  5. Click OK — processing applies iterative stochastic folding, auto-plays mangled result.
Quick tip: Start with Default for balanced glitchy texture. Try Gentle Folds for subtle temporal artifacts without heavy destruction. Use Aggressive Folds for extreme mangling, heavy stutters. Micro Glitch creates dense, rapid glitches (12 iterations, short distances). Processing instant (<1 second). Each run produces different result (stochastic = random). Run multiple times to explore variations. Works on any audio — speech, music, noise, percussion. More effective on complex material (drums, full mixes) than simple tones. Output replaces original sound object. Increase iterations (6 → 10+) for more destruction. Decrease for subtlety.
Important: HIGHLY DESTRUCTIVE — irreversibly mangles audio. Not subtle effect. Always work on copies. STOCHASTIC = UNPREDICTABLE — each run different, not reproducible. No undo. Very high iterations (>15) create near-total destruction, possibly white noise. Very low threshold (<0.2) folds most samples (heavy effect). Very high (>0.8) folds few samples (subtle). Very short fold distances (<3) create high-frequency artifacts, aliasing-like sounds. Very long (>20) create obvious delays/echoes rather than glitches. Extreme amplitude ranges (e.g., 0.3-2.0) create volume fluctuations, potentially harsh. Processing operates on sample indices — behavior depends on sample rate (44.1kHz typical). Material-dependent: percussive sounds show obvious stutters, sustained tones create texture changes.

Time Folding Theory

Temporal Averaging Concept

What is Time Folding?

Metaphor: Folding paper brings distant points into contact

Linear time (normal audio): Sample: 1 2 3 4 5 6 7 8 9 10 11 12 | | | | | | | | | | | | → → → → → → → → → → → → Each sample independent, temporal sequence preserved Time-folded (example fold): Sample 5 folded with samples 10 and 3: new_sample[5] = (sample[5] + sample[10] + sample[3]) / 3 Distant time points "folded" together Temporal structure disrupted Creates artifacts, glitches, stutters

Why Averaging (Not Replacement)?

Averaging = smoothing:

Formula (per folded sample): output = (sample[n] + sample[n+forward] + sample[n-backward]) / divisor Where: sample[n] = current sample forward = random offset ahead (e.g., +8 samples) backward = random offset behind (e.g., -4 samples) divisor = 3 (typical, creates average of 3 points) Effect: "Time echo" or "temporal blur" Current mixed with past and future

Stochastic Gating

Probability-Based Processing

Concept: Each sample randomly folded or varied based on threshold

Per-sample decision (each iteration): 1. Generate random probability: p = random(0, 1) 2. Compare to threshold: IF p < threshold: FOLD: output = (current + forward + backward) / divisor ELSE: VARY: output = current × random_amplitude(0.7, 1.2) 3. Result: Some samples folded, others varied Creates irregular, glitchy texture Not uniform processing Example: threshold = 0.5 50% of samples (average) folded 50% of samples amplitude-varied Distribution random, not regular

Adaptive Threshold Evolution

Concept: Threshold changes between iterations

Threshold drift over iterations: Iteration 1: threshold = 0.5 (50% folded) ↓ + random(0.2, 0.2) Iteration 2: threshold = 0.63 (63% folded) ↓ + random(0.2, 0.2) Iteration 3: threshold = 0.71 (71% folded) ↓ + random(0.2, 0.2) Iteration 4: threshold = 0.82 (82% folded) ↓ constrained to max 0.9 Iteration 5: threshold = 0.90 (90% folded) Iteration 6: threshold = 0.90 (capped) Early iterations: less folding (subtle) Later iterations: more folding (aggressive) Creates evolving character

Why adaptive?

Random Fold Distances

Variable Temporal Offsets

Formula: distance = total_samples / random(min, max)

Example: 44100 samples (1 second @ 44.1kHz) fold_distance_min = 3 fold_distance_max = 12 Iteration 1: random(3,12) = 7.2 distance = 44100 / 7.2 = 6125 samples = 0.139 seconds offset Iteration 2: random(3,12) = 4.1 distance = 44100 / 4.1 = 10756 samples = 0.244 seconds offset Iteration 3: random(3,12) = 10.8 distance = 44100 / 10.8 = 4083 samples = 0.093 seconds offset Each iteration uses different offset Creates varied temporal mixing Unpredictable glitch patterns

Forward vs Backward Distances

Asymmetric averaging:

Forward offset: fold_distance (full) Backward offset: fold_distance / fold_backward_divisor Example: distance = 1000, divisor = 2 Forward: +1000 samples Backward: -500 samples (half) Why asymmetric? - Creates directionality (not symmetric around current) - Backward typically shorter (prevents reading before start) - Different forward/backward creates asymmetric temporal blur - More "echo from future" than "echo from past" Adjustable via fold_backward_divisor parameter

Iterative Compounding

Multi-Pass Processing

Each iteration processes already-folded audio

Processing cascade: INPUT (original audio) ↓ [Iteration 1: 50% folded] Partially glitched ↓ [Iteration 2: 60% folded] More glitched (folding folded samples) ↓ [Iteration 3: 70% folded] Heavily glitched ↓ [Iteration 4: 80% folded] Very glitched ↓ [Iteration 5: 90% folded] Extremely glitched ↓ [Iteration 6: 90% folded] OUTPUT (nearly unrecognizable) Each pass amplifies artifacts Temporal structure increasingly destroyed Original material progressively obscured

Why Multiple Iterations?

Single iteration:

Multiple iterations:

Amplitude Variation (Non-Folded Samples)

Purpose

When sample not folded, apply random amplitude scaling

output = input × random(amplitude_min, amplitude_max) Default: random(0.7, 1.2) Effect: - Prevents complete temporal destruction - Retains some original samples (varied, not folded) - Creates volume fluctuations - Adds additional randomness layer Example: sample = 0.5 random amplitude = 1.1 output = 0.5 × 1.1 = 0.55 Sample preserved but slightly louder Contributes to glitchy, irregular character

Complete Processing Algorithm

INITIALIZE: adaptive_threshold = initial_threshold (0.5) FOR iteration = 1 to fold_iterations (6): STEP 1: Adapt threshold (after first iteration) IF iteration > 1: adaptive_threshold += random(var_min, var_max) adaptive_threshold = constrain(min_limit, max_limit) STEP 2: Calculate fold distance fold_distance = total_samples / random(dist_min, dist_max) STEP 3: Process each sample FOR each sample n: probability = random(0, 1) IF probability < adaptive_threshold: # FOLD forward = sample[n + fold_distance] backward = sample[n - fold_distance/backward_divisor] output[n] = (sample[n] + forward + backward) / average_divisor ELSE: # VARY output[n] = sample[n] × random(amp_min, amp_max) END FOR STEP 4: Normalize to scale_peak (0.96) RESULT: Stochastically time-folded audio

Comparison to Other Temporal Effects

EffectTemporal LogicPredictabilityCharacter
Delay/EchoFixed offset, mixHighRhythmic repeats
ReverbMultiple delays + filteringHighSpace simulation
Time StretchPlayback rate changeHighPitch/speed change
GranularWindowed chunksMediumTextures, clouds
Buffer ShuffleChunk reorderingMediumStutters, jumps
Stochastic FoldingRandom sample mixingLowGlitches, chaos

Parameters & Presets

Preset Options

🎵 Default (balanced)

Parameters: 6 iterations, threshold 0.5→0.9, distances 3-12, amps 0.7-1.2

Character: Moderate glitching, balanced destruction

Best for: General glitch effects, experimental processing

💫 Gentle Folds

Parameters: 4 iterations, threshold 0.4→0.85, distances 5-15, amps 0.9-1.1

Character: Subtle artifacts, minimal destruction

Best for: Adding texture without heavy mangling, mixing applications

🔥 Aggressive Folds

Parameters: 9 iterations, threshold 0.6→0.95, distances 2-10, amps 0.5-1.5

Character: Heavy destruction, extreme stuttering

Best for: Harsh glitch, sound design, experimental music

⚡ Micro Glitch

Parameters: 12 iterations, threshold 0.55→0.90, distances 2-6, amps 0.6-1.4

Character: Dense, rapid micro-glitches, digital artifacts

Best for: IDM, glitch electronica, extreme sound design

Custom Parameters

ParameterTypeDefaultDescription
PresetoptionDefaultChoose preset configuration
fold_iterationsnatural6Number of processing passes
initial_adaptive_thresholdpositive0.5Starting probability (0-1)
threshold_variation_minpositive0.2Minimum threshold increase
threshold_variation_maxpositive0.2Maximum threshold increase
threshold_min_limitpositive0.1Threshold floor
threshold_max_limitpositive0.9Threshold ceiling
fold_distance_minpositive3Minimum divisor for fold offset
fold_distance_maxpositive12Maximum divisor for fold offset
amplitude_minpositive0.7Minimum amplitude variation
amplitude_maxpositive1.2Maximum amplitude variation
fold_average_divisorpositive3Divisor for 3-sample average
fold_backward_divisorpositive2Backward offset scaling
scale_peakpositive0.96Output normalization level
play_after_processingbooleanyesAuto-play result

Parameter Details

fold_iterations

Range: 1-20 (practical 3-12)

Default: 6

Effect:

initial_adaptive_threshold

Range: 0.1-0.9

Default: 0.5 (50% folding probability)

Effect: Starting point for probability. Lower = less folding initially. Higher = more folding from start. Drifts upward over iterations.

threshold_variation_min & max

Range: 0.0-0.5

Defaults: 0.2 (both)

Effect: Controls how much threshold increases each iteration. Higher values = faster approach to max threshold. Min=Max = consistent increase. Min

fold_distance_min & max

Range: 2-50

Defaults: 3, 12

Effect: Temporal offset range. Lower = shorter distances (tight glitches). Higher = longer distances (obvious delays). Formula: samples / random(min,max)

amplitude_min & max

Range: 0.3-2.0

Defaults: 0.7, 1.2

Effect: Volume variation for non-folded samples. Narrow range (0.9-1.1) = subtle. Wide range (0.5-1.5) = obvious fluctuations.

fold_average_divisor

Range: 2-5

Default: 3 (averaging 3 samples)

Effect: Lower = louder folds (less division). Higher = quieter folds (more division). Typically 3 (current + forward + backward) / 3.

fold_backward_divisor

Range: 1-4

Default: 2 (backward = forward/2)

Effect: Controls backward offset relative to forward. Higher = shorter backward offset. Creates asymmetric temporal blur.

Applications

Glitch Music / IDM