コンテンツにスキップ

Stretcher

WSOLA(Waveform Similarity Overlap-Add)time-stretch engine で、ピッチに影響を与えずに再生速度を変更します。Web Worker を使用してリアルタイム audio 処理を行います。

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

createStretcherEngine()

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

指定されたバッファに対して WSOLA time-stretch engine を作成します。

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;
}
オプションデフォルト説明
temponumber1Time-stretch 比率(0.5 = 半速、2 = 倍速)
offsetnumber0開始位置(秒)
loopbooleanfalseループ再生
throughAudioNode[][]経由する audio node
destinationAudioNodectx.destination出力先
timeupdateIntervalnumber250進捗イベントの間隔(ms)
workerPoolSizenumber-WSOLA worker スレッド数

StretcherEngine メソッド

再生制御

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

設定

setTempo(tempo: number): void;

再生中に time-stretch 比率を変更します。

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

状態

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

イベント

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

クリーンアップ

dispose(): void;

再生を停止し、worker を終了し、すべてのリソースを解放します。

イベント

イベント説明
progressポジション更新
bufferhealthBuffer health の状態が変化
bufferingWorker buffer underrun、音声が途切れる可能性あり
bufferedUnderrun から回復
chunkready新しいチャンクの処理が完了
completeすべてのチャンクの処理が完了
ended再生が終端に到達
errorワーカーでエラーが発生

StretcherStatus

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

エンジンの内部状態(変換進捗、buffer health、再生位置)に関する詳細な status オブジェクト。

play() 経由の使用

Stretcher を使用する最も簡単な方法は、play() 関数に 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);