Phrase Rewriter — v1.0 User Guide

Compositional Archetype Engine for acoustic phrase transformation. Segments a sound, extracts phrase features, and rewrites it according to one of eight structural logics: Constellation, Cloud, Resonance, Center, Becoming, Distance, Mass, Multiplication.

Author: Shai Cohen Affiliation: Department of Music, Bar‑Ilan University, Israel Version: 1.0 (2026) License: MIT License Repo: GitHub
Contents:

What this does

Phrase Rewriter treats an audio recording as a sequence of phrases – events segmented by acoustic novelty. It then rewrites the material according to a chosen compositional archetype, a formal logic that determines which source events are selected, how they are ordered, scaled, and layered, and what kind of new structure emerges.

Not a time‑stretcher, not a random splice machine. The engine extracts phrase‑level features (activity, tension, strength, pitch, brightness, etc.) and uses them to guide the rewrite. The result preserves the acoustic character of the source while imposing a new narrative shape. Eight archetypes: Constellation (crystallized point‑field), Cloud (overlapping density), Resonance (sustained emphasis), Center (radial repetition), Becoming (gradual transformation), Distance (sparse, isolated events), Mass (gravitational cluster), Multiplication (cascading copies).

Quick start

  1. In Praat, select exactly one Sound object.
  2. Run script…PhraseRewriter.praat.
  3. Choose a Mode (Constellation, Cloud, Resonance, …).
  4. Adjust Preserve_source (how much original phrase character remains).
  5. Adjust Rewrite_intensity (strength of the transformation).
  6. Select Duration_policy (keep original length, allow shorter, allow longer).
  7. Optionally enable Run_variation to randomise the seed each time.
  8. Click OK – Praat extracts phrase features (pitch, intensity, HNR, formants), exports CSV, launches Python engine, and imports the result as originalname_rewritten_Mode.
Quick tip: For speech, start with Becoming (gradual transformation) or Cloud (dense texture). For melodic material, try Constellation with a small pitch shift (±2 semitones) to create a sparkling field of fragments.
Important: Python dependencies: numpy, scipy, soundfile. The analysis uses Praat’s built‑in pitch, harmonicity, intensity, and formant objects – ensure your sound is long enough (>0.5 s) for reliable extraction. The Constellation mode has extra controls (Pitch_shift_semitones, Fragment_length_scale) that are ignored by other modes.

The eight compositional archetypes

ModeLogicTypical result
Constellation Phrase is crystallised into short point‑fragments (stars, satellites, echoes, shadows) distributed across time with role‑based spacing grammar. Pitch‑shift and fragment length can be controlled independently. Sparkling field of grains, articulated silence between, latent phrase contour preserved.
Cloud Dense, overlapping repetitions with varying density and overlap fraction. Events are selected with repetition‑avoidance logic. Ambient wash, blurred texture, no clear foreground.
Resonance Selects strongest events and repeats them with emphatic duration scaling and optional “echo” layers (with increased blur/resonance). Sustained, ringing quality – like emphasising resonant frequencies.
Center The strongest event becomes a “center” repeated with an arch‑shaped gain profile; satellite events are placed around it. Radial structure, like a motif radiating from a core.
Becoming Events appear in source order, but each successive event is longer, louder, and more blurred – a gradual transformation across the phrase. Evolution from faint/dry to prominent/wet.
Distance Sparse selection of strong events, placed with large gaps. Optional faint echoes. Isolated, monumental events separated by silence.
Mass All events gravitate toward a temporal center, creating a dense cluster with Gaussian spread. Duration policy is bypassed – output stays tightly clustered. Gravitational collapse around a central point.
Multiplication Each source event spawns multiple copies, each fainter and more blurred, cascading in time. Echo‑cascade, like a ripple effect.

Pipeline — six stages

Stage 1 – Feature extraction (Praat) – pitch, intensity, HNR, F1‑F3 at 10 ms hop → CSV.
Stage 2 – Build phrase features (Python) – smooth, derive activity, tension, onset strength.
Stage 3 – Event segmentation – novelty‑based boundary detection, event strength computed from activity/tension.
Stage 4 – Generate rewrite plan – mode‑specific logic: selection, ordering, dur_scale, gain, blur, resonance.
Stage 5 – Render output – extract clips, apply resampling, blur, resonance, gain, overlay with crossfade.
Stage 6 – Normalize & write stats – active‑region RMS matching, JSON‑like stats for Praat visualisation.

All acoustic processing is in Python (numpy/scipy). No external models.

Parameters & defaults

Global parameters

ParameterDefaultDescription
ModeConstellationSelects the compositional logic.
Preserve_source0.60How much original phrase character remains (0–1). Higher → more faithful durations, less fragmentation.
Rewrite_intensity0.55Strength of the transformation (0–1). Affects degree of blur, resonance, repetition, etc.
Duration_policykeep near originalkeep / shorter / longer – scales final duration relative to source.
Variation_amount0.20Amount of stochastic jitter applied to plan (0–1).
Seed42Random seed for reproducibility.
Run_variation0If checked, seed is randomly varied each run.

Constellation‑only controls

These appear only when Mode = Constellation. They are ignored in other modes.

ParameterDefaultDescription
Pitch_shift_semitones0.0Shift pitch of every fragment (varispeed resampling). Positive = up, negative = down. Duration changes proportionally – but the plan’s dur_scale compensates transparently.
Fragment_length_scale1.0Multiplier for the target onset‑bite duration (0.1–4.0). At 1.0, fragments are ~90–200 ms; at 2.0 they are roughly twice as long. This is not a speed change – it simply takes a longer window from the source clip, then plays it at its original speed (dur_scale stays near 1.0).

Constellation – deep dive

Constellation is the most sophisticated archetype. It treats the phrase as a latent field of points waiting to be crystallised. The algorithm:

  1. Seed selection – picks 30–70% of events (density controlled by preserve_source). Seeds are chosen based on strength, tension, and (when fragment_length_scale > 1) longer duration.
  2. Fragment crystallisation – each seed is broken into 1–3 point‑fragments. The target duration (onset_trim_sec) is ~90–200 ms multiplied by fragment_length_scale. This is a trim, not a resample – so pitch_shift works independently.
  3. Role assignment – fragments are labelled star, satellite, echo, shadow based on score tiers. Each role has its own gain range, gap spacing, dur_scale multiplier, and trim multiplier.
  4. Spacing grammar – stars open wider gaps, satellites cluster, echoes trail stars, shadows flicker briefly. High‑tension zones become denser.
  5. Companion generation – ~35% of stars spawn an additional echo or shadow companion, creating genuine constellation feel.

The result is a field of articulate grains, with latent phrase contour preserved by the order of stars, and no compression‑ratio chirps because dur_scale stays near 1.0.

Role properties (Constellation)

RoleGain rangeGap multiplierDur_scale multiplierTrim multiplierBlur
⭐ Star0.75–0.950.55 + 0.35×intensity1.15 + 0.15×preserve1.300.0
🛰️ Satellite0.44–0.640.28 + 0.18×intensity1.001.000.0
📢 Echo0.20–0.370.14 + 0.10×intensity0.85 − 0.10×intensity0.800.08+0.12×intensity
👻 Shadow0.07–0.170.10 + 0.15×variation0.70 − 0.08×intensity0.600.12+0.18×intensity

Visualization (Praat picture)

When Draw_visualization = 1, the script draws a multi‑panel plot containing:

Tip: The phrase shape panel gives a quick overview of which events are strong (tall bars) and their activity/tension balance. The rewrite plan panel reveals how source events are re‑ordered and placed in time.

FAQ / troubleshooting

“Python not found” or missing packages

Install: pip install numpy scipy soundfile. On Windows, ensure Python is in PATH (the script tries py, python, python3).

Output is silent / very quiet

Check the RMS values in the Info window. If rms_out_active is very low, the rewrite may have selected very quiet fragments. Increase Preserve_source or lower Variation_amount. In Constellation, ensure fragments are not too short (lower Fragment_length_scale).

Constellation pitch_shift has no effect or sounds like varispeed

Pitch_shift is implemented as varispeed resampling (duration changes). But the plan’s dur_scale compensates automatically, so the overall output timing is correct. For subtle shifts on speech, keep pitch_shift ≤ 3 semitones. For radical grains, use larger values – the resulting duration change is absorbed into the fragment’s placement.

Fragment_length_scale seems to affect pitch? No, it doesn't.

Fragment_length_scale only trims a longer/shorter window from the source clip. The clip is then played at its original speed (dur_scale ≈ 1.0). So there is no pitch change. Pitch_shift is completely independent and can be combined freely.

Mass mode output is much longer than expected

Mass mode intentionally bypasses the duration policy scaling – it produces a tight cluster near the original center. If you see a long output, check that you didn't accidentally enable a different mode.

Active‑region RMS matching

The output is normalised so that the RMS of its active (non‑silent) portions matches the input’s active RMS. This prevents sparse outputs (Constellation, Distance) from being too quiet.

Command‑line usage of phrase_rewriter.py

The Python engine can be run independently (for batch processing):

python phrase_rewriter.py input.wav features.csv output.wav stats.txt \ mode preserve intensity durPolicy variation seed hop_sec [--pitch_shift N] [--fragment_length S]

features.csv must be the CSV exported by Praat with columns: time, pitch, voiced, hnr, intensity, f1, f2, f3.