Morphic Form — Grain Placement Engine — User Guide
Spectral-preserving grain placement system inspired by attractor dynamics and gradient descent. Controls ONLY grain placement parameters (size, density, jitter, backtrack, repeat) while leaving spectral content untouched.
What this does
This script implements a Morphic Form grain placement engine — a system that generates new sonic structures by controlling ONLY the placement parameters of grains extracted from a source sound. Unlike granular synthesis that alters spectral content, this engine preserves the original spectral character completely, reshaping only when grains occur, how long they are, how much jitter they have, and whether they repeat or backtrack.
🌀 What is Morphic Form?
Morphic Form is a conceptual model where two behavioral attractors define extremes of grain placement:
- Attractor A (Stable / Sparse / Coherent): larger grains, lower density, low jitter, mostly forward motion, rare repeats, occasional silence gaps
- Attractor B (Turbulent / Dense / Unstable): shorter grains, higher density, high jitter, frequent backtracks and repeats, no silence gaps
A gradient descent state walks smoothly from A toward B over the output duration, modulated frame-by-frame by local acoustic features (intensity, activity, voicing) extracted from the original. The output can be shorter or longer than the source via decoupled time ratios.
Key Features:
- 6 Preset Strategies — Slow Bloom, Tidal Surge, Nervous Scatter, Still Center, Time Stretch, Collapse, plus Custom
- Spectral Preservation — No spectral alteration; only grain placement parameters are modified
- Two-Attractor Model — Behavioral poles define placement extremes
- Gradient Descent State — Smoothly walks from A to B with inertial updates
- Feature Modulation — Local intensity, activity, and voicing affect attractor pull
- Decoupled Duration Control — Output can be shorter or longer than source via time ratio
- Grain Schedule Assembly — Up to 6000 grains with crossfades between grains, hard cuts for silence
- Comprehensive Visualization — 6-panel display showing waveforms, morph curves, features, and grain read map
Technical Implementation: (1) Feature Extraction: Intensity, voicing, and frame-to-frame activity from source (mapped to output timeline). (2) Morphic Curve: Gestural pacing (Linear/Accelerate/Decelerate) scaled by morph_intensity. (3) Attractor Definitions: A and B parameters derived from base values. (4) Gradient Descent: Per-frame state update with local feature push and inertia. (5) Grain Schedule: Generate grains walking output timeline, reading source with time ratio and wrapping. (6) Assembly: Extract grains with 10% fades, concatenate with crossfades between grains. (7) Visualization: 6-panel display with all analysis data.
Quick start
- In Praat, select exactly one Sound object (any duration, any content).
- Run script… → select
Morphic_Form.praat. - Choose Preset (2-7 for specific strategies, 1 for custom).
- Adjust morphic control parameters (morph intensity, base grain, base density, max jitter).
- Set output duration ratio (1.0 = same as input, 2.0 = double, 0.5 = half).
- Select pacing curve (Linear, Accelerate, Decelerate).
- Enable Draw_visualization for analysis display.
- Click OK — engine extracts features, generates grain schedule, assembles output.
Morphic Form Theory
The Two-Attractor Model
🎯 Attractor Definitions
| Parameter | Attractor A (Stable) | Attractor B (Turbulent) |
|---|---|---|
| Grain size | base_grain_ms × 1.35 | base_grain_ms × 0.67 |
| Density (grains/s) | base_density_gps × 0.55 | base_density_gps × 1.90 |
| Jitter (ms) | max_jitter_ms × 0.08 | max_jitter_ms |
| Backtrack probability | 0.02 | 0.22 |
| Repeat probability | 0.04 | 0.28 |
| Silence probability | 0.07 | 0.00 |
| Silence duration (ms) | 40.0 | 0.0 |
Conceptual meaning:
- A: Coherent, predictable, spacious — like a stable texture or sustained tone
- B: Chaotic, dense, unstable — like turbulent noise or rapid-fire gestures
Gradient Descent State
📉 State Update Equation
For each analysis frame i:
Parameters:
- gd_lr = 0.22 — learning rate (inertia) — higher = faster response
- local_weight = 0.30 — how much local features affect target
- activity = normalized frame-to-frame intensity change
- voicing = 1 if pitch detected, 0 otherwise
Effect: The state smoothly tracks the target while being pulled toward regions of high activity or unvoiced sound, creating a responsive, living texture.
Pacing Curves (Gestural Accumulator)
Output Duration Control
Grain Schedule Generation
Preset Strategies
Preset 2: Slow Bloom (gentle A→B, large grains)
🌸 Gradual Unfolding
Morph: 0.60 | Base grain: 52 ms | Density: 17 g/s
Jitter: 7 ms | Pacing: Linear | Ratio: 1.0×
Character: Gentle transition from stable, spacious texture to moderately denser placement
Use on: Pads, drones, ambient material
Preset 3: Tidal Surge (aggressive A→B, accelerating)
🌊 Building Momentum
Morph: 0.90 | Base grain: 30 ms | Density: 38 g/s
Jitter: 28 ms | Pacing: Accelerate | Ratio: 1.2×
Character: Slow start, then rapid acceleration to turbulent, dense placement with high jitter
Use on: Buildups, crescendos, dramatic gestures
Preset 4: Nervous Scatter (B-dominant, dense + jittery)
⚡ Chaotic Dispersion
Morph: 0.95 | Base grain: 22 ms | Density: 52 g/s
Jitter: 40 ms | Pacing: Linear | Ratio: 0.85×
Character: Immediately turbulent — high density, extreme jitter, compressed duration
Use on: Glitch, percussion, chaotic textures
Preset 5: Still Center (A-dominant, minimal morphing)
🧘 Stable Core
Morph: 0.15 | Base grain: 68 ms | Density: 11 g/s
Jitter: 4 ms | Pacing: Decelerate | Ratio: 1.0×
Character: Mostly stable throughout — large grains, low density, minimal jitter
Use on: Sustained tones, meditation, background textures
Preset 6: Time Stretch (2× duration, slow drift)
⏱️ Temporal Expansion
Morph: 0.45 | Base grain: 60 ms | Density: 20 g/s
Jitter: 12 ms | Pacing: Decelerate | Ratio: 2.0×
Character: Double duration with slow morph — source material wraps, creating repetitions
Use on: Ambient expansion, time dilation effects
Preset 7: Collapse (half duration, rapid compression)
📉 Temporal Compression
Morph: 0.80 | Base grain: 25 ms | Density: 45 g/s
Jitter: 20 ms | Pacing: Accelerate | Ratio: 0.5×
Character: Half duration, rapid morph — source material compressed, creating density
Use on: Transitions, quick gestures, compression effects
Parameters & Controls
Morphic Control
| Parameter | Default | Description |
|---|---|---|
| Morph_intensity | 0.75 | 0.0 = stay at A entirely | 1.0 = fully reach B |
| Base_grain_ms | 40.0 | Reference grain duration (ms) — scaled for A/B |
| Base_density_gps | 25.0 | Reference density (grains/second) — scaled for A/B |
| Max_jitter_ms | 15.0 | Maximum jitter at attractor B (ms) |
Duration
| Parameter | Default | Description |
|---|---|---|
| Output_duration_ratio | 1.0 | 1.0 = same as input, 2.0 = double, 0.5 = half |
Pacing Curve
| Parameter | Default | Description |
|---|---|---|
| Pacing_curve | Linear | Linear, Accelerate (slow start), Decelerate (fast start) |
Fixed Parameters (internal)
| Parameter | Value | Description |
|---|---|---|
| gd_lr | 0.22 | Gradient descent learning rate (inertia) |
| local_weight | 0.30 | Weight of local feature modulation |
| af_hop_s | 0.050 | Analysis frame hop (seconds) |
| max_grains | min(6000, out_dur×80) | Maximum grains to generate |
| fade_percent | 10% | Grain fade in/out length |
| xfade_max | 20 ms | Maximum crossfade between grains |
Output
| Parameter | Default | Description |
|---|---|---|
| Draw_visualization | 1 | Generate 6-panel analysis display |
| Play_result | 1 | Audition after processing |
Visualization & Analysis
6-Panel Display
Reading the Grain Read Map
- Each dot: A single grain, plotted at its output time (x) and source read position (y)
- Color gradient: Early grains (blue) to late grains (orange) — shows temporal evolution
- Gray reference line: Proportional read (diagonal with wraps) — where grains would be if reading source linearly
- Vertical scatter: Jitter — grains reading from different source positions at same output time
- Backtracking: Dots appearing earlier in source than previous grains at same output time
- Wraps: For ratio > 1.0, dots wrap from bottom to top when source repeats
Reading the Morph Curve Panel
- Light blue fill: Target morph curve (from pacing curve × morph_intensity)
- Red line: Actual morph curve (may differ due to feature modulation)
- Green line: Grain size normalized (1 = attractor A, 0 = attractor B) — should roughly follow inverse of morph
- Divergence: Where red and blue differ, local features are modulating the target
Applications
Electroacoustic Composition
Use case: Generating evolving textures from static source material
Technique: Slow Bloom or Tidal Surge presets on sustained sounds
Workflow:
- Record or select a 10-30 second source with interesting timbre (instrumental note, field recording, vocal phrase)
- Apply Slow Bloom preset for gentle evolution
- Layer multiple outputs with different morph intensities
- Use as background texture or structural element
Rhythmic Variation
Use case: Creating rhythmic variations from percussive loops
Technique: Nervous Scatter or Collapse presets on drum loops
Settings:
- Source: 4-8 bar drum loop
- Preset: Nervous Scatter (high density, high jitter)
- Adjust base_grain_ms to match rhythmic feel (30-50 ms for detail, 80-120 ms for longer gestures)
- Output duration ratio: 1.0 for same length, or 0.5 for compressed variation
Result: Percussive material rearranged into new rhythmic patterns while preserving timbre
Time Dilation/Compression
Use case: Creating extended or condensed versions of material
Technique: Time Stretch or Collapse presets
Applications:
- Ambient expansion: Time Stretch (2.0×) on environmental recordings
- Quick gestures: Collapse (0.5×) on spoken phrases for rhythmic effects
- Source material for further processing: Generate multiple time-scaled versions
Research & Education
Use case: Demonstrating attractor dynamics and gradient descent in audio
Technique: Enable visualization, compare presets on simple test signals
Learning outcomes:
- See how attractor parameters affect grain placement
- Observe gradient descent state tracking target with inertia
- Understand relationship between features (intensity, activity) and local modulation
- Explore time ratio effects on source reading
Practical Workflow Examples
🎬 Film Score: Tension Buildup
Goal: Create 30-second tension cue from 10-second drone
Settings:
- Source: 10-second low drone
- Preset: Tidal Surge
- Custom: ratio = 3.0× (30s output), morph_intensity = 0.95
- Pacing: Accelerate
Result: Drone gradually transforms from stable to turbulent over 30 seconds, with source material wrapping and repeating
🎚️ Electronic Music: Glitch Break
Goal: Create glitchy break from 4-bar drum loop
Settings:
- Source: 8-second drum loop
- Preset: Nervous Scatter
- Base_grain_ms: 25 (short for detail)
- Ratio: 1.0
Result: Drum hits scattered into dense, jittery texture — perfect for glitch transitions
🎙️ Voice Processing: Textural Voice
Goal: Transform spoken phrase into abstract texture
Settings:
- Source: 5-second spoken phrase
- Preset: Slow Bloom
- Base_grain_ms: 60 (preserves phoneme length)
- Ratio: 2.0× (10-second output)
Result: Voice becomes abstract texture — words dissolve into grain clouds while preserving spectral character
Troubleshooting Common Issues
Cause: density too low or grain size too large for source duration
Solution: Increase base_density_gps, reduce base_grain_ms, or use shorter source
Cause: Grain count insufficient to fill duration, or pad/trim not applied
Solution: Check max_grains scaling, increase density, or manually adjust ratio
Cause: Fades too short or crossfades not applied correctly
Solution: Increase fade percentage in script (currently 10%), ensure crossfade applied for grain+grain transitions
Cause: Morph intensity too low, or attractor B parameters not reached
Solution: Increase morph_intensity, check that max_jitter_ms is >0, increase base_density_gps
Cause: Many grains (>2000) and high-resolution plotting
Solution: Reduce grain count (lower density), or disable visualization for final render
Advanced Techniques
- Extreme A: Increase att_a_grain_ms (×2.0), decrease att_a_density (×0.3), set att_a_sil_prob = 0.2
- Extreme B: Decrease att_b_grain_ms (×0.4), increase att_b_density (×3.0), set att_b_bt_prob = 0.5, att_b_rep_prob = 0.5
- No silences: Set att_a_sil_prob = 0.0
- No backtracking: Set att_b_bt_prob = 0.0
Modify local_push calculation to emphasize different features. For example, increase activity weight for more responsiveness to transients, or decrease voicing weight for less pitch influence.
- gd_lr: Higher (0.3-0.5) = faster response but more oscillation
- local_weight: Higher (0.5-0.7) = more feature influence, less smoothness
Ratios > 5.0 or < 0.2 may produce extreme results (many wraps or severe skipping). Useful for experimental textures.