Self-Reflective Feedback — User Guide

Single-stage self-reflective feedback loop. Praat runs a chosen transformation, exports a preview, Python analyzes it and returns updated parameters, and the process repeats until metrics stabilise or max_iter is reached. Supported stages: MDS Space Navigator, Spectral Freeze & Glitch, Crystalline Cascade, 4-Channel Canon.

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

What this does

This script implements a Self-Reflective Feedback loop — an iterative system where Praat runs a chosen transformation, exports a preview, Python analyzes it and returns updated parameters, and the process repeats until metrics stabilise or max_iter is reached. The system adapts its own parameters based on acoustic analysis of each iteration's output.

Key Features:

Technical Implementation: (1) Stage Selection: Choose from four supported transformations. (2) Iteration Loop: For each iteration, run transformation, export preview WAV. (3) Python Analysis: Compute metrics, compare with previous, update parameters per stage rules. (4) Early Stop Check: All metrics stable within tolerance? Stop. (5) User Dialog: After default_iter, prompt user. (6) Final Output: Return last iteration's result.

Quick start

  1. In Praat, select exactly one Sound object (any duration, any content).
  2. Run script… → select SelfReflectiveFeedback.praat.
  3. Choose Stage (1-4 for different transformations).
  4. Set iteration control: max_iter, default_iter, tolerance.
  5. Enable options: Play_after_each_iter, Debug.
  6. Click OK — loop begins, showing each iteration's progress in Info window.
Quick tip: Start with MDS Space Navigator on a 10-20 second recording with clear events. Set max_iter=5, default_iter=2, tolerance=0.03. Watch the Info window as parameters adapt each iteration. After 2 iterations, a dialog will appear — you can continue automatically, iterate once more, or stop. The final output appears as "source_reordered" (MDS), "source_glitch" (Freeze), etc.
Important: PYTHON DEPENDENCIES — Requires Python with numpy, scipy, soundfile installed. STAGE SCRIPTS must be present in the plugin's subdirectories. PREVIEW EXTRACTION adapts to duration: <4s = full, 4-8s = two windows, ≥8s = three windows, each shifted to nearest flux peak. METRICS STABILISATION checks all five metrics; if any changes exceed tolerance, loop continues.

Self-Reflective Theory

The Feedback Loop

For iteration i: 1. Run transformation T with parameters Pᵢ on input S₀ → output Sᵢ 2. Extract preview window(s) Wᵢ from Sᵢ 3. Compute metrics Mᵢ = {centroid_mean, centroid_var, spectral_flatness, rms_energy_var, spectral_flux} 4. If i > 1 and ∀ metrics: |Mᵢ - Mᵢ₋₁| / max(|Mᵢ₋₁|, ε) < tolerance → stop 5. Update parameters: Pᵢ₊₁ = update_rule(Pᵢ, Mᵢ, Mᵢ₋₁) 6. Increment i

Adaptive Preview Extraction

📊 Intelligent Window Selection

duration = len(audio) / sr if duration < 4.0: preview = full audio elif duration < 8.0: base_positions = [0.25, 0.75] × duration else: base_positions = [0.25, 0.50, 0.75] × duration window_length = min(3.0, 0.10 × duration) seconds For each base position: find nearest spectral flux peak within ±10% duration extract window centered at that position preview = concatenate all windows

This ensures analysis focuses on representative, event-rich portions of the audio.

Acoustic Metrics

📈 Five Key Descriptors

MetricFormulaInterpretation
centroid_meanΣ f·|S(f)| / Σ |S(f)| averaged over framesAverage spectral brightness
centroid_varvariance of centroid across framesSpectral stability/variation
spectral_flatnessgeometric_mean / arithmetic_mean of magnitude spectrum0 = tonal, 1 = noise-like
rms_energy_varvariance of per-frame RMS energyDynamic range variation
spectral_fluxmean positive frame-to-frame spectral changeRate of spectral evolution

Early Stopping Logic

stop_flag = ∀ k ∈ {centroid_mean, centroid_var, flatness, rms_var, flux}: |Mᵢ[k] - Mᵢ₋₁[k]| / max(|Mᵢ₋₁[k]|, 1e-10) ≤ tolerance[k] Default tolerances: • centroid_mean: 0.03 • centroid_var: 0.03 • spectral_flatness: 0.02 • rms_energy_var: 0.02 • spectral_flux: 0.03

Supported Stages

Stage 1: MDS Space Navigator

🗺️ MDS Space Navigator

Reflective parameters: silence_threshold_db, min_sounding_interval_s, silence_between_words_s

Fixed parameters: min_silent_interval, similarity_metric, max_formant_Hz, n_formants, n_MFCC, ordering, play_result

Adaptation logic:

  • Low novelty (flux < 0.005 or centroid_var < 300): Lower threshold (-3dB), smaller min_sounding (-0.01s)
  • High novelty (flux > 0.05 or centroid_var > 8000): Increase silence_between (+0.05s), raise threshold (+3dB)

Output naming: source_reordered

Stage 2: Spectral Freeze & Glitch

❄️ Spectral Freeze & Glitch

Reflective parameters: freeze_points, freeze_repeat_divisor, artifact_amplitude

Fixed parameters: preset, freeze_duration_divisor, freeze_length_min/max_factor, scale_peak, draw_visualization, play_result

Adaptation logic:

  • Too noisy (flatness > 0.15): Reduce artifact_amplitude (-0.02), decrease freeze_points (-1)
  • Too static (flux < 0.003): Increase freeze_points (+2), reduce repeat_divisor (-0.5)

Output naming: source_glitch

Stage 3: Crystalline Cascade

💎 Crystalline Cascade

Reflective parameters: modulation_depth, convolution_mix, wet_dry_percent

Fixed parameters: preset, tail_duration, poisson_density, pulse_width, pulse_period, exponential_base, modulation_frequency, layer2_amplitude, scale_peak, draw_visualization, play_result

Adaptation logic:

  • Too washed out (flatness > 0.20 or centroid_var > 9000): Reduce wet_dry (-8%), reduce modulation_depth (-0.05)
  • Too static (centroid_var < 200): Increase wet_dry (+8%), increase convolution_mix (+0.05)

Output naming: source_cascade_Custom

Stage 4: 4-Channel Canon

🎵 4-Channel Canon

Reflective parameters: shift_percent_1..4, delay_2..4 (delay_1 fixed at 0)

Fixed parameters: preset, resample_frequency, fade_time, output_format, draw_visualization, play_result

Adaptation logic:

  • Too homogeneous (flux < 0.002): Widen pitch intervals (+2% per shift), increase delays (+0.05s)
  • Too chaotic (flux > 0.06): Tighten pitch intervals (-2% per shift), reduce delays (-0.05s)

Output naming: source_canon4ch_Custom

Parameters & Controls

Stage Selection

ParameterDefaultDescription
StageMDS Space NavigatorChoose transformation: MDS, Freeze, Cascade, Canon

Iteration Control

ParameterDefaultDescription
Max_iter3Maximum number of iterations
Default_iter1Auto-iterations before user prompt
Tolerance0.03Relative change threshold for early stop (0.01–0.10)

Options

ParameterDefaultDescription
Play_after_each_iter0Audition each iteration's result
Debug0Print detailed Python commands and metrics

Metrics & Adaptation Rules

MDS Space Navigator

silence_threshold_db = clamp(threshold ± 3.0, 5.0, 55.0) min_sounding_interval = clamp(interval ± 0.01, 0.02, 0.50) silence_between_words = clamp(words ± 0.05, 0.02, 1.50) Rules: if (flux < 0.005) or (centroid_var < 300): threshold -= 3.0 min_sounding -= 0.01 if (flux > 0.05) or (centroid_var > 8000): silence_between += 0.05 threshold += 3.0

Spectral Freeze & Glitch

freeze_points = clamp(points ± 1-2, 1, 30) freeze_repeat_divisor = clamp(divisor ± 0.5, 1.0, 8.0) artifact_amplitude = clamp(amp ± 0.02, 0.01, 1.0) Rules: if flatness > 0.15: amp -= 0.02 points -= 1 if flux < 0.003: points += 2 divisor -= 0.5

Crystalline Cascade

modulation_depth = clamp(depth ± 0.05, 0.0, 1.0) convolution_mix = clamp(mix ± 0.05, 0.0, 1.0) wet_dry_percent = clamp(wet ± 8.0, 0.0, 100.0) Rules: if (flatness > 0.20) or (centroid_var > 9000): wet -= 8.0 depth -= 0.05 if centroid_var < 200: wet += 8.0 mix += 0.05

4-Channel Canon

shift_percent_N = clamp(shift ± 2.0, -50.0, 50.0) delay_N = clamp(delay ± 0.05, 0.05, 5.0) delay_3 must be ≥ delay_2 + 0.1 delay_4 must be ≥ delay_3 + 0.1 Rules: if flux < 0.002: shift_percent_2 += 2.0 shift_percent_3 += 2.0 delays += 0.05 if flux > 0.06: shift_percent_2 -= 2.0 shift_percent_3 -= 2.0 delay_2 = max(0.1, delay_2 - 0.05)

Applications

Algorithmic Composition

Use case: Creating self-optimising transformations that converge to stable characteristics

Technique: Run MDS Space Navigator or Spectral Freeze with moderate max_iter

Workflow:

Sound Design

Use case: Exploring parameter spaces through guided feedback

Technique: Crystalline Cascade or 4-Channel Canon with user intervention

Applications:

Research & Education

Use case: Studying acoustic metrics and their relationship to parameter changes

Technique: Enable debug mode, examine logs

Learning outcomes:

Practical Workflow Examples

🎬 Film Scene: Tuning MDS

Goal: Optimise MDS parameters for a specific recording

Settings:

  • Source: 20-second ambient recording
  • Stage: MDS Space Navigator
  • max_iter=10, default_iter=3, tolerance=0.02
  • Play_after_each_iter=1 (audition progress)

Result: Parameters adapt to the material's acoustic characteristics, converging to stable settings

🎚️ Electronic Music: Freeze Exploration

Goal: Explore freeze parameter space

Settings:

  • Source: 8-second synth stab
  • Stage: Spectral Freeze & Glitch
  • max_iter=5, default_iter=1, tolerance=0.04
  • User intervention at each iteration

Result: Guided exploration: after each iteration, user decides to continue or stop based on sound

🎙️ Voice Processing: Canon Tuning

Goal: Optimise 4-channel canon parameters for vocal material

Settings:

  • Source: 10-second vocal phrase
  • Stage: 4-Channel Canon
  • max_iter=6, tolerance=0.03
  • Debug=1 to see metrics and updates

Result: Delays and pitch shifts adapt to vocal spectral characteristics, converging to optimal spatialisation

Troubleshooting Common Issues

Problem: Python not found or missing packages
Cause: Python not installed, or packages missing
Solution: Install Python and required packages: pip install numpy scipy soundfile
Problem: Stage script not found
Cause: Plugin directory structure incorrect
Solution: Ensure all stage scripts are in their expected subdirectories (Time & Granular/, Reverb/, Spatial & Surround/)
Problem: Loop never stabilises
Cause: Tolerance too low, or material inherently unstable
Solution: Increase tolerance (0.04-0.06), or set max_iter to limit iterations
Problem: Preview extraction too slow
Cause: Very long files with flux calculation
Solution: Reduce file length, or modify _spectral_flux_curve parameters
Problem: User dialog not appearing
Cause: default_iter > max_iter, or loop ended early
Solution: Ensure default_iter ≤ max_iter, and loop hasn't converged earlier

Advanced Techniques

Custom tolerance per metric:

In params_in.json, override individual tolerances: {"centroid_mean": 0.05, "spectral_flatness": 0.01, ...}

Modify preview extraction:

In build_preview(), adjust duration thresholds, window lengths, or peak detection parameters.

Add new stages:

Extend the script with new stage-specific update functions and parameter parsing.

Batch processing:

Use Praat's scripting to run the self-reflective loop on multiple files with different initial parameters.