Paulstretch — User Guide

Extreme time-stretching algorithm: creates massive temporal expansion (4x-100x+) with phase randomization for ethereal, ambient, "smeared" textures without pitch shift or rhythmic artifacts.

Author: Shai Cohen Affiliation: Department of Music, Bar-Ilan University, Israel Version: 0.1 (2025) License: MIT License Repo: https://github.com/ShaiCohen-ops/Praat-plugin_AudioTools
Contents:

What this does

This script implements the Paulstretch algorithm — a specialized extreme time-stretching technique developed by Nasca Octavian Paul (2006) that creates massive temporal expansion (typically 4x-100x or more) without pitch shifting. Unlike traditional time-stretching (PSOLA, phase vocoder) which maintain transients and rhythmic structure, Paulstretch deliberately destroys these for smooth, ambient, "frozen" textures. Process: (1) Divide audio into overlapping windowed frames (Hanning window), (2) Convert each frame to frequency domain (FFT), (3) Randomize phase of all frequency bins (preserving magnitude), (4) Convert back to time domain (IFFT), (5) Overlap-add with extended hop size (stretch_factor × hop_in). Result: spectral content preserved, temporal structure obliterated. Creates ethereal soundscapes from any source material.

Key Features:

What is Paulstretch? Developed 2006 by Nasca Octavian Paul for creating "infinite" time-stretches. Unlike phase vocoders (maintain phase coherence for intelligibility), Paulstretch randomizes phase → destroys temporal structure but preserves spectral character. Result: any audio → ambient drone/pad. Famous applications: (1) Music: Justin Bieber's "U Smile" stretched 800x (35 minutes) became viral ambient track (J. Biebz "U Smile 800% Slower"). (2) Sound design: Film/game ambiences, pad creation, texture generation. (3) Experimental music: Spectral transformation, microsound exploration. Algorithm intentionally anti-fidelity → embraces "smearing" as aesthetic goal. Related to granular synthesis but uses FFT frames instead of time-domain grains. This implementation: faithful to original algorithm, optimized for Praat's formula/spectrum objects.

Technical Implementation: (1) Setup: Convert stereo→mono if needed, Calculate window size in samples (e.g., 0.25s × 44100Hz = 11025 samples, rounded to even), Calculate hop sizes: hop_out = window × (1 - overlap), hop_in = hop_out / stretch_factor, Calculate output duration = input_duration × stretch_factor, Determine number of frames needed. (2) Frame processing loop: For each frame: Extract windowed segment from input (Hanning window, centered at t_in), Pad if needed (boundaries), Convert to spectrum (FFT), Randomize phases: for each bin, magnitude = √(re² + im²), new_phase = random(-π, +π), re' = magnitude × cos(new_phase), im' = magnitude × sin(new_phase), except DC/Nyquist (preserve zero phase), Convert back to time domain (IFFT), Apply Hanning window again (smooth edges), Overlap-add to output sound at position t_out. (3) Finalization: Normalize to 0.99 peak, Auto-play. Key insight: Phase randomization = temporal incoherence. Original phase = temporal alignment → transients, attacks. Random phase = no alignment → smooth, drone-like. Overlap-add with extended hop = temporal dilation.

Quick start

  1. In Praat, select exactly one Sound object.
  2. Run script…Paulstretch.praat.
  3. Set parameters: stretch_factor (4.0 default = 4x longer), window_size (0.25 sec default), overlap_percent (50 default).
  4. Click OK — script displays progress in Info window (may take 30 seconds to several minutes).
  5. Result auto-plays and appears in Objects window: "originalname_paulstretch_4.0x".
Quick tip: Start with stretch_factor 4.0 for moderate expansion (4x duration). Try 8.0-16.0 for very stretched, ambient results. Use 20.0-50.0+ for extreme "infinite" drones. Increase window_size (0.25 → 0.5) for smoother results (less "grainy"). Decrease (0.25 → 0.1) for more texture (retains some transients). Adjust overlap_percent (50 → 75) for smoother output, (50 → 25) for more artifacts. Processing time depends on: input duration, stretch factor, window size. Expect 30 sec - 5 min for typical files. Info window shows progress (0% → 100%). Works on any audio — speech, music, noise, synthesis. Best results on harmonically rich material.
Important: VERY LONG PROCESSING TIME — Praat may appear frozen (normal). Check Info window for progress updates. Long inputs + high stretch = very long processing (potentially 10+ minutes). Consider trimming to 30-60 seconds for experimentation. Stereo automatically converted to mono (phase randomization per-channel would create phase cancellation issues). Very high stretch factors (>100x) create extremely long outputs — ensure sufficient disk space and memory. Very small window sizes (<0.1s) may create artifacts, "bubbly" textures. Very large (>1.0s) create very smooth but potentially "boring" results. Output can be MUCH louder or quieter than input (spectral content dependent) — normalization to 0.99 helps but monitor levels. Algorithm destroys rhythmic information — not suitable for maintaining beats/transients.

Paulstretch Theory

Time-Stretching Fundamentals

Traditional vs Extreme Stretching

Traditional time-stretching (PSOLA, phase vocoder):

Paulstretch (extreme stretching):

Temporal structure transformation: INPUT (1 second, 44100 samples): Attack | Sustain | Release ↓ ↓ ↓ [Sharp transients, rhythmic events] TRADITIONAL STRETCH (2x): Attack | Sustain | Release ↓ ↓ ↓ [Transients preserved, twice as long] PAULSTRETCH (8x): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Smooth, continuous texture, no transients] [Original spectral content "frozen in time"] [8 seconds of ethereal drone] Key difference: Phase randomization eliminates time-domain structure

Phase Randomization

What is Phase?

Complex number representation of spectrum:

Each frequency bin in FFT: Complex number = real + imaginary Or: magnitude × e^(iφ) where φ = phase Magnitude: "How loud" this frequency Phase: "When" this frequency oscillates (relative to time zero) Example: Bin 440 Hz: magnitude = 0.8, phase = π/4 Contributes: 0.8 × sin(2π × 440 × t + π/4) Phase determines temporal alignment: - Coherent phases (natural) → sharp transients - Random phases → no temporal alignment → smooth

Phase Randomization Process

For each frequency bin:

STEP 1: Extract magnitude and phase original_real = spectrum[bin].real original_imag = spectrum[bin].imaginary magnitude = √(real² + imag²) original_phase = atan2(imag, real) STEP 2: Generate random phase new_phase = random(-π, +π) (Uniformly distributed between -180° and +180°) STEP 3: Reconstruct with new phase new_real = magnitude × cos(new_phase) new_imag = magnitude × sin(new_phase) STEP 4: Replace in spectrum spectrum[bin].real = new_real spectrum[bin].imaginary = new_imag Exception: DC (bin 1) and Nyquist (bin N) keep phase = 0 (These must be real-valued) Result: Same magnitude spectrum, random phases

Why Randomize Phase?

Natural audio:

Randomized audio:

Analogy: Orchestra tuning

Coherent phases (original):
All musicians play note simultaneously
→ Loud, clear attack
→ Recognizable rhythm

Random phases (Paulstretch):
Musicians play same notes but start randomly
→ No clear attack (entries staggered)
→ Smooth, continuous blend
→ Individual pitches audible, but no rhythm

Overlap-Add Synthesis

Windowing and Frame Extraction

Hanning window formula:

w(n) = 0.5 × (1 - cos(2πn / N)) Where: n = sample index (0 to N-1) N = window length Shape: Bell curve (smooth to zero at edges) Purpose: Prevent spectral leakage in FFT Effect: Frames smoothly fade in/out Applied twice in Paulstretch: 1. Before FFT (analysis window) 2. After IFFT (synthesis window) Double windowing → very smooth reconstruction

Hop Sizes and Stretching

Key parameters:

window_size: Duration of each frame (e.g., 0.25s) overlap_percent: Overlap between frames (e.g., 50%) Calculations: hop_out = window_size × (1 - overlap_percent/100) hop_in = hop_out / stretch_factor Example: window=0.25s, overlap=50%, stretch=4x hop_out = 0.25 × (1 - 0.5) = 0.125s hop_in = 0.125 / 4 = 0.03125s Input frames extracted every hop_in (31.25ms) Output frames placed every hop_out (125ms) Ratio hop_out/hop_in = stretch_factor
Frame placement visualization: INPUT (1 second): Frame: 1 2 3 4 5 6 ... Time: 0ms 31ms 63ms 94ms 125ms 156ms |-----|-----|-----|-----|-----| OUTPUT (4 seconds, stretch=4x): Frame: 1 2 3 4 5 Time: 0ms 125ms 250ms 375ms 500ms |-------|-------|-------|-------| Same frames, different spacing More overlap in output → smoother, more redundancy Creates time dilation

Overlap-Add Reconstruction

Process:

FOR each output sample position: value = 0 FOR each overlapping frame: value += frame[position] × window[position] output[position] = value Multiple frames contribute to each output sample Windows ensure smooth transitions High overlap (75%) → more smoothness Low overlap (25%) → more texture/artifacts 50% overlap typical (good balance)

Complete Algorithm Pipeline

INITIALIZE: Convert stereo → mono if needed Calculate window_samples, hop_in, hop_out Calculate n_frames needed Create empty output sound (duration × stretch_factor) FOR each frame (0 to n_frames-1): STEP 1: Extract input frame t_in = frame × hop_in Extract window_size centered at t_in Pad if at boundaries (zero-pad) STEP 2: Window and analyze Apply Hanning window Convert to spectrum (FFT) STEP 3: Randomize phases FOR each frequency bin: magnitude = √(re² + im²) new_phase = random(-π, +π) new_re = magnitude × cos(new_phase) new_im = magnitude × sin(new_phase) spectrum[bin] = new_re + i×new_im STEP 4: Synthesize Convert to time domain (IFFT) Apply Hanning window again STEP 5: Overlap-add t_out = frame × hop_out Add windowed frame to output at t_out END FOR FINALIZE: Normalize output to 0.99 peak Play and display RESULT: Massively stretched, smooth, ambient audio

Why Paulstretch Sounds Different

🎵 Perceptual Characteristics

What you hear:

  • Pitch preserved: Spectral content unchanged → recognizable tones/harmonics
  • Rhythm destroyed: Phase randomization → no attacks, no beats
  • Smooth texture: Overlap-add + windowing → continuous flow
  • "Frozen" quality: Sounds seem suspended in time
  • Ambient character: Natural reverb-like quality (but different mechanism)
  • Spectral evolution visible: Can hear individual harmonics drifting

Why it works musically: Reveals "inner life" of sounds. Short percussive hits → sustained chords. Speech → vowel drones. Music → harmonic texture. Unpredictable results encourage experimentation.

Comparison to Other Techniques

TechniqueMethodStretch RangeCharacterUse Case
PSOLATime-domain overlap0.5x-2xNatural, clearPitch correction
Phase VocoderFFT phase adjustment0.25x-4xArtifact-proneTempo change
GranularWindowed grains0.1x-10x+TexturedSound design
PaulstretchFFT + phase random4x-∞Smooth, ambientExtreme stretch
Tape slow-downPlayback rate0.1x-1.0xPitch dropsAnalog effect

Parameters

Parameter Table

ParameterTypeDefaultDescription
stretch_factorpositive4.0Time multiplication factor (2.0-100.0+)
window_sizepositive0.25Frame duration in seconds
overlap_percentpositive50Frame overlap percentage (0-90)

Parameter Details

stretch_factor

Range: 2.0-1000.0+ (practical 4.0-50.0)

Default: 4.0 (4× duration)

Effect:

Processing time: Higher stretch = more frames = longer processing

Example: 1-minute input × 10x = 10-minute output

window_size

Range: 0.05-2.0 seconds (practical 0.1-1.0)

Default: 0.25 seconds

Effect:

Trade-off:

Frequency resolution: Larger window = better frequency resolution (narrower FFT bins)

overlap_percent

Range: 0-90% (practical 25-75%)

Default: 50%

Effect:

Processing impact: Higher overlap = more frames = longer processing time

Recommended: 50% (optimal balance per original algorithm)

Parameter Combinations

🎼 Moderate Ambient (General Use)

Settings: stretch_factor 8.0, window_size 0.25, overlap 50

Character: Clear Paulstretch effect, smooth and ambient

Use: Creating pads from samples, ambient soundscapes

🌊 Ultra Smooth

Settings: stretch_factor 16.0, window_size 0.5, overlap 75

Character: Extremely smooth, "liquid" quality

Use: Deep ambient, meditation music, drone compositions

✨ Textured Stretch

Settings: stretch_factor 6.0, window_size 0.1, overlap 40

Character: Granular-like texture, some transient information retained

Use: Sound design, experimental textures, less ambient results

🌌 Infinite Drone

Settings: stretch_factor 50.0+, window_size 0.3, overlap 60

Character: Nearly static, single-chord quality, "eternal"

Use: Long-form ambient, installation art, background atmospheres

Applications

Ambient Music Production

Use case: Creating pads and atmospheres from any source

Technique:

Famous example: Stretching pop songs (J. Bieber, Dolly Parton) creates viral ambient tracks

Sound Design / Film Scoring

Use case: Creating otherworldly, ethereal soundscapes

Applications: