Paulstretch — User Guide
Spectral time stretching by overlapping FFT frames, preserving each frame's spectral magnitudes while randomizing interior-bin phases, then overlap-adding the resynthesized frames on a slower-moving source trajectory.
What this does
Paulstretch creates a new mono or stereo sound whose duration is approximately the requested stretch factor times the source duration. The engine first converts the selected source to mono, then analyzes overlapping Hann-windowed FFT frames. Spectral magnitudes are retained while interior-bin phases are randomized, and the resynthesized frames are overlap-added on an expanded output timeline.
The process does not deliberately shift spectral frequencies. Its characteristic temporal smearing comes from the source/output hop relationship and phase randomization rather than varispeed resampling.
How the stretch works
The core timing relationship is:
Successive analysis frames therefore move through the source by hopIn, while their resynthesized versions advance through the output by the larger or smaller hopOut. The output target is:
A factor above 1 expands time; a positive factor below 1 is also accepted and contracts the requested duration.
Frame-centre alignment
Frame i is centered at i × hopIn in the source and written at:
The output workspace extends half a window before time 0 and half a window after the target. After overlap-add, the result is trimmed to the requested 0…targetDuration interval. This keeps the first source frame centered on output time 0 rather than adding a half-window latency.
Quick start
- Select exactly one Sound object.
- Run
Paulstretch.praat. - Choose Custom, Subtle Stretch, Classic Paulstretch, Extreme Stretch, or Quick Test.
- Choose a Speed_mode.
- For Custom, set stretch factor, requested window size, overlap, mono/stereo output and stereo phase offset.
- Run the script. The result is named from the source and preset.
FFT window, edge handling & overlap-add
Power-of-two effective window
Window_size_s is a request. After the working sample rate is chosen, the requested sample count is rounded up to the next power of two:
The effective window must contain at least four samples. When the rounding changes the requested duration by more than 0.5 ms, the actual value is reported in the Info window.
Edge frames
At the start and end of the source, the available audio is extracted rectangularly and placed at the correct offset inside a complete zero-padded frame. Only after padding is the full Hann analysis window applied. This prevents a truncated edge frame from being incorrectly re-windowed as if its shorter duration were a complete FFT frame.
Double windowing
Every usable frame receives:
- a Hann window before FFT analysis;
- a second Hann window after inverse FFT.
Overlap-add normalization
The script accumulates the exact synthesis-Hann weights in a parallel normalization Sound. After all frames are added:
This compensates for the changing number and summed weight of overlapping synthesis windows. Overlap_percent therefore primarily changes frame density and processing load rather than being used as an output-gain control.
Spectral magnitude & phase randomization
Each Hann-windowed frame is transformed to a Spectrum and then to its two-row complex Matrix. For every interior frequency bin, the script first freezes the original magnitude:
It then draws one random phase and rebuilds the complex pair coherently:
The first and final spectral bins are left unchanged. Thus the interior-bin magnitudes of each analyzed frame are retained while their phases are replaced.
Stereo phase mode
When Create_stereo is enabled, L and R are not processed with unrelated randomness. Every frame receives one unpredictable integer seed. Both rendered channels reinitialize from that same seed, so they use the same base random phase sequence.
- offset = 0: L and R are identical.
- offset > 0: the right channel receives a controlled constant phase offset for interior FFT bins.
- DC and the final spectral bin are not phase-shifted.
The parameter is validated only to be non-negative; values above 2 are mathematically periodic modulo 2 because the offset is multiplied by π.
Speed modes
| Mode | Working-rate rule | Final sample rate |
|---|---|---|
| Full Quality | Use the original sample rate. | Original sample rate. |
| Balanced | If source rate > 22050 Hz, downsample the mono engine source to 22050 Hz. Otherwise keep the source rate. | Upsample back to the original rate when downsampling occurred. |
| Fast | If source rate > 11025 Hz, downsample the mono engine source to 11025 Hz. Otherwise keep the source rate. | Upsample back to the original rate when downsampling occurred. |
Both downsampling and final upsampling use Praat Resample with precision 50. The effective power-of-two FFT window is calculated after the working sample rate has been selected.
Presets
| Preset | Stretch | Window request | Overlap | Output | Stereo offset |
|---|---|---|---|---|---|
| Subtle Stretch | 2× | 0.25 s | 75% | Stereo | 0.2 × π |
| Classic Paulstretch | 8× | 0.25 s | 75% | Stereo | 0.3 × π |
| Extreme Stretch | 16× | 0.50 s | 80% | Stereo | 0.4 × π |
| Quick Test | 4× | 0.15 s | 75% | Mono | 0 |
| Custom defaults | 4× | 0.25 s | 75% | Stereo | 0.3 × π |
Named presets overwrite stretch, window, overlap, stereo creation and stereo offset. They do not overwrite Speed_mode, Draw_visualization or Play_result.
Parameters & limits
| Parameter | Default | Validation / exact role |
|---|---|---|
| Preset | Custom | Custom plus four named presets. |
| Speed_mode | Balanced | Full source rate, max 22.05 kHz working rate, or max 11.025 kHz working rate. |
| Stretch_factor | 4.0 | Must be > 0. Sets both hop ratio and target duration. |
| Window_size_s | 0.25 | Positive request; converted to a power-of-two sample count at the working rate. |
| Overlap_percent | 75 | Must be > 0 and < 100. |
| Create_stereo | On | Off = mono result; On = generated stereo pair. |
| Stereo_phase_offset | 0.3 | Non-negative right-channel phase offset in units of π. |
| Draw_visualization | On | Draw the v1.3 process view. |
| Play_result | On | Play the completed Sound. |
The requested settings are rejected if they imply more than 250,000 analysis frames.
Visualization
The v1.3 Picture output follows the current engine directly:
- Engine input: the same mono-fold decision used by Paulstretch, not an arbitrary original channel. The displayed copy remains unnormalized.
- Stretched output: mono, or blue L plus amber R in stereo mode.
- Shared amplitude scale: Input and Output use the same vertical range, so their displayed levels can be compared directly.
- Process panel: WINDOW → KEEP MAGNITUDE → RANDOMIZE PHASE → OVERLAP-ADD.
- Hop annotation: reports the actual source advance, output advance and requested stretch ratio.
- Stereo annotation: reports the right-channel phase offset when active.
- Spectrograms: complete input versus the first min(10 s, output duration) of output, up to min(5 kHz, Nyquist).
- Summary: stretch, effective window, overlap, frame count, duration, mono/stereo mode, speed mode and measured render time.
Output behavior
Duration
Before optional sample-rate restoration, the assembled result is trimmed to:
The resulting duration is therefore the requested stretch target subject only to ordinary sample-grid/resampling precision.
Peak safety
The final Sinc70 peak is attenuated only when it exceeds 0.95:
This is an attenuate-only safety ceiling. Quiet output is not normalized upward.
Naming
The source Sound is left unchanged. Temporary processing, normalization and visualization objects are removed.