FSM Event Generator — Kotoński Edition — User Guide

Algorithmic composition tool: finite-state machine generating deterministic event sequences inspired by Włodzimierz Kotoński's stochastic synthesis techniques.

Author: Shai Cohen Work: Aela (1967) - Stochastic Synthesis Version: 1.0 (2025) Implementation: Praat scripting language
Contents:

What this does

This script implements a finite-state machine (FSM) event generator for algorithmic composition, inspired by Polish composer Włodzimierz Kotoński's stochastic synthesis techniques as heard in Aela (1967). The tool generates sequences of sonic events (tones and noise bands) based on a deterministic state machine with four compositional states.

Key Features:

What is stochastic synthesis? Pioneered by Polish composer Włodzimierz Kotoński in the 1960s, stochastic synthesis uses probability distributions and algorithmic processes to generate musical events. Unlike serialism's rigid rules, stochastic methods create structures through controlled randomness, producing organic, evolving textures. Aela (1967) was one of the first Polish electroacoustic works using these techniques, creating pointillistic textures of tones and noise bands with carefully controlled densities and frequency distributions.

Technical Implementation: (1) FSM Initialization: Four states with unique parameter sets for event duration, gaps, frequencies, and amplitude envelopes. (2) Event Generation: For each of N events, determine current state, generate event parameters based on state characteristics. (3) State Transitions: Progress through states based on preset strategy or custom progression rules. (4) Audio Rendering: Create each event as either tone (sinusoid with attack/release) or noise band (filtered Gaussian noise). (5) Visualization: Generate score-like graphic showing event timing, frequency, type, and state. (6) Analysis: Calculate statistics about the composition's structure and balance.

Quick start

  1. In Praat, ensure no objects are selected.
  2. Run script… → select FSM_Generator_Kotonski_Edition.praat.
  3. Choose Preset (1-5 for Kotoński-inspired strategies, 6 for custom).
  4. Set Duration_s (total composition length in seconds).
  5. Set Num_events (total number of sonic events).
  6. Adjust Global_amplitude, attack/release times as needed.
  7. If using Custom preset, set compositional controls (state progression, transition mode, etc.).
  8. Enable Draw_score for visual output, Play_result for immediate audition.
  9. Click OK — script generates composition, displays statistics, creates "FSM_[name]" sound object.
Quick tip: Start with Preset 1: Aela I for sparse pointillistic texture. Use Preset 3: Aela III for dense high clusters. Enable Draw_score to see visual representation of the composition (events plotted as lines/bands with color-coded states). Check Info window for detailed statistics about event distribution, timing, and frequency ranges. Output sound object appears in Praat Objects window as "FSM_[preset_name]" — you can play, save, or further process it.
Important: PROCESSING TIME scales with number of events and duration — large values (e.g., 1000+ events) may take minutes. MEMORY USAGE increases with duration × sample rate — very long compositions at high sample rates may require significant RAM. FREQUENCY RANGE should stay within Nyquist limit (sample_rate/2) — script clamps automatically but extreme values may cause artifacts. VISUALIZATION may be slow for very dense compositions (500+ events) — disable if performance is critical. DETERMINISTIC — same parameters always produce same output (seed-free algorithm).

Compositional Theory

Finite-State Machine Composition

🎵 Four Compositional States

State 1: Sparse Pointillism — Short events, long gaps, high register

State 2: Bass Punctuations — Longer events, shorter gaps, low register

State 3: Dense Clusters — Very short events, moderate gaps, mid-high register

State 4: Textural Bands — Medium events, very short gaps, wide frequency range

Each state defines probability distributions for event duration, gaps, frequency range, amplitude, and event type (tone/noise).

State Characteristics

StateDuration RangeGap RangeFrequency FocusTypical Density
State 115–25 ms350–650 msHigh (800–6000 Hz)Sparse (0.5–2 events/sec)
State 2100–350 ms20–80 msLow (60–500 Hz)Moderate (2–5 events/sec)
State 310–40 ms5–30 msMid-high (1500–7000 Hz)Dense (5–15 events/sec)
State 4150–450 ms25–75 msWide (200–5000 Hz)Medium (3–8 events/sec)

Stochastic Synthesis Principles

Kotoński's Approach

Włodzimierz Kotoński (1925–2014) – Polish composer Key work: Aela (1967) – first Polish stochastic electroacoustic composition Methodology: 1. Define probability distributions for musical parameters 2. Use random processes within controlled boundaries 3. Create evolving textures through parameter manipulation 4. Balance between order (structure) and chaos (variation) In this implementation: • Deterministic instead of random (reproducible results) • FSM provides structural framework • Sine waves + filtered noise as basic sonic materials • Parameter evolution through state transitions

Event Generation Algorithm

FOR each event i (1 to Num_events): STEP 1: Determine current state Based on preset strategy or custom progression STEP 2: Generate event parameters duration = base_dur[state] + variation * sin(2π * i / prime) gap = base_gap[state] + variation * cos(2π * i / prime) amplitude = base_amp + modulation * sin(2π * i / prime) frequency = min_f + range * (position + width * sin(2π * i / prime)) STEP 3: Determine event type Tone (sinusoid) or noise band (filtered noise) Based on state preference or mixed strategy STEP 4: Schedule event start_time = cumulative_time cumulative_time += duration + gap STEP 5: State transition check Move to next state based on transition rules END FOR Result: Ordered sequence of sonic events with controlled evolution

Audio Event Types

Tones (Sinusoids)

Formula for tone event: s(t) = A × sin(2π × f × t) × envelope(t) Where: A = amplitude (0.0–1.0, scaled by Global_amplitude) f = frequency (Hz, within state's frequency range) envelope(t) = attack/release window Attack/Release shape: Cosine-shaped fades at start and end Attack time = Attack_ms / 1000 seconds Release time = Release_ms / 1000 seconds Sustained portion at full amplitude between fades Example: 440 Hz tone, 100 ms duration, 10 ms attack, 15 ms release • First 10 ms: cosine fade in • Middle 75 ms: full amplitude • Last 15 ms: cosine fade out

Noise Bands (Filtered Noise)

Formula for noise band: s(t) = A × GaussianNoise(0,1) × envelope(t) Post-processing: Bandpass filter (Hann window) Center frequency = f (Hz) Bandwidth = B (Hz) Filter passband: [f - B/2, f + B/2] Where: GaussianNoise(0,1) = normally distributed random samples envelope(t) = same attack/release as tones Bandwidth controlled per state (typically 200–1500 Hz) Example: 1000 Hz center, 800 Hz bandwidth • Generate white noise • Apply bandpass filter 600–1400 Hz • Apply amplitude envelope Result: noise "band" centered at 1000 Hz

State Transition Strategies

Built-in Preset Strategies

PRESET 1: Aela I - Sparse Pointillism • Equal distribution across 4 states • High frequency focus (800–6000 Hz) • Long gaps, short events • Tones only PRESET 2: Aela II - Bass Punctuations • Equal distribution across 4 states • Low frequency focus (60–500 Hz) • Short gaps, longer events • Tones only PRESET 3: Aela III - Dense High Cluster • Equal distribution across 4 states • High-mid frequency (1500–7000 Hz) • Very short gaps, very short events • Tones only, high density PRESET 4: Aela IV - Filtered Noise Bands • Equal distribution across 4 states • Wide frequency range (200–5000 Hz) • Medium gaps, medium events • Noise bands only, various bandwidths PRESET 5: Aela V - Mixed Texture • Equal distribution across 4 states • Mixed frequency range (150–4000 Hz) • Alternating tone/noise events • Variable density and timing

Custom Transition Modes

Linear cycle: 1 → 2 → 3 → 4 → 1 → 2 → ... • Simple sequential progression • Equal time/events per state Palindrome: 1 → 2 → 3 → 4 → 3 → 2 → 1 → ... • Symmetrical structure • Center-focused form Emphasize sparse: 1 → 3 → 1 → 3 → ... • Alternates sparse states only • Creates contrast between high sparse and dense sparse Emphasize dense: 2 → 4 → 2 → 4 → ... • Alternates dense states only • Creates contrast between low dense and textural dense Transition triggers: • Event-based: Change every N events • Time-based: Change at duration percentages • Hybrid: Both event and time triggers

Preset Strategies

Preset 1: Aela I - Sparse Pointillism

🎵 High Register, Long Silences

Duration: 50.0 seconds

Events: 80 total (1.6 events/second)

Frequency range: 800–6000 Hz (high register)

Event type: Tones only

Character: Delicate, pointillistic texture with considerable silence between events

Inspiration: Kotoński's sparse high-register passages in Aela

Preset 2: Aela II - Bass Punctuations

🎵 Low Interruptions, Weighted Presence

Duration: 40.0 seconds

Events: 60 total (1.5 events/second)

Frequency range: 60–500 Hz (low register)

Event type: Tones only

Character: Bass-registral punctuations with weighty presence

Inspiration: Low-frequency interruptions in stochastic works

Preset 3: Aela III - Dense High Cluster

🎵 Tight Swarm, High Density

Duration: 35.0 seconds

Events: 200 total (5.7 events/second)

Frequency range: 1500–7000 Hz (high-mid register)

Event type: Tones only

Character: Dense swarm of high-frequency events with minimal gaps

Inspiration: Cluster textures in electroacoustic music

Preset 4: Aela IV - Filtered Noise Bands

🎵 Spectral Drift, Noise Textures

Duration: 55.0 seconds

Events: 90 total (1.6 events/second)

Frequency range: 200–5000 Hz (wide spectrum)

Event type: Noise bands only

Character: Evolving noise bands with spectral drift

Inspiration: Colored noise textures in granular synthesis

Preset 5: Aela V - Mixed Texture

🎵 Alternating Characters, Balanced

Duration: 60.0 seconds

Events: 150 total (2.5 events/second)

Frequency range: 150–4000 Hz (balanced spectrum)

Event type: Mixed tones and noise (alternating)

Character: Balanced alternation between pitched and noisy events

Inspiration: Contrasting material in stochastic composition

Parameters & Controls

Global Parameters

ParameterTypeDefaultDescription
Presetoption menu1 (Aela I)Compositional strategy
Duration_spositive real45.0Total composition length (seconds)
Sample_ratepositive integer44100Audio sampling rate (Hz)
Num_eventspositive integer120Total number of sonic events
Global_amplitudepositive real0.6Overall amplitude scaling (0.0–1.0)
Attack_mspositive real10Attack time per event (milliseconds)
Release_mspositive real15Release time per event (milliseconds)
Draw_scorebooleanyesGenerate visual score
Play_resultbooleanyesPlay after generation

Custom Mode Parameters

ParameterTypeDefaultDescription
State_progressionoption menuLinear cycleHow states progress (4 options)
Transition_modeoption menuEvent-basedWhen state transitions occur (3 options)
Transition_every_Npositive integer25Events between transitions (event-based mode)
Frequency_min_Hzpositive real80Minimum event frequency (Hz)
Frequency_max_Hzpositive real8000Maximum event frequency (Hz)
Density_multiplierreal1.0Global density scaling (<1 = denser, >1 = sparser)
State1_typeoption menuTonesEvent type preference for state 1
State2_typeoption menuTonesEvent type preference for state 2
State3_typeoption menuTonesEvent type preference for state 3
State4_typeoption menuTonesEvent type preference for state 4
Noise_bandwidth_Hzpositive real800Default bandwidth for noise bands (Hz)

Workflow & Output

Processing Pipeline

1. PARAMETER SETUP • Load preset or custom parameters • Initialize FSM with 4 states • Set up event arrays 2. EVENT GENERATION LOOP FOR each of N events: • Determine current state (FSM logic) • Generate event parameters based on state • Schedule event timing • Check for state transition END FOR 3. AUDIO RENDERING FOR each generated event: • Create tone or noise sound object • Apply amplitude envelope (attack/release) • For noise: apply bandpass filtering • Mix into master sound END FOR • Apply global fades (10ms start/end) • Normalize peak to 0.9 4. VISUALIZATION (if enabled) • Draw score with events as lines/bands • Color-code by state • Add axes, labels, legend, info panel 5. ANALYSIS & OUTPUT • Calculate statistics • Display in Info window • Create "FSM_[name]" sound object • Play if enabled

Output Information

📊 Compositional Statistics

The script provides detailed statistics in Praat's Info window:

  • Event distribution across 4 states (counts and percentages)
  • Material balance between tones and noise events
  • Timing statistics (average duration, gaps, sound/silence ratio)
  • Frequency range covered by the composition
  • Processing times for each stage (generation, rendering, visualization)
  • Final output details (duration, peak amplitude, name)

Visual Score Features

SCORE VISUALIZATION ELEMENTS: 1. Title Section • "FSM Generator - Kotoński Edition" • Preset name 2. Main Score Area • Black background with subtle grid • X-axis: time (0 to duration seconds) • Y-axis: frequency (Hz, logarithmic-like spacing) • Events plotted as: - Tones: vertical line at start, horizontal line for duration - Noise bands: multiple horizontal lines within bandwidth 3. Color Coding • State 1: Cyan (brightness = amplitude) • State 2: Green (brightness = amplitude) • State 3: Yellow (brightness = amplitude) • State 4: Orange (brightness = amplitude) 4. Legend & Info Panel • Event type symbols explanation • Color key for states • Composition parameters summary

Practical Applications

Algorithmic Composition

Use case: Generating structured electroacoustic textures

Technique: Use presets as starting points, then customize

Workflow:

Teaching Stochastic Methods

Use case: Demonstrating algorithmic composition principles

Learning outcomes:

Sound Design

Use case: Creating evolving textures for media

Technique: Custom mode with specific state progressions

Applications:

Troubleshooting Common Issues

Problem: Processing very slow
Cause: Large Num_events value or high sample rate
Solution: Reduce Num_events (start with 50–200), use 44100 Hz sample rate
Problem: Audio clipping/distortion
Cause: Global_amplitude too high or too many overlapping events
Solution: Reduce Global_amplitude (0.3–0.7 range), increase gaps via Density_multiplier > 1.0
Problem: No high frequencies audible
Cause: Frequency_max_Hz too low or state settings favoring low frequencies
Solution: Increase Frequency_max_Hz (4000–10000 Hz), try Preset 1 or 3
Problem: Visualization missing or incomplete
Cause: Praat Picture window too small or composition too dense
Solution: Increase Praat Picture window size, reduce Num_events for clearer visualization