Advanced Chaotic Granular Synthesis — User Guide
Chaos-theory-driven granular synthesis: uses mathematical chaotic systems (Logistic, Hénon, Lorenz) to control grain timing and frequency for complex, evolving textures with deterministic yet unpredictable behavior.
What this does
This script implements chaos-based granular synthesis — generating complex sonic textures using mathematical chaotic systems to control grain parameters. Three chaotic systems available: (1) Logistic Map: Simple 1D chaotic recurrence for frequency modulation. (2) Hénon Map: 2D chaotic system for more complex frequency patterns. (3) Lorenz System: 3D continuous-time chaotic attractor for atmospheric textures. Process: (1) Pre-generates grain parameters using chaotic evolution, (2) Splits synthesis into manageable chunks to avoid formula limits, (3) Creates grains with frequencies derived from chaotic state variables, (4) Combines multiple layers with different chaotic trajectories, (5) Applies spatial processing for stereo effects.
Key Features:
- 3 Chaotic Systems — Different mathematical behaviors for different textures
- Chunk-Based Optimization — Splits synthesis into 2-second chunks to avoid formula limits
- Grain Parameter Pre-generation — Computes all grain parameters before synthesis
- Chaotic Frequency Control — Grain frequencies evolve through chaotic trajectories
- Deterministic Randomness — Same parameters = same chaotic sequence (reproducible)
- Ultra-Fast Performance — Optimized chunking and formula generation
- Preset Configurations — Pre-tuned settings for different chaotic behaviors
Technical Implementation: (1) Parameter pre-generation: For each layer, calculate total grains = duration × density. For each grain: generate random time (uniform), evolve chaotic system, derive frequency from chaotic state, store parameters in arrays. (2) Chunking: Split duration into 2-second chunks. For each chunk: build formula string with grains whose times fall in chunk, limit to max_grains_per_chunk (30) to avoid formula limits. (3) Chunk synthesis: Create Sound from formula for each chunk. (4) Concatenation: Concatenate chunk sounds into layer. (5) Layer mixing: Combine all layers into final sound. (6) Spatial processing: Apply stereo effects if requested. Key innovations: Pre-generation avoids recomputing chaos during formula building. Chunking avoids Praat's formula length limits. Deterministic chaos ensures reproducibility.
Quick start
- In Praat, ensure no objects selected (generates from scratch).
- Run script… →
advanced_chaotic_granular.praat. - Choose preset (Logistic Sparse recommended for first try).
- Or select Custom and adjust parameters manually.
- Set Duration (sec) for output length.
- Choose Synthesis_mode for chaotic system type.
- Set Grain_density for texture density.
- Choose Spatial_mode for stereo image.
- Click OK — chaotic synthesis runs with progress updates.
- Output named "chaotic_presetname" appears in Objects window.
- Output automatically played when complete.
Chaos Theory Foundations
What is Chaos?
Mathematical Definition
Key properties of chaotic systems:
🌀 Core Chaotic Properties
1. Deterministic: Follows exact mathematical rules (no randomness)
2. Sensitive to initial conditions: "Butterfly effect" — small changes → large differences
3. Topologically mixing: Evolves to explore entire state space
4. Dense periodic orbits: Contains periodic solutions arbitrarily close to any point
5. Bounded: Stays within finite region of state space
6. Aperiodic: Never exactly repeats (infinite period)
Chaos vs Randomness
Critical distinction:
- Truly unpredictable
- No underlying pattern
- Independent events
- Example: White noise
- Audio: static, hiss
CHAOTIC PROCESS:
- Appears random but deterministic
- Complex underlying patterns
- Dependent evolution
- Example: Weather system
- Audio: evolving, structured textures
FOR SYNTHESIS:
Chaos offers:
- Reproducibility (same seed = same output)
- Rich structure (mathematical patterns)
- Control parameters (tweak chaos behavior)
- Evolution (time-dependent changes)
Chaotic Systems in Synthesis
Why Chaos for Sound?
Musical advantages of chaotic systems:
🎵 Chaotic Sound Characteristics
Natural evolution: Sounds "alive", not static
Complex patterning: Rich internal structure
Controlled unpredictability: Wild but bounded
Parameter sensitivity: Small tweaks → new textures
Reproducibility: Compositional control
Mathematical foundation: Deep structure to explore
Mapping Chaos to Audio Parameters
How chaotic variables become sound:
Mathematical Implementation
Chaotic Evolution Algorithm
Initialize chaotic system with parameters
total_grains = round(duration × density)
For grain = 1 to total_grains:
grain_time[grain] = randomUniform(0, duration-0.2)
grain_duration[grain] = 0.08 + 0.15×random()
# Evolve chaotic system
If Logistic Map:
x = r × x × (1 - x)
freq = base × (0.3 + 1.4×x) × layer_scale
If Hénon Map:
new_x = 1 - a×x² + y
y = b × x
x = new_x
freq = base × (0.5 + x) × layer_scale
If Lorenz System:
dx = σ×(y - x)×dt
dy = (x×(28 - z) - y)×dt
dz = (x×y - 2.667×z)×dt
x = x + dx; y = y + dy; z = z + dz
freq = base × (0.5 + 0.5×(x/20 + 0.5)) × layer_scale
grain_frequency[grain] = freq
grain_amplitude[grain] = base_amp_scale
End For
Key insight: Chaotic evolution independent of grain time
Grains placed at random times, frequencies from chaotic sequence
Deterministic vs Stochastic Elements
What's deterministic vs random in this synthesis:
- Grain frequency sequence
- Chaotic system evolution
- Layer frequency relationships
- Overall texture character
STOCHASTIC (Random):
- Grain timing (uniform random)
- Grain duration (random within range)
- Grain amplitude (fixed per layer)
- Parameter randomization (if enabled)
HYBRID APPROACH:
Chaos provides structured evolution
Randomness provides natural timing
Combination: structured yet organic textures
Chaotic Algorithms
System 1: Logistic Map
📈 Logistic Map (Discrete 1D Chaos)
Equation: xₙ₊₁ = r·xₙ·(1 - xₙ)
Parameters: r ∈ [0,4], x ∈ [0,1]
Chaotic regime: r ≈ 3.57-4.0
Script defaults: r = 3.7, x₀ = 0.5
Frequency mapping: f = base·(0.3 + 1.4·x)·layer_scale
Sonic character: Wild fluctuations, sudden jumps
Best for: Dramatic textures, unpredictable evolution
Logistic Map Behavior
System 2: Hénon Map
🔄 Hénon Map (Discrete 2D Chaos)
Equations: xₙ₊₁ = 1 - a·xₙ² + yₙ, yₙ₊₁ = b·xₙ
Parameters: a = 1.4, b = 0.3 (canonical)
State: (x,y) ∈ ℝ², x ≈ [-1.5,1.5]
Script defaults: a = 1.4, b = 0.3, (x₀,y₀) = (0.1,0.1)
Frequency mapping: f = base·(0.5 + x)·layer_scale
Sonic character: Complex patterns, swirling evolution
Best for: Intricate textures, mathematical beauty
Hénon Map Characteristics
System 3: Lorenz System
🌪️ Lorenz System (Continuous 3D Chaos)
Equations: dx/dt = σ(y-x), dy/dt = x(ρ-z)-y, dz/dt = xy-βz
Parameters: σ=10, ρ=28, β=8/3 (canonical)
State: (x,y,z) ∈ ℝ³, butterfly attractor
Script defaults: σ=10, (x₀,y₀,z₀) = (0.1,0,0), dt=0.01
Frequency mapping: f = base·(0.5 + 0.5·(x/20 + 0.5))·layer_scale
Sonic character: Smooth evolution, atmospheric, flowing
Best for: Ambient textures, evolving drones, atmospheric beds
Lorenz System Details
Algorithm Comparison
| System | Dimensions | Type | Frequency Range | Evolution Character | Sonic Result |
|---|---|---|---|---|---|
| Logistic Map | 1D | Discrete | Base×[0.72,1.56] | Sudden jumps, wild swings | Dramatic, unpredictable |
| Hénon Map | 2D | Discrete | Base×[0,2.0] | Complex patterns, swirling | Intricate, mathematical |
| Lorenz System | 3D | Continuous | Base×[0.25,1.25] | Smooth flows, atmospheric | Evolving, ambient |
Chunking Optimization
The Chunking Problem
Why Chunking is Necessary
⚡ Performance Challenge
Problem: Praat formula strings have length limits
Example: 10 seconds × 20 grains/sec × 3 layers = 600 grains
Per grain: ~300 characters in formula
Total: 600 × 300 = 180,000 characters
Praat limit: Approximately 1,000,000 characters practical
Risk: Formula too long → Praat error or crash
Solution: Split into manageable chunks
Chunking Strategy
chunk_duration = 2.0 seconds
num_chunks = ceil(total_duration / chunk_duration)
max_grains_per_chunk = 30 (safety limit)
For each layer:
For chunk = 1 to num_chunks:
chunk_start = (chunk-1) × chunk_duration
chunk_end = min(chunk × chunk_duration, total_duration)
chunk_formula$ = "0"
grains_added = 0
For each grain in pre-generated list:
If grain_time in [chunk_start, chunk_end):
If grains_added < max_grains_per_chunk:
Add grain term to chunk_formula$
grains_added = grains_added + 1
Else:
Skip remaining grains (safety)
Create Sound from formula: chunk_formula$
Concatenate all chunk sounds → layer sound
Advantage: Each chunk has limited formula length
Trade-off: Some grains may be skipped in dense textures
Chunk Implementation Details
Grain Allocation to Chunks
Max Grains Per Chunk Limit
Limit: max_grains_per_chunk = 30 grains
Reason: Prevent formula length overflow
Calculation: 30 grains × ~300 chars = ~9,000 chars (safe)
Effect: In dense textures, some grains skipped
Which grains: Later grains in chunk skipped (simple sequential)
Audible effect: Slightly less dense than expected
Workaround: Reduce grain_density or increase chunk_duration
Alternative: Manual adjustment for very dense textures
Concatenation Process
Layer Assembly
Step 1: Generate all chunks
Create Sound L1C1, L1C2, ..., L1CN (for layer 1)
Each chunk: 2 seconds (except last)
Formula with ≤30 grains
Step 2: Concatenate chunks
selectObject: "Sound L1C1"
for i=2 to N: plusObject: "Sound L1Ci"
layer_sound = Concatenate
Renamed: "layer_1"
Step 3: Cleanup chunks
for i=1 to N: removeObject: "Sound L1Ci"
Step 4: Repeat for each layer
Creates layer_1, layer_2, ..., layer_N
Step 5: Mix layers
final = Copy of layer_1
for i=2 to N: Formula: "self + object(layer_i, x)"
Cleanup layers
Performance Benefits
| Aspect | Without Chunking | With Chunking | Improvement |
|---|---|---|---|
| Formula Length | Unlimited (risky) | ≤ 9,000 chars | Avoids crashes |
| Memory Usage | Large strings | Smaller strings | More stable |
| Praat Overhead | Single huge formula | Many small formulas | Better error handling |
| Grain Limit | Theoretical only | 30 per chunk | Controlled density |
| Debugging | Difficult | Per chunk possible | Easier troubleshooting |
Parameters & Effects
Core Synthesis Parameters
| Parameter | Type | Default | Range | Description |
|---|---|---|---|---|
| Duration (sec) | positive | 10 | 1-60 | Total output length |
| Base frequency (Hz) | positive | 120 | 20-2000 | Center frequency for chaotic mapping |
| Grain density (grains/sec) | positive | 8 | 1-50 | Average grains per second per layer |
| Number of layers | integer | 3 | 1-8 | Independent chaotic layers to combine |
| Randomize parameters | boolean | 1 (yes) | 0/1 | Add variation to chaotic parameters |
| Fade time (sec) | positive | 2 | 0-10 | Fade in/out duration at boundaries |
Mode Selection Parameters
| Parameter | Type | Options | Description |
|---|---|---|---|
| Synthesis mode | optionmenu | Logistic Map, Hénon Map, Lorenz System | Chaotic system controlling grain frequencies |
| Spatial mode | optionmenu | Mono, Stereo Wide | Stereo processing and spatialization |
| Normalize output | boolean | 0/1 | Scale peak amplitude to 0.9 |
| Play after | boolean | 0/1 | Auto-play result after processing |
Preset Configurations
1 Custom
User-defined parameters
Use: Full manual control
2 Logistic Sparse
Duration: 10s, Density: 8
3 layers, Logistic Map
3 Hénon Texture
Duration: 12s, Density: 6
4 layers, Hénon Map, Stereo
4 Lorenz Atmospheric
Duration: 15s, Density: 5
3 layers, Lorenz System
Chaotic Parameter Ranges
- r: 3.5 to 3.9 (chaotic regime)
- Initial x: Fixed at 0.5
- Layer density multiplier: 0.7 to 1.3× base density
r < 3.57: periodic or fixed point (not chaotic)
r > 3.9: potentially too extreme
- a: 1.2 to 1.6
- b: 0.2 to 0.4
- Initial (x,y): Fixed at (0.1,0.1)
- Layer density multiplier: 0.8 to 1.2× base density
Canonical values: a=1.4, b=0.3
Different parameters create different attractor shapes
- σ (sigma): 8 to 12
- ρ (rho): Fixed at 28 (critical value)
- β (beta): Fixed at 8/3 ≈ 2.667
- Initial (x,y,z): (0.1,0,0)
- Layer density multiplier: 0.75 to 1.25× base density
ρ=28 is classical chaotic value
σ variation changes attractor dynamics
Performance Considerations
Max grains per chunk: 30 grains
Chunk duration: 2.0 seconds
Max density per layer: 30/2 = 15 grains/sec
For multiple layers: Multiply by layer count
Example: 3 layers × 15 = 45 grains/sec total max
If exceeded: Grains skipped (later ones in chunk)
Solution: Reduce grain_density or increase chunk_duration in script
Warning sign: Info window shows "X grains" but texture seems sparse
Applications
Algorithmic Composition
Use case: Generate complex textures for contemporary music
Technique: Use different chaotic systems for different sections
Example: Logistic Map for intense sections, Lorenz for ambient bridges
Sound Design for Media
Use case: Create evolving textures for film, games, installations
Technique: Parameter exploration to match mood/scene
Workflow:
- Logistic Map: tension, chaos, instability
- Hénon Map: complexity, intricacy, patterns
- Lorenz System: atmosphere, flow, environment
Scientific Sonification
Use case: Hear chaotic system behavior
Technique: Map chaotic variables directly to audio
Application: Education, research, data exploration
Generative Art
Use case: Create never-repeating sound installations
Technique: Long durations, parameter automation
Advantage: Deterministic yet always evolving
Psychoacoustic Research
Use case: Study perception of chaotic vs random textures
Technique: Controlled parameter variation
Benefit: Precise mathematical control over stimulus
Practical Workflow Examples
🎬 Film: Tense Undercurrent
Goal: Create unsettling, tense background for thriller scene
Settings:
- Synthesis mode: Logistic Map
- Base frequency: 90 Hz (uneasy low end)
- Grain density: 12 grains/sec
- Layers: 4
- Randomize parameters: Yes (for variation between takes)
- Spatial mode: Stereo Wide
- Duration: Match scene length
Post-processing: Add subtle pitch modulation, light reverb
Result: Unpredictable, tense texture that never settles
🎵 Music: Evolving Ambient Pad
Goal: Create slowly evolving pad for ambient track
Settings:
- Synthesis mode: Lorenz System
- Base frequency: 220 Hz (A3)
- Grain density: 6 grains/sec
- Layers: 3
- Randomize parameters: No (for consistency)
- Spatial mode: Mono (for further processing)
- Duration: 30 seconds
Integration: Process with reverb, delay, gentle filtering
Result: Smooth, evolving pad with mathematical beauty
🎮 Game: Magic Energy Field
Goal: Create complex magical energy texture
Settings:
- Synthesis mode: Hénon Map
- Base frequency: 350 Hz
- Grain density: 8 grains/sec
- Layers: 4
- Randomize parameters: Yes (different for each spell type)
- Spatial mode: Stereo Wide
- Duration: 8 seconds (loop point)
Post-processing: Add spectral effects, volume envelope
Result: Intricate, complex magical energy sound
Advanced Techniques
- Generate multiple sections: Different parameters for intro/body/outro
- Crossfade manually: Blend between different chaotic states
- Chaotic parameter modulation: Change r, a, σ over time via script
- Hybrid systems: Switch between chaotic systems within one piece
Requires modifying script or running multiple times and combining
- MIDI mapping: Map chaotic parameters to MIDI controllers
- Real-time generation: Modify script for real-time parameter changes
- Data-driven chaos: Use external data to seed chaotic parameters
- Interactive installations: User input controls chaotic evolution
Advanced modifications enable interactive chaotic synthesis
- Chaos + samples: Use chaotic frequency control on sampled grains
- Multi-scale chaos: Different chaotic systems for different frequency ranges
- Chaotic modulation: Use chaotic output to modulate other synthesis parameters
- Feedback systems: Audio output feeds back into chaotic parameters
Chaotic synthesis as modulation source for other techniques
Troubleshooting Common Issues
Causes: Grain density too low, grains skipped due to chunk limit
Solutions: Increase grain_density, check chunk limit isn't exceeded
Causes: Chaotic parameters in extreme regime, frequency range too wide
Solutions: Adjust chaotic parameters, reduce base_frequency range
Causes: Chaotic system in periodic window, too few grains
Solutions: Change chaotic parameters, increase grain density
Causes: High grain count, many layers, long duration
Solutions: Reduce parameters, be patient with chunking overhead
Causes: Grains crossing chunk boundaries, phase discontinuities
Solutions: Use shorter grains, ensure grains don't cross boundaries
Creative Parameter Explorations
| Exploration | Parameter Settings | Expected Result | Creative Use |
|---|---|---|---|
| Micro-chaos | Duration: 1s, Density: 30, Layers: 1 | Intense chaotic burst | Percussive chaotic hits |
| Harmonic chaos | Base: 440Hz, Narrow frequency range | Chaotic variations around pitch | Detuned chaotic tones |
| Dense chaotic cloud | Density: 20, Layers: 5, Short grains | Thick chaotic texture | Chaotic noise beds |
| Sparse atmospheric | Density: 2, Layers: 3, Long grains | Occasional chaotic events | Ambient punctuations |
| Parameter sweep | Generate multiple with changing r/a/σ | Evolving chaotic character | Chaotic metamorphosis |
Technical Implementation Details
Grain Formula Construction
Optimized Grain Formula
Chaotic State Management
State Evolution Independent of Time
Chaotic evolution independent of grain timing
Why:
Grains placed at random times (uniform)
Chaotic sequence evolves per grain count
NOT per time elapsed
Result:
Chaotic frequency sequence same regardless of:
- When grains occur in time
- Grain density
- Duration between grains
Alternative approach (not used):
Evolve chaos per time step
Map time to chaotic state
More complex, less flexible
Current approach advantage:
Simple, predictable chaotic sequence
Decouples timing from frequency evolution
Spatial Processing
Stereo Wide Implementation
Performance Optimization Details
Pre-generation vs On-the-fly
- Separation of concerns: Parameter calculation separate from synthesis
- Performance: Compute chaos once, not during formula building
- Flexibility: Can modify parameters before synthesis
- Debugging: Can inspect parameter arrays
- Memory efficiency: Arrays smaller than formula strings
Trade-off: Requires storing all parameters in memory (arrays)