Skip to content

stretcher

A WSOLA (Waveform Similarity Overlap-Add) time-stretch engine that changes playback speed without affecting pitch. Uses Web Workers for real-time audio processing.

import { createStretcherEngine } from "waa-play/stretcher";

createStretcherEngine()

createStretcherEngine(
ctx: AudioContext,
buffer: AudioBuffer,
options: StretcherOptions,
): StretcherEngine;

Create a WSOLA time-stretch engine for the given buffer.

const engine = createStretcherEngine(ctx, buffer, {
tempo: 0.75,
loop: true,
});
engine.start();

StretcherOptions

interface StretcherOptions {
tempo?: number;
offset?: number;
loop?: boolean;
through?: AudioNode[];
destination?: AudioNode;
timeupdateInterval?: number;
workerPoolSize?: number;
}
OptionTypeDefaultDescription
temponumber1Time-stretch ratio (0.5 = half speed, 2 = double speed)
offsetnumber0Start position in seconds
loopbooleanfalseLoop playback
throughAudioNode[][]Audio nodes to route through
destinationAudioNodectx.destinationOutput destination
timeupdateIntervalnumber250Interval for progress events in ms
workerPoolSizenumber-Number of WSOLA worker threads

StretcherEngine Methods

Playback Control

start(): void;
pause(): void;
resume(): void;
seek(position: number): void;
stop(): void;

Configuration

setTempo(tempo: number): void;

Change the time-stretch ratio during playback.

engine.setTempo(1.5); // Speed up to 1.5x

State

getCurrentPosition(): number;
getStatus(): StretcherStatus;
getSnapshot(): PlaybackSnapshot;

Events

on(event: string, handler: Function): () => void;
off(event: string, handler: Function): void;

Cleanup

dispose(): void;

Stop playback, terminate workers, and release all resources.

Events

EventDescription
progressPosition updated
bufferhealthBuffer health status changed
bufferingWorker buffer underrun, audio may stutter
bufferedBuffer recovered from underrun
chunkreadyA new chunk has been processed
completeAll chunks have been processed
endedPlayback reached the end
errorAn error occurred in a worker

StretcherStatus

interface StretcherStatus {
phase: string;
conversion: { ... };
buffer: { ... };
playback: { ... };
}

Detailed status object containing information about the engine’s internal state, including conversion progress, buffer health, and playback position.

Usage via play()

The simplest way to use the stretcher is through the play() function with preservePitch: true:

import { play } from "waa-play/play";
const playback = play(ctx, buffer, {
playbackRate: 0.75,
preservePitch: true,
});
// Change speed while preserving pitch
playback.setPlaybackRate(1.5);