Delay Array Processor — User Guide

Temporal structure transformation: applies iterative time-domain delays based on divisor arrays to create complex echo patterns, rhythmic textures, and temporal granulation effects.

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 iterative delay array processing — a temporal transformation technique that creates complex delay patterns by applying multiple delay operations sequentially. The algorithm divides the sample length by specified divisors to calculate delay offsets, then applies a difference formula that creates echoes, rhythmic textures, and temporal granulation. Four divisors processed iteratively create compound delay structures impossible with single delay lines. Result: transformed temporal structure where original material is layered with time-shifted copies at mathematically-defined intervals, creating everything from subtle chorusing to dense granular textures.

Key Features:

What are delay arrays? Traditional delays: single delay line with feedback, simple echo at fixed time. Delay arrays: multiple delay operations with different time offsets, applied iteratively. This script uses divisor-based delays where delay_time = total_samples / divisor. Process: (1) First iteration: Apply delay based on divisor_1 (e.g., samples/2). (2) Second iteration: Apply delay based on divisor_2 to result of step 1. (3) Continue: Repeat for divisors 3 and 4. (4) Result: Compound temporal structure with multiple overlapping echoes. The difference formula self[col+b] - self[col] creates the delay effect by subtracting each sample from its delayed version, emphasizing transients and creating rhythmic patterns. Applications: Experimental composition (temporal textures), sound design (complex echoes), rhythmic transformation (metric modulation), granular-like effects (dense time-layering).

Technical Implementation: (1) Input: Select Sound object, specify four divisor values (positive numbers). (2) Copy sound: Create working copy to preserve original. (3) Calculate sample count: Get total number of samples (a). (4) Iterative processing: For each divisor (1-4): Calculate delay offset b = a/divisor, Apply formula: self[col+b] - self[col] (subtracts current sample from delayed sample), Result becomes input for next iteration. (5) Scaling: Normalize peak to 0.99 (prevents clipping from accumulation). (6) Playback: Automatic audition of result. Key insight: Each iteration compounds the effect. First pass creates one delay pattern, second pass delays that result creating interaction between delays, continuing creates increasingly complex temporal structures. The difference operation (subtraction) emphasizes changes/transients while reducing sustained tones, creating rhythmic, pulsating textures.

Quick start

  1. In Praat, select exactly one Sound object.
  2. Run script…delay_array.praat.
  3. Choose Preset: Default, Fine, Coarse, Extreme, or Custom.
  4. If Custom, adjust divisor_1 through divisor_4 values.
  5. Set scale_peak (normalization level, default 0.99).
  6. Set number_of_iterations (how many divisors to apply, 1-4).
  7. Click OK — processing completes instantly, result auto-plays.
  8. Output appears as "soundObj" in Objects window.
Quick tip: Start with Default preset (2, 4, 8, 10) for moderate effect — creates clear rhythmic echoes without extreme density. Try Fine preset (2, 3, 5, 7) for tighter, more granular texture with closely-spaced delays. Use Coarse preset (4, 8, 12, 16) for slower, more spacious echoes. Extreme preset (2, 6, 12, 24) creates dramatic transformation with widely-spaced delays. Adjust number_of_iterations to control complexity: 1 iteration = single delay, 4 iterations = full compound effect. Processing is instantaneous (no progress bar needed). Result automatically plays for immediate audition. Material with strong transients (percussion, speech) works especially well.
Important: DESTRUCTIVE TRANSFORMATION — creates new temporal structure, doesn't preserve original alongside delays like traditional echo. The difference formula self[col+b] - self[col] is subtractive, not additive. Result emphasizes changes/transients while reducing sustained tones. Very small divisors (<2) create extremely short delays (phase effects, comb filtering). Very large divisors (>50) create long delays (sparse echoes, potential silence gaps). Divisor order matters — different sequences create different results even with same numbers. Iterations compound: 4 iterations with aggressive divisors may create extreme, unrecognizable transformations. Peak scaling to 0.99 prevents clipping but may reduce overall level. No undo — always work on copies. Preset values carefully chosen for musical results; random divisors may create unusable output.

Delay Theory

Divisor-Based Delay Calculation

Basic Formula

Delay offset calculation:

Given: a = total number of samples n = divisor value Calculate: b = a / n Where: b = delay offset in samples Example: 44100 samples (1 second at 44.1kHz), divisor = 2 b = 44100 / 2 = 22050 samples Delay time = 22050 / 44100 = 0.5 seconds Example: 88200 samples (2 seconds at 44.1kHz), divisor = 4 b = 88200 / 4 = 22050 samples Delay time = 22050 / 44100 = 0.5 seconds Insight: Delay is proportional to total duration Longer sounds → longer delays at same divisor

Delay Time Relationships

Common divisors and their musical meanings:

Divisor = 2 → Delay = 1/2 duration (half-note delay) Divisor = 3 → Delay = 1/3 duration (triplet delay) Divisor = 4 → Delay = 1/4 duration (quarter-note delay) Divisor = 8 → Delay = 1/8 duration (eighth-note delay) Divisor = 16 → Delay = 1/16 duration (sixteenth-note delay) Example: 1-second sound Divisor 2 → 500ms delay Divisor 4 → 250ms delay Divisor 8 → 125ms delay Divisor 10 → 100ms delay Example: 4-second sound Divisor 2 → 2000ms delay (2 seconds) Divisor 4 → 1000ms delay (1 second) Divisor 8 → 500ms delay (half second) Divisor 10 → 400ms delay Musical note: If sound is one bar, divisors create metric subdivisions

The Difference Formula

Subtractive Delay Operation

Core algorithm:

Formula: self[col+b] - self[col] Where: self[col] = current sample value self[col+b] = sample delayed by b samples Result = difference between delayed and current Expanded: output[i] = input[i+b] - input[i] Effect: When signal changes: Large difference → emphasized When signal steady: Small difference → reduced Result: Transients emphasized, sustained tones reduced Creates rhythmic, pulsating character Contrast with additive delay: Additive: output = input + delayed_input (echo preservation) Subtractive: output = delayed_input - input (difference emphasis)

Why Subtraction?

Sonic characteristics:

📊 Difference Operation Effects

Transient emphasis:

Sudden change: input[i]=0, input[i+b]=1 → output = 1-0 = 1 (preserved)

Attack preserved and emphasized


Sustain reduction:

Steady tone: input[i]=0.5, input[i+b]=0.5 → output = 0.5-0.5 = 0 (canceled)

Sustained portions reduced or eliminated


Rhythmic creation:

Periodic material creates rhythmic pulses at delay intervals

Percussive sources → rhythmic echoes

Tonal sources → rhythmic granulation


Use: Creates textural, rhythmic transformations vs simple echo repetition

Iterative Processing

Compounding Effect

Sequential application:

Iteration 1: b1 = a / divisor_1 result1 = input[col+b1] - input[col] Iteration 2: b2 = a / divisor_2 result2 = result1[col+b2] - result1[col] (Processes result of iteration 1) Iteration 3: b3 = a / divisor_3 result3 = result2[col+b3] - result2[col] (Processes result of iteration 2) Iteration 4: b4 = a / divisor_4 result4 = result3[col+b4] - result3[col] (Processes result of iteration 3) Final output = result4 Key insight: Each iteration operates on previous result Creates compound temporal structure Interactions between delay patterns Exponentially increasing complexity

Complexity Accumulation

Why iterations matter:

1 Iteration (n=1): Simple delay pattern
Single delay offset, basic echo effect
Relatively transparent, clear delay time

2 Iterations (n=2): Compound delays
Two delay patterns interact
Creates cross-rhythms, more complex texture

3 Iterations (n=3): Dense temporal structure
Three-way interaction between delays
Granular-like density, rhythmic complexity

4 Iterations (n=4): Maximum complexity
Four-way compound delays
Very dense, potentially chaotic temporal texture
Original material heavily transformed

Recommendation: Start with 2-3 iterations, use 4 for extreme effects

Delay Array Patterns

Harmonic vs Inharmonic Divisors

Divisor relationships affect periodicity:

Harmonic divisors (integer multiples): [2, 4, 8, 16] — Powers of 2 [3, 6, 12, 24] — Multiples of 3 Result: Periodic, rhythmically coherent patterns Delays align with each other Inharmonic divisors (unrelated): [2, 3, 5, 7] — Prime numbers [2, 5, 11, 17] — Mixed primes Result: Aperiodic, complex cross-rhythms Delays create interference patterns Example comparison: Harmonic [2,4,8,16]: Delays: 1/2, 1/4, 1/8, 1/16 duration All align at 1/16 subdivisions Rhythmically regular Inharmonic [2,3,5,7]: Delays: 1/2, 1/3, 1/5, 1/7 duration Create polyrhythmic texture No common alignment Musical choice: Harmonic for metric effects, inharmonic for complex textures

Complete Processing Pipeline

SETUP: Select Sound object Choose preset or specify divisors [d1, d2, d3, d4] Set number_of_iterations (1-4) Set scale_peak (normalization, default 0.99) INITIALIZATION: Copy sound → "soundObj" Get number of samples → a Store divisors in variables ITERATIVE PROCESSING: FOR k = 1 to number_of_iterations: Get current divisor: n = divisor[k] Calculate delay offset: b = a / n Apply difference formula: FOR each sample position col: self[col] = self[col+b] - self[col] END FOR Result becomes input for next iteration END FOR FINALIZATION: Scale peak to scale_peak (0.99 default) Prevents clipping from accumulation OUTPUT: Play result (automatic audition) "soundObj" available in Objects window

Preset Patterns

Preset Overview

PresetDivisorsCharacterBest For
Default2, 4, 8, 10Balanced rhythmic textureGeneral use, moderate complexity
Fine2, 3, 5, 7Tight, granular, prime-basedDense textures, polyrhythms
Coarse4, 8, 12, 16Spacious, slower echoesSparse patterns, clear delays
Extreme2, 6, 12, 24Dramatic, widely-spacedRadical transformation
CustomUser-definedUnlimited possibilitiesExperimental design

Default Preset (2, 4, 8, 10)

🎵 Balanced Standard Pattern

Divisors: 2, 4, 8, 10

Delay ratios: 1/2, 1/4, 1/8, 1/10 duration

Character: Mix of binary (2,4,8) and decimal (10) subdivisions

Effect: Clear rhythmic echoes with moderate density

Musical context: Binary divisions create metric coherence, 10 adds variation

Typical applications:

Fine Preset (2, 3, 5, 7)

🎯 Prime Number Granulation

Divisors: 2, 3, 5, 7 (first four primes)

Delay ratios: 1/2, 1/3, 1/5, 1/7 duration

Character: Inharmonic, aperiodic, complex cross-rhythms

Effect: Tight granular texture, dense temporal layering

Mathematical: Prime-based delays create maximum aperiodicity

Typical applications:

Coarse Preset (4, 8, 12, 16)

🌊 Spacious Echo Pattern

Divisors: 4, 8, 12, 16

Delay ratios: 1/4, 1/8, 1/12, 1/16 duration

Character: Slower delays, more spacious, clearer separation

Effect: Distinct echoes, less dense than Fine

Harmonic: 4,8,16 related (powers of 2); 12 adds variation

Typical applications:

Extreme Preset (2, 6, 12, 24)

⚡ Radical Transformation

Divisors: 2, 6, 12, 24

Delay ratios: 1/2, 1/6, 1/12, 1/24 duration

Character: Wide range from half-duration to 1/24

Effect: Dramatic transformation, large delays + fine subdivisions

Risk: May create very abstract, unrecognizable results

Typical applications:

Custom Preset Design

Guidelines for custom divisors:
  • Small divisors (2-4): Long delays, obvious echoes
  • Medium divisors (5-12): Moderate delays, balanced effect
  • Large divisors (13+): Short delays, granular effect
  • Very large (50+): Ultra-short delays, may create comb filtering
  • Harmonic sequences: Use multiples (2,4,8 or 3,6,12) for rhythmic coherence
  • Prime sequences: Use primes (2,3,5,7,11,13) for complex interactions
  • Mixed approach: Combine harmonic + prime (2,3,8,13) for varied texture

🔬 Experimental Divisor Ideas

Fibonacci sequence: [1, 2, 3, 5] — Natural growth pattern

Powers of 2: [2, 4, 8, 16] — Binary metric divisions

Powers of 3: [3, 9, 27, 81] — Exponential spacing

Descending: [16, 12, 8, 4] — Reverse progression

Random primes: [7, 13, 19, 23] — Complex aperiodicity

Clustered: [10, 11, 12, 13] — Tight delay variations

Golden ratio approximations: [2, 3, 5, 8] — Fibonacci subset

Parameters

Primary Parameters

ParameterTypeDefaultDescription
PresetoptionDefaultChoose preset pattern or Custom
divisor_1positive2First delay divisor (overridden by preset)
divisor_2positive4Second delay divisor
divisor_3positive8Third delay divisor
divisor_4positive10Fourth delay divisor
scale_peakpositive0.99Peak normalization level (prevents clipping)
number_of_iterationsnatural4How many divisors to apply (1-4)

Parameter Details

Divisor Values

Constraints and recommendations:

Valid range: Any positive number > 0 (Script type: "positive" enforces this) Practical range: 1.5 to 100 Below 1.5: Very long delays (may exceed sample length) Above 100: Ultra-short delays (phase effects, comb filtering) Typical usage: 2-8: Long delays, clear echoes 9-20: Medium delays, rhythmic patterns 21-50: Short delays, granular textures 51+: Micro-delays, spectral effects Decimal values allowed: divisor = 2.5 → Delay = samples / 2.5 Creates non-integer sample offsets May create interesting artifacts Warning: divisor > sample_count Results in delay offset < 1 sample Minimal or no effect

Scale Peak

Normalization behavior:

Purpose: Prevent clipping from signal accumulation Iterative processing can increase amplitude Peak normalization scales to safe level Default: 0.99 (99% of maximum, -0.09dB) Leaves small headroom for safety Prevents digital clipping