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.

Author: Shai Cohen Version: 2.0 (2025) Technique: Chunk Shuffle Canon Category: Composition Citation: Cohen, S. (2025). Praat AudioTools
Contents:

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:

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

  1. In Praat, select exactly one Sound object (minimum 1 second, any content).
  2. Run script… → select Polyphonic_Improviser.praat.
  3. Choose Preset (2-7 for specific strategies, 1 for custom).
  4. Set chunk parameters (number of chunks, crossfade).
  5. Configure voices (number, transformation mode, V1/V2 speeds).
  6. Set entry timing (quantize to BPM or manual delay).
  7. In the advanced dialog, set V3/V4 speeds, amplitudes, and pans.
  8. Enable Draw_visualization for analysis display.
  9. Click OK — engine extracts chunks, transforms, shuffles, assembles, creates "source_poly_improv_v2".
Quick tip: Start with Slow Canon preset on a 5-10 second melodic phrase. Enable visualization — you'll see the left/right channel waveforms with beat grid (light dotted) and voice entry markers (colored dotted). The shuffle map shows how each voice reorders the source chunks. Listen to how the voices interweave in canon, each with its own speed and pan. The output appears as "source_poly_improv_v2" in the Objects window.
Important: MINIMUM DURATION — Source must be at least 1 second. CHUNK COUNT affects texture: fewer chunks (4-8) preserve longer gestures, more chunks (16-24) create granular textures. TAPE SPEED changes both pitch and duration — ratio >1 = higher pitch, shorter; <1 = lower pitch, longer. LENGTHEN changes only duration (time-stretch via overlap-add) — ratio >1 = shorter (faster), <1 = longer (slower). ENTRY DELAY must be less than source duration × nChunks / speed ratio to avoid gaps at end.

Canon & Shuffle Theory

The Canon Structure

A traditional canon has voices entering at regular intervals, each imitating the leader. In this engine: V1 (Leader) : enters at time 0, speed ratio r₁, pan p₁ V2 (Comes) : enters at time Δ, speed ratio r₂, pan p₂ V3 : enters at time 2Δ, speed ratio r₃, pan p₃ V4 : enters at time 3Δ, speed ratio r₄, pan p₄ where Δ = entry_delay_s Each voice plays through all N chunks in its own shuffled order. Total output duration ≈ Δ × (numV - 1) + (srcDur / r₁)

Shuffle Algorithm

🔄 Fisher-Yates with Voice Offset

Each voice gets a different shuffle of the N chunks, determined by:

  1. Start with array [1, 2, 3, ..., N]
  2. Advance random state by (v-1) × N draws (ensures voice offset)
  3. 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

ModeImplementationEffectUse Case
Tape speedOverride sampling frequency by ratio, then resample backPitch changes with duration (like varispeed)Traditional canon transpositions, organ stops
LengthenOverlap-add time-stretch by factor = 1/ratioDuration changes, pitch preservedRhythmic 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

When quantize_entries = 1: beatDur = 60 / tempo_bpm entry_delay_s = beatDur × noteBeats Note value to beats mapping: Whole note (4 beats) | Dotted whole (6 beats) Half note (2 beats) | Dotted half (3 beats) Quarter note (1 beat) | Dotted quarter (1.5 beats) Eighth note (0.5 beats) | 2 bars (8 beats) | 4 bars (16 beats) The beat grid is drawn on waveform panels as light dotted lines. Voice entry markers appear as colored dotted lines matching voice colors.

Voice Defaults

VoiceRoleDefault RatioDefault PanEntry
V1Leader1.00-0.35 (left-center)0
V2Comes1.059 (+1 semitone)+0.40 (right-center)Δ
V3Third0.50 (-8vb)-0.75 (left)
V4Fourth1.50+0.75 (right)

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

ParameterDefaultDescription
Number_of_chunks12How many pieces to divide source into (2-200)
Crossfade_ms30.0Smoothing between chunks (milliseconds)
Number_of_voices32-4 voices in the canon
Transform_modeTape speedTape speed (pitch+time) or Lengthen (time only)
V1_speed_ratio1.00Speed ratio for voice 1
V2_speed_ratio1.059Speed ratio for voice 2 (+1 semitone)
Quantize_entries0Use BPM/note values for entry timing
Tempo_bpm120.0Tempo for quantized entries (BPM)
Note_valueQuarterNote duration for entry spacing
Entry_delay_s3.0Manual entry delay (seconds)

Advanced Dialog Parameters

ParameterDefaultDescription
V3_speed_ratio0.50Speed ratio for voice 3 (octave down)
V4_speed_ratio1.50Speed ratio for voice 4
V1_amplitude1.0Amplitude multiplier for voice 1
V2_amplitude0.85Amplitude multiplier for voice 2
V3_amplitude0.75Amplitude multiplier for voice 3
V4_amplitude0.65Amplitude multiplier for voice 4
V1_pan-0.35Pan position (-1=left, 0=center, +1=right)
V2_pan0.40Pan position for voice 2
V3_pan-0.75Pan position for voice 3
V4_pan0.75Pan position for voice 4

Output Parameters

ParameterDefaultDescription
Draw_visualization1Generate 4-panel analysis display
Play_output1Audition after processing

Visualization & Analysis

4-Panel Display

Polyphonic Improviser Visualization: Panel 1: TITLE • Script name, preset, source name, voice count, chunk count, mode, duration Panel 2: LEFT CHANNEL WAVEFORM • X-axis: Time, Y-axis: Amplitude • Light gray background with zero line • Light dotted grid = beat divisions (if quantized) • Colored dotted vertical lines = voice entry markers (V1 blue, V2 red, V3 green, V4 purple) • Blue waveform = left channel • Title: "Left channel (light dotted=beats | colored dotted=voice entries)" Panel 3: RIGHT CHANNEL WAVEFORM • Same axes as left • Red waveform = right channel • Title: "Right channel" • X-axis: Time (s) Panel 4: CHUNK SHUFFLE MAP • X-axis: Output slot (1 to nChunks) • Y-axis: Voice rows (V1 at bottom, V2 above, etc.) • Top row (src) shows source chunk numbers with color gradient (dark to light = early to late) • Each voice row shows the shuffled order: - Number in cell = source chunk index - Color intensity = source position (darker = earlier, lighter = later) - Cell background = voice color tinted by source position • Title: "Chunk Shuffle Map (color intensity = source position)" Panel 5: ACTIVE SPAN PER VOICE • X-axis: Output time (s) • Y-axis: Voice rows • Colored bars showing when each voice is active: - Bar from entry time to end of shuffled chunks - Bar labeled with voice, speed ratio, pan • Beat grid overlay (light dotted) • Title: "Active Span per Voice (entry -> end of shuffled chunks)" Panel 6: STATS PANEL • Source info, chunk info, crossfade, transform mode • Voice parameters (ratios, pans) • Entry timing details (BPM, beat, delay, note value) • Output filename and duration

Reading the Shuffle Map

What the numbers and colors mean:
  • 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

What the bars show:
  • 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:

Rhythmic Variation

Use case: Creating rhythmic variations from drum loops

Technique: Rhythmic Echo preset with quantized entries

Settings:

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:

Research & Education

Use case: Teaching canon, shuffle algorithms, and polyphony

Technique: Enable visualization, compare presets on simple test signals

Learning outcomes:

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

Problem: Output has clicks between chunks
Cause: Crossfade too short or missing, or chunk boundaries not faded
Solution: Increase crossfade_ms, ensure 10ms fades are applied (script does this automatically)
Problem: Voices end before output duration
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)
Problem: Tape speed artifacts (warbling)
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
Problem: Output too short/long
Cause: Misestimation of output duration (script uses V1 pass × speeds)
Solution: Adjust entry delays or speed ratios; script automatically pads/trims to calculated duration
Problem: Stereo image unbalanced
Cause: Pan values too extreme or voice amplitudes mismatched
Solution: Adjust pans in advanced dialog, balance amplitudes

Advanced Techniques

Custom shuffle seeding:

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.

Hybrid mode (not in UI):

Modify script to use different transform modes per voice — e.g., V1 tape speed, V2 lengthen. Edit the transformation loop to check voice index.

Chunk size variation:

The script uses equal-sized chunks. For variable sizes, pre-segment the source using TextGrid and modify extraction accordingly.

Multi-channel output:

The output is stereo. For multi-channel (5.1, 8-channel), modify panning to use multiple channel gains.