Reich Generator — User Guide
Loop-based auto-phasing in Praat: a static loop is set against a slightly faster drifting copy, with optional pitch transformation, random pitch perturbation, and a static third voice.
What this does
Reich Generator selects a short active region from one Sound, turns that region into a repeating mono loop, and builds a stereo texture from two main voices. Voice 1 repeats the loop at its measured duration. Voice 2 may first receive a pitch transformation and Gaussian pitch perturbation, then its playback rate is increased by a precisely calculated ratio so that it completes one extra loop during the requested phase-cycle duration. An optional Voice 3 adds a static unison or octave layer.
Core behavior:
- Random loop selection: up to 40 candidate regions are tested inside the requested loop-length range.
- Zero-crossing loop boundaries: accepted candidates are snapped near their beginning and end to reduce discontinuities at repetition points.
- Exact cycle-rate calculation: Voice 2 is made slightly faster so that its loop phase returns to unison after the requested cycle duration.
- Optional pitch transformation: Voice 2 supports unison, +7 semitones, octave down, or octave up. Voice 3 supports static unison, octave down, or octave up.
- Optional stochastic pitch perturbation: Voice 2 can receive Gaussian PitchTier perturbations expressed in semitones.
- Reproducible random choices: a non-zero seed reproduces loop selection, random start offset, and pitch perturbations.
- Fixed output duration: non-zero start offsets do not shorten the requested render.
Quick start
- Select exactly one Sound object.
- Run
Reich_Generator.praat. - Choose one of the four presets, or Manual (Settings below).
- Set Total_Duration_min. This parameter is not replaced by the presets.
- Set V3_Level_dB_relative if a third voice is used; presets also leave this mix-balance control unchanged.
- Use Random_seed = 0 for a fresh random sequence, or a non-zero integer for repeatable random choices.
- Leave Create_polar_phase_wheel enabled to draw the process visualization.
- Use Play_result to choose whether the final Sound is played automatically.
V3_Level_dB_relative, Total_Duration_min, Random_seed, or the visualization/playback switches.
What is loop phasing?
Two repeating copies, slightly different loop rates
In this script, “phase” means the relative position of two repeating loop cycles. It is not the instantaneous waveform phase of every frequency component. Voice 1 repeats the selected loop at its original loop duration; Voice 2 repeats a slightly shorter post-drift loop. Their cycle positions therefore move continuously relative to one another.
Start offset
The offset is measured against the actual post-drift Voice-2 loop duration:
- 0% (Unison Start): no initial loop-cycle offset.
- 50% (Anti-Phase): Voice 2 starts half of its own post-drift loop later.
- Random: the offset is sampled uniformly from one complete post-drift Voice-2 loop.
Here “50%” or “180°” means half a loop cycle. It does not mean polarity inversion of the waveform and does not imply complete destructive cancellation.
Processing pipeline
1. Source preparation
A private zero-based copy of the selected Sound is created. For multichannel material, the script normally analyzes the channel average. RMS is also measured independently for every channel. If the averaged mono copy falls below 10% of the strongest channel RMS, indicating strong cancellation in the fold-down, the strongest-RMS channel is used instead.
2. Activity-aware loop selection
The loop-duration range is clamped to the available source duration. Candidate duration and start position are drawn uniformly at random. A candidate is accepted when its RMS exceeds the activity floor:
After acceptance, the beginning and end are moved to nearby zero crossings when usable crossings are available. The visualization highlights these final snapped boundaries, not the earlier random candidate.
3. Voice 2: interval, perturbation, drift
If the requested interval is not unison, or if flutter is non-zero, the loop is converted to a Praat Manipulation with a 75–600 Hz pitch-analysis range. PitchTier values are multiplied by the selected interval ratio. Gaussian perturbation is then applied multiplicatively in log-frequency space:
This parameter is therefore a standard deviation in semitones. It is stochastic pitch perturbation, not a physical model of tape capstan wow/flutter. If the loop contains no voiced PitchTier points, Voice-2 interval and flutter operations have no effect; the script reports this in the Info window.
After PitchTier resynthesis, the exact phase-drift ratio is applied by sampling-rate override followed by resampling.
4. Voice 3: static anchor
Voice 3, when enabled, is derived from the same base loop and does not drift. Octave modes use the same Manipulation/PitchTier mechanism. Its intensity is set relative to the measured base-loop intensity:
The default is −6 dB relative. If an octave transform is requested but the PitchTier contains no voiced points, the octave transform has no effect.
5. Repeating walls and offset
Each processed loop is concatenated repeatedly and cropped to the required length. Voice 2 is built to Total_Duration + offset before its beginning is removed, so its final duration remains exactly the requested output duration.
6. Stereo mix and final level
With no Voice 3, Voice 1 becomes the left channel and Voice 2 the right channel. With Voice 3 enabled, Praat combines Voice 1 with Voice 3 and converts that pair to mono for the left side; Voice 2 and Voice 3 are combined in the same way for the right side. The two sides are then combined to stereo. Finally, the complete stereo Sound is peak-scaled to 0.99.
Parameters & presets
Form parameters
| Parameter | Default | Behavior |
|---|---|---|
| Preset | Classic Reich | Four defined presets plus Manual. |
| Min_loop_sec | 0.6 | Manual minimum candidate duration; must be positive and ≤ Max_loop_sec. |
| Max_loop_sec | 1.5 | Manual maximum candidate duration; clamped to source duration. |
| V2_Interval | Perfect Fifth (+7st) | Manual Voice-2 pitch mode: Unison, +7 st, octave down, octave up. |
| V3_Mode | None | None, static unison, static octave down, or static octave up. |
| V3_Level_dB_relative | −6.0 dB | Voice-3 intensity target relative to the measured base-loop intensity. Presets do not replace it. |
| Cycle_Duration_min | 1.0 | Manual time for one full relative loop-phase cycle. Must be positive. |
| Start_Offset | Random | Manual initial loop-cycle relationship: 0%, 50%, or random. |
| Flutter_Amount_st | 0.05 | Gaussian PitchTier perturbation standard deviation in semitones; must be ≥ 0. |
| Total_Duration_min | 1.0 | Requested final output duration; presets do not replace it. |
| Random_seed | 0 | 0 = fresh unpredictable sequence; non-zero = reproducible random choices. |
| Create_polar_phase_wheel | Yes | Draws the complete process visualization. |
| Play_result | Yes | Plays the final Sound after processing. |
Preset values
| Preset | Loop range | V2 | V3 | Cycle | Start | Flutter |
|---|---|---|---|---|---|---|
| Classic Reich (Speech / Unison) | 0.5–1.0 s | Unison | None | 1.0 min | 0% | 0.00 st |
| Deep Space (Sub-Bass Shadow) | 2.0–4.0 s | Unison | Low Shadow | 5.0 min | 50% | 0.10 st |
| Holy Trinity (5th + High Anchor) | 0.8–1.2 s | +7 st | High Shimmer | 3.0 min | Random | 0.02 st |
| Broken Tape (Flutter + Random Offset) | 0.4–0.9 s | Unison | Center Anchor | 1.5 min | Random | 0.30 st |
Visualization
When Create_polar_phase_wheel is enabled, the script draws a process visualization with a deliberately dominant phase wheel and three supporting bands.
Phase wheel
The square inner viewport is set explicitly so the polar geometry remains circular. The angular position is the calculated Voice-2 minus Voice-1 loop-cycle phase. The path radius uses a cosine-derived visual “beating depth”:
This is a process diagram derived from loop-cycle phase. Its radius and colour are not measurements of the rendered waveform amplitude or spectral interference.
Source strip
The original source waveform is drawn in neutral gray. The orange region and boundary lines mark the exact loop retained after zero-crossing snapping. For multichannel sources this panel draws the original Sound, while the loop-analysis signal may be the channel average or, when cancellation protection is triggered, the strongest-RMS channel.
Relative phase trajectory
This panel shows the same calculated relative loop-cycle phase against output time, in degrees. Reference lines mark 0°, 90°, 180°, 270°, and 360°. A blue marker indicates the initial phase and a red marker the final phase. Wrap discontinuities are not connected across the 360°→0° boundary.
Summary
The summary reports the source name, measured loop duration, requested cycle duration, number of unison returns within the render, start-offset mode, Voice-2/Voice-3 modes, flutter amount, final duration, and left/right voice roles.
Output & edge cases
Output naming
The final stereo Sound is named:
Only the final Sound remains selected at completion. Intermediate loop, manipulation, pitch-tier, wall, and mix objects are removed during normal completion.
Randomness and reproducibility
A non-zero Random_seed initializes Praat's predictable generator before the script makes random choices. The seed affects candidate loop selection, Random start offset, and Voice-2 Gaussian pitch perturbations. After all random choices have been made, the script restores Praat's safe/unpredictable random mode so later scripts do not inherit the predictable state.
Short, quiet, silent, and unvoiced sources
- If the selected source is shorter than the requested loop maximum, the loop range is clamped to available duration.
- Quiet but valid material can pass through the adaptive activity floor; a numerically silent source exits.
- If no active candidate is found in 40 attempts, the script exits without producing a render.
- Pitch transformations and Gaussian PitchTier perturbation require voiced PitchTier points. They do not transform unvoiced material when no such points exist.
Multichannel input
The generated loop is mono even when the source is multichannel. The normal analysis path averages channels. When that average nearly cancels relative to the strongest channel, the strongest-RMS channel is used instead. The final generated result is stereo because the static and drifting walls are assigned to separate output sides.