Peephole Montage — User Guide

Marks listening points on a Sound, extracts windows around those points in chronological order, optionally adapts or transforms the extracts, and assembles them with butt joints, raised-cosine overlaps, or explicit gaps.

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

What this does

Peephole Montage separates human selection from automated assembly. You decide which moments matter by placing PointProcess marks while listening. The script then turns each valid mark into one source window, processes those windows according to the selected style, and assembles the resulting segments in the chronological order of the marks.

The marks are points, not regions. Each point becomes the temporal anchor for a window whose extent is determined by the symmetric/asymmetric settings and, in Adaptive Context mode, by local signal context.

The original Sound is never modified. The PointProcess is deliberately kept after rendering so the same marks can be reused with different montage settings.

Two-run interactive workflow

Run 1 — create and edit the marks

  1. Select exactly one Sound and run the script.
  2. The script creates an empty PointProcess named peephole_marks with the same time domain as the Sound.
  3. Praat opens the Sound and PointProcess together in View & Edit.
  4. Listen and place points with Ctrl-P at the desired moments.
  5. Return to the Objects window when marking is complete.

Run 2 — render the montage

  1. Select both the original Sound and the PointProcess.
  2. Run the script again.
  3. The script validates the domains, reads all marks, creates the peephole segments, processes them, and assembles the result.
There is no script-specific Continue button inside the editor. Closing or leaving the editor does not automatically resume the first run: rendering begins only when the Sound and PointProcess are selected and the script is run again.

A PointProcess whose time domain does not overlap the Sound is rejected. A partially different time domain is reported, and individual points outside the Sound are skipped. A PointProcess with another name is accepted but reported as a note.

Window extraction

Symmetric

start = mark - Window_length / 2 end = mark + Window_length / 2

Asymmetric

The sentence field is parsed for numeric pre= and post= entries. Defaults are 0.3 s before and 0.2 s after:

start = mark - pre end = mark + post

If either value cannot be parsed or is non-positive, that value falls back to its default and the Info window reports the fallback.

File edges

Every window is clamped to the Sound domain. A window cut by the beginning or end of the file is therefore shorter than requested and is marked as clipped in the visualization.

Extraction uses a rectangular window. A candidate whose final available source window is not longer than 2 ms is skipped.

Four montage styles

StyleWhat it actually changes
Pure peepholeNo style transformation. Use the requested source window, then apply the selected edge/join behavior.
Adaptive context windowsChanges the source-window lengths before extraction according to local intensity and a preceding-pause test. It is not an amplitude ramp.
Unreliable narratorOptionally swaps L/R on stereo segments and applies an increasingly wide random pitch-bias range across the marked sequence.
MicroscopeChanges segment duration by pitch-preserving PSOLA or by varispeed, with an optional multichannel-to-mono path.
Style processing happens before edge fades. Fade duration is measured on the processed segment, so a requested 10 ms fade remains a 10 ms output-domain fade even after Microscope stretching.

Adaptive context windows

This style begins with the ordinary symmetric or asymmetric pre/post lengths, then modifies them from two measurements.

File-relative intensity scale

The script creates a mono analysis copy and measures the file's Intensity 10th and 90th percentiles. If they are usable, the local mean intensity around each mark is normalized between them:

intensityNorm = clamp( (localMean_dB - q10_dB) / (q90_dB - q10_dB), 0, 1 )

This makes the adaptation relative to the current recording rather than assuming that fixed absolute recording levels such as 40–80 dB are universally meaningful. If valid percentiles cannot be obtained, the implementation falls back to 40–80 dB.

Pause-before test

For base pre-window length P, the local context window begins at mark-P. The preceding comparison region extends from approximately mark-3P to that context-window start. It is considered a pause when:

precedingMean_dB < localMean_dB - 10 dB

Adapted lengths

usePre = basePre × (1 + 0.5 × pauseBefore) usePost = basePost × (1.2 - 0.4 × intensityNorm)

These adapted boundaries are still clamped to the source time domain.

Unreliable narrator

Reproducible randomness

If Random_seed is positive, it is used directly. If it is 0, the script first creates an unpredictable seed, prints the actual integer seed used for that take, and then reinitializes predictably from it. Copying that reported seed into the form reproduces the same random decisions.

Stereo flip

When UN_random_stereo_flip is enabled and a processed segment has exactly two channels, each segment has a 50% chance of having L and R exchanged. Mono segments and sources with more than two channels are not channel-flipped.

Progressive pitch-bias range

For mark index i out of N total marks:

biasRange_i = (i / N) × UN_pitch_bias_range semitones_i = uniform(-biasRange_i, +biasRange_i)

Later marks therefore permit a wider mutation range. Shifts whose magnitude is at most 0.01 semitone are skipped.

Pitch shifting uses Praat Manipulation. Every channel is processed separately with the same frequency ratio:

ratio = 2^(semitones / 12) PitchTier frequencies *= ratio

The channels are then recombined in their original order. This is pitch transformation rather than varispeed; duration is not deliberately multiplied by the pitch ratio. Quality depends on the selected Pitch_floor/Pitch_ceiling and on the suitability of the material for Praat's pitch-based resynthesis.

Microscope

Microscope_time_factor is a duration factor. A factor of exactly 1 bypasses the time-stretch engine and copies the segment directly.

Preserve pitch = On

The script creates a Manipulation and inserts the requested factor into its DurationTier. Resynthesis uses overlap-add.

The pitch-analysis bounds are the form's Pitch_floor and Pitch_ceiling. This mode is most appropriate when Praat can obtain a useful periodicity/pitch representation; polyphonic or noisy material can produce artifacts.

Preserve pitch = Off

The script uses true varispeed:

Override sampling frequency: sourceRate / Microscope_time_factor then Resample back to sourceRate

Thus duration and pitch move together. For a factor above 1, the segment becomes longer and lower; for a factor below 1, shorter and higher. All channels are preserved in this path.

The Info report lists the measured achieved ratio of processed duration to extracted source duration. Factors below 0.25 or above 4 are accepted but reported as extreme.

Edge fades & transition modes

Fade type

FadeImplementation
NoneNo explicit outer/segment edge envelope.
LinearTrue linear sample-amplitude ramps.
Raised cosinePraat Fade in / Fade out half-cycle raised-cosine ramps.

For per-segment fades, the effective fade is limited to:

effectiveFade = min(Fade_duration, 0.45 × processedSegmentDuration)

This prevents the two edge ramps from meeting or crossing inside a very short segment.

1. Butt joint with edge fades — default

Each processed peephole receives its selected edge fade and all segments are concatenated directly. With Linear or Raised cosine selected, each internal seam therefore falls toward zero at the end of one segment and rises from zero at the next. With Fade=None it is a hard butt joint.

2. Raised-cosine overlap

The requested overlap is limited by the shortest processed segment:

actualOverlap = min(Transition_amount, 0.40 × shortestProcessedSegment)

Praat Concatenate with overlap supplies the raised-cosine crossfades at all internal joins. Individual segments are deliberately not edge-faded beforehand. If Fade_type is Linear or Raised cosine, that selected fade is applied only to the first and last outside edges of the completed montage.

Approximate duration for N processed segments:

sum(segment durations) - (N - 1) × actualOverlap

3. Gap between peepholes

After each segment except the last, the script inserts digital silence of exactly Transition_amount with the same channel count and sample rate as the segments. Segment edge fades still operate normally.

sum(segment durations) + (N - 1) × Transition_amount

Output gain handling

The script measures the ordinary sample absolute extremum after assembly and offers three modes:

ModeBehavior
Attenuate only (never boost)If the measured peak exceeds Peak_target, scale down to the target. Otherwise leave level unchanged.
Peak (scale to target)Any non-silent result is scaled up or down so its measured sample peak equals Peak_target.
NoneNo final gain change.
Peak_target is validated to the interval (0,1]. Invalid values fall back to 0.99. The measurement uses Praat's sample extremum mode None, not Sinc70 true/intersample-peak estimation.

Parameters

ParameterDefaultRole
Window_length_(s)0.5Total symmetric source-window duration.
Asymmetric_windowsOffUse parsed pre/post lengths instead of Window_length/2.
Asymmetricpre=0.3 post=0.2Sentence field from which the two asymmetric lengths are extracted.
Fade_typeRaised cosineNone, Linear, or Raised cosine.
Fade_duration_(s)0.01Requested final-domain edge fade.
Transition_modeButt jointButt joint, raised-cosine overlap, or gap.
Transition_amount_(s)0.02Requested overlap or exact gap duration; not used by butt mode.
Montage_stylePure peepholePure, Adaptive context, Unreliable narrator, or Microscope.
Random_seed00 creates and reports a take seed; positive values reproduce stochastic decisions.
UN_random_stereo_flipOn50% L/R swap for exactly two-channel segments in Unreliable Narrator.
UN_pitch_bias_range_(semitones)0.5Maximum end-of-sequence ± pitch range; negative values are clamped to 0.
Microscope_time_factor2.0Positive duration factor.
Microscope_preserve_pitchOnUse pitch-preserving Manipulation/DurationTier instead of varispeed.
Microscope_downmix_stereoOffWhen pitch-preserving Microscope receives multichannel input, optionally downmix the segment before stretching.
Pitch_floor / Pitch_ceiling75 / 600 HzPitch bounds used by Manipulation-based pitch shifting and Microscope.
Output_gain_handlingAttenuate onlyAttenuate-only ceiling, target peak scaling, or none.
Peak_target0.99Sample-peak target/ceiling.
Output_namepeephole_montageName of the rendered Sound.
Draw_visualizationOnDraw the edit map.
Play_resultOnPlay the finished montage.

Visualization — the edit map

The v0.3 Picture view is organized around the actual editing decisions rather than a generic spectrogram:

  1. Source with marks and windows: each used PointProcess mark is numbered. Blue-tinted windows fit fully inside the file; red-tinted windows were clipped by a file edge.
  2. Montage timeline: one lane per peephole. The faint gray extent shows the extracted source duration; the colored block shows the duration after style processing. Unreliable Narrator mutations and Microscope ratios can appear inside the blocks.
  3. Transition geometry: timeline positions use the exact butt/overlap/gap duration arithmetic used for assembly.
  4. Output waveform: the completed montage after gain handling.
  5. Summary: style, used/skipped marks, source and output durations, sampled-source percentage, fade range, transition mode, clipped windows, seed, gain mode and peak change.
Source and Output waveforms are autoscaled independently in the current visualization. The panel is therefore an edit/timing map, not a level-comparison display.

Output behavior

Channel count

Pure Peephole, Adaptive Context, Unreliable Narrator pitch shifting, gap assembly and Microscope varispeed preserve the source channel count. Two deliberate exceptions are possible:

When pitch-preserving Microscope keeps multichannel audio, each channel is resynthesized independently with the same duration factor and then recombined.