Acoustic Grammar Reducer — User Guide

An offline structural audio reducer that analyzes a selected Sound, estimates acoustically supported event boundaries and structural salience, and rebuilds the original recording as a shorter montage containing the strongest structural spans.

Author: Shai Cohen Affiliation: Department of Music, Bar-Ilan University, Israel Praat front end: v1.7 (2026) Python engine: pGTTM v1.4 License: MIT License Dependencies: Praat + Python 3 + NumPy + pandas
Contents:

What is this?

Acoustic Grammar Reducer is a structural audio reduction system that analyzes temporal, pitch, dynamic, and timbral relations in a recording and constructs a relative acoustic hierarchy from them. It detects acoustically supported event boundaries, merges weaker boundaries into larger groups, scores the resulting groups for structural salience, and uses the highest-ranked structural spans to create a shorter montage from the original recording. The result is an acoustically derived structural skeleton whose content depends on the current source and parameter settings.

The simplest description:
Give it a recording. It finds event boundaries, groups neighboring events, ranks the resulting groups by structural importance, keeps the strongest groups, and splices those original pieces together into a new Sound.

The montage is intended to expose a reduced structural backbone of the source rather than reproduce the whole recording.

Why “grammar”?

Here, “grammar” means a hierarchy inferred from relations among acoustic events. The system borrows two ideas from GTTM-style musical organization:

The implementation turns those ideas into measurable acoustic decisions. Boundaries are supported by timing, pitch, dynamics, and timbre; structural heads are supported by duration, pitch stability, intensity, and low pitch variance.

How the application works

The application treats the recording as a sequence of acoustically defined events and larger structural units. It begins by measuring changes in pitch, intensity, timing, and spectral/formant characteristics across the Sound. These measurements are then used to locate event onsets and to estimate where acoustically supported group boundaries occur.

Once these initial events have been identified, the reducer evaluates how strongly each boundary separates one region from the next. Boundaries supported by larger timing gaps, pitch changes, dynamic drops, or timbral shifts are more likely to remain. Weaker boundaries are merged, allowing short local events to form larger acoustic groups.

The resulting groups are then evaluated for structural salience. Duration, pitch stability, intensity peaks, and pitch variance contribute to a head score for each group. A dynamic-programming stage uses these scores together with minimum-spacing constraints to select a structural backbone rather than simply choosing the loudest or longest events.

L0 — Primary AnchorsThe strongest and most widely spaced structural points in the reduction.
L1 — Phrase HeadsAdditional structurally important groups that form the main retained backbone.
L2 — OrnamentsSecondary groups that remain part of the analysis hierarchy but are not retained in the reduced montage.
L3 — Low-salience materialGroups ranked lowest by the current acoustic model and parameter settings.

The final reduction is created from the L0 and L1 spans. Praat cuts those regions directly from the original Sound, keeps them in their original temporal order, optionally aligns edit points to nearby zero crossings, and joins them with short overlaps. The result is a compressed version of the performance that retains the highest-ranked structural regions under the current acoustic model while omitting lower-ranked material.

In practical terms:
the application transforms a continuous recording into an inspectable acoustic hierarchy, then uses that hierarchy as an edit map for producing a shorter structural version of the same performance.

Complete pipeline

Input: one selected Praat Sound
Praat: choose one representative analysis channel; calculate Pitch, Formant, and Intensity tracks
Praat: export a temporary analysis WAV and write time-aligned acoustic features to CSV
Python / NumPy: spectral-flux onset detection + adaptive peak picking
Python: onset-bounded raw segments → GPR-style boundary strengths → weak-boundary merging
Python: pTSR-style head scores → dynamic-programming hierarchy L0 / L1 / L2 / L3
Python: TextGrid + EDL containing the retained L0/L1 spans
Praat: cut those spans from the original Sound, optionally snap boundaries to nearby zero crossings, and concatenate with overlap
Output: pGTTM Skeleton Montage + optional analysis TextGrid + process visualization
The analysis and the montage use different audio objects deliberately. Analysis uses one representative channel; the final montage is cut from the untouched original Sound and therefore preserves its original channel count and sampling rate.

Stage 1 — Acoustic analysis in Praat

Representative-channel policy

For a multichannel source, the script does not average channels to mono. Averaging can cancel anti-phase material and create a misleadingly weak analysis signal. Instead, it measures whole-file RMS for every real channel and selects the strongest-RMS channel for analysis.

This channel is used for:

The final montage itself is still extracted from the original multichannel Sound.

Frame table

At each analysis frame, Praat writes:

FeatureUse
F0 + voiced flagPitch level, pitch intervals, and pitch stability.
F0 in centsRegister-independent pitch differences and variance.
F1–F4 frequenciesFormant description; F1/F2 are used in GPR timbre-change scoring.
F1–F4 bandwidthsStored in the inspectable acoustic feature table.
Intensity in dBOnset evidence and dynamic-boundary evidence.

The default frame step is 10 ms. The user can set it between 2 and 50 ms.

Temporary WAV

A throwaway copy of the analysis channel is peak-scaled to 0.99 before 16-bit WAV export. This protects the temporary WAV from clipping. It does not alter the Praat Intensity measurements, which were already calculated from the unscaled analysis channel.

Stage 2A — Acoustic onset detection

Onsets are detected in Python from two complementary cues:

onset function = flux_weight × normalized spectral flux + (1 - flux_weight) × normalized positive dB rise

Spectral flux

The spectral part uses:

Both spectral flux and the positive intensity derivative are robustly normalized against their own distribution before mixing. This prevents one exceptional transient from compressing every other event toward zero.

Adaptive threshold

The default detector does not use one flat global threshold. After optional moving-average smoothing, a candidate peak must clear a local median floor by the chosen onset margin:

threshold(t) = local median of onset function(t) + Onset threshold

This is why the same engine can be tuned differently for a plucked attack, a bowed note change, speech, or a continuous texture.

Peak picking

An accepted onset must:

The first frame always anchors the beginning of the first segment.

Stage 2B — GPR-style grouping

Every accepted onset initially creates a raw segment. The engine then evaluates the boundary between each pair of consecutive segments using four relative cues:

CueAcoustic evidenceInterpretation in this implementation
IOITime from the previous segment startA longer separation can support a stronger boundary.
Pitch leapAbsolute change in mean F0, measured in centsA larger pitch discontinuity can support a stronger boundary.
Dynamic dropPrevious intensity peak minus following segment mean, half-wave rectifiedA drop in energy can support separation.
Timbre shiftEuclidean change in mean F1/F2A formant shift can support separation.

Each cue is min–max normalized within the current file, then the selected Grouping style supplies the weights.

boundary strength = weighted mean( normalized IOI, normalized pitch leap, normalized dynamic drop, normalized F1/F2 shift )

Weak-boundary merging is a quantile

Merge weakest fraction is not an absolute strength threshold. A value of 0.50 means:

Merge approximately the weakest 50% of the measured boundaries in this file, while retaining the stronger half.

The engine resolves that requested fraction to the corresponding boundary-strength cut. This makes the control meaningful even when one recording has boundary strengths centered around 0.15 and another around 0.35.

If all boundary strengths are identical, the engine keeps them rather than inventing a distinction that is not present in the evidence.

Stage 2C — pTSR-style structural head scoring

After weak boundaries have been merged, each surviving group receives a structural head score.

raw head score = w1 × normalized duration + w2 × normalized pitch stability + w3 × normalized intensity peak - w4 × normalized pitch variance

The combined score is then renormalized to 0…1 within the current set of groups.

ComponentMeaning
DurationLonger groups can receive greater structural weight.
Pitch stabilityVoiced groups with smaller F0 spread in cents receive higher stability.
Intensity peakStronger local peaks can contribute structural salience.
Pitch variance penaltyLarge within-group F0 spread in cents reduces the score.
Pitch stability and pitch-variance penalty are two transforms of the same underlying pitch-spread measurement. They are retained as separate controls because the presets are calibrated that way, but they should not be interpreted as independent acoustic evidence.

Why dynamic programming?

The engine does not simply take the highest scores. It selects a well-spaced structural backbone. A weighted one-dimensional dynamic program maximizes total selected score while enforcing a minimum time gap between chosen group starts.

A second dynamic-programming pass selects Primary Anchors inside that head backbone, so every L0 Anchor originates from a group that already qualified for the structural head pool.

The L0–L3 hierarchy

L0 — Primary AnchorHighest structural tier. Chosen from within the head backbone with the larger anchor-spacing constraint.
L1 — Phrase HeadStructural head retained in the backbone but not promoted to L0.
L2 — OrnamentHigher-scoring part of the non-head remainder.
L3 — Artifact / NoiseLower-scoring part of the non-head remainder.
L3 is a ranking label, not a diagnosis. A segment labeled “Artifact / Noise” is not proven to be literal noise, an error, or an unwanted sound. It means only that the segment ranked in the lowest structural class under the current acoustic model and settings.

The final montage keeps L0 + L1. L2 and L3 remain visible in the analysis hierarchy but do not enter the EDL used for audio splicing.

Stage 3 — Building the Skeleton Montage

The Python engine writes an edit decision list containing the original-time spans classified as L0 or L1. Praat then cuts those exact regions from the original Sound.

Zero-crossing snapping

When enabled, each cut boundary is moved to the nearest zero crossing only if that crossing lies within a small window. The default window is 5 ms. On multichannel material, the crossing is measured on the same strongest-RMS channel used for the acoustic analysis.

Crossfade

Retained chunks are concatenated in their original temporal order. The default overlap is 10 ms. Requested overlaps at or below 0.5 ms are treated as no overlap and use ordinary concatenation.

If the requested crossfade is too long for the shortest retained chunk, Praat automatically clamps it to 45% of that chunk rather than allowing the overlap to swallow the segment.

What is preserved?

There is no pitch shifting, time stretching, spectral reconstruction, or final peak normalization in the montage stage.

Retention target

Target retention controls the desired fraction of the original duration represented by the structural head pool before crossfading.

It is a target, not an absolute cap. At least one head always survives. If the single strongest segment already exceeds the requested budget, the result intentionally overshoots the target instead of returning silence.

The retention budget is applied before Stage 3 edits. The finished montage can differ slightly from that pre-splice duration: zero-crossing snapping can move each cut by up to 5 ms, and adjacent chunks shorten the combined timeline by the overlap used for crossfading.

Input material presets

The material preset answers one practical question: what does an event boundary look like acoustically in this recording? It changes onset detection and supplies a default weak-boundary merge fraction. Grouping style, Structural style, Reduction density, and pitch range remain independent.

MaterialOnset marginMin IOIFlux weightSmoothingMedian windowDefault merge
Custom.3580 ms.603 frames1.0 s.50
Staccato / plucked.4060 ms.551 frame.5 s.55
Legato / sustained.20180 ms.905 frames1.0 s.42
Percussive / transient-dense.4540 ms.501 frame.5 s.60
Speech / vocal.2890 ms.603 frames.7 s.45
Continuous texture.30300 ms.957 frames2.0 s.35
Mixed ensemble.32100 ms.653 frames1.0 s.50
If Merge weakest fraction = -1, the material preset supplies the value shown above. Any explicit value from 0 to 1 entered on the form overrides the preset and is honored.

Grouping and structural styles

Grouping style — GPR cue weights

StyleIOIPitchDynamicsTimbrePractical effect
Balanced1.01.01.01.0Equal treatment of all four boundary cues.
Rubato-tolerant.41.21.21.2Reduces the authority of timing gaps.
Strict-tempo2.0.8.8.8Gives timing separation more weight.
Timbre-focus.6.8.82.0Emphasizes F1/F2 change as a grouping cue.

Structural style — pTSR head-score weights

StyleDurationPitch stabilityIntensity peakVariance penalty
Balanced1.01.01.0.5
Duration-favoring2.0.7.7.3
Stability-favoring.62.0.81.0
Dynamics-favoring.6.72.0.3

Reduction density

Reduction density controls the target proportions of structural levels and the minimum spacing between selected heads.

PresetL0 targetL1 targetL2 share of remainderAnchor gapHead gap
Sparse.08.22.30.80 s.35 s
Balanced.15.35.30.40 s.15 s
Dense.25.45.30.20 s.08 s

These are targets and selection constraints, not promises that every recording will produce exactly those proportions. The actual result depends on the number, duration, spacing, and scores of the groups found in that file.

Parameter reference

ControlDefaultMeaning
Input materialLegato / sustainedChooses onset-detector behavior and the preset merge fraction.
Time step.01 sPraat feature-analysis frame spacing; clamped to .002–.05 s.
Pitch floor / ceiling75 / 600 HzPraat Pitch analysis range. Choose a range appropriate to the source register.
Onset threshold.35Custom-mode margin above the local median onset floor; material presets override it.
Min IOI80 msCustom-mode refractory spacing between accepted onsets; material presets override it.
Grouping styleBalancedRelative weighting of IOI, pitch, dynamics, and timbre at boundaries.
Merge weakest fraction-1-1 follows the material preset. 0 keeps all measured boundaries; 1 requests maximal weak-boundary merging.
Structural styleBalancedRelative weighting of duration, pitch stability, intensity peak, and pitch variance.
Target retention.45Desired source-duration fraction for the L0+L1 head pool before Stage 3 edits; clamped to .02–1.00 and treated as a target, not a guaranteed hard cap.
Reduction densityBalancedControls L0/L1 target counts and minimum spacing.
Crossfade10 msRequested overlap between retained chunks; clamped to 0–200 ms, limited to 45% of the shortest retained chunk, and effectively disabled at 0.5 ms or below.
Snap to zero crossingsOnMoves each cut to a nearby zero crossing on the analysis channel when one exists within 5 ms.
Draw visualizationOnCreates the five-panel pGTTM process figure.
Play resultOnPlays the finished montage.
Import analysis TextGridOnImports the hierarchy as a Praat TextGrid referring to the original Sound timeline.
Keep intermediate filesOffPreserves the CSV, TextGrid, EDL, and figure tables in the working directory. It does not preserve the temporary analysis WAV.
DebugOffRequests Python diagnostic logging and, after a successful Python stage, preserves the temporary analysis WAV in the temporary directory.

Outputs and intermediate artifacts

Primary output

Sound: [name]_pGTTM_Skeleton_Montage

This is the actual deliverable: retained original-audio spans in source order, joined with the requested overlap.

Optional TextGrid

TextGrid: [name]_pGTTM_analysis

The TextGrid refers to the original Sound timeline, not the montage timeline.

TierTypeContent
Grouping_MacroIntervalTierAll merged acoustic groups.
TimeSpan_HeadsIntervalTierSame group spans, labeled where they are L0 Anchor or L1 Head.
Ornaments_Level2_3TextTierPoints at the onset of L2 Ornament and L3 Artifact-ranked groups.

Intermediate files

By default the CSV, TextGrid, EDL, and figure tables are scratch and are deleted after a successful run once the Sound, optional imported TextGrid, and figure have been created. Keep intermediate files moves those artifacts to the working directory and leaves them there. The temporary analysis WAV is separate: it remains in the temporary directory and is preserved after the Python stage only when Debug is enabled. Failed runs leave diagnostic artifacts in place where possible.

Analysis visualization

The figure deliberately separates the control domain from the audio that was actually produced.

I — Onset Detection Function

Shows the mixed spectral-flux / dB-rise onset function, the adaptive local-median-plus-margin threshold curve, and the accepted onset positions.

II — GPR Boundary Strength

One stem per raw boundary. The resolved quantile cut is drawn explicitly, and the display distinguishes boundaries that survive from boundaries absorbed by merging.

III — pTSR Head-Score Field

Plots merged-group duration on a logarithmic X axis against head score on Y. Point color/size indicates the final L0–L3 class.

IV — Reduction Map

The upper band shows every merged group in its structural class. The lower band shows only L0/L1 material — exactly the material passed to the EDL and therefore eligible for the montage.

V — The Montage Itself

A measured spectrogram of the finished output Sound. Vertical marks show montage splice locations rather than source-time boundaries.

QC strip

The summary reports detector settings, onset count, resolved merge cut, group count, L0–L3 counts, retained duration, crossfade, final peak, and RMS.

Why the pipeline remains practical on long files

The implementation is deliberately split between Praat and Python according to the operations each handles efficiently.

Several design choices specifically avoid length-dependent bottlenecks:

Interpretive limits

The hierarchy is relative to the current recording and settings. Boundary strengths and head scores are normalized inside that file. A score of .8 in one recording is not an absolute equivalent of .8 in another.

Recommended way to use it

  1. Choose the material preset that best describes how boundaries manifest in the recording.
  2. Set a realistic Pitch floor/ceiling for the source.
  3. Begin with Balanced Grouping, Balanced Structural style, Balanced Reduction density, and Target retention around .45.
  4. Inspect Panels I–IV before judging the audio. They show why material was kept or removed.
  5. If too few genuine onsets are detected, adjust the material type or Custom onset settings.
  6. If the montage is too close to the source, reduce Target retention and/or merge a smaller fraction of boundaries so the reducer has more groups to choose from.
  7. If the result is too fragmented, increase weak-boundary merging or use Sparse density.
  8. Use the imported TextGrid when you need to inspect the hierarchy on the source timeline.