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.
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.
Quick start
- In Praat, select exactly one Sound object.
- Run script… →
PhraseRewriter.praat. - Choose a Mode (Constellation, Cloud, Resonance, …).
- Adjust Preserve_source (how much original phrase character remains).
- Adjust Rewrite_intensity (strength of the transformation).
- Select Duration_policy (keep original length, allow shorter, allow longer).
- Optionally enable Run_variation to randomise the seed each time.
- Click OK – Praat extracts phrase features (pitch, intensity, HNR, formants),
exports CSV, launches Python engine, and imports the result as
originalname_rewritten_Mode.
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
| Mode | Logic | Typical 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 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
| Parameter | Default | Description |
|---|---|---|
| Mode | Constellation | Selects the compositional logic. |
| Preserve_source | 0.60 | How much original phrase character remains (0–1). Higher → more faithful durations, less fragmentation. |
| Rewrite_intensity | 0.55 | Strength of the transformation (0–1). Affects degree of blur, resonance, repetition, etc. |
| Duration_policy | keep near original | keep / shorter / longer – scales final duration relative to source. |
| Variation_amount | 0.20 | Amount of stochastic jitter applied to plan (0–1). |
| Seed | 42 | Random seed for reproducibility. |
| Run_variation | 0 | If checked, seed is randomly varied each run. |
Constellation‑only controls
These appear only when Mode = Constellation. They are ignored in other modes.
| Parameter | Default | Description |
|---|---|---|
| Pitch_shift_semitones | 0.0 | Shift pitch of every fragment (varispeed resampling). Positive = up, negative = down. Duration changes proportionally – but the plan’s dur_scale compensates transparently. |
| Fragment_length_scale | 1.0 | Multiplier 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:
- 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.
- 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. - 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.
- Spacing grammar – stars open wider gaps, satellites cluster, echoes trail stars, shadows flicker briefly. High‑tension zones become denser.
- 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)
| Role | Gain range | Gap multiplier | Dur_scale multiplier | Trim multiplier | Blur |
|---|---|---|---|---|---|
| ⭐ Star | 0.75–0.95 | 0.55 + 0.35×intensity | 1.15 + 0.15×preserve | 1.30 | 0.0 |
| 🛰️ Satellite | 0.44–0.64 | 0.28 + 0.18×intensity | 1.00 | 1.00 | 0.0 |
| 📢 Echo | 0.20–0.37 | 0.14 + 0.10×intensity | 0.85 − 0.10×intensity | 0.80 | 0.08+0.12×intensity |
| 👻 Shadow | 0.07–0.17 | 0.10 + 0.15×variation | 0.70 − 0.08×intensity | 0.60 | 0.12+0.18×intensity |
Visualization (Praat picture)
When Draw_visualization = 1, the script draws a multi‑panel plot containing:
- Input waveform with red event boundaries.
- Output waveform (rewritten).
- Input and output spectrograms (0–5 kHz).
- Phrase shape panel – each event shown as two stacked bars:
- Blue = activity (intensity change + pitch presence)
- Red = tension (brightness + lack of HNR)
- Bar height = strength (activity + tension combined)
- Rewrite plan panel – dots at (output start time, source event index). Dot colour indicates gain: dark grey (quiet) → orange (loud). This shows the structural mapping.
- Mode colour strip – coloured bar with mode name.
- Summary panel with event count, plan steps, durations, RMS, preserve/intensity values.
FAQ / troubleshooting
Install: pip install numpy scipy soundfile. On Windows, ensure Python is in PATH
(the script tries py, python, python3).
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).
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 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 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.
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):
features.csv must be the CSV exported by Praat with columns:
time, pitch, voiced, hnr, intensity, f1, f2, f3.