High-quality time-stretching of audio files — make them faster or slower without changing pitch and without artifacts.
Reverse-engineered from Adobe Audition 2020's Izotope Omega engine (dvaaudiodsp.framework, dsp::stretch::omega namespace) and implemented as a pure Python/NumPy library.
pip install stretch-audioimport numpy as np
from stretch_audio import time_stretch, time_stretch_multichannel
# Mono — slow down by 1.5×
output = time_stretch(audio, rate=1.5, sample_rate=44100)
# Mono — speed up by 2×
output = time_stretch(audio, rate=0.5, sample_rate=44100)
# Stereo — shape (2, N)
output = time_stretch_multichannel(stereo, rate=1.25, sample_rate=44100)audio is a 1-D float32 or float64 NumPy array. The output is float32 with length round(len(audio) * rate).
| Parameter | Default | Description |
|---|---|---|
rate |
— | Stretch ratio. >1 = slower, <1 = faster. Clamped to [1/16, 16] in the engine. |
sample_rate |
44100 |
Audio sample rate in Hz |
n_fft |
auto | FFT window size (power of two). Auto-selected from sample_rate to target ~46 ms (2048 at 44100 Hz). Pass explicitly to override. |
hop_length |
n_fft // 4 |
Analysis hop — 75% overlap, matching the engine's hardcoded hop_divisor = 4 |
transient_sensitivity |
1.0 |
0 = pure phase vocoder, higher = more transient locking. Engine modes: Music = 1.0, Speech = 0.5, Off = 0.0 |
The implementation matches the Transient-Aware Phase Vocoder (TAPV) used in Audition's Omega engine:
- STFT analysis — periodic Hanning window, 75% overlap (
PrecomputeWindows) - Transient detection — positive spectral flux on the power spectrum with an adaptive local-mean threshold and non-maximum suppression (
TransientsInfo::DetectTransientsOfPowerSpectrum+DiscardWeakerBlocks) - Phase vocoder — for tonal frames, instantaneous frequency is estimated per bin and the phase accumulator is advanced by
true_freq × synthesis_hop. For transient frames the accumulator is reset to the raw analysis phase, preserving attack shape exactly. (OmegaEngineImpl::ScheduleGranules) - Overlap-add synthesis — IFFT + pre-normalised synthesis window + OLA (
DispatchOLA,PasteCurrentGranule) - Polyphase resampling — exact output length via sinc resampling (
OmegaEngineImpl::ResampleOutput)
The engine internally precomputes 32 log-spaced window sizes from ~1 ms to ~100 ms and selects adaptively per frame. The fixed-window PV here targets ~46 ms — wide enough for good frequency resolution, narrow enough to avoid temporal smearing. n_fft scales with sample_rate:
| Sample rate | Default n_fft |
Window length |
|---|---|---|
| 22050 Hz | 1024 | 46 ms |
| 44100 Hz | 2048 | 46 ms |
| 48000 Hz | 2048 | 43 ms |
| 96000 Hz | 4096 | 43 ms |
git clone https://github.com/your-username/stretch-audio
cd stretch-audio
uv sync --dev
uv run pytest