PraatPbind — Declarative Pattern Engine — User Guide

Integrates a SuperCollider-style event pattern system (Pbind syntax) into Praat's analysis–resynthesis workflow. Define event-based control structures using compact one-line expressions, compiled into PitchTier and IntensityTier control curves.

Author: Shai Cohen Affiliation: Department of Music, Bar-Ilan University, Israel Version: 1.0 (2026) License: MIT License Citation: Cohen, S. (2026). PraatPbind Repo: https://github.com/ShaiCohen-ops/Praat-plugin_AudioTools
Contents:

What this does

This script implements PraatPbind — a declarative pattern engine that integrates a SuperCollider-style event pattern system into Praat's analysis–resynthesis workflow. Users define event-based control structures using compact one-line Pbind expressions, which are interpreted by a Python engine and compiled into time-aligned PitchTier and IntensityTier control curves. These curves are then applied to the source sound via Manipulation-based resynthesis.

🎛️ What is Pbind?

In SuperCollider, Pbind is a pattern that binds symbolic keys to patterns of values. This implementation supports a subset of the SuperCollider pattern syntax:

  • Pitch keys: degree (major scale index), midinote (MIDI note), freq (Hz)
  • Temporal keys: dur (event spacing), legato (segment scaling)
  • Dynamic key: amp (linear amplitude, 0-1)
  • Pattern types: Pseq, Prand, Pwrand, Pwhite, Pexprand, Pstutter, constants

The result is an event stream that drives pitch and amplitude over time, resynthesized from the source sound.

Key Features:

Technical Implementation: (1) Analysis: Extract source duration and sample rate. (2) Pbind Parsing: Python parses the Pbind expression into pattern descriptors. (3) Event Generation: Iterate patterns to generate event list (time, dur, pitch, amp, legato). (4) Tier Construction: Convert events to stepwise PitchTier and IntensityTier points. (5) Resynthesis: Apply tiers via Manipulation. (6) Visualization: 5-panel display.

Quick start

  1. In Praat, select exactly one Sound object (any duration, any content).
  2. Run script… → select PraatPbind.praat.
  3. Choose Preset (2-9 for specific patterns, 1 for custom).
  4. Edit the Pbind expression if using custom mode.
  5. Set base frequency (Hz) for degree scaling and seed for reproducibility.
  6. Enable Draw_visualization for analysis display.
  7. Click OK — engine parses pattern, generates events, resynthesizes.
Quick tip: Start with MajorUp preset on a 10-20 second sustained sound (pad, drone, vocal). Enable visualization — you'll see the pitch contour with colored steps (blue→red gradient indicating pitch height) and amplitude bars below. Listen to how the source follows the pattern: major scale degrees [0,1,2,4,7] repeating, with random amplitude. The output appears as "source_eventgen" in the Objects window.
Important: PYTHON DEPENDENCIES — Only Python standard library required (no extra packages). PBIND SYNTAX must be exactly one line with no line breaks. DURATION of output is the same as input — events are generated until time reaches source duration. LEGATO < 1 creates gaps (staccato); > 1 creates overlaps. FINITE PATTERNS (e.g., Pseq with finite repeats) stop early if they run out before the duration.

Pbind Theory & Syntax

Basic Syntax

Pbind(key1 = pattern1, key2 = pattern2, ...) Keys: • degree — major scale index (0 = root, 1 = 2nd, 2 = 3rd, etc.) • midinote — MIDI note number (60 = C4) • freq — frequency in Hz (raw, no scaling) • dur — event spacing in seconds • amp — linear amplitude (0-1) • legato — multiplier for dur (segment_dur = dur × legato) Example: Pbind(degree=Pseq([0,1,2,4,7],inf), dur=0.25, amp=Pwhite(0.1,0.5,inf))

Pattern Types

📊 Supported Pattern Generators

PatternSyntaxDescriptionExample
PseqPseq([list], repeats)Cycles through list in orderPseq([0,2,4,5], 3)
PrandPrand([list], count)Random picks from listPrand([60,62,64], 10)
PwrandPwrand([vals], [weights], count)Weighted random picksPwrand([0,4,7], [0.5,0.3,0.2], inf)
PwhitePwhite(lo, hi, count)Uniform random floatPwhite(0.1, 0.5, inf)
PexprandPexprand(lo, hi, count)Exponentially distributed floatPexprand(0.05, 0.5, inf)
PstutterPstutter(pattern, count)Repeats each value count timesPstutter(Pseq([0,4,7],inf), 3)
ConstantnumberFixed value0.3

Repeats/Count: Use inf for infinite (until duration ends) or an integer for finite length.

Pitch Conversion

🎵 From Patterns to Frequency

degree → Hz: d = round(degree) (degrees can be non-integer, e.g., 2.5) octave = d // 7 semitone = MAJOR_SCALE[d % 7] + octave × 12 Hz = baseHz × 2^(semitone / 12) midinote → Hz: Hz = 440 × 2^((midinote - 69) / 12) freq → Hz: Hz = value (used directly)

Major scale degrees: [0, 2, 4, 5, 7, 9, 11]

Examples: degree=0 → root, degree=2 → 3rd, degree=4 → 5th, degree=7 → octave, degree=9 → 9th (octave+2nd), etc.

Event Timing

Each event i has: • start time t = sum of previous durs • duration dur (from pattern) • segment_dur = dur × legato (what actually appears in tiers) • If legato < 1: gaps between events (staccato) • If legato > 1: overlapping events Tier points: step function from t to t + segment_dur at value, with a closing point at total duration to ensure full coverage.

Stopping Rules

Event generation stops when: (a) current time ≥ source duration, OR (b) any finite pattern exhausts its values (Pseq with finite repeats, etc.) If no events are generated (e.g., empty patterns), a fallback single event is inserted at t=0 with duration = source duration.

Preset Patterns

Preset 2: MajorUp

🎵 Major Scale Ascending

Pbind(degree=Pseq([0,1,2,4,7],inf), dur=0.25, amp=Pwhite(0.1,0.5,inf))

Character: Major scale degrees [0,1,2,4,7] (root, 2nd, 3rd, 5th, octave) repeating, random amplitude

Use on: General purpose, melodic exploration

Preset 3: RandomWalk

🎲 Chromatic Walk

Pbind(degree=Pseq([0,1,2,3,4,5,6],inf), dur=0.15, amp=Pwhite(0.2,0.6,inf))

Character: Chromatic scale degrees, faster dur, wider amplitude range

Use on: Random-walk textures

Preset 4: Pulses

⚡ Rhythmic Pulses

Pbind(degree=Pseq([0,0,7,0,0,4],inf), dur=0.10, amp=Pwhite(0.05,0.9,inf))

Character: Repeating rhythmic pattern (root, root, octave, root, root, fifth), fast

Use on: Rhythmic textures, pulses

Preset 5: MidiMelody

🎹 MIDI Note Sequence

Pbind(midinote=Pseq([60,62,64,65,67,69],inf), dur=0.2, amp=Pwhite(0.3,0.7,inf))

Character: C major scale in MIDI notes, moderate amplitude

Use on: Melodic phrases, explicit pitch control

Preset 6: RawFreq

📊 Frequency Sweep

Pbind(freq=Pwhite(200,800,inf), dur=0.1, amp=0.4)

Character: Random frequencies between 200-800 Hz, constant amplitude

Use on: Spectral exploration, noise-based material

Preset 7: LegatoPhrase

🎻 Legato Articulation

Pbind(degree=Pseq([0,2,4,7],inf), dur=0.3, amp=Pwhite(0.3,0.7,inf), legato=0.6)

Character: Major triad degrees, legato=0.6 creates staccato phrasing

Use on: Articulation exploration

Preset 8: WeightedChord

⚖️ Weighted Random

Pbind(degree=Pwrand([0,4,7],[0.5,0.3,0.2],inf), dur=0.2, amp=Pwhite(0.2,0.6,inf))

Character: Weighted random chord tones (root 50%, third 30%, fifth 20%)

Use on: Probability-based textures

Preset 9: Stutter

🔁 Stutter Effect

Pbind(degree=Pstutter(Pseq([0,4,7],inf),3), dur=0.1, amp=Pwhite(0.2,0.7,inf))

Character: Each chord tone repeated 3 times before moving to next

Use on: Stutter effects, repeated patterns

Parameters & Controls

Pbind Parameters

ParameterDefaultDescription
PbindMajorUp presetOne-line Pbind expression (see syntax guide)

Global Parameters

ParameterDefaultDescription
BaseHz220Base frequency for degree scaling (A3 = 220 Hz)
Seed42Random seed for deterministic results

Output

ParameterDefaultDescription
Draw_visualization1Generate 5-panel analysis display
Play_result1Audition after processing

Visualization & Analysis

5-Panel Display

PraatPbind Visualization: Panel 1: TITLE • Script name, source name, preset, base Hz, seed Panel 2: ORIGINAL WAVEFORM • Gray waveform • Red dotted lines = event boundaries (at each t) • Title: "Original (N events)" Panel 3: OUTPUT WAVEFORM • Blue waveform = resynthesized output • Title: "EventGen" • X-axis: Time (s) Panel 4: PITCH CONTOUR (main panel) • X-axis: Time (0 to duration) • Y-axis: MIDI note number • Background: Light gray • Grid lines: - Thick lines = octaves (C notes) - Medium lines = perfect fifths - Thin lines = other notes • Note labels at left margin (C2, C3, etc.) • Colored step lines for each event: - Color = pitch height (blue=low, red=high) - Brightness = amplitude (darker = louder) • Onset dots at each event start • Thin gray lines connect consecutive events • Title: "Pitch contour (color = pitch height • brightness = amplitude)" Panel 5: AMPLITUDE BARS • X-axis: Time, Y-axis: dB • Background: Light gray • Horizontal line at mean dB • Colored bars for each event (color from pitch contour) • Title: "Amplitude (dB)" Panel 6: SUMMARY PANEL • Preset, base Hz, seed • Events count, duration, MIDI range, dB range • Point counts for pitch and intensity tiers • Full Pbind expression

Reading the Pitch Contour

What the colors and lines mean:
  • Colored step lines: Each horizontal segment represents one event, at constant pitch
  • Color gradient: Blue = low pitch, red = high pitch — shows register
  • Brightness: Brighter = lower amplitude, darker = higher amplitude
  • Onset dots: Red dots mark event start times
  • Connecting lines: Thin gray lines connect consecutive events, showing pitch jumps
  • Grid lines: Thick = octaves (C), medium = perfect fifths, thin = other notes — helps reading pitch

Interpreting the Amplitude Bars

What the bars show:
  • Bar height: Amplitude in dB (higher on y-axis = louder)
  • Bar color: Matches pitch contour color — helps correlate pitch and amplitude
  • Horizontal line: Mean dB level across all events
  • Duration: Bar width = event duration × legato (may leave gaps if legato < 1)

Applications

Electroacoustic Composition

Use case: Creating algorithmic pitch/amplitude structures from any source

Technique: Custom Pbind patterns on sustained sounds

Workflow:

Algorithmic Composition

Use case: Generating note sequences with probability and repetition

Technique: WeightedChord or RandomWalk presets

Examples:

Sound Design for Media

Use case: Creating rhythmic pulses, frequency sweeps, articulated textures

Technique: Pulses or RawFreq presets

Applications:

Research & Education

Use case: Teaching pattern-based composition, SuperCollider concepts

Technique: Compare presets on same source, examine pitch contours

Learning outcomes:

Practical Workflow Examples

🎬 Film Scene: Tension Riser

Goal: Create 30-second tension riser from pad

Settings:

  • Source: 30-second synth pad
  • Custom Pbind: Pbind(degree=Pseq([0,1,2,3,4,5,6,7,8,9,10,11],1), dur=2.5, amp=0.5)
  • BaseHz = 110 (A2)

Result: Chromatic scale over 30 seconds, rising in pitch — classic riser

🎚️ Electronic Music: Generative Melody

Goal: Generate infinite melody from single note

Settings:

  • Source: 20-second cello note
  • Pbind: Pbind(degree=Prand([0,2,4,5,7,9,11],inf), dur=Pexprand(0.1,0.5,inf), amp=Pwhite(0.2,0.8,inf))

Result: Randomly wandering melody with varied durations and dynamics

🎙️ Voice Processing: Expressive Phrasing

Goal: Apply rhythmic phrasing to vocal sample

Settings:

  • Source: 10-second vocal phrase
  • Pbind: Pbind(degree=Pseq([0,2,4,5],inf), dur=0.3, amp=0.5, legato=0.5)

Result: Staccato articulation (legato=0.5) creates gaps between notes

Troubleshooting Common Issues

Problem: Python not found
Cause: Python not installed or not in PATH
Solution: Install Python 3 and ensure it's in PATH
Problem: Pbind parsing error
Cause: Syntax error in Pbind expression
Solution: Check parentheses, commas, pattern syntax — use examples as reference
Problem: No events generated
Cause: Patterns empty or dur too large
Solution: Check pattern lists are non-empty, reduce dur
Problem: Output has clicks at event boundaries
Cause: legato < 1 creating gaps, or overlaps with no crossfade
Solution: Use legato=1 for continuous, or accept that gaps may click
Problem: Pitch too high/low
Cause: baseHz inappropriate for source, or degree values too extreme
Solution: Adjust baseHz, or use midinote/freq for direct control

Advanced Techniques

Nested patterns:

Pstutter can wrap any pattern, creating complex repetition structures. For example: Pstutter(Prand([0,2,4],inf), 3) repeats each random note 3 times.

Finite vs infinite:

Use finite repeats (e.g., Pseq([0,1,2], 5)) to create patterns that stop before the duration ends — useful for sectional forms.

Combining pitch domains:

Only one pitch key can be used per Pbind. Choose degree for scale-based, midinote for exact MIDI, freq for raw Hz.

Multi-channel input:

Script converts to mono. For stereo, modify to process each channel separately or sum to mono.