| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Try it in the browser: Pitch and tempo changer. Runs on this package, nothing is uploaded.
Time stretching algorithms — umbrella over @audio/stretch-* atoms.
| Atom | Algorithm | Domain | Quality | CPU | Best for |
|---|---|---|---|---|---|
| @audio/stretch-wsola | WSOLA | time | ★★★ | low | speech, real-time |
| @audio/stretch-psola | PSOLA | time | ★★★★ | medium | speech, monophonic instruments |
| @audio/stretch-pvoc | plain phase vocoder | freq | ★★ | medium | educational baseline |
| @audio/stretch-pvoc-lock | phase-locked vocoder | freq | ★★★★ | medium | general music |
| @audio/stretch-pghi | phase-gradient vocoder | freq | ★★★★ | medium | vibrato, glides, chirps |
| @audio/stretch-transient | transient-aware vocoder | freq | ★★★★★ | medium | music with percussion |
| @audio/stretch-hybrid | HPSS hybrid | freq+time | ★★★★ | high | full mixes — drums over tonal |
| @audio/stretch-paulstretch | PaulStretch | freq | — | medium | extreme stretch (ambient, drones) |
| @audio/stretch-sms | Sinusoidal Modeling | sinusoidal | ★★★★ | high | harmonic / tonal material |
For pitch shifting, see the @audio/shift-* family.
Install the umbrella (all atoms):
npm install @audio/stretch
import { transient, wsola } from '@audio/stretch'
let slower = transient(samples, { factor: 2 }) // 2× slower, same pitch
let fast = wsola(samples, { factor: 0.75 }) // 1.33× faster
let write = transient({ factor: 1.5 }) // real-time streaming
write(block1)
write(block2)
write() // → remaining samplesOr install just the atom you need — each is self-contained:
npm install @audio/stretch-transient
import transient from '@audio/stretch-transient'
let out = transient(samples, { factor: 2 })Float32Array in/out; a channel array [L, R] (or Float64Array) is accepted and processed per channel — parity with @audio/shift. Output sizes may be variable — small or empty early chunks are normal in streaming.
Waveform Similarity Overlap-Add. Divides signal into overlapping frames and places them at new synthesis positions, but before placing each frame searches ±delta samples for the read position that maximizes cross-correlation with the natural progression of the previous grain through the input — eliminating the phase cancellation (flanging) of plain OLA. No FFT overhead.
import wsola from '@audio/stretch-wsola'
wsola(data, { factor: 1.5 })
wsola(data, { factor: 0.5, delta: 512 })| Param | Default | |
|---|---|---|
| factor | 1 | Time stretch ratio |
| frameSize | 2048 | Window size |
| hopSize | frameSize/4 | Hop between frames |
| delta | frameSize/4 | Search range (±samples) |
Use when: Speech, real-time with tight CPU budgets, moderate ratios (0.5–2×).
Not for: Polyphonic music with sustained tones — frequency-domain methods handle harmonics better.
Pitch-Synchronous Overlap-Add. Detects pitch period via autocorrelation, then windows grains at pitch cycle boundaries. Because grains align with the pitch cycle there are no phase discontinuities at overlaps — cleaner than WSOLA for monophonic pitched signals.
import psola from '@audio/stretch-psola'
psola(data, { factor: 1.5 })
psola(data, { factor: 0.75, sampleRate: 48000 })
psola(data, { factor: 2, minFreq: 100, maxFreq: 400 }) // male voice range| Param | Default | |
|---|---|---|
| factor | 1 | Time stretch ratio |
| sampleRate | 44100 | For pitch detection frequency range |
| minFreq | 80 | Lowest expected pitch (Hz) |
| maxFreq | 500 | Highest expected pitch (Hz) |
Use when: Speech, solo vocals, monophonic instruments, factors 0.5–2×.
Not for: Polyphonic material — autocorrelation finds one pitch period so chords get mangled. Extreme ratios (>2×) cause gaps.
Plain phase vocoder. Each bin's phase advances at its instantaneous frequency independently. Magnitudes are preserved but incoherent inter-harmonic phase relationships give complex signals a diffuse, "underwater" quality.
import pvoc from '@audio/stretch-pvoc'
pvoc(data, { factor: 2 })| Param | Default | |
|---|---|---|
| factor | 1 | Time stretch ratio |
| frameSize | 2048 | FFT size (power of 2) |
| hopSize | frameSize/4 | Hop between frames |
Use when: Educational baseline, simple tonal signals.
Not for: General music — use pvoc-lock or transient.
Phase-locked vocoder (Laroche & Dolson, 1999). After propagating phases, locks non-peak bins to their nearest spectral peak's rotation. Restores harmonic phase coherence, eliminating phasiness.
import pvocLock from '@audio/stretch-pvoc-lock'
pvocLock(data, { factor: 2 })Same options as pvoc.
Use when: General music — tonal/ambient material where transient resets aren't needed.
Not for: Percussive material where attacks matter — use transient.
Phase Gradient Heap Integration — "Phase Vocoder Done Right" (Průša & Holighaus, 2017). Synthesis phase is integrated from the analysis phase gradients, visiting bins in magnitude order via a max-heap: no peak picking, no transient heuristics; chirps, vibrato and glides stay coherent by construction.
import pghi from '@audio/stretch-pghi'
pghi(data, { factor: 2 })| Param | Default | |
|---|---|---|
| factor | 1 | Time stretch ratio |
| frameSize | 2048 | FFT size (power of 2) |
| hopSize | frameSize/8 | Hop — gradient integration wants dense frames |
| tolerance | 1e-6 | Bins below tolerance×max get random phase |
Use when: modulated material — vibrato, glissandi, pitch-unstable sources.
Not for: steady polyphony — pvoc-lock's identity locking reproduces intra-partial phases exactly where gradient integration only approximates them.
Transient-aware phase-locked vocoder (Röbel, 2003). Measures spectral flux between frames; on a sharp onset it resets to the original analysis phase instead of propagating it, preserving attack sharpness on drums and plucks. Implies phase locking.
import transient from '@audio/stretch-transient'
transient(data, { factor: 2 })
transient(data, { factor: 1.5, transientThreshold: 2.0 }) // less sensitive detection| Param | Default | |
|---|---|---|
| factor | 1 | Time stretch ratio |
| frameSize | 2048 | FFT size (power of 2) |
| hopSize | frameSize/4 | Hop between frames |
| transientThreshold | 1.5 | Spectral flux threshold (higher = fewer resets) |
Use when: The right default for most music — percussion, mixed sources.
Not for: Voice/speech — use psola. Extreme stretch — use paulstretch.
Harmonic/percussive hybrid (Driedger & Müller). Median-filter HPSS splits the spectrogram into two layers; the harmonic layer goes through the phase-locked vocoder, the percussive layer through short-frame OLA — chords stay coherent and attacks stay sharp, where one algorithm must trade one for the other.
import hybrid from '@audio/stretch-hybrid'
hybrid(data, { factor: 2 })| Param | Default | |
|---|---|---|
| factor | 1 | Time stretch ratio |
| frameSize | 2048 | FFT size for HPSS + harmonic path |
| percFrame | 512 | OLA frame for the percussive layer |
| harmMedian | 17 | Median filter across time (frames) |
| percMedian | 17 | Median filter across frequency (bins) |
Use when: full mixes — drums over tonal material.
Cost: separation + two stretches ≈ 4–6× the CPU of pvoc-lock alone.
Extreme time stretching via phase randomization (Nasca, 2006). Preserves magnitudes but replaces all phases with random values, producing smooth, dreamlike textures. Designed for large factors.
import paulstretch from '@audio/stretch-paulstretch'
paulstretch(data, { factor: 8 })
paulstretch(data, { factor: 100, frameSize: 8192 })| Param | Default | |
|---|---|---|
| factor | 8 | Time stretch ratio (best >2×) |
| frameSize | 4096 | FFT size (larger = smoother) |
| seed | 0x1f123bb5 | PRNG seed (deterministic output) |
Use when: Ambient music, sound design, drone generation, 8×–1000× stretch.
Not for: Small ratios (<2×) — sounds washed out. Not for preserving rhythm or transients.
Sinusoidal Modeling Synthesis (Serra 1989, McAulay-Quatieri 1986). Decomposes audio into individually tracked sinusoidal partials and resynthesizes at the new time rate. Each partial's frequency and magnitude are interpolated independently — no phase spreading or bin-by-bin artifacts.
import sms from '@audio/stretch-sms'
sms(data, { factor: 2 })
sms(data, { factor: 0.5, maxTracks: 80 })
sms(data, { factor: 3, frameSize: 4096 })| Param | Default | |
|---|---|---|
| factor | 1 | Time stretch ratio |
| frameSize | 2048 | FFT frame size |
| hopSize | frameSize/4 | Hop between frames |
| maxTracks | 60 | Max simultaneous sinusoidal tracks |
| minMag | 1e-4 | Peak detection threshold (linear) |
| freqDev | 3 | Max frequency deviation (bins) for track continuation |
| residualMix | 1 | Stochastic residual blended into the sinusoidal output |
Use when: Harmonic / tonal content — instruments, chords, vocals — where the phase vocoder introduces smearing. Default residualMix=1 blends breath, noise, and transient energy alongside the sinusoidal model.
Not for: Noise-dominated material.
Every atom is self-contained (framing/OLA helpers inlined; the phase-locking engine lives in @audio/spectral-pvoc). Output quality is evaluated with @audio/quality:
import { lsd, spectralSim, chordBalance, chordRetention, modulationDepth } from '@audio/quality'lsd (log-spectral distance), spectralSim (cosine similarity), chordBalance, chordRetention, and modulationDepth (AM depth per partial) evaluate algorithm output against a reference.
| Command | What it does |
|---|---|
| node scripts/compare.js | writes compare.html — interactive waveforms, playback, internal-vs-external comparisons |
| node scripts/bench.js | throughput and ×realtime numbers for batch and streaming |
| node scripts/diagnose.js | targeted diagnostics for specific algorithm behaviors |
Demo for a lightweight browser listening matrix.
| Back | FazBrowse Home | New Git URL |