Polyphonic Improviser — Chunk Shuffle Canon — User Guide
All material derived from the input. Each voice gets an independently shuffled ordering of source chunks, applies speed/pitch transformation, and enters at staggered times — a canon by delay plus shuffle.
What this does
This script implements a Polyphonic Improviser — a chunk-shuffle canon engine that generates multi-voice polyphonic textures entirely from a single source sound. No synthesis or PSOLA is used; all material is derived by dividing the source into chunks, shuffling them independently per voice, applying speed/pitch transformations, and staggering entries in canon style.
🎼 What is a Chunk Shuffle Canon?
A traditional canon imitates a melody at a time delay. This engine extends the concept:
- Source divided into N equal audible chunks
- Each voice gets an independently shuffled ordering of those chunks
- Speed/pitch transformation via tape speed (pitch+time) or lengthen (time only)
- Staggered entries — voices enter at regular delays (quantized to beats or manual)
- Voices panned across stereo field and mixed additively
The result: a complex polyphonic texture where every sound is derived from the original, yet the shuffled order and transformations create entirely new relationships.
Key Features:
- 6 Preset Strategies — Slow Canon, Dense Cluster, Spectral Drift, Rhythmic Echo, Mirror Scatter, Microtonal Haze, plus Custom
- Variable Chunk Count — 2-200 chunks from source
- 2 Transformation Modes — Tape speed (pitch+time) or Lengthen (time only via overlap-add)
- Up to 4 Voices — Each with independent speed ratio, amplitude, pan, and shuffled order
- Entry Timing — Quantized to beats (BPM + note value) or manual delay
- Crossfaded Chunks — Smooth concatenation with adjustable crossfade
- Voice-Offset Shuffling — Fisher-Yates shuffle seeded per voice for unique orderings
- Comprehensive Visualization — 4-panel display with waveforms, shuffle map, active spans, stats
Technical Implementation: (1) Chunk Extraction: Divide source into N equal chunks. (2) Transformation: Apply tape speed (override SR + resample) or lengthen (overlap-add) per voice per chunk. (3) Shuffling: Fisher-Yates shuffle with voice-offset seeding. (4) Assembly: Prepend entry silence, concatenate shuffled chunks with crossfades, trim/pad to output duration. (5) Panning: Convert pan value to L/R gains, mix voices additively. (6) Visualization: 4-panel display with waveforms, shuffle map, active spans.
Quick start
- In Praat, select exactly one Sound object (minimum 1 second, any content).
- Run script… → select
Polyphonic_Improviser.praat. - Choose Preset (2-7 for specific strategies, 1 for custom).
- Set chunk parameters (number of chunks, crossfade).
- Configure voices (number, transformation mode, V1/V2 speeds).
- Set entry timing (quantize to BPM or manual delay).
- In the advanced dialog, set V3/V4 speeds, amplitudes, and pans.
- Enable Draw_visualization for analysis display.
- Click OK — engine extracts chunks, transforms, shuffles, assembles, creates "source_poly_improv_v2".
Canon & Shuffle Theory
The Canon Structure
Shuffle Algorithm
🔄 Fisher-Yates with Voice Offset
Each voice gets a different shuffle of the N chunks, determined by:
- Start with array [1, 2, 3, ..., N]
- Advance random state by (v-1) × N draws (ensures voice offset)
- For i from N down to 2:
- j = random integer from 1 to i
- swap elements at positions i and j
This creates a unique permutation for each voice while keeping the algorithm deterministic (same parameters always produce same shuffles).
Visualization: The shuffle map panel shows each voice's output slots (columns) with the source chunk index displayed, color-coded by source position (darker = earlier, brighter = later).
Transformation Modes
🎚️ Tape Speed vs. Lengthen
| Mode | Implementation | Effect | Use Case |
|---|---|---|---|
| Tape speed | Override sampling frequency by ratio, then resample back | Pitch changes with duration (like varispeed) | Traditional canon transpositions, organ stops |
| Lengthen | Overlap-add time-stretch by factor = 1/ratio | Duration changes, pitch preserved | Rhythmic variations, tempo changes without pitch shift |
Example: ratio = 2.0
- Tape speed: pitch up one octave, duration halved
- Lengthen: duration halved (faster), pitch unchanged
Entry Timing & Quantization
Voice Defaults
| Voice | Role | Default Ratio | Default Pan | Entry |
|---|---|---|---|---|
| V1 | Leader | 1.00 | -0.35 (left-center) | 0 |
| V2 | Comes | 1.059 (+1 semitone) | +0.40 (right-center) | Δ |
| V3 | Third | 0.50 (-8vb) | -0.75 (left) | 2Δ |
| V4 | Fourth | 1.50 | +0.75 (right) | 3Δ |
Preset Strategies
Preset 2: Slow Canon
🎵 Gradual, Spacious Canon
Chunks: 8 | Crossfade: 80 ms
Voices: 3 | Mode: Tape speed
Ratios: V1=1.00, V2=1.059, V3=0.50
Entry: 4 bars @ 72 BPM (8.0 s)
Character: Spacious, cathedral-like canon with octave drop in V3, long entries
Use on: Sustained tones, ambient material, slow melodies
Preset 3: Dense Cluster
🌫️ Dense, Cloud-like
Chunks: 24 | Crossfade: 15 ms
Voices: 4 | Mode: Tape speed
Ratios: V1=1.00, V2=1.059, V3=1.122, V4=0.944
Entry: Quarter note @ 120 BPM (0.5 s)
Character: Dense, clustered texture with semitone cloud — voices pile up quickly
Use on: Textural material, granular effects, dense passages
Preset 4: Spectral Drift
🌊 Time-Stretched Evolution
Chunks: 6 | Crossfade: 120 ms
Voices: 3 | Mode: Lengthen
Ratios: V1=1.00, V2=0.85, V3=1.20
Entry: 6.0 s (manual)
Character: Subtle time-stretching, long crossfades, gradual spectral evolution
Use on: Drone music, ambient, slow transformations
Preset 5: Rhythmic Echo
🥁 Percussive Canon
Chunks: 16 | Crossfade: 25 ms
Voices: 4 | Mode: Tape speed
Ratios: V1=1.00, V2=1.498 (fifth), V3=0.50, V4=0.749
Entry: Half note @ 100 BPM (1.2 s)
Character: Rhythmic, echo-like with fifth and octave relationships
Use on: Percussion, rhythmic loops, dance music
Preset 6: Mirror Scatter
🪞 Inverse Ratio Pairs
Chunks: 20 | Crossfade: 10 ms
Voices: 4 | Mode: Tape speed
Ratios: V1=1.00, V2=1.00, V3=1.33, V4=0.75
Entry: Quarter note @ 90 BPM (0.67 s)
Character: V3/V4 form inverse pair, creating mirrored pitch relationships
Use on: Experimental, mirror structures, canonic inversions
Preset 7: Microtonal Haze
🌀 Subtle Detuning
Chunks: 10 | Crossfade: 60 ms
Voices: 4 | Mode: Lengthen
Ratios: V1=1.00, V2=1.025, V3=0.975, V4=1.05
Entry: 1.5 s (manual)
Character: Tiny microtonal shifts create beating and phasing effects
Use on: Drone, sustained tones, ethereal textures
Parameters & Controls
Main Form Parameters
| Parameter | Default | Description |
|---|---|---|
| Number_of_chunks | 12 | How many pieces to divide source into (2-200) |
| Crossfade_ms | 30.0 | Smoothing between chunks (milliseconds) |
| Number_of_voices | 3 | 2-4 voices in the canon |
| Transform_mode | Tape speed | Tape speed (pitch+time) or Lengthen (time only) |
| V1_speed_ratio | 1.00 | Speed ratio for voice 1 |
| V2_speed_ratio | 1.059 | Speed ratio for voice 2 (+1 semitone) |
| Quantize_entries | 0 | Use BPM/note values for entry timing |
| Tempo_bpm | 120.0 | Tempo for quantized entries (BPM) |
| Note_value | Quarter | Note duration for entry spacing |
| Entry_delay_s | 3.0 | Manual entry delay (seconds) |
Advanced Dialog Parameters
| Parameter | Default | Description |
|---|---|---|
| V3_speed_ratio | 0.50 | Speed ratio for voice 3 (octave down) |
| V4_speed_ratio | 1.50 | Speed ratio for voice 4 |
| V1_amplitude | 1.0 | Amplitude multiplier for voice 1 |
| V2_amplitude | 0.85 | Amplitude multiplier for voice 2 |
| V3_amplitude | 0.75 | Amplitude multiplier for voice 3 |
| V4_amplitude | 0.65 | Amplitude multiplier for voice 4 |
| V1_pan | -0.35 | Pan position (-1=left, 0=center, +1=right) |
| V2_pan | 0.40 | Pan position for voice 2 |
| V3_pan | -0.75 | Pan position for voice 3 |
| V4_pan | 0.75 | Pan position for voice 4 |
Output Parameters
| Parameter | Default | Description |
|---|---|---|
| Draw_visualization | 1 | Generate 4-panel analysis display |
| Play_output | 1 | Audition after processing |
Visualization & Analysis
4-Panel Display
Reading the Shuffle Map
- Numbers: The source chunk index (1 to N) placed in each output slot
- Color intensity: Darker = earlier source position, lighter = later source position
- Top row (src): Shows original order — numbers 1..N with gradient from dark to light
- Voice rows: Each voice's unique permutation — look for patterns (e.g., all chunks scattered, or some clustering)
- Vertical alignment: Which chunks appear at the same output slot across voices — creates vertical harmonies
Reading the Active Span Plot
- Bar start: Voice entry time (colored dotted lines in waveform panels)
- Bar end: When voice finishes its shuffled chunks (varies by speed ratio)
- Overlap regions: Where multiple voices are active simultaneously — creates polyphonic texture
- Beat grid: Light dotted lines help see rhythmic relationships between entries
Applications
Electroacoustic Composition
Use case: Generating complex polyphonic textures from simple source material
Technique: Slow Canon or Spectral Drift presets on sustained instrumental phrases
Workflow:
- Record a 5-10 second phrase (instrumental, vocal, found sound)
- Apply Slow Canon preset for spacious, cathedral-like texture
- Listen to how voices interweave at different speeds and pans
- Export and use as a section in a larger composition
- Layer multiple outputs with different chunk counts for complexity
Rhythmic Variation
Use case: Creating rhythmic variations from drum loops
Technique: Rhythmic Echo preset with quantized entries
Settings:
- Source: 4-bar drum loop at 120 BPM
- Preset: Rhythmic Echo
- Adjust chunk count: 16-32 for granular feel, 8 for longer gestures
- Experiment with different note values for entry spacing
Result: Rhythmic canon where each voice reinterprets the loop at different speeds and pan positions
Drone & Ambient Generation
Use case: Creating evolving drone textures
Technique: Microtonal Haze or Spectral Drift presets on sustained tones
Applications:
- Long drones: Use few chunks (4-6) with long crossfades (100-200 ms)
- Beating textures: Microtonal ratios (1.01, 0.99) create phase beating
- Layered evolution: Multiple outputs with different ratios create complex beating patterns
Research & Education
Use case: Teaching canon, shuffle algorithms, and polyphony
Technique: Enable visualization, compare presets on simple test signals
Learning outcomes:
- Understand canon structure through visual active spans
- See how shuffling creates new relationships between chunks
- Hear how speed ratios affect pitch and duration
- Explore relationship between entry delay and polyphonic density
Practical Workflow Examples
🎬 Film Score: Tension Buildup
Goal: Create 60-second tension cue from 8-second drone
Settings:
- Source: 8-second low drone
- Preset: Slow Canon (modified)
- Chunks: 6 (longer gestures)
- V1=1.0, V2=1.059, V3=0.5, V4=0.75
- Entry: 8.0 s (manual) — creates long, overlapping entries
Result: 64-second texture with voices gradually entering, each at different pitches and pans
🎚️ Electronic Music: Buildup Riser
Goal: Create 30-second riser from 2-second synth stab
Settings:
- Source: 2-second synth chord
- Preset: Dense Cluster
- Chunks: 24 (granular)
- Entry: Eighth note @ 140 BPM (0.21 s) — very fast entries
Result: 28-second dense, granular buildup with rapid voice entries
🎙️ Voice Processing
Goal: Transform spoken phrase into choral texture
Settings:
- Source: 5-second spoken phrase
- Preset: Mirror Scatter
- Chunks: 10
- Mode: Tape speed
- V1=1.0, V2=1.0, V3=1.33, V4=0.75
- Entry: Quarter note @ 90 BPM (0.67 s)
Result: 35-second choral texture with voices at different pitches, creating a "round" effect
Troubleshooting Common Issues
Cause: Crossfade too short or missing, or chunk boundaries not faded
Solution: Increase crossfade_ms, ensure 10ms fades are applied (script does this automatically)
Cause: Entry delay too large, or speed ratios causing shortened chunks
Solution: Reduce entry_delay_s, or adjust speeds (tape speed ratio >1 shortens duration)
Cause: Resampling quality (50-point) may cause artifacts at extreme ratios
Solution: Increase resampling quality in script (change 50 to 100), or use Lengthen mode
Cause: Misestimation of output duration (script uses V1 pass × speeds)
Solution: Adjust entry delays or speed ratios; script automatically pads/trims to calculated duration
Cause: Pan values too extreme or voice amplitudes mismatched
Solution: Adjust pans in advanced dialog, balance amplitudes
Advanced Techniques
The voice offset seeding ensures different shuffles per voice. For reproducible results, keep same parameters. To explore new permutations, change chunk count or voice count.
Modify script to use different transform modes per voice — e.g., V1 tape speed, V2 lengthen. Edit the transformation loop to check voice index.
The script uses equal-sized chunks. For variable sizes, pre-segment the source using TextGrid and modify extraction accordingly.
The output is stereo. For multi-channel (5.1, 8-channel), modify panning to use multiple channel gains.