npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@audio/stretch

v2.0.4

Published

Time stretching — umbrella for @audio/stretch-* atoms (WSOLA, phase vocoder variants, PaulStretch, PSOLA, SMS)

Downloads

634

Readme

@audio/stretch test npm license

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.

Usage

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 samples

Or 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.

Time domain

wsola@audio/stretch-wsola

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.

psola@audio/stretch-psola

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.

Frequency domain

pvoc@audio/stretch-pvoc

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.

pvoc-lock@audio/stretch-pvoc-lock

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.

pghi@audio/stretch-pghi

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@audio/stretch-transient

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.

hybrid@audio/stretch-hybrid

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.

paulstretch@audio/stretch-paulstretch

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

sms@audio/stretch-sms

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.

Quality metrics — @audio/quality

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.

Research & comparison

| 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.

See also

References

  • Verhelst, W. & Roelands, M. (1993). "An overlap-add technique based on waveform similarity (WSOLA)." ICASSP.
  • Laroche, J. & Dolson, M. (1999). "Improved phase vocoder time-scale modification of audio." IEEE Trans. Speech Audio Processing.
  • Röbel, A. (2003). "A new approach to transient processing in the phase vocoder." DAFx.
  • Nasca, P. (2006). "PaulStretch — extreme time stretching." paulnasca.com.
  • Moulines, E. & Charpentier, F. (1990). "Pitch-synchronous waveform processing techniques for text-to-speech synthesis using diphones." Speech Communication, 9(5-6).
  • Driedger, J. & Müller, M. (2016). "A review of time-scale modification of music signals." Applied Sciences, 6(2).
  • Serra, X. (1989). "A System for Sound Analysis/Transformation/Synthesis Based on a Deterministic plus Stochastic Decomposition." PhD thesis, Stanford.
  • McAulay, R.J. & Quatieri, T.F. (1986). "Speech analysis/synthesis based on a sinusoidal representation." IEEE Trans. ASSP, 34(4).

MIT