コンテンツにスキップ

関数 API

モジュールごとに整理された、tree-shake 可能な個別関数です。各関数は AudioContext を第一引数に取ります(BYO Context パターン)。

import { createContext } from "waa-play/context";
import { loadBuffer } from "waa-play/buffer";
import { play } from "waa-play/play";
const ctx = createContext();
const buffer = await loadBuffer(ctx, "/audio/track.mp3");
const playback = play(ctx, buffer);

play

コア再生エンジン。AudioBufferSourceNode をステートマシン、ポジショントラッキング、イベントシステムでラップします。

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

play()

play(ctx: AudioContext, buffer: AudioBuffer, options?: PlayOptions): Playback;

AudioBuffer を再生します。制御可能な Playback ハンドルを返します。

const playback = play(ctx, buffer, {
offset: 10,
loop: true,
playbackRate: 1.5,
through: [gain, filter],
});

PlayOptions

オプションデフォルト説明
offsetnumber0開始位置(秒)
loopbooleanfalseループを有効にする
loopStartnumber0ループ開始点(秒)
loopEndnumberdurationループ終了点(秒)
playbackRatenumber1再生速度倍率
throughAudioNode[][]経由する audio node(effect chain)
destinationAudioNodectx.destination出力先ノード
timeupdateIntervalnumber250timeupdate イベントの間隔(ms)
preservePitchbooleanfalse再生速度変更時に pitch を保持(Stretcher Engine を使用)

Playback メソッド

// State
getState(): PlaybackState; // "playing" | "paused" | "stopped"
getCurrentTime(): number;
getDuration(): number;
getProgress(): number; // [0, 1]
// Control
pause(): void;
resume(): void;
togglePlayPause(): void;
seek(position: number): void;
stop(): void;
// Configuration
setPlaybackRate(rate: number): void;
setLoop(loop: boolean): void;
// Events
on(event: string, handler: Function): () => void; // Returns unsubscribe
off(event: string, handler: Function): void;
// Cleanup
dispose(): void;

Playback イベント

イベントペイロード説明
play-再生開始
pause-一時停止
resume-一時停止から再開
seeknumber指定位置にシーク(秒)
stop-再生停止
ended-自然に終了
loop-先頭にループ
statechangePlaybackState状態が変化
timeupdatenumberポジション更新(timeupdateInterval 間隔で発火)
buffering-Stretcher Engine が buffering 中
buffered-Stretcher Engine の buffering 完了

PlaybackSnapshot

interface PlaybackSnapshot {
state: PlaybackState;
position: number;
duration: number;
progress: number;
stretcher?: StretcherSnapshotExtension;
}

context

AudioContext ライフサイクルユーティリティ。

import { createContext, resumeContext, ensureRunning, now } from "waa-play/context";

createContext()

createContext(options?: { sampleRate?: number; latencyHint?: AudioContextLatencyCategory | number }): AudioContext;

resumeContext()

resumeContext(ctx: AudioContext): Promise<void>;

一時停止中の AudioContext を再開します。ユーザージェスチャーハンドラから呼び出してください。

ensureRunning()

ensureRunning(ctx: AudioContext): Promise<void>;

AudioContext が "running" 状態であることを保証します。複数回呼び出しても安全です。

now()

now(ctx: AudioContext): number;

ctx.currentTime のショートハンド。


buffer

音声ファイルの読み込みとデコード。

import { loadBuffer, loadBufferFromBlob, loadBuffers, getBufferInfo } from "waa-play/buffer";

loadBuffer()

loadBuffer(ctx: AudioContext, url: string, options?: { onProgress?: (progress: number) => void }): Promise<AudioBuffer>;

音声ファイルを取得してデコードします。onProgress(0–1)で進捗をトラッキングできます。

loadBufferFromBlob()

loadBufferFromBlob(ctx: AudioContext, blob: Blob): Promise<AudioBuffer>;

Blob または File から AudioBuffer をデコードします。

loadBuffers()

loadBuffers(ctx: AudioContext, map: Record<string, string>): Promise<Map<string, AudioBuffer>>;

キーと URL のマップから複数の音声ファイルを並行して読み込みます。

getBufferInfo()

getBufferInfo(buffer: AudioBuffer): { duration: number; numberOfChannels: number; sampleRate: number; length: number };

nodes

Audio node ファクトリとルーティングユーティリティ。

import { createGain, rampGain, createAnalyser, createFilter, createPanner, createCompressor, chain, disconnectChain } from "waa-play/nodes";

ノードファクトリ

createGain(ctx: AudioContext, initialValue?: number): GainNode;
createAnalyser(ctx: AudioContext, options?: { fftSize?: number; smoothingTimeConstant?: number }): AnalyserNode;
createFilter(ctx: AudioContext, options?: { type?: BiquadFilterType; frequency?: number; Q?: number; gain?: number }): BiquadFilterNode;
createPanner(ctx: AudioContext, pan?: number): StereoPannerNode;
createCompressor(ctx: AudioContext, options?: { threshold?: number; knee?: number; ratio?: number; attack?: number; release?: number }): DynamicsCompressorNode;

ユーティリティ

rampGain(gain: GainNode, target: number, duration: number): void;
getFrequencyData(analyser: AnalyserNode): Float32Array;
getFrequencyDataByte(analyser: AnalyserNode): Uint8Array;

ルーティング

chain(...nodes: AudioNode[]): void; // ノードを直列に接続
disconnectChain(...nodes: AudioNode[]): void; // チェーン接続を切断

emitter

最小限の型安全イベントエミッター。

import { createEmitter } from "waa-play/emitter";

createEmitter()

createEmitter<Events extends Record<string, unknown>>(): Emitter<Events>;
type MyEvents = { progress: number; complete: void };
const emitter = createEmitter<MyEvents>();
emitter.on("progress", (v) => console.log(v)); // Returns unsubscribe fn
emitter.emit("progress", 0.5);
emitter.clear(); // Remove all handlers

Emitter メソッド

on<K>(event: K, handler: (data: Events[K]) => void): () => void;
off<K>(event: K, handler: (data: Events[K]) => void): void;
emit<K>(event: K, data: Events[K]): void;
clear(event?: keyof Events): void;

waveform

AudioBuffer からビジュアル波形データを抽出。

import { extractPeaks, extractPeakPairs, extractRMS } from "waa-play/waveform";

関数

extractPeaks(buffer: AudioBuffer, options?: ExtractPeaksOptions): number[];
extractPeakPairs(buffer: AudioBuffer, options?: ExtractPeaksOptions): PeakPair[];
extractRMS(buffer: AudioBuffer, options?: ExtractPeaksOptions): number[];

オプション

オプションデフォルト説明
resolutionnumber200抽出するデータポイント数
channelnumber0チャンネルインデックス(-1 で全チャンネル)

PeakPair{ min: number; max: number } です。


fade

GainNode オートメーションによるフェードイン/アウトとクロスフェードユーティリティ。

import { fadeIn, fadeOut, crossfade, autoFade } from "waa-play/fade";

関数

fadeIn(gain: GainNode, target: number, options?: FadeOptions): void;
fadeOut(gain: GainNode, options?: FadeOptions): void;
crossfade(gainA: GainNode, gainB: GainNode, options?: CrossfadeOptions): void;
autoFade(playback: Playback, gain: GainNode, options?: AutoFadeOptions): () => void;

autoFade は開始時にフェードイン、終了前にフェードアウトを適用します。クリーンアップ関数を返します。

オプション

オプションデフォルト説明
durationnumber1フェード時間(秒)
curveFadeCurve"linear""linear" | "exponential" | "equal-power"

AutoFadeOptionsduration の代わりに fadeIn / fadeOut(秒)を使用します。


scheduler

先読みベースのイベントスケジューラと BPM クロック。

import { createScheduler, createClock } from "waa-play/scheduler";

createScheduler()

createScheduler(ctx: AudioContext, options?: { lookahead?: number; interval?: number }): Scheduler;
オプションデフォルト説明
lookaheadnumber0.1先読み時間(秒)
intervalnumber25タイマー間隔(ms)

Scheduler メソッド: schedule(id, time, callback), cancel(id), start(), stop(), dispose().

createClock()

createClock(ctx: AudioContext, options?: { bpm?: number }): Clock;

BPM ベースのクロック。デフォルト 120 BPM。

Clock メソッド: beatToTime(beat), getCurrentBeat(), getNextBeatTime(), setBpm(bpm), getBpm().


synth

合成 audio buffer を生成。

import { createSineBuffer, createNoiseBuffer, createClickBuffer } from "waa-play/synth";
createSineBuffer(ctx: AudioContext, frequency: number, duration: number): AudioBuffer;
createNoiseBuffer(ctx: AudioContext, duration: number): AudioBuffer;
createClickBuffer(ctx: AudioContext, frequency: number, duration: number): AudioBuffer;

adapters

Framework 統合ユーティリティ。React の useSyncExternalStore と互換性があります。

import { getSnapshot, subscribeSnapshot, onFrame, whenEnded, whenPosition } from "waa-play/adapters";

関数

getSnapshot(playback: Playback): PlaybackSnapshot;
subscribeSnapshot(playback: Playback, callback: (snap: PlaybackSnapshot) => void): () => void;
onFrame(playback: Playback, callback: (snap: PlaybackSnapshot) => void): () => void;
whenEnded(playback: Playback): Promise<void>;
whenPosition(playback: Playback, position: number): Promise<void>;

React の例

import { useSyncExternalStore, useCallback } from "react";
import { getSnapshot, subscribeSnapshot } from "waa-play/adapters";
function usePlayback(playback: Playback) {
const subscribe = useCallback(
(cb: () => void) => subscribeSnapshot(playback, cb),
[playback],
);
const snap = useCallback(
() => getSnapshot(playback),
[playback],
);
return useSyncExternalStore(subscribe, snap, snap);
}