Skip to content

JavaScript/TypeScript API リファレンス

libsonare JavaScript/TypeScript パッケージの API リファレンス。

概要

libsonare は Web アプリケーション向けのオーディオ解析、マスタリング、ミキシング、編集 DSP を提供します。npm パッケージは WebAssembly ビルドです。実際の呼び出しでは、多くの関数がデコード済みの Float32Array PCM を受け取ります。PCM とは、MP3 や WAV などのファイルを展開した後の生のサンプル値です。読み込み用途には Audio.fromMemory* ファクトリがあり、エンコード済みバイト列をメモリ内でデコードできます(WAV/MP3 はネイティブ WASM デコーダ、AAC/OGG/FLAC は任意のブラウザデコーダ)。

最初のブラウザ実装では、手順を絞ると迷いにくくなります。

  1. アプリ起動時に await init() を 1 回呼ぶ。
  2. ユーザーのファイルをサンプルへデコードし、元の sampleRate を保持する。
  3. まず detectBpm(samples, sampleRate) のような小さな関数を 1 つ呼ぶ。
  4. その後で analyze、マスタリング、ミキシング、ストリーミング API へ進む。
カテゴリ関数ユースケース
クイック解析detectBpm, detectKey, detectBeatsDJアプリ、音楽プレイヤー、ビート同期
総合解析analyze, analyzeWithProgress音楽制作、楽曲メタデータ
オーディオエフェクトhpss, timeStretch, pitchShift, spectralEditリミックス、練習ツール、領域補修
特徴量melSpectrogram, chroma, mfccML 入力、可視化
マスタリングmasterAudio, masteringChain, StreamingMasteringChainLUFS(Loudness Units relative to Full Scale)ターゲット、True Peak リミッター、プリセット、ストリーミングチェーン
ミキシングmixStereo, Mixer, mixingScenePresetNamesステムミックス、ルーティング、オートメーション、メーター
編集 DSPpitchCorrectToMidi, noteStretch, spectralEdit, voiceChange, StreamingRetune, RealtimeVoiceChangerボーカル補正、ノート編集、ピッチ/フォルマント変更
Audio クラスAudio.fromBuffer, Audio.fromMemory, Audio.fromMemoryWithBrowserFallbackファイル読み込みと、よく使う関数をメソッド形式で呼ぶための補助

用語について

オーディオ解析が初めてですか?用語集 で BPM、STFT、Chroma などの用語の説明をご覧ください。

多くの関数はファイルパスではなくデコード済み PCM を受け取ります

ブラウザ版の多くの関数は、MP3 や WAV のパスではなく、デコード済みの PCM サンプルと sampleRate を受け取ります。エンコード済みバイト列からサンプルへ変換するには、Web Audio API(AudioContext.decodeAudioData)で自分でデコードするか、後述の Audio.fromMemory / Audio.fromMemoryWithBrowserFallback ファクトリを使います。これらはエンコード済みバイト列をメモリ内でデコードします。WAV/MP3 は同梱 WASM デコーダを使い、AAC/OGG/FLAC は必要に応じてブラウザ側デコードを使います。

バインディングごとの機能対応は 機能マップ を参照してください。マスタリングプロセッサの登録一覧とミキシングシーン形式は、マスタリングプロセッサミキシングシーン JSON にまとめています。

このリファレンスの読み方

このページは 3 段階で読むと迷いにくくなります。

  1. まず 目的から API を選ぶ で、使う関数ファミリーを 1 つ選ぶ。
  2. そのファミリーの節だけを読み、使用例 から近いレシピを 1 つ動かす。
  3. 戻り値の正確な形、オプション引数、実行環境間の違いが必要になったら、型定義や詳細表に戻る。

ブラウザアプリでは、await init() で WASM を初期化し、ファイルを先に PCM へデコードし、Float32Array サンプルと元の sampleRate を渡す、という基本を常に守ってください。

単発 API のリクエストオブジェクト

トップレベルの単発解析・エフェクト・マスタリング・メータリング・特徴量・ミキサー・ボイスチェンジャー API は、名前付きのリクエストオブジェクトを標準形式として使います。すべての入力が名前で分かり、引数順を崩さず任意設定を増やせ、TypeScript の *Request 型も利用できます。位置引数形式は互換オーバーロードであり、既定値、検証、エラー、結果、進捗コールバックは同じです。

typescript
// 推奨: リクエストオブジェクト形式
const bpm = detectBpm({ samples, sampleRate });
const mastered = masterAudio({
  samples,
  sampleRate,
  preset: 'pop',
  overrides: { loudness: { targetLufs: -14 } },
  onProgress: (progress, stage) => console.log(stage, progress),
});

// 既存コード向けの位置引数形式も利用可能
const legacyBpm = detectBpm(samples, sampleRate);

リクエストのフィールド名は Node と WASM で同じ camelCase です。Python は JavaScript 形式の options object ではなく、従来どおりキーワード引数(detect_bpm(samples, sample_rate=...))を使います。

長い処理をキャンセルする

進捗を報告するリクエストは cancel も受け取ります。これは onProgress が発火するのと 同じネイティブ境界でポーリングされる述語で、true を返すと呼び出しが中断されます。

typescript
import { ErrorCode, isSonareError, masterAudio } from '@libraz/libsonare';

let abandoned = false;
cancelButton.onclick = () => { abandoned = true; };

try {
  const mastered = masterAudio({
    samples,
    sampleRate,
    preset: 'pop',
    onProgress: (progress, stage) => updateUi(progress, stage),
    cancel: () => abandoned,
  });
} catch (error) {
  if (!(isSonareError(error) && error.code === ErrorCode.Cancelled)) throw error;
}

キャンセルされた呼び出しは SONARE_ERROR_CANCELLED(エラーコード 8)で例外になり、 出力を確保しません。途中結果を調べることはできません。Python も同じ述語を cancel= で受け取ります。

入力は変換されずに検証されます

Node と WASM は、以前なら黙って解釈し直していた値を拒否します。型の合わないリペア・ ダイナミクスのオプション、未知のトラック種別・キャプチャソース・ピッチ補正モード、 負のスペクトラム設定、宣言されていない enum の綴りや序数、数値でも真偽値でもない マスタリングのオーバーライド値などです。インスタンスメソッドも destroy() 後は解放済み ハンドルに触れずに例外を投げます。以前は意外なデフォルト値になっていた箇所で、 呼び出し地点に SonareError が返るようになります。

目的から API を選ぶ

関数数が多いため、まず「何を作りたいか」から最小の API を選ぶのが近道です。

やりたいこと最初に使う API理由
トラックのテンポ、キー、ビートだけ欲しいdetectBpm, detectKey, detectBeatsanalyze(...) 全体を走らせず、必要な値だけを直接得られます
曲全体のメタデータが欲しいanalyze または個別の analyze* ヘルパーanalyze は概要、個別ヘルパーは詳細向きです
ライブビジュアライザや更新されていく BPM/キー/コード UIStreamAnalyzer小さな音声ブロックを処理し、UI が最新フレームを読み出せます
ブラウザでマスタリングや配信プレビューmasterAudio*, masteringChain*, StreamingMasteringChainまずプリセット、必要に応じて名前付きプロセッサへ進めます
ステムのバランス、センド、バス、メーターmixStereo または Mixerまず一括レンダー、ルーティングが必要ならシーンミキサーを使います
ボーカル、ノート、スペクトル領域を編集したいpitchCorrectToMidi, noteStretch, spectralEdit, voiceChange, StreamingRetune, RealtimeVoiceChanger解析ではなく音そのものを変える API です
部屋の残響、明瞭度、等価ルーム推定、ルーム生成を扱いたいanalyzeImpulseResponse, detectAcoustic, estimateRoom, synthesizeRir, roomMorph楽曲ではなく録音空間を説明・適用します

インストール

bash
npm install @libraz/libsonare
bash
yarn add @libraz/libsonare
bash
pnpm add @libraz/libsonare

インポート

typescript
import {
  init,
  Audio,
  detectBpm,
  detectKey,
  detectBeats,
  detectOnsets,
  analyze,
  analyzeWithProgress,
  version
} from '@libraz/libsonare';

初期化

init(options?)

WASM モジュールを初期化します。解析関数を使用する前に呼び出す必要があります。

typescript
async function init(options?: {
  locateFile?: (path: string, prefix: string) => string;
}): Promise<void>

例:

typescript
import { init, detectBpm } from '@libraz/libsonare';

// 基本的な初期化
await init();

// カスタムファイルロケーション
await init({
  locateFile: (path, prefix) => `/custom/wasm/path/${path}`
});

isInitialized()

モジュールが初期化済みかどうかを確認します。

typescript
function isInitialized(): boolean

version()

ライブラリのバージョンを取得します。

typescript
function version(): string  // 例: "1.7.2"

capabilities()

実際に読み込まれているビルドの内容を返します。CLI が doctor で表示するのと同じレポートです。 同期関数で、init() の後にのみ有効です。

typescript
function capabilities(): {
  version: string;
  abi: { project: number; engine: number };
  platform: string;
  features: { mastering: boolean; mixing: boolean; fx: boolean; ffmpeg: boolean };
  decode: { builtin: string[]; ffmpeg: string[] };
  simd: string;
  hardwareConcurrency: number;
}

推測せず features で分岐してください。mixing を持たないビルドには Mixer がありません。 また decode.builtin を見れば、ブラウザ側のフォールバックを試す前に、そのモジュールが どの形式を開けるか分かります。

capabilityCatalog()

各プロセッサ、そのパラメータ記述子、組み込みプリセット一覧を、機械可読なカタログとして 返します。C ABI が公開し Python が capability_catalog として公開しているのと同じ正規 JSON で、schemas/capability-catalog.schema.json で検証されます。

min / max / default は常に null

レジストリは範囲を公開する汎用インターフェースを持たないため、推測値を入れる代わりに すべてのパラメータで minmaxdefaultnull として返します。このカタログは 「そのビルドがどのプロセッサ/パラメータを公開しているか」「型・単位・リアルタイム安全性」 を知るためのもので、スライダーの範囲決めには使えません。値の範囲は各プロセッサの リファレンスページを参照してください。

typescript
function capabilityCatalog(): {
  version: string;
  abi: { project: number; engine: number };
  processors: Array<{
    id: string;
    kind: 'realtime' | 'offline' | 'pair';
    realtimeInsertable: boolean;
    stereoOnly: boolean;
    latencySamples: number;
    tailSamples: number;
    /** リアルタイム処理コストの目安。インサート不可のプロセッサでは必ず null */
    realtimeCost: 'low' | 'moderate' | 'high' | null;
    channelPolicy: 'multichannel' | 'stereoPairOnly' | 'perChannel' | 'passthrough';
    category: string;
    params: Array<{
      name: string;
      id: number;
      rtSafe: boolean;
      type: 'boolean' | 'number';
      min: number | null;
      max: number | null;
      default: boolean | number | null;
      unit: string | null;
    }>;
  }>;
  presets: {
    mastering: string[];
    synth: string[];
    mixingScene: string[];
    voiceChanger: string[];
  };
}

汎用のパラメータ UI はこれを基に作れます。各スライダーの範囲と既定値は、手で管理する表では なくカタログから得られます。コアが把握していない範囲は明示的な null で報告されるので、 0 ではなく「上限・下限なし/不明」として扱ってください。

abiVersion()

C POD 公開 API 全体を集約したネイティブ ABI バージョンを返します。ビルド済みバイナリを読み込む際に保存・比較しておくと、互換性のない JS/ネイティブ成果物の組み合わせを早期に検出できます。

typescript
function abiVersion(): number

projectAbiVersion()

Project のシリアライズ、バウンス、リアルタイムエンジンのクリップ交換で使う project/editing POD 公開 API の ABI バージョンを返します。

typescript
function projectAbiVersion(): number

voiceChangerAbiVersion()

ネイティブ/FFI の公開 API が使う、リアルタイムボイスチェンジャーの POD 設定 ABI バージョンを返します。これはプリセット JSON の schemaVersion とは別物です。プリセット JSON は現在 1 で、ユーザー作成プリセットを受け入れる前に validateRealtimeVoiceChangerPresetJson(...) で検証してください。

typescript
function voiceChangerAbiVersion(): number

ボイスプリセットアクセサ

プリセット JSON を解析せずに、正規の voice-character プリセット ID や解決済みのフラットな POD 設定が必要なときに使います。

typescript
function voiceCharacterPresetId(preset: VoicePresetId | number): VoicePresetId | null
function realtimeVoiceChangerPresetConfig(preset: VoicePresetId | number): RealtimeVoiceChangerPodConfig

voiceCharacterPresetId(...) は未知の数値序数で null を返します。未知の文字列 ID は例外になります。 realtimeVoiceChangerPresetConfig(...) は解決済み POD 設定を返す必要があるため、無効な序数や未知の ID で例外になります。

解決済みの RealtimeVoiceChangerPodConfig は両 JavaScript 公開 API で camelCase キー(inputGainDbwetMixformantFactorlimiterIspCeilingDbtp など)を使います。対応する C / Python の POD フィールドは snake_case のままです。

リアルタイム環境ヘルパー

これらは RealtimeEngine が使う実行環境の公開範囲を確認するためのヘルパーです。AudioWorklet / SharedArrayBuffer 経路を接続する前に、ページの分離ポリシーやブラウザ差分を確認できます。

typescript
function engineAbiVersion(): number
function engineCapabilities(): {
  engineAbiVersion: number;
  expectedEngineAbiVersion: number;
  abiCompatible: boolean;
  sharedArrayBuffer: boolean;
  atomics: boolean;
  audioWorklet: boolean;
  mode: 'sab' | 'postMessage';
}
function hasFfmpegSupport(): boolean

hasFfmpegSupport() は、読み込まれたビルドが FFmpeg 経由のデコードに対応しているかを返します。ブラウザ向け WASM npm パッケージはデコード済み PCM を扱うため通常 false で、ファイルの直接デコードは Python/native ビルド側で行います。

解析関数

detectBpm(samples, sampleRate)

オーディオサンプルから BPM (テンポ) を検出します。

ユースケース

  • DJ ソフトウェア: トラック間のテンポをマッチングしてシームレスなミキシング
  • 音楽プレイヤー: テンポ情報の表示、テンポ別プレイリストの自動生成
  • フィットネスアプリ: ワークアウト強度に合わせた音楽選択
  • ビート同期: ビジュアライゼーションやアニメーションを音楽に同期
typescript
function detectBpm(samples: Float32Array, sampleRate?: number): number
パラメータ説明
samplesFloat32Arrayモノラルオーディオサンプル (範囲 -1.0 〜 1.0)
sampleRate?numberサンプルレート (Hz)(デフォルト: 22050。例: 44100)

実際のサンプルレートを必ず渡す

ここでは sampleRate は任意(既定は 22050 Hz)ですが、ブラウザでデコードした音声はほぼ常に 44100 または 48000 Hz です。バッファの実際の audioBuffer.sampleRate を渡してください。さもないと検出される BPM が狂います。同じことは detectKeydetectBeatsanalyze にも当てはまります。これらも sampleRate は任意で既定は同じ 22050 Hz なので、実際のレートを渡してください。

戻り値: 検出された BPM の数値。

typescript
const bpm = detectBpm(samples, sampleRate);
console.log(`BPM: ${bpm}`);

detectKey(samples, sampleRate)

オーディオサンプルから音楽キーを検出します。ルート音(C, D, E...)とモード(メジャー/マイナー)を返します。

ユースケース

  • ハーモニックミキシング: DJがスムーズなトランジションのためにキーをマッチング(カメロットホイール)
  • 移調: ボーカルレンジに合わせたキー変更の提案
  • 音楽レコメンデーション: 互換性のあるキーの曲を検索
  • 練習ツール: ミュージシャンが一緒に演奏するためのキー表示
typescript
function detectKey(samples: Float32Array, sampleRate?: number): Key  // sampleRate 既定: 22050

戻り値: Key オブジェクト

typescript
interface Key {
  root: PitchClass;      // 0-11 (C=0, B=11)
  mode: Mode;            // Major、Minor、またはモード値。Mode enum 参照
  confidence: number;    // 0.0 〜 1.0
  name: string;          // "C major", "A minor"
  shortName: string;     // "C", "Am"
}

const KeyProfile = {
  KrumhanslSchmuckler: 0,
  Temperley: 1,
  Shaath: 2,
  FaraldoEDMT: 3,
  FaraldoEDMA: 4,
  FaraldoEDMM: 5,
  BellmanBudge: 6,
} as const;
typescript
const key = detectKey(samples, sampleRate);
console.log(`キー: ${key.name}`);
console.log(`信頼度: ${(key.confidence * 100).toFixed(1)}%`);

detectBeats(samples, sampleRate)

オーディオサンプルからビート時刻を検出します。各ビートの推定タイムスタンプを返します。

ユースケース

  • 音楽ビジュアライゼーション: 各ビートでエフェクトをトリガー
  • リズムゲーム: オーディオからノートチャートを生成
  • 動画編集: ビートに合わせた自動カット
  • ループ作成: 完璧なループポイントを見つける
typescript
function detectBeats(samples: Float32Array, sampleRate?: number): Float32Array  // sampleRate 既定: 22050

戻り値: 秒単位のビート時刻の Float32Array

typescript
const beats = detectBeats(samples, sampleRate);
console.log(`${beats.length} 個のビートを検出`);
for (let i = 0; i < beats.length; i++) {
  console.log(`ビート ${i + 1}: ${beats[i].toFixed(3)}秒`);
}

detectOnsets(samples, sampleRate)

オーディオサンプルからオンセット時刻(音の立ち上がり)を検出します。ビートより細かい粒度 - すべての音をキャプチャ。

ユースケース

  • ドラム採譜: 個々のドラムヒットを検出
  • オーディオからMIDI: オーディオをノートイベントに変換
  • サンプルスライシング: トランジェントで自動的にオーディオをセグメント化
typescript
function detectOnsets(samples: Float32Array, sampleRate?: number): Float32Array  // sampleRate 既定: 22050

analyze(samples, sampleRate) 高負荷

総合的な音楽解析を実行します。BPM、キー、ビート、コード、セクション、音色などを返します。

ユースケース

  • 音楽ライブラリ管理: 楽曲にメタデータを自動タグ付け
  • 音楽制作: リファレンストラックの解析
  • DJ準備: すべてのトラック情報を一度に取得
  • 音楽教育: 楽曲構造の学習

パフォーマンス

これは最も重い API です。長いオーディオファイル(3分以上)の場合は、analyzeWithProgress を使用して進捗を表示するか、関連するセグメントのみを解析することを検討してください。

typescript
function analyze(samples: Float32Array, sampleRate?: number): AnalysisResult  // sampleRate 既定: 22050

戻り値: 総合的な AnalysisResultanalyze() を 1 回呼ぶだけで、コード、セクション、音色、ダイナミクス、リズム、メロディ、楽曲形式、拍ごとの強度まで含む結果が、どのバインディングでも返ります。そのため、1 つのフィールドだけが欲しい場合を除き、個別のヘルパーを使う必要はほとんどありません。

typescript
const result = analyze(samples, sampleRate);
console.log(`BPM: ${result.bpm}`);
console.log(`キー: ${result.key.name}`);
console.log(`コード数: ${result.chords.length}`);
console.log(`楽曲形式: ${result.form}`);

analyzeWithProgress(samples, sampleRate, onProgress) 高負荷

進捗レポート付きで analyze(...) と同じ総合解析を実行します。

typescript
function analyzeWithProgress(
  samples: Float32Array,
  sampleRate: number | undefined,  // undefined なら 22050 の既定を使う
  onProgress: (progress: number, stage: string) => void
): AnalysisResult

sampleRate はコールバックより前の位置引数ですが undefined を受け付け、その場合は analyze と同じ 22050 Hz の既定値を使います。実際のレートを渡してください。

進捗ステージ:

ステージ説明進捗
"features"特徴量の事前計算0.0
"bpm"BPM 検出0.15
"key"キー検出0.15
"beats"ビートトラッキング0.25
"chords"コード認識0.40
"sections"セクション検出0.55
"timbre"音色解析0.70
"dynamics"ダイナミクス解析0.80
"rhythm"リズム解析0.90
"melody"メロディ解析0.95
"complete"完了1.0
typescript
const result = analyzeWithProgress(samples, sampleRate, (progress, stage) => {
  console.log(`${stage}: ${Math.round(progress * 100)}%`);
});

目的別の詳細解析ヘルパー

多くの場合は 1 回の呼び出しで十分

analyze() はコード、セクション、音色、ダイナミクス、リズム、メロディ、楽曲形式、拍ごとの強度まで返します。個別ヘルパーが必要になるのは、1 つのフィールドだけが欲しいときや、高レベル API では隠れている設定を渡したいときだけです。

analyze(...) が広すぎる、または逆に詳細が足りない場合は、個別の解析ヘルパーを使います。入力は同じくモノラルの Float32Array ですが、高レベル API では隠れている設定を渡せます。

目的関数補足
ダウンビート/小節頭detectDownbeats(samples, sampleRate)秒単位の小節頭候補。detectBeats と組み合わせるとグリッド表示に向きます。
キー候補の順位付き一覧detectKeyCandidates(samples, sampleRate, options?)トップ候補が曖昧な曲や、モード・プロファイルを絞りたい場合に使います。
詳細なテンポ候補analyzeBpm(samples, sampleRate, ...)最良 BPM だけでなく、候補とテンポ根拠を返します。
リズム傾向analyzeRhythm(samples, sampleRate, ...)グルーヴ、シンコペーション、規則性を見ます。
ダイナミクスanalyzeDynamics(samples, sampleRate, ...)ダイナミックレンジ、ラウドネスレンジ、クレストファクター、圧縮傾向を見ます。
音色analyzeTimbre(samples, sampleRate, ...)ブライトネス、ウォームス、密度、粗さ、複雑さを返します。
コードdetectChords(samples, sampleRate, options?)コード区間を { chords } として返します。HMM 平滑化、キー文脈、転回形、chromaMethod: 'stft' | 'nnls' を指定できます。
セクションanalyzeSections(samples, sampleRate, ...)イントロ、Aメロ、サビ、ブリッジ、アウトロなどの構造を推定します。長尺入力で内部の境界グリッドがプーリングされても、start / end は元タイムライン上の正確な秒数を保ちます。
メロディanalyzeMelody(samples, sampleRate, ...)ピッチ追跡ベースの単音メロディ輪郭です。
typescript
const keys = detectKeyCandidates(samples, sampleRate, {
  modes: [Mode.Major, Mode.Minor],
  profile: 'krumhansl',
  genreHint: 'pop',
});

const { chords } = detectChords(samples, sampleRate, {
  useHmm: true,
  useKeyContext: true,
  keyRoot: keys[0].key.root,
  keyMode: keys[0].key.mode,
  chromaMethod: 'nnls',
});

const sections = analyzeSections(samples, sampleRate);

chordFunctionalAnalysis(samples, keyRoot, keyMode, sampleRate?, options?)

指定したキーを基準に、検出されたコード進行を機能(ローマ数字)和声解析します。内部でコード検出を実行し、検出された各コードにラベルを付けるため、detectKey(...) から得た keyRootkeyMode と、detectChords(...) に渡すのと同じ options をそのまま渡します。

typescript
function chordFunctionalAnalysis(
  samples: Float32Array,
  keyRoot: PitchClass,
  keyMode?: Mode,
  sampleRate?: number,
  options?: ChordDetectionOptions,
): string[]   // 検出されたコードごとに 1 つのローマ数字ラベル。例: ["I", "IV", "V", "vi"]
typescript
const key = detectKey(samples, sampleRate);
const roman = chordFunctionalAnalysis(samples, key.root, key.mode, sampleRate);
console.log(roman);  // 例: ["I", "IV", "V", "vi"]

detectKey(...)detectKeyCandidates(...) は同じ KeyDetectionOptions を受け取ります。

グループ
制御項目modes, profile, genreHint, useHpss, loudnessWeighted, highPassHz
プロファイル名ks, krumhansl, temperley, shaath, keyfinder, faraldo-edmt / edmt, faraldo-edma / edma, faraldo-edmm / edmm, bellman-budge / bellman
ジャンルヒントauto, edm, electronic, dance, pop, classical, jazz

ルーム音響解析

これらの関数は、曲そのものではなく録音空間を説明・適用する API です。

目的使う API
きれいなインパルス応答(IR)を測るanalyzeImpulseResponse(...)
通常音声から部屋の減衰を推定するdetectAcoustic(...)
音声から実用的な部屋モデルを推定するestimateRoom(...)
寸法からモノラルのルームインパルス応答を作るsynthesizeRir(...)
目標ルームの響きを音作り効果として足すroomMorph(...)

RIR とルームモーフィング

RIR は room impulse response(ルームインパルス応答)の略で、部屋が短い音にどう反応するかを表すサンプル列です。roomMorph(...) は音作り効果であり、残響除去ではありません。

typescript
const ir = analyzeImpulseResponse(impulseResponseSamples, sampleRate, 6, 30);
console.log(ir.rt60, ir.edt, ir.c50, ir.c80, ir.confidence);

const blind = detectAcoustic(roomRecording, sampleRate, {
  nOctaveBands: 6,
  nThirdOctaveSubbands: 24,
  minDecayDb: 30,
  noiseFloorMarginDb: 10,
});
console.log(blind.isBlind, blind.rt60Bands);

const estimate = estimateRoom(roomRecording, sampleRate, {
  referenceAbsorption: 0.15,
  nOctaveBands: 6,
});
console.log(estimate.volume, estimate.length, estimate.width, estimate.height);
console.log(estimate.drrDb, estimate.confidence, estimate.absorptionBands);

const rir = synthesizeRir({ lengthM: 7, widthM: 5, heightM: 3, absorption: 0.2 });
console.log(rir.sampleRate, rir.rir.length, rir.hasError);

const morphed = roomMorph(samples, sampleRate, { lengthM: 12, widthM: 9, heightM: 4, wet: 0.6 });

analyzeImpulseResponse(samples, sampleRate?, nOctaveBands?, minDecayDb?)minDecayDb は減衰フィットのしきい値で、既定値は 30 です。

RT60、EDT、C50、C80、D50、バンド別配列、ルーム推定、生成 RIR、信頼度の読み方は ルーム音響解析 を参照してください。

オーディオエフェクト

hpss(samples, sampleRate, kernelHarmonic?, kernelPercussive?, nFft?, hopLength?, hardMask?) 高負荷

HPSS(Harmonic / Percussive Source Separation。倍音成分/打撃成分の分離)。音源を倍音成分(ボーカル、シンセなどの持続音)と打撃成分(ドラム、過渡音)に分離します。

ユースケース

  • リミックス: ドラムを分離または除去する
  • カラオケ: ボーカルを除去して伴奏だけを取り出す(倍音成分を使用)
  • 解析精度の向上: クリーンなコード検出のために倍音成分のみを使う
  • ドラム抽出: サンプリング用に打撃成分だけを取り出す
HPSS · FULL MIXIDLE
HPSS — 旋律と打楽器を分ける

スペクトログラムでは、持続する音程の音は横方向のすじを、打楽器の打点は縦方向のすじを描きます。HPSS はまさにそれを利用します。時間方向のメディアンフィルタは横(倍音成分)を、周波数方向のメディアンフィルタは縦(打撃成分)を残します。表示を切り替えると、Full は両方、Harmonic はすじ(和音とベース、打楽器なし)、Percussive は縦すじ(ドラム、旋律なし)になります。再生すると各レイヤーを単独で聴けます。先に分離しておくと、後段のビート追跡やピッチ追跡がきれいになることがよくあります。

レイヤー

パフォーマンス

HPSS は STFT(短時間フーリエ変換)とメディアンフィルター処理を必要とします。処理時間は音源の長さに比例します。

typescript
function hpss(
  samples: Float32Array,
  sampleRate?: number,        // デフォルト: 22050
  kernelHarmonic?: number,    // デフォルト: 31
  kernelPercussive?: number,   // デフォルト: 31
  nFft?: number,               // デフォルト: 2048
  hopLength?: number,          // デフォルト: 512
  hardMask?: boolean           // デフォルト: false
): HpssResult

interface HpssResult {
  harmonic: Float32Array;
  percussive: Float32Array;
  sampleRate: number;
}

hpssWithResidual(...) は同じカーネル、STFT、マスクのオプションを受け取り、 倍音/打撃のどちらにも分類されなかった残差成分も返します。

typescript
function hpssWithResidual(
  samples: Float32Array,
  sampleRate?: number,
  kernelHarmonic?: number,
  kernelPercussive?: number,
  nFft?: number,               // デフォルト: 2048
  hopLength?: number,          // デフォルト: 512
  hardMask?: boolean           // デフォルト: false
): HpssWithResidualResult

harmonic(samples, sampleRate) 高負荷

音源から倍音成分を抽出します。

typescript
function harmonic(samples: Float32Array, sampleRate?: number): Float32Array  // sampleRate 既定: 22050

percussive(samples, sampleRate) 高負荷

音源から打撃成分を抽出します。

typescript
function percussive(samples: Float32Array, sampleRate?: number): Float32Array  // sampleRate 既定: 22050

timeStretch(samples, sampleRate, rate, nFft?, hopLength?) 高負荷

ピッチを変えずにテンポを変更します。Rate < 1.0 = 遅く、> 1.0 = 速く。

ユースケース

  • 練習ツール: 難しいパッセージを学ぶために音楽をスローダウン
  • DJミキシング: トラック間のテンポをマッチング
  • ポッドキャスト編集: スピーチの速度調整
  • 音楽制作: サンプルをプロジェクトのテンポに合わせる
PARAM SWEEP · TIME STRETCHIDLE
タイムストレッチ — 音程はそのまま、長さを変える

タイムストレッチはピッチシフトのちょうど逆で、音程はそのままに、音の長さを変えます。レート(rate)をドラッグするとドラムの打点が広がったり詰まったりして波形がパネルを占める幅も変わりますが、下のスペクトルはほとんど動きません。1.0 より下では遅く長く、1.0 より上では速く短くなります。レンダーごとにピークを揃えているので、速いレートがそのまま小さく聞こえることはありません。聞こえるレベルを決めているのはデモ側で、ストレッチではありません。再生すると、チップマンク効果なしにグルーヴのテンポだけが変わるのが聴けます。

レート
1 ×

パフォーマンス

フェーズボコーダーアルゴリズムを使用。処理時間はオーディオの長さに比例します。

typescript
function timeStretch(
  samples: Float32Array,
  sampleRate: number,
  rate: number,      // 0.5 = 半速、2.0 = 倍速
  nFft?: number,     // デフォルト: 2048
  hopLength?: number // デフォルト: 512
): Float32Array

pitchShift(samples, sampleRate, semitones, nFft?, hopLength?) 高負荷

長さを変えずにピッチを変更します。半音単位で測定(+12 = 1オクターブ上)。

ユースケース

  • キーマッチング: ミキシング用に曲を移調
  • ボーカルチューニング: ボーカルピッチの補正や調整
  • クリエイティブエフェクト: ハーモニー作成、チップマンク/ディープボイスエフェクト
  • 楽器練習: 演奏しやすいキーに移調

パフォーマンス

タイムストレッチとリサンプリングを組み合わせます。処理時間はオーディオの長さに比例します。

typescript
function pitchShift(
  samples: Float32Array,
  sampleRate: number,
  semitones: number,   // +12 = 1オクターブ上
  nFft?: number,        // デフォルト: 2048
  hopLength?: number    // デフォルト: 512
): Float32Array

編集 DSP

これらの関数は解析だけでなく、信号そのものを変更します。Audio インスタンスメソッドとしても利用でき、その場合は保持している sampleRate が自動的に使われます。

typescript
function pitchCorrectToMidi(
  samples: Float32Array,
  sampleRate: number,
  currentMidi: number,
  targetMidi: number,
): Float32Array

// 追跡したピッチ輪郭を、フレーム単位で固定のターゲット音にリチューンします。
// f0Hz は hopLength に揃えたフレームごとの f0 トラック(例: pitchYin/pitchPyin の出力)です。
// 対応する voiced/voicedProb 配列を渡すと無声音フレームをスキップでき、
// 無声音または NaN のフレームはそのまま残ります。
function pitchCorrectToMidiTimevarying(
  samples: Float32Array,
  f0Hz: Float32Array,
  targetMidi: number,
  sampleRate: number,
  hopLength: number,
  voiced?: VoicedFlags,
  voicedProb?: Float32Array,
): Float32Array

// 追跡したピッチ輪郭を、音楽的なスケール(オートチューン)または固定音にスナップします。
// mode 'scale' は有声フレームを最も近いスケール構成音へ引き寄せ、
// mode 'midi'(既定)は pitchCorrectToMidiTimevarying と同じ挙動になります。
function pitchCorrectTimevarying(
  samples: Float32Array,
  f0Hz: Float32Array,       // hopLength に揃えたフレームごとの f0 トラック
  sampleRate?: number,      // 既定 22050
  hopLength?: number,       // 既定 512
  options?: PitchCorrectOptions,
): Float32Array

interface PitchCorrectOptions {
  mode?: 'midi' | 'scale';         // 既定 'midi'
  targetMidi?: number;             // 'midi' モードでの固定音。既定 69(A4)
  scaleRoot?: number;              // スケールのルートピッチクラス 0-11。既定 0(C)
  scaleModeMask?: number;          // 12 ビットの構成音マスク。既定 C メジャー
  referenceMidi?: number;          // スケールグリッドの基準。既定 69(A4)
  retuneAmount?: number;           // 0 = バイパス、1 = 完全スナップ。既定 1
  maxCorrectionSemitones?: number; // フレームごとのクランプ(セミトーン)。既定 12
  retuneSpeedMs?: number;          // グライドの時定数。既定 50
  vibratoThresholdCents?: number;  // これ未満の補正はバイパス。既定 20
  voiced?: VoicedFlags;            // フレームごとの有声フラグ(真値 / 非ゼロ = 有声)
  voicedProb?: Float32Array;       // フレームごとの有声確率 0-1
}

// フレームごとの有声判定。f0Hz のフレーム数と 1 対 1 で対応します。
type VoicedFlags =
  | Int32Array
  | Uint8Array
  | Float32Array
  | readonly number[]
  | readonly boolean[];

VoicedFlagsvoiced 引数と PitchCorrectOptions.voiced が受け付ける型です。解析側が返す形をそのまま含んでいるため、boolean[] である PitchResult.voicedFlag を変換なしでピッチ補正へ渡せます。

typescript
const pitch = pitchPyin(samples, sampleRate);
const tuned = pitchCorrectToMidiTimevarying(
  samples,
  pitch.f0,
  69,
  sampleRate,
  512,
  pitch.voicedFlag,   // boolean[] is accepted as-is
  pitch.voicedProb,
);

voicedvoicedProb は、どちらも f0Hz と同じ長さである必要があります。長さが食い違うと RangeError'pitchCorrectToMidiTimevarying: voiced length must match f0Hz length')を投げます。SonareError ではないため isSonareError では捕捉できません。

typescript
function noteStretch(
  samples: Float32Array,
  sampleRate: number,
  options?: {
    onsetSample?: number,    // ノートのオンセット位置(サンプル)
    offsetSample?: number,   // ノートのオフセット位置(サンプル)
    stretchRatio?: number,   // >1 で区間を長くし、<1 で短くする
  },
): Float32Array

// ノート区間の長さを変えずに、新しいオンセット位置へ移動する
// (長さは変えずオンセットを変えない noteStretch を補完する)。
function noteMove(
  samples: Float32Array,
  sampleRate?: number,
  options?: {
    onsetSample?: number,        // ノートのオンセット位置(サンプル)
    offsetSample?: number,       // ノートのオフセット位置(サンプル)。既定は入力の長さ
    targetOnsetSample?: number,  // 区間のオンセットの移動先
  },
): Float32Array

Audio.noteStretch(options?)Audio.noteMove(options?)Audio インスタンス上の対応メソッドです(サンプルレートはインスタンスの値を使用)。

typescript
function spectralEdit(
  samples: Float32Array,
  sampleRate: number,
  ops?: Array<{
    startSample?: number;
    endSample?: number;
    lowHz?: number;
    highHz?: number;
    gainDb?: number;
    mode?: 'gain' | 'attenuate' | 'mute' | 'heal';
  }>,
  options?: {
    nFft?: number;
    hopLength?: number;
    window?: 'hann' | 'hamming' | 'blackman' | 'rectangular';
    healRadiusFrames?: number;
  },
): Float32Array

function voiceChange(
  samples: Float32Array,
  sampleRate?: number,        // デフォルト: 22050
  options?: {
    pitchSemitones?: number,  // 負の値で下げる。既定 0
    formantFactor?: number,   // >1 で明るく、<1 で暗く。既定 1.0
  },
): Float32Array

対応する CLI 例:

bash
sonare pitch-correct vocal.wav --current-midi 68.7 --target-midi 69 -o corrected.wav
sonare note-stretch take.wav --onset 12000 --offset 24000 --ratio 1.25 -o held.wav
sonare voice-change vocal.wav --pitch-semitones 3 --formant-factor 1.05 -o voice.wav

pitchCorrectTimevarying(...) はスケールスナップ式オートチューンの経路です。スケールマスク、mode、リチューンの効き方の詳細は 編集 DSP を参照してください。領域指定の例とオプションの考え方は スペクトル編集 を参照してください。

normalize(samples, sampleRate, targetDb?, mode?)

オーディオを目標レベルに正規化します。mode の既定値は 'peak' で、 RMS レベルを目標にする場合は 'rms' を指定します。

typescript
function normalize(
  samples: Float32Array,
  sampleRate: number,
  targetDb?: number,        // デフォルト: 0.0 (フルスケール)
  mode?: 'peak' | 'rms'     // デフォルト: 'peak'
): Float32Array

trim(samples, sampleRate, thresholdDb?, frameLength?, hopLength?)

オーディオの始めと終わりから無音を除去します。

typescript
function trim(
  samples: Float32Array,
  sampleRate: number,
  thresholdDb?: number,   // デフォルト: -60.0
  frameLength?: number,   // デフォルト: 2048
  hopLength?: number      // デフォルト: 512
): Float32Array

これは Audio レベルの単純なしきい値トリムです。librosa 互換の フレーム RMS / topDb ベースの無音判定と、元音源上の開始・終了サンプル位置が 必要な場合は、下の trimSilence(...) を使います。

特徴抽出

stft(samples, sampleRate, nFft?, hopLength?) 中負荷

短時間フーリエ変換(STFT)を計算します。

typescript
function stft(
  samples: Float32Array,
  sampleRate?: number, // デフォルト: 22050
  nFft?: number,      // デフォルト: 2048
  hopLength?: number  // デフォルト: 512
): StftResult

interface StftResult {
  nBins: number;
  nFrames: number;
  nFft: number;
  hopLength: number;
  sampleRate: number;
  magnitude: Float32Array;
  power: Float32Array;
}

stftDb(samples, sampleRate, nFft?, hopLength?) 中負荷

STFT を計算し、dB スケールで返します。

typescript
function stftDb(
  samples: Float32Array,
  sampleRate?: number, // デフォルト: 22050
  nFft?: number,      // デフォルト: 2048
  hopLength?: number  // デフォルト: 512
): { nBins: number; nFrames: number; db: Float32Array }

melSpectrogram(samples, sampleRate, nFft?, hopLength?, nMels?) 中負荷

メルスペクトログラムを計算します。人間のピッチ知覚に合わせた周波数表現。

typescript
function melSpectrogram(
  samples: Float32Array,
  sampleRate?: number, // デフォルト: 22050
  nFft?: number,      // デフォルト: 2048
  hopLength?: number, // デフォルト: 512
  nMels?: number,     // デフォルト: 128
  fmin?: number,      // デフォルト: 0(librosa の既定)
  fmax?: number,      // デフォルト: 0 = sampleRate / 2
  htk?: boolean       // デフォルト: false = Slaney 式。true で HTK
): MelSpectrogramResult

interface MelSpectrogramResult {
  nMels: number;
  nFrames: number;
  sampleRate: number;
  hopLength: number;
  power: Float32Array;
  db: Float32Array;
}

mfcc(samples, sampleRate, nFft?, hopLength?, nMels?, nMfcc?) 中負荷

MFCC(メル周波数ケプストラム係数)を計算します。スペクトル包絡のコンパクトな表現。

typescript
function mfcc(
  samples: Float32Array,
  sampleRate?: number, // デフォルト: 22050
  nFft?: number,      // デフォルト: 2048
  hopLength?: number, // デフォルト: 512
  nMels?: number,     // デフォルト: 128
  nMfcc?: number,     // デフォルト: 20
  fmin?: number,      // デフォルト: 0(librosa の既定)
  fmax?: number,      // デフォルト: 0 = sampleRate / 2
  htk?: boolean,      // デフォルト: false = Slaney 式。true で HTK
  lifter?: number     // デフォルト: 0 = リフタリングなし
): MfccResult

interface MfccResult {
  nMfcc: number;
  nFrames: number;
  coefficients: Float32Array;
}

fminfmax で Mel 帯域の端を制限でき、htk: true で Slaney ではなく HTK の Mel 式を使います。lifter は librosa の lifter 引数に対応し、高次のケプストラム係数を弱めるケプストラム/正弦リフタリングを行います(0 でリフタリングなし)。逆変換ヘルパー(melToStftmelToAudiomfccToAudio)も対応する fminfmaxhtk 引数を取るため、両側で同じ値を保てば往復しても結果が一致します。

chroma(samples, sampleRate, nFft?, hopLength?) 中負荷

クロマグラム(ピッチクラス分布)を計算します。すべての周波数を12のピッチクラス(C, C#, D, ..., B)にマッピング。

CHROMA · PITCH CLASSIDLE
クロマグラム — ハーモニーを12ビンに畳む

すべての周波数を12のピッチクラスのどれかへ畳み込むため、オクターブは忘れられ、ハーモニーだけが残ります。このクリップは C–Am–F–G を循環します。コードが変わるたびに点灯する行が移るのを見て、再生して進行を追ってください。

typescript
function chroma(
  samples: Float32Array,
  sampleRate?: number, // デフォルト: 22050
  nFft?: number,      // デフォルト: 2048
  hopLength?: number  // デフォルト: 512
): ChromaResult

interface ChromaResult {
  nChroma: number;        // 12
  nFrames: number;
  sampleRate: number;
  hopLength: number;
  features: Float32Array;
  meanEnergy: number[];   // [12] ピッチクラスごと
}

スペクトル特徴

typescript
// スペクトル重心 (Hz)
function spectralCentroid(
  samples: Float32Array,
  sampleRate?: number,  // 既定: 22050
  nFft?: number,
  hopLength?: number
): Float32Array

// スペクトル帯域幅 (Hz)
function spectralBandwidth(
  samples: Float32Array,
  sampleRate?: number,  // 既定: 22050
  nFft?: number,
  hopLength?: number,
  p?: number             // ミンコフスキー指数、既定: 2
): Float32Array

// スペクトルロールオフ (Hz)
function spectralRolloff(
  samples: Float32Array,
  sampleRate?: number,  // 既定: 22050
  nFft?: number,
  hopLength?: number,
  rollPercent?: number  // 既定: 0.85
): Float32Array

// スペクトル平坦度 (0=調性的, 1=ノイズ的)
function spectralFlatness(
  samples: Float32Array,
  sampleRate?: number,  // 既定: 22050
  nFft?: number,
  hopLength?: number
): Float32Array

// スペクトルコントラスト行列、形状は (nBands + 1) x nFrames
function spectralContrast(
  samples: Float32Array,
  sampleRate?: number,
  nFft?: number,
  hopLength?: number,
  nBands?: number,
  fmin?: number,
  quantile?: number
): Matrix2dResult

// フレームごとの多項式スペクトル係数、形状は (order + 1) x nFrames
function polyFeatures(
  samples: Float32Array,
  sampleRate?: number,
  nFft?: number,
  hopLength?: number,
  order?: number
): Matrix2dResult

// ゼロ交差率
function zeroCrossingRate(
  samples: Float32Array,
  sampleRate?: number,  // 既定: 22050
  frameLength?: number,
  hopLength?: number
): Float32Array

// 波形がゼロを横切るサンプル位置
function zeroCrossings(
  samples: Float32Array,
  threshold?: number,
  refMagnitude?: boolean,
  pad?: boolean,
  zeroPos?: boolean
): Int32Array

// RMSエネルギー
function rmsEnergy(
  samples: Float32Array,
  sampleRate?: number,  // 既定: 22050
  frameLength?: number,
  hopLength?: number
): Float32Array

波形ピーク WASM/Node

チャンネルごとの min/max バケットで、全サンプル配列を UI に送らずに波形の概観を描けます。samplesPerBucket でバケット幅を指定し(既定 512)、waveformPeakPyramid はズームレベルごとに 1 つのレポートを返します。

typescript
function waveformPeaks(
  samples: Float32Array,   // channels > 1 のときはインターリーブ
  channels: number,
  options?: { samplesPerBucket?: number },  // 既定 512
): WaveformPeaksReport

function waveformPeakPyramid(
  samples: Float32Array,
  channels: number,
  options?: { samplesPerBucketLevels?: number[] },  // 既定 [512, 1024, 2048, 4096]
): WaveformPeaksReport[]

interface WaveformPeaksReport {
  min: Float32Array;        // チャンネルメジャー
  max: Float32Array;        // チャンネルメジャー
  channels: number;
  bucketCount: number;
  samplesPerBucket: number;
}

CQT / VQT / NNLS クロマ / 逆変換 / ラウドネス

これらは単なる追加特徴量ではなく、目的が違います。

目的使う API理由
音楽的なピッチ軸の表現cqt(...), pseudoCqt(...), hybridCqt(...)オクターブ方向に音高と対応しやすい Constant-Q 表現です。擬似/ハイブリッド版はビンごとの速度と精度のバランスを変えます。
帯域幅を調整したピッチ表現vqt(...)CQT に近く、低域の安定性を調整できます。
コード検出向けのクロマchromaCqt(...), nnlsChroma(...), chromaCens(...), bassChroma(...)Constant-Q、NNLS、CENS、低域寄りのクロマは、通常の STFT クロマよりコードや低音域の処理に向く場合があります。
スペクトル形状の詳細spectralContrast(...), polyFeatures(...), zeroCrossings(...), onsetStrengthMulti(...)librosa 互換のコントラスト帯域、多項式係数、ゼロ交差インデックス、マルチバンドオンセット強度を返します。
ピッチ/チューニングずれpitchTuning(...), estimateTuning(...)検出済み周波数または音声から、ビン単位のチューニングずれを推定します。
分解とリミックスdecompose(...), decomposeWithInit(...), nnFilter(...), remix(...), phaseVocoder(...), hpssWithResidual(...)NMF 分解、初期化方式を選べる NMF、近傍フィルタ、区間リミックス、時間スケーリング、残差付き HPSS。
特徴量や音声の近似復元melToStft, melToAudio, mfccToMel, mfccToAudio, cqtToAudio, vqtToAudio可視化、デバッグ、特徴量の往復確認に使います。CQT/VQT の入力は振幅行列です。
配信向けラウドネス測定lufs, lufsInterleaved, momentaryLufs, shortTermLufs, ebur128LoudnessRangeITU-R BS.1770 / EBU R128 系のラウドネス値。マルチチャンネル Integrated LUFS と LRA(ラウドネスレンジ。曲全体でラウドネスがどれだけ変動するか)も含みます。
typescript
const cqtResult = cqt(samples, sampleRate, 512, 32.7, 84, 12);
const vqtResult = vqt(samples, sampleRate, 512, 32.7, 84, 12, -1);
const pseudo = pseudoCqt(samples, sampleRate);
const hybrid = hybridCqt(samples, sampleRate);
const cqtChroma = chromaCqt(samples, sampleRate);
const nnls = nnlsChroma(samples, sampleRate, { hopLength: 512 });
const cens = chromaCens(samples, sampleRate);
const bass = bassChroma(samples, sampleRate);
const loudness = lufs(samples, sampleRate);

const contrast = spectralContrast(samples, sampleRate);
const poly = polyFeatures(samples, sampleRate);
const crossings = zeroCrossings(samples);
const onsetBands = onsetStrengthMulti(samples, sampleRate);
const tuning = estimateTuning(samples, sampleRate);
const offset = pitchTuning(pitch.f0);
const { w, h } = decompose(spectrogram, nFeatures, nFrames, 8);
const warmStarted = decomposeWithInit(spectrogram, nFeatures, nFrames, 8, 50, 2.0, 'nndsvd');
const filtered = nnFilter(spectrogram, nFeatures, nFrames);
const remixed = remix(samples, Int32Array.from([0, sampleRate, sampleRate, 2 * sampleRate]));
const stretched = phaseVocoder(samples, sampleRate, 1.5);
const hpssResidual = hpssWithResidual(samples, sampleRate);
const multichannel = lufsInterleaved(interleavedStereo, 2, sampleRate);
const lra = ebur128LoudnessRange(samples, sampleRate);
const reconstructed = melToAudio(mel.power, mel.nMels, mel.nFrames, sampleRate);
const cqtPreview = cqtToAudio(cqtResult.magnitude, cqtResult.nBins, cqtResult.nFrames, sampleRate, 512, 32.7, 12);
const vqtPreview = vqtToAudio(vqtResult.magnitude, vqtResult.nBins, vqtResult.nFrames, sampleRate, 512, 32.7, 12, 0, 32);

chromaCqt(samples, sampleRate?, hopLength?, nChroma?)librosa.feature.chroma_cqt に直接対応します(対数周波数/Constant-Q でのピッチ畳み込み)。一方 nnlsChroma(samples, sampleRate?, options?) は別物の音符活性化クロマで、NNLS(非負最小二乗法)で倍音の漏れを抑えます。コードや低音域の処理ではこちらの方がすっきりする場合が多いです。options.hopLength の既定値は 512 です。

ソースビルド C++ CLI で近いコマンド:

bash
sonare cqt song.wav
sonare vqt song.wav
sonare nnls-chroma song.wav
sonare lufs song.wav --json
sonare mel-to-audio song.wav -o mel-preview.wav

復元の制約とパラメータは 逆変換特徴量、librosa 互換の詳細は librosa 互換性 を参照してください。

ピッチ検出 中負荷

typescript
// YIN アルゴリズム
function pitchYin(
  samples: Float32Array,
  sampleRate?: number,   // デフォルト: 22050
  frameLength?: number,  // デフォルト: 2048
  hopLength?: number,    // デフォルト: 512
  fmin?: number,         // デフォルト: 65 Hz
  fmax?: number,         // デフォルト: 2093 Hz
  threshold?: number,    // デフォルト: 0.1
  fillNa?: boolean       // 互換性のために維持。YIN は常に有限の f0 を返す
): PitchResult

// pYIN アルゴリズム(確率的 YIN + HMM 平滑化)
function pitchPyin(
  samples: Float32Array,
  sampleRate?: number,   // デフォルト: 22050
  frameLength?: number,
  hopLength?: number,
  fmin?: number,
  fmax?: number,
  threshold?: number,
  fillNa?: boolean       // デフォルト: false。true なら無声音 f0 フレームを 0 にする
): PitchResult

interface PitchResult {
  f0: Float32Array;
  voicedProb: Float32Array;
  voicedFlag: boolean[];
  nFrames: number;
  medianF0: number;
  meanF0: number;
}

YIN は、voicedFlag が無声音と示すフレームも含め、すべてのフレームで有限の推定値を返します。

pYIN は既定では無声音の NaN を保持します。後段で 0 が必要な場合だけ fillNa: true を指定してください。

単位変換

これらの関数は軽量で高速です。

typescript
// Hz <-> Mel (Slaney 式)
function hzToMel(hz: number): number
function melToHz(mel: number): number

// Hz <-> MIDI ノート番号 (A4 = 440 Hz = 69)
function hzToMidi(hz: number): number
function midiToHz(midi: number): number

// Hz <-> ノート名
function hzToNote(hz: number): string      // "A4", "C#5"
function noteToHz(note: string): number

// 時間 <-> フレーム
function framesToTime(frames: number, sr: number, hopLength: number): number
function timeToFrames(time: number, sr: number, hopLength: number): number

// フレーム <-> サンプル (librosa.frames_to_samples / samples_to_frames 相当)
function framesToSamples(frames: number, hopLength?: number, nFft?: number): number
function samplesToFrames(samples: number, hopLength?: number, nFft?: number): number

// dB 変換(ベクトル)
function powerToDb(values: Float32Array, ref?: number, amin?: number, topDb?: number): Float32Array
function amplitudeToDb(values: Float32Array, ref?: number, amin?: number, topDb?: number): Float32Array
function dbToPower(values: Float32Array, ref?: number): Float32Array
function dbToAmplitude(values: Float32Array, ref?: number): Float32Array

メータリング

デコード済みバッファから、レベル、ダイナミクス、ステレオイメージの統計値を返す単体メーターです。マスタリングチェーンやストリーミングエンジンとは独立しています。

Float32Array、またはステレオの左右ペアを渡すと、値またはレポートが返ります。

各関数は、validate フラグ(既定 true)を持つ options を任意で受け取ります。ホットパスでは validate: false を指定して、JavaScript 側の O(n) の NaN/Inf 事前スキャンを省略できます。ただし非有限のサンプルをコアへ通すための手段ではありません。ネイティブ層が必ず再検証するため、NaN/Inf を含むバッファは変わらず例外になります(該当インデックスを示さない、汎用のネイティブメッセージになるだけです)。空バッファのチェックは常に実行されます。

単一チャンネルのレベルメーター

typescript
// サンプルピーク(dBFS)
function meteringPeakDb(samples: Float32Array, sampleRate?: number, options?: ValidateOptions): number
// RMS レベル(dBFS)
function meteringRmsDb(samples: Float32Array, sampleRate?: number, options?: ValidateOptions): number
// クレストファクター(ピーク − RMS、dB)
function meteringCrestFactorDb(samples: Float32Array, sampleRate?: number, options?: ValidateOptions): number
// 平均(DC)オフセット(リニア振幅)
function meteringDcOffset(samples: Float32Array, sampleRate?: number, options?: ValidateOptions): number
// サンプル間ピーク(ISP、いわゆる True Peak)を dBFS で返す。oversampleFactor は 1..16 の 2 の冪(0 / 省略で 4)
function meteringTruePeakDb(samples: Float32Array, sampleRate?: number, oversampleFactor?: number, options?: ValidateOptions): number
// thresholdDb 未満のフレームの割合、範囲 [0, 1]。thresholdDb 既定 -45、
// frameLength 既定 1024、hopLength 既定 256。
function meteringSilenceRatio(
  samples: Float32Array,
  sampleRate?: number,
  thresholdDb?: number,
  frameLength?: number,
  hopLength?: number,
  options?: ValidateOptions
): number

ステレオのレベルメーター

単一チャンネルのメーターが必要とする 0.5 * (left + right) のダウンミックスではなく、左右 2 チャンネルをそのまま読むレベルメーターです。上のメーターと違い、リクエストオブジェクト専用です。位置引数のオーバーロードはなく、位置引数で呼ぶと例外になります。

typescript
// Crest factor over a channel pair, dB. Peak is taken across both channels
// and RMS is measured over the two together.
function meteringCrestFactorDbStereo(request: MeteringStereoRequest): number

interface MeteringStereoRequest extends ValidateOptions {
  left: Float32Array;
  right: Float32Array;
  sampleRate?: number;
}
typescript
const crestDb = meteringCrestFactorDbStereo({ left, right, sampleRate });

左右が逆相になりうる素材では、こちらを使ってください。逆相のペアはダウンミックスで打ち消し合い、RMS が小さく出るぶんクレストファクターが過大に出ます。完全な逆相ペアでの実測値は、ステレオ版が 11.64 dB、ダウンミックス経由が 0.00 dB でした。

meteringStereoCorrelationmeteringStereoWidth も、位置引数形式に加えて同じ MeteringStereoRequest を受け付けます。

クリッピングとダイナミックレンジ

typescript
function meteringDetectClipping(
  samples: Float32Array,
  sampleRate?: number,
  options?: MeteringDetectClippingOptions
): ClippingReport

interface MeteringDetectClippingOptions extends ValidateOptions {
  threshold?: number;        // 線形絶対値のしきい値。既定: 0.999
  minRegionSamples?: number; // 報告する最小連続長。既定: 1
}

function meteringDynamicRange(
  samples: Float32Array,
  sampleRate?: number,
  options?: MeteringDynamicRangeOptions
): DynamicRangeReport

interface MeteringDynamicRangeOptions extends ValidateOptions {
  windowSec?: number;      // 0 / 省略で 3 秒
  hopSec?: number;         // 0 / 省略で 1 秒
  lowPercentile?: number;  // 省略または負値で 0.10(0 は文字どおり 0 パーセンタイル)
  highPercentile?: number; // 省略または負値で 0.95
}

interface ClippingReport {
  clippedSamples: number;
  clippingRatio: number;
  maxClippedPeak: number;
  regions: ClippingRegion[];
}
interface ClippingRegion {
  startSample: number;
  endSample: number;
  length: number;
  peak: number;
}
interface DynamicRangeReport {
  dynamicRangeDb: number;
  lowPercentileDb: number;
  highPercentileDb: number;
  windowRmsDb: Float32Array;
}

ステレオイメージ

typescript
// チャンネル間の非中心化相関(コサイン類似度、−1..1)
function meteringStereoCorrelation(left: Float32Array, right: Float32Array, sampleRate?: number, options?: ValidateOptions): number
// ミッド/サイドのステレオ幅: 0 = モノラル、約 1 = 広いステレオ。上限なし
// (完全な逆相などでミッド信号が無音なら Infinity)
function meteringStereoWidth(left: Float32Array, right: Float32Array, sampleRate?: number, options?: ValidateOptions): number
// Mid/side point series. One point per sample by default; pass maxPoints for a
// display-sized, deterministically decimated point set (0 / >= length = one point per sample).
function meteringVectorscope(left: Float32Array, right: Float32Array, sampleRate?: number, options?: ScopeOptions): VectorscopeReport
// Phase-scope point series plus summary stats. maxPoints decimates the point cloud the same way;
// the summary stats are always computed over the full-resolution signal.
function meteringPhaseScope(left: Float32Array, right: Float32Array, sampleRate?: number, options?: ScopeOptions): PhaseScopeReport

interface ScopeOptions extends ValidateOptions {
  maxPoints?: number;   // 0 / omit / >= length = one point per input sample
}

// Deprecated aliases: pass maxPoints to meteringVectorscope / meteringPhaseScope instead.
// They simply delegate and are kept for backward compatibility.
function meteringVectorscopeDecimated(left: Float32Array, right: Float32Array, sampleRate?: number, maxPoints?: number, options?: ValidateOptions): VectorscopeReport
function meteringPhaseScopeDecimated(left: Float32Array, right: Float32Array, sampleRate?: number, maxPoints?: number, options?: ValidateOptions): PhaseScopeReport

interface VectorscopeReport {
  mid: Float32Array;
  side: Float32Array;
}
interface PhaseScopeReport {
  mid: Float32Array;
  side: Float32Array;
  radius: Float32Array;
  angleRad: Float32Array;
  correlation: number;
  averageAbsAngleRad: number;
  maxRadius: number;
}

meteringStereoCorrelationmeteringStereoWidthmeteringVectorscopemeteringPhaseScopeleftright が同じ長さである必要があります。

meteringStereoWidth は正規化された百分率ではなく、サイド/ミッドのエネルギー比です。0 は完全なモノラル、約 1 は広いステレオ、より大きな有限値はデコリレーションまたは逆相成分が増えていることを表します。2 にクランプしてはいけません。ミッドチャンネルが無音なら、意図的に Infinity を返します。

スペクトラムスナップショット

meteringSpectrum は信号全体を Welch 平均したものです(50% オーバーラップの Hann フレームに分割し、各パワースペクトルを平均)。時間平均しないフレーム単独のスナップショットが必要な場合は meteringSpectrumFrame を使い、frameOffset 位置引数で解析フレームの開始位置を指定します。

typescript
function meteringSpectrum(
  samples: Float32Array,
  sampleRate?: number,
  options?: SpectrumOptions & ValidateOptions
): SpectrumReport

// フレーム単独の真のスナップショット(Hann 窓を掛けた nFft の FFT 1 回)。meteringSpectrum のように
// 時間平均しない。解析フレームは [frameOffset, frameOffset + nFft) を対象とし、末尾を超えた分はゼロ埋め。
function meteringSpectrumFrame(
  samples: Float32Array,
  sampleRate?: number,
  frameOffset?: number,
  options?: SpectrumOptions & ValidateOptions
): SpectrumReport

interface SpectrumOptions {
  nFft?: number;                 // 0 / 省略で 2048
  applyOctaveSmoothing?: boolean;
  octaveFraction?: number;       // 例: 3 = 1/3 オクターブ。0 / 省略で 3
  dbRef?: number;                // 0 / 省略で 1.0
  dbAmin?: number;               // 0 / 省略でライブラリの下限値
}
interface SpectrumReport {
  frequencies: Float32Array;
  magnitude: Float32Array;
  power: Float32Array;
  db: Float32Array;
  nFft: number;
  sampleRate: number;
}

スケール量子化

ピッチ補正のターゲットを構築するための 12-TET(12 平均律)スケールヘルパーです。

modeMask は 12 ビットのマスクで、ビット irootPitchClass、C = 0)を基準とした i 番目のピッチクラスを有効化します。自然な長調は 0b101010110101 です。

referenceMidi はチューニングの基準音です。A4 = 69 にするには 0 を渡します。

typescript
// (小数を含む)MIDI 番号を最も近い有効なピッチクラスにスナップ
function scaleQuantizeMidi(root: number, modeMask: number, midi: number, referenceMidi?: number): number
// 補正量(量子化後 − 入力)をセミトーンで返す
function scaleCorrectionSemitones(root: number, modeMask: number, midi: number, referenceMidi?: number): number
// pitchClass(0..11)が root を基準に modeMask で有効か
function scalePitchClassEnabled(root: number, modeMask: number, pitchClass: number): boolean

scaleQuantizeMidi(...)pitchCorrectToMidi(...) と組み合わせると、検出した音を最も近いスケール構成音へリチューンできます。

librosa 互換ヘルパー

librosa 互換ヘルパー群です。対応する librosa 関数に合わせており、WASM・Node・Python すべてのバインディングから利用できます。以下はシグネチャの一覧です。各ヘルパーが対応する librosa 関数(引数の対応関係)と使いどころは、librosa 互換性 を参照してください。

プリエンファシス/ディエンファシス

typescript
function preemphasis(samples: Float32Array, coef?: number, zi?: number): Float32Array  // coef 既定 0.97
function deemphasis(samples: Float32Array, coef?: number, zi?: number): Float32Array

zi はストリーミング処理で前ブロック末尾の値を受け渡すための初期条件です。

テスト信号の生成

フィクスチャ、キャリブレーション、クリックトラック向けの決定的な信号です。アセットファイルは要りません。

typescript
function tone(request?: ToneRequest): Float32Array
function chirp(request?: ChirpRequest): Float32Array
function clicks(request: ClicksRequest): Float32Array

スペクトルからの再構成とピッチ候補

typescript
function griffinLim(request: GriffinLimRequest): Float32Array
function reassignedSpectrogram(request: ReassignedSpectrogramRequest): ReassignedSpectrogramResult
function piptrack(request: PiptrackRequest): PiptrackResult
function melDelta(request: MelDeltaRequest): Float32Array
function spectralFlux(request: SpectralFrameRequest & { lag?: number }): Float32Array
function onsetBacktrack(request: OnsetBacktrackRequest): Int32Array

griffinLim は STFT の振幅行列から音声を再構成します。melToAudiomfccToAudio は その mel 領域ラッパーです。onsetBacktrack は検出したオンセットフレームを直前のエネルギー 極小点まで戻します。オンセット位置で音を切り出す前に通しておきたい処理です。

spectralBandwidth は Minkowski 指数 p を指定できます(位置引数では 5 番目、 リクエストオブジェクトでは p)。p = 2 固定ではありません。

構造と自己類似度

セグメンテーション系は、構造解析の土台になる行列を作ります。

typescript
function segmentCrossSimilarity(request: SegmentCrossSimilarityRequest): SegmentMatrix
function segmentRecurrenceMatrix(request: SegmentRecurrenceMatrixRequest): SegmentMatrix
function segmentRecurrenceToLag(request: SegmentRecurrenceToLagRequest): SegmentMatrix
function segmentLagToRecurrence(request: SegmentLagToRecurrenceRequest): SegmentMatrix
function segmentPathEnhance(request: SegmentPathEnhanceRequest): SegmentMatrix
function segmentSubsegment(request: SegmentSubsegmentRequest): Int32Array
function segmentAgglomerative(request: SegmentAgglomerativeRequest): Int32Array

「セクションはどこか」への既製の答えは analyzeSections(...) です。自己類似度プロットを 描きたい、あるいは強調済みの recurrence 行列に自前の境界検出をかけたい、といった理由で 中間行列そのものが欲しいときにこちらを使います。

ノートセグメンテーション

モノフォニックの F0 トラックを、安定したノート区間に切り分けます。すでに手元にある トラック(pitchYin / pitchPyin、あるいは自前のトラッカーの出力)を、それを生成した フレームレートと一緒に渡します。

typescript
interface NoteSegmentsRequest {
  f0Hz: Float32Array;
  voicedProb: Float32Array;
  /** 渡したトラックの 1 秒あたりフレーム数 */
  frameRate: number;
  segmentationThresholdCents?: number;
  minNoteMs?: number;
  referenceHz?: number;
}

function noteSegments(request: NoteSegmentsRequest): Array<{
  frameStart: number;
  frameEnd: number;
  startSeconds: number;
  endSeconds: number;
  medianCents: number;
}>

f0HzvoicedProb は長さが等しく、0 でない必要があります。0 Hz のフレームと 0.5 未満の確率は無声として扱われ、そこでノートが切れます。

無音トリム/無音分割

typescript
function trimSilence(
  samples: Float32Array,
  topDb?: number,        // 既定 60
  frameLength?: number,  // 既定 2048
  hopLength?: number,    // 既定 512
): { audio: Float32Array; startSample: number; endSample: number }

function splitSilence(
  samples: Float32Array,
  topDb?: number,
  frameLength?: number,
  hopLength?: number,
): Int32Array  // [start0, end0, start1, end1, ...] のフラット配列

trimSilencelibrosa.effects.trim)はフレーム RMS とピーク RMS からの topDb 差で 無音を判定し、トリム後の音声と元音源上の [startSample, endSample) 範囲を返します。 単純なしきい値トリムの trim(samples, sampleRate, thresholdDb) とは別物です。 splitSilencelibrosa.effects.split)は非無音区間をサンプル単位の開始/終了ペアで返します。

フレーミング/パディングのヘルパー

typescript
function frameSignal(
  samples: Float32Array,
  frameLength: number,
  hopLength: number,
): { nFrames: number; frames: Float32Array }  // row-major

function padCenter(values: Float32Array, targetSize: number, padValue?: number): Float32Array
function fixLength(values: Float32Array, targetSize: number, padValue?: number): Float32Array
function fixFrames(frames: Int32Array, xMin?: number, xMax?: number, pad?: boolean): Int32Array

frameSignallibrosa.util.framepadCenter / fixLength / fixFrames は対応する librosa.util の同名関数と互換です。

ピーク検出/ベクトル正規化

typescript
function peakPick(
  values: Float32Array,
  preMax: number,
  postMax: number,
  preAvg: number,
  postAvg: number,
  delta: number,
  wait: number,
): Int32Array  // ピーク位置のインデックス

function vectorNormalize(
  values: Float32Array,
  normType?: number,  // 0=inf, 1=L1, 2=L2, 3=power(既定 0)
  threshold?: number, // 既定 1e-12
): Float32Array

peakPicklibrosa.util.peak_pick(オンセット包絡線などの 1 次元信号に対する後処理)、 vectorNormalizelibrosa.util.normalize に対応します。peakPick の窓パラメータや 各 normType の意味は librosa 互換性 を参照してください。

PCEN(チャンネル別エネルギー正規化)

typescript
function pcen(
  values: Float32Array,
  nBins: number,
  nFrames: number,
  options?: {
    sampleRate?: number;
    hopLength?: number;
    timeConstant?: number;  // 既定 0.4
    gain?: number;          // 既定 0.98
    bias?: number;          // 既定 2.0
    power?: number;         // 既定 0.5
    eps?: number;           // 既定 1e-6
  },
): Float32Array

pcenlibrosa.pcen 互換です。入力は row-major の [nBins x nFrames] メルスペクトログラム、出力も同じレイアウトです。

Tonnetz/Tempogram/PLP

typescript
function tonnetz(
  chromagram: Float32Array,   // row-major [nChroma x nFrames]
  nChroma: number,
  nFrames: number,
): Float32Array               // [6 x nFrames]

function tempogram(
  onsetEnvelope: Float32Array,
  sampleRate: number,
  hopLength?: number,         // 既定 512
  winLength?: number,         // 既定 384
  mode?: 'autocorrelation' | 'auto' | 'ac' | 'cosine' | 0 | 1,  // 既定 'autocorrelation'
): { nFrames: number; winLength: number; data: Float32Array }

function fourierTempogram(
  onsetEnvelope: Float32Array,
  sampleRate?: number,
  hopLength?: number,
  winLength?: number,
): { nBins: number; nFrames: number; data: Float32Array }

function cyclicTempogram(
  onsetEnvelope: Float32Array,
  sampleRate: number,
  hopLength?: number,
  winLength?: number,
  bpmMin?: number,            // 既定 60
  nBins?: number,             // 既定 60
): { nFrames: number; nBins: number; data: Float32Array }

function tempogramRatio(
  tempogramData: Float32Array,
  winLength?: number,
  sampleRate?: number,
  hopLength?: number,
  factors?: Float32Array | number[], // 既定 [0.5, 1, 2, 3, 4]
): Float32Array

function plp(
  onsetEnvelope: Float32Array,
  sampleRate: number,
  hopLength?: number,
  tempoMin?: number,          // 既定 30
  tempoMax?: number,          // 既定 300
  winLength?: number,
): Float32Array

tempogram では、mode: 'cosine' で窓内コサイン類似度の変種になります('auto''ac'01 の alias も受け付けます)。各ヘルパーが対応する librosa の特徴量は librosa 互換性、使い分けは リアルタイムとストリーミング を参照してください。

リサンプリング

resample(samples, srcSr, targetSr) 中負荷

r8brain アルゴリズムを使用した高品質リサンプリング。

typescript
function resample(
  samples: Float32Array,
  srcSr: number,
  targetSr: number
): Float32Array

Audio クラス

Audio クラスは、よく使う関数をメソッド形式で呼ぶための入口です。サンプルとサンプルレートを内部で保持するため、各呼び出しで渡し直す必要がありません。

Audio.fromBuffer(samples, sampleRate)

サンプルデータから Audio インスタンスを作成します。

typescript
const audio = Audio.fromBuffer(samples, 44100);

sampleRate は省略可能で、既定は 48000 です。保持された値はすべてのインスタンスメソッドに渡されるため、必ずバッファ本来のサンプルレートを指定してください。

Audio.fromMemory(bytes)

WAV や MP3 などのエンコード済みオーディオバイト列(Uint8Array)をネイティブ WASM デコーダでデコードし、Audio インスタンスを返します。同梱デコーダが対応しない形式の場合は SonareError をスローします。

typescript
const audio = Audio.fromMemory(new Uint8Array(await file.arrayBuffer()));

Audio.fromMemoryWithBrowserFallback(bytes, options?)

asyncPromise<Audio> を返します。まず Audio.fromMemory を試みます。同梱デコーダが AAC・OGG・FLAC などの形式を読めない場合は、ブラウザのコーデックスタック(AudioContext.decodeAudioData)で代わりにデコードします。ブラウザでデコードしたマルチチャンネル音声は、返される Audio オブジェクトが 1 本のサンプル列を持つようにモノラルへダウンミックスされます。任意の BrowserAudioDecodeOptionsaudioContext / createAudioContext / targetSampleRate)を受け取り、このヘルパー自身が生成したコンテキストは後で閉じられます。

typescript
const audio = await Audio.fromMemoryWithBrowserFallback(
  new Uint8Array(await file.arrayBuffer()),
);

プロパティ

プロパティ説明
audio.dataFloat32Arrayサンプルデータ
audio.lengthnumberサンプル数
audio.sampleRatenumberサンプルレート(Hz)
audio.durationnumber長さ(秒)

インスタンスメソッド

Audio クラスは、よく使う単発ヘルパーをメソッド形式で呼ぶための入口です。サンプルとサンプルレートを内部に保持するので、毎回渡す必要がありません。

analyzeSections(...)analyzeMelody(...)analyzeDynamics(...)analyzeTimbre(...)、ルーム音響系の関数は、WASM パッケージでは独立した関数として呼び出します。

typescript
import {
  init,
  Audio,
  analyzeSections,
  analyzeMelody,
  analyzeDynamics,
  analyzeTimbre,
  detectAcoustic,
} from '@libraz/libsonare';

await init();

const audio = Audio.fromBuffer(samples, 44100);

// 解析
const bpm = audio.detectBpm();
const key = audio.detectKey();
const keyCandidates = audio.detectKeyCandidates();
const beats = audio.detectBeats();
const downbeats = audio.detectDownbeats();
const onsets = audio.detectOnsets();
const result = audio.analyze();
const chords = audio.detectChords({ useHmm: true });
const sections = analyzeSections(audio.data, audio.sampleRate);
const melody = analyzeMelody(audio.data, audio.sampleRate);
const dynamics = analyzeDynamics(audio.data, audio.sampleRate);
const timbre = analyzeTimbre(audio.data, audio.sampleRate);
const acoustic = detectAcoustic(audio.data, audio.sampleRate);

// エフェクト
const { harmonic, percussive } = audio.hpss();
const corrected = audio.pitchCorrectToMidi(68.7, 69);
const held = audio.noteStretch({ onsetSample: 12000, offsetSample: 24000, stretchRatio: 1.25 });
const voice = audio.voiceChange({ pitchSemitones: 3, formantFactor: 1.05 });
const stretched = audio.timeStretch(1.5);
const shifted = audio.pitchShift(2);
const normalized = audio.normalize(-3.0);
const trimmed = audio.trim(-60.0);

// 特徴抽出
const stftResult = audio.stft();
const mel = audio.melSpectrogram();
const mfcc = audio.mfcc();
const chroma = audio.chroma();
const nnls = audio.nnlsChroma();
const env = audio.onsetEnvelope();
const loudness = audio.lufs();
const centroid = audio.spectralCentroid();
const bandwidth = audio.spectralBandwidth();
const rolloff = audio.spectralRolloff();
const flatness = audio.spectralFlatness();
const zcr = audio.zeroCrossingRate();
const rms = audio.rmsEnergy();
const pitch = audio.pitchPyin();

// リサンプリング
const resampled = audio.resample(22050);

引数のデフォルト値(nFfthopLengthnMels など)はスタンドアロン関数と同じです。

ストリーミング API

ストリーミング API は、リアルタイムの音声解析とビジュアライゼーションを可能にします。バッチ解析とは異なり、ストリーミングは音声をチャンクごとに処理し、低レイテンシを実現します。

使い分け

  • バッチ API: 録音済みファイル、総合解析(BPM、キー、コード、セクション)
  • ストリーミング API: ライブ音声、ビジュアライゼーション、リアルタイムフィードバック

この節は StreamAnalyzer の型/クラスリファレンスです。実際に動かすレシピ、AudioWorklet ブリッジ、出力フォーマットの詳細、プログレッシブ推定の解説は リアルタイムとストリーミング を参照してください。

StreamConfig

StreamAnalyzer の設定オプション。

typescript
interface StreamConfig {
  sampleRate?: number;         // デフォルト: 44100(ストリームの既定。22050 ではない)
  nFft?: number;               // デフォルト: 2048
  hopLength?: number;          // デフォルト: 512
  nMels?: number;              // デフォルト: 128
  fmin?: number;               // デフォルト: 0
  fmax?: number;               // デフォルト: 0(= sr/2)
  tuningRefHz?: number;        // デフォルト: 440
  computeMel?: boolean;        // デフォルト: true
  computeChroma?: boolean;     // デフォルト: true
  computeOnset?: boolean;      // デフォルト: true
  computeSpectral?: boolean;   // デフォルト: true
  emitEveryNFrames?: number;   // デフォルト: 1(スロットリングなし)
  magnitudeDownsample?: number;// デフォルト: 1
  maxPendingFrames?: number;   // デフォルト: 4096。超過時は新たに生成した出力フレームを破棄
  maxProgressionEntries?: number; // デフォルト: 4096。コード/小節進行をそれぞれ保持する上限で、超過時は最古を破棄
  keyUpdateIntervalSec?: number;  // デフォルト: 5
  bpmUpdateIntervalSec?: number;  // デフォルト: 10
  window?: number;             // 0=Hann(既定), 1=Hamming, 2=Blackman, 3=Rectangular
  outputFormat?: 0;            // レガシー。省略するか Float32(0)を使う
}

outputFormat はソース互換性のためだけに残っており、指定する場合は 0 でなければなりません。量子化読み出しは readFramesU8 または readFramesI16 を明示して選びます。内部解析は常に float です。リアルタイムとストリーミング を参照してください。

旧来の computeMagnitude フラグはサポートされなくなり、指定するとコンストラクタが例外を投げます。マグニチュードのフレームは StreamAnalyzer の読み出し経路では公開されないため、このフラグは削除されました。マグニチュードのデータが必要な場合は、オフラインで stftstftDb を使うか、スペクトラムメータリングのヘルパーを使ってください。

streamAnalyzerConfigDefaults() は、上記の各フィールドについてライブラリの既定値を保持した、すべての項目が入った StreamConfigDefaults オブジェクト(Required<StreamConfig>)を返します。設定 UI の初期値として使ったり、ユーザー指定の設定との差分計算に使えます。StreamAnalyzer 自身も、省略されたフィールドにはこの同じ既定値を適用します。

StreamAnalyzer クラス

typescript
class StreamAnalyzer {
  constructor(config: StreamConfig);

  // 音声チャンクを処理(内部オフセット追跡)
  process(samples: Float32Array): void;

  // 明示的で連続したサンプルオフセットで処理。ギャップ、シーク、または process() からの切り替え前には reset() が必要
  processWithOffset(samples: Float32Array, sampleOffset: number): void;

  // 読み取り可能なフレーム数
  availableFrames(): number;

  // 処理済みフレームを読み取り(完全な float 精度)
  readFrames(maxFrames: number): FrameBuffer;

  // 帯域削減転送/可視化向けの量子化読み出し
  // (quantizeConfig を渡すと音量が極端に大きい/小さいストリームの量子化範囲を調整できる;
  // リアルタイムとストリーミング → カスタム量子化範囲 を参照)
  readFramesU8(maxFrames: number, quantizeConfig?: StreamQuantizeConfig): StreamFramesU8;   // Uint8 特徴量配列
  readFramesI16(maxFrames: number, quantizeConfig?: StreamQuantizeConfig): StreamFramesI16; // Int16 特徴量配列

  // 新しいストリーム用に状態をリセット
  reset(baseSampleOffset?: number): void;

  // 統計情報と、音声が届くにつれて更新される推定を取得
  stats(): AnalyzerStats;

  // 処理済みの総フレーム数
  frameCount(): number;

  // 現在の時間位置(秒)
  currentTime(): number;

  // サンプルレートを取得
  sampleRate(): number;

  // パターンロックタイミング用の予想総再生時間を設定
  setExpectedDuration(durationSeconds: number): void;

  // 大音量/圧縮音声用のノーマライゼーションゲインを設定
  setNormalizationGain(gain: number): void;

  // チューニング基準周波数を設定(デフォルト: 440 Hz)
  setTuningRefHz(refHz: number): void;

  // リソースを解放(使用終了時に呼び出し)。`delete()` が正規で、`dispose()` はその alias。
  delete(): void;
  dispose(): void;
}

FrameBuffer

postMessage での効率的な転送用の Structure-of-Arrays 形式。

typescript
interface FrameBuffer {
  nFrames: number;
  nMels: number;
  nChroma: number;             // クロマがあれば 12、なければ 0
  featureFlags: number;        // MEL=1, CHROMA=2, ONSET=4, SPECTRAL=8
  timestamps: Float32Array;      // [nFrames]
  mel: Float32Array;             // [nFrames * nMels]。MEL がなければ空
  chroma: Float32Array;          // [nFrames * nChroma]。CHROMA がなければ空
  onsetStrength: Float32Array;   // [nFrames]。ONSET がなければ空
  rmsEnergy: Float32Array;       // [nFrames]
  spectralCentroid: Float32Array;// [nFrames]。SPECTRAL がなければ空
  spectralFlatness: Float32Array;// [nFrames]。SPECTRAL がなければ空
  chordRoot: Int32Array;         // [nFrames]。CHROMA がなければ空
  chordQuality: Int32Array;      // [nFrames]。CHROMA がなければ空
  chordConfidence: Float32Array; // [nFrames]。CHROMA がなければ空
}

ChordChange

検出されたコード変化。

typescript
interface ChordChange {
  root: PitchClass;
  quality: ChordQuality;
  startTime: number;
  confidence: number;
}

BarChord

小節境界で検出されたコード(ビート同期)。

typescript
interface BarChord {
  barIndex: number;
  root: PitchClass;
  quality: ChordQuality;
  startTime: number;
  confidence: number;
}

PatternScore

既知のコード進行パターンの一致スコア。

typescript
interface PatternScore {
  name: string;   // パターン名(例: "royalRoad", "pop")
  score: number;  // 一致スコア(0-1)
}

AnalyzerStats

typescript
interface AnalyzerStats {
  totalFrames: number;
  totalSamples: number;
  durationSeconds: number;
  pendingFrames: number;       // 現在バッファされている未読フレーム数
  droppedOutputFrames: number; // 上限で新たに生成されたフレームを破棄した数
  droppedChordProgressionEntries: number; // 上限到達時に破棄された最古のコード進行エントリ数
  droppedBarProgressionEntries: number;   // 上限到達時に破棄された最古の小節進行エントリ数
  estimate: ProgressiveEstimate;
}

ProgressiveEstimate

処理された音声が増えるにつれて精度が向上する BPM、キー、コードの推定値。

typescript
interface ProgressiveEstimate {
  // BPM 推定
  bpm: number;              // 未推定の場合は 0
  bpmConfidence: number;    // 0-1、時間とともに増加
  bpmCandidateCount: number;

  // キー推定
  key: PitchClass;          // 0-11(C-B)
  keyMinor: boolean;
  keyConfidence: number;    // 0-1、時間とともに増加

  // コード推定(現在)
  chordRoot: PitchClass;
  chordQuality: ChordQuality;
  chordConfidence: number;
  chordStartTime: number;
  chordProgression: ChordChange[];     // 検出されたコード変化
  barChordProgression: BarChord[];     // 小節同期コード
  currentBar: number;                  // 現在の小節インデックス
  barDuration: number;                 // 小節の長さ(秒)

  // パターン検出
  votedPattern: BarChord[];            // 各パターン位置の投票済みコード
  patternLength: number;              // 繰り返しパターンの長さ(デフォルト: 4小節)
  detectedPatternName: string;        // 最も一致するパターン名(例: "royalRoad")
  detectedPatternScore: number;       // 一致スコア(0-1)
  allPatternScores: PatternScore[];   // 全既知パターンのスコア

  // 統計情報
  accumulatedSeconds: number;
  usedFrames: number;
  updated: boolean;         // このフレームで推定が更新された場合 true
}

使い方、AudioWorklet 統合、タイミング

StreamAnalyzer を実際に動かすレシピ(AudioWorklet からブロックを流し込む、フレームを読み出す、emitEveryNFrames でスロットリングする、FrameBuffer のストリーム時間タイムスタンプを AudioContext.currentTime に対応付ける)は、AudioWorklet ハンドシェイクとデータフロー図とともに リアルタイムとストリーミング にあります。

WASM オブジェクトの解放

StreamAnalyzerMixerStreamingEqualizerStreamingMasteringChain は WASM ヒープメモリを指す embind ハンドルで、JavaScript のガベージコレクタは回収できません。使い終わったら delete() を呼んでください(StreamAnalyzerdispose() も受け付け、一部のクラスは destroy() を alias として公開します)。analyze() のような通常の関数は普通の JS 値を返すので後始末は不要です。Node ネイティブの解放方法は異なるため、ネイティブバインディング を参照してください。

型定義

AnalysisResult

typescript
interface AnalysisResult {
  bpm: number;
  bpmConfidence: number;
  bpmCandidates: BpmHypothesis[];           // 上位から順に並んだ候補
  key: Key;
  timeSignature: TimeSignature;
  timeSignatureCandidates: TimeSignature[]; // 上位から順に並んだ候補
  beatTimes: Float32Array;  // beats[].time のコピー。librosa 互換コードで便利
  beats: Beat[];            // 各拍の強度を含むオブジェクト配列
  chords: Chord[];
  sections: Section[];
  timbre: Timbre;
  dynamics: Dynamics;
  rhythm: RhythmFeatures;
  melody: MelodyContour;
  form: string;  // 例: "IABABCO"
}

interface BpmHypothesis {
  value: number;
  confidence: number;
  /** 報告された `bpm` との関係 */
  relation: 'primary' | 'half' | 'double' | 'other';
}

bpmtimeSignature は勝ち残った値で、2 つの *Candidates 配列はその背後にある 順位付きの候補群です。テンポは本質的に曖昧で、ハーフタイム感とその倍テンポは同じ曲の どちらも妥当な読み方になり得ます。1 つの数字だけを見せて祈るのではなく、代替案を提示できます。

typescript
const { bpm, bpmCandidates } = analyze({ samples, sampleRate });
const halfTime = bpmCandidates.find((c) => c.relation === 'half');
if (halfTime && halfTime.confidence > 0.4) {
  offerAlternative(halfTime.value);   // 「84 BPM かもしれません」
}

同じ配列は C ABI・Node・Python にもあります。

Beat

typescript
interface Beat {
  time: number;      // 秒
  strength: number;  // 0.0 〜 1.0
}

Chord

typescript
interface Chord {
  root: PitchClass;
  bass: PitchClass;     // 転回形のベース音
  quality: ChordQuality;
  start: number;       // 秒
  end: number;         // 秒
  confidence: number;
  name: string;        // "C", "Am", "G7"
}

Section

typescript
interface Section {
  type: SectionType;
  start: number;
  end: number;
  energyLevel: number;
  confidence: number;
  name: string;  // "Intro", "Verse 1", "Chorus"
}

TimeSignature

typescript
interface TimeSignature {
  numerator: number;    // 例: 4
  denominator: number;  // 例: 4
  confidence: number;
}

Timbre

typescript
interface Timbre {
  brightness: number;   // 0.0 〜 1.0
  warmth: number;
  density: number;
  roughness: number;
  complexity: number;
}

interface TimbreFrame {
  brightness: number;
  warmth: number;
  density: number;
  roughness: number;
  complexity: number;
}

interface TimbreAnalysisResult extends TimbreFrame {
  spectralCentroid: Float32Array;
  spectralFlatness: Float32Array;
  spectralRolloff: Float32Array;
  timbreOverTime: TimbreFrame[];
}

Dynamics

typescript
interface Dynamics {
  dynamicRangeDb: number;
  peakDb: number;
  rmsDb: number;
  loudnessRangeDb: number;
  crestFactor: number;
  isCompressed: boolean;
}

RhythmFeatures

typescript
interface RhythmFeatures {
  syncopation: number;
  grooveType: string;  // "straight", "shuffle", "swing"
  patternRegularity: number;
  tempoStability: number;
  timeSignature: TimeSignature;
}

MelodyContour

typescript
interface MelodyContour {
  pitchRangeOctaves: number;
  pitchStability: number;
  meanFrequency: number;
  vibratoRate: number;     // Hz
  pitches: MelodyPoint[];  // フレームごとのピッチ軌跡
}

MelodyPoint

typescript
interface MelodyPoint {
  time: number;        // フレーム時刻(秒)
  frequency: number;   // 推定 f0(Hz、無声音のときは 0)
  confidence: number;  // 有声らしさ、0.0〜1.0
}

列挙型

PitchClass

typescript
const PitchClass = {
  C: 0, Cs: 1, D: 2, Ds: 3, E: 4, F: 5,
  Fs: 6, G: 7, Gs: 8, A: 9, As: 10, B: 11
} as const;

Mode

typescript
const Mode = {
  Major: 0,
  Minor: 1,
  Dorian: 2,
  Phrygian: 3,
  Lydian: 4,
  Mixolydian: 5,
  Locrian: 6
} as const;

ChordQuality

typescript
const ChordQuality = {
  Major: 0, Minor: 1, Diminished: 2, Augmented: 3,
  Dominant7: 4, Major7: 5, Minor7: 6, Sus2: 7, Sus4: 8,
  Unknown: 9, Add9: 10, MinorAdd9: 11, Dim7: 12,
  HalfDim7: 13, Major9: 14, Dominant9: 15, Sus2Add4: 16
} as const;

SectionType

typescript
const SectionType = {
  Intro: 0, Verse: 1, PreChorus: 2, Chorus: 3,
  Bridge: 4, Instrumental: 5, Outro: 6, Unknown: 7
} as const;

エラーハンドリング

モジュールが未初期化の場合、すべての関数はエラーをスローします。まず await init() を呼んでください。

ネイティブ(C++)側の失敗は、構造化された SonareError としてスローされます。Error のサブクラスで、C ABI のエラー enum をそのまま映した数値の code と正準名 codeName を持つため、メッセージ文字列の照合ではなく原因コードで分岐できます。同じ失敗はどのバインディング(WASM / Node ネイティブ / Python / C ABI)でも同じ数値コードを報告します。パッケージは ErrorCode enum、SonareError クラス、型ガード isSonareError(value) をエクスポートします。

各 facade は非有限数、不正な enum/インデックス値、過大なリソースを DSP やシリアライズへ渡す前に一貫して拒否します。これらは入力不正として扱い、バインディングが暗黙にクランプしたり不正値を受理したりすることへ依存しないでください。

typescript
import { ErrorCode, isSonareError, Mixer } from '@libraz/libsonare';

try {
  const mixer = Mixer.fromSceneJson(sceneJson, 48000, 512);
} catch (error) {
  if (isSonareError(error) && error.code === ErrorCode.InvalidParameter) {
    // 例: 'send timing must be a string ("pre" or "post")'
    console.error(`scene rejected: ${error.codeName}: ${error.message}`);
  } else {
    throw error;
  }
}
ErrorCode
Ok0
FileNotFound1
InvalidFormat2
DecodeFailed3
InvalidParameter4
OutOfMemory5
NotSupported6
InvalidState7
Cancelled8
Unknown99

このコードは Python の SonareError.code および C ABI の SonareError enum と一致し、Python CLI は同じコードを終了コードへ対応付けます。

マスタリング API

ブラウザ向けパッケージには /ja/mastering デモと同じ名前付きマスタリングプロセッサが含まれます。Web Audio API などでデコードした Float32Array のチャンネルバッファを渡し、戻り値のサンプルをアプリ側で WAV などに書き出します。

この節では JS の入口と、その結果/設定の型を一覧します。各プロセッサの働き、プリセット一覧、解析/アシスタントが返す JSON は、マスタリングプロセッサマスタリングアシスタント を参照してください。

typescript
import { init, masterAudioStereo, masteringChainStereo } from '@libraz/libsonare'

await init()

// ステージを明示したフルチェーン
const result = masteringChainStereo(left, right, sampleRate, {
  spectral: { airBand: { amount: 0.35, shelfFrequencyHz: 14000 } },
  maximizer: { truePeakLimiter: { ceilingDb: -1, oversampleFactor: 4 } },
  loudness: { targetLufs: -14, ceilingDb: -1, truePeakOversample: 4 },
})
console.log(result.outputLufs, result.outputTruePeakDbtp, result.outputLra)
if (result.loudnessTargetLimited) {
  console.warn('トゥルーピーク上限のため、要求した LUFS 目標には届きませんでした。')
}
console.log(result.stageGainReductions)

// プリセット + ネストした上書き(型定義どおりの MasteringChainConfig 形式)
const presetResult = masterAudioStereo(left, right, sampleRate, 'pop', {
  loudness: { targetLufs: -14 },
  maximizer: { truePeakLimiter: { releaseMs: 50 } },
})

これらにはそれぞれ (progress, stage) => void のコールバックを取る *WithProgress 変種があります。masteringProcess(...) / masteringProcessStereo(...) は名前付きプロセッサを 1 つ実行し、masteringStereoAnalyze(...) は JSON レポートを返します。

オフラインのチェーン/プリセット結果には、outputTruePeakDbtpoutputLraloudnessTargetLimitedstageGainReductions が含まれます。

loudnessTargetLimited が true なら、True Peak 上限のため要求した LUFS 目標には届いていません。目標ではなく実際の outputLufs を報告してください。各 StageGainReduction は、ダイナミクスまたはマキシマイザーの直近のゲインリダクションを示します。

report — 処理前後を 1 つのオブジェクトで

オフラインチェーンの結果は report も持ちます。これは「実際に何が起きたか」の要約で、 自分で入力を測り直して組み立てる必要がなくなります。

typescript
interface MasteringReport {
  before: MasteringLoudnessSummary;
  after: MasteringLoudnessSummary;
  appliedGainDb: number;
  maxGainReductionDb: number;
  loudnessTargetLimited: boolean;
  /** 対数等間隔 32 バンドの「後 − 前」エネルギー差(dB) */
  bandEnergyDeltaDb: Float32Array;
}

interface MasteringLoudnessSummary {
  integratedLufs: number;
  maxMomentaryLufs: number;
  maxShortTermLufs: number;
  truePeakDbtp: number;
  loudnessRange: number;
}
typescript
const { report } = masteringChainStereo(left, right, sampleRate, config);
console.log(report.before.integratedLufs, '→', report.after.integratedLufs);
console.log(report.after.loudnessRange - report.before.loudnessRange, 'LU 変化');
drawTiltCurve(report.bandEnergyDeltaDb);   // 32 バンド。正なら処理後の方が明るい

同じオブジェクトが C ABI・ctypes・Node・Python・両 CLI のレポートファイルにミラーされて いるため、CLI から書き出したレポートとブラウザで読むレポートは同じ形になります。

説明可能なマスタリングのヘルパー(masteringAudioProfile(...)masteringAssistantSuggest(...)masteringStreamingPreview(...))は JSON 文字列を返します。正確な形、受け付けるオプション、提案をレンダー済みマスターに変換する方法は マスタリングアシスタント を参照してください。リファレンストラック用途では masteringPairProcessorNames()masteringPairAnalyze() を使います(サンプルレートを揃え、長さも近づける)。

説明可能なヘルパーのステレオ版

この 3 つには、チャンネルペアを直接計測するステレオ版があります。いずれも、リクエストオブジェクト専用です。位置引数のオーバーロードはなく、位置引数で呼ぶと例外になります。

typescript
function masteringAudioProfileStereo(request: MasteringStereoParamsRequest): string
function masteringAssistantSuggestStereo(request: MasteringStereoParamsRequest): string
function masteringStreamingPreviewStereo(request: MasteringStreamingPreviewStereoRequest): string

interface MasteringStereoParamsRequest {
  left: Float32Array;
  right: Float32Array;
  sampleRate?: number;
  params?: MasteringProcessorParams;
}

interface MasteringStreamingPreviewStereoRequest {
  left: Float32Array;
  right: Float32Array;
  sampleRate?: number;
  platforms?: StreamingPlatform[];
}
typescript
const profile = JSON.parse(masteringAudioProfileStereo({ left, right, sampleRate }));
const suggestion = JSON.parse(masteringAssistantSuggestStereo({ left, right, sampleRate }));
const preview = JSON.parse(
  masteringStreamingPreviewStereo({
    left,
    right,
    sampleRate,
    platforms: [{ name: 'Spotify', targetLufs: -14, ceilingDb: -1 }],
  }),
);

ステレオ素材ならこちらを使ってください。モノラル版は 0.5 * (left + right) のダウンミックスを計測するため、相関の低い素材では約 6 dB 低く出ます。積分ラウドネス、そこから導かれる正規化ゲイン、天井に当たるリスクの判断が、そろって同じぶんだけ過小に報告されます。相関の低いピンクノイズのペア(48 kHz、4 秒)での実測値は、ダウンミックス経由が -22.55 LUFS、ステレオ版が -16.44 LUFS で、差は 6.11 dB でした。Spotify の normalizationGainDb もダウンミックス経由が +8.55、ステレオ版が +2.44 です。相関の高いペアでは差が 3.01 dB まで縮みますが、これは単純に半分になったぶんで、残りの約 3 dB がデコリレーションによるものです。

ステレオプロファイルのうち、左右両チャンネルから計測されるのは loudness ブロックだけです。積分 LUFS と LRA はチャンネル加算したプログラムから求め、True Peak は左右の大きいほうを採ります。スペクトル、ダイナミクス、テンポの各フィールドは絶対レベルではなく形と時間を表すため、引き続きダウンミックス上で計測され、masteringAudioProfile の値とそのまま比較できます。

masteringStreamingPreviewStereoplatforms の扱いはモノラル版と同じです。省略するか空配列を渡すと、組み込みの Spotify / Apple Music / YouTube のセットにフォールバックし、例外ではなく 3 行分の結果を返します。

StreamingEqualizer

StreamingEqualizer は、ブロック単位で動かすリアルタイム安全な EQ オブジェクトです。

最大 24 バンド、zero-latency / natural / linear の位相モード、ダイナミック EQ、ミッド/サイド処理、外部サイドチェイン、スペクトルスナップショット、オフラインのリファレンスマッチを扱えます。

WASM 版では先に init() を呼び、使い終わったら delete() で解放します。

typescript
import { init, StreamingEqualizer } from '@libraz/libsonare';
await init();

const eq = new StreamingEqualizer({ sampleRate: 48000, maxBlockSize: 512 });
try {
  eq.setBand(0, {
    type: 'HighShelf',
    frequencyHz: 8000,
    gainDb: 4,
    q: 0.7,
    enabled: true,
  });
  eq.setPhaseMode(1); // 1 = zero-latency, 2 = natural, 3 = linear
  eq.setAutoGain(true);

  const { left, right } = eq.processStereo(leftBlock, rightBlock);
  console.log(eq.spectrum(), eq.latencySamples(), left, right);
} finally {
  eq.delete();
}

ファイル単位の EQ / フィルタ処理に対応するソースビルド C++ CLI 例:

bash
sonare eq track.wav --type 2 --frequency-hz 8000 --gain-db 4 --q 0.7 -o eq.wav
sonare filter track.wav --type hp --cutoff 80 -o filtered.wav

StreamingRetune

StreamingRetune は、ブロック単位で動かすモノラルのピッチリチューン用オブジェクトです。グレインとディレイの状態を呼び出し間で保持するため、最初のブロック前に prepare()、使い終わったら delete() を呼びます。

typescript
import { init, StreamingRetune } from '@libraz/libsonare';
await init();

const retune = new StreamingRetune({ semitones: 3, mix: 1, grainSize: 0 });
retune.prepare(48000, 512);

try {
  const out = retune.processMono(inputBlock);
  retune.setConfig({ semitones: -2, mix: 0.75 });
  console.log(out, retune.config(), retune.grainSize());
} finally {
  retune.delete();
}

ソースビルド C++ CLI でのオフラインファイル処理に近いコマンド:

bash
sonare pitch-shift vocal.wav --semitones 3 -o shifted.wav
sonare voice-change vocal.wav --pitch-semitones 3 --formant-factor 1.0 -o voice.wav

RealtimeVoiceChanger

RealtimeVoiceChanger はプリセットで動かすライブ音声チェーン(ハイパス、ゲート、リチューン、フォルマント、EQ、コンプレッサー、ディエッサー、リバーブ、リミッターの各段)で、音声ブロックをまたいで状態を保持します。モニタリング、AudioWorklet 形式の処理、または voiceChange(...) では単純すぎるチャンク単位の音声処理で使います。標準プリセット ID は realtimeVoiceChangerPresetNames() で取得し、プリセット JSON は realtimeVoiceChangerPresetJson(...) で取得、validateRealtimeVoiceChangerPresetJson(...) で検証できます(スキーマバージョン 1)。RealtimeVoiceChangerConfigInput は厳密な型で、6 種類の VoicePresetId 文字列、または dspmacros のどちらか一方だけを持つプリセットオブジェクトを指定します。

typescript
import { init, RealtimeVoiceChanger, realtimeVoiceChangerPresetNames } from '@libraz/libsonare';
await init();

const changer = new RealtimeVoiceChanger(realtimeVoiceChangerPresetNames()[1]); // 例: "bright-idol"
changer.prepare(48000, /*maxBlockSize=*/128, /*channels=*/1);
try {
  const out = changer.processMono(inputBlock);
  const realtime = changer.createRealtimeMonoBuffer(128); // ゼロコピーの WASM ヒープビュー
  realtime.input.set(inputBlock.subarray(0, 128));
  realtime.process();
  console.log(out, realtime.output, changer.latencySamples());
} finally {
  changer.delete();
}

ゼロコピーバッファヘルパー(createRealtimeMonoBuffercreateRealtimeInterleavedBuffercreateRealtimePlanarBuffer)は changer が所有する WASM ヒープのビューを返します。リアルタイムループ内で再利用し、delete() 後は破棄してください。プリセット一覧とチェーン各段は リアルタイムボイスチェンジャー を参照してください。

voiceChangeRealtime(samples, sampleRate?, preset?, options?)

voiceChangeRealtime(...)RealtimeVoiceChanger をバッファ全体に対してオフラインで一括適用する便利関数です。内部で changer を構築・準備し、ブロック単位のレンダリングループを実行したうえで破棄します(Python の voice_change_realtime や Node の同等関数と同じ考え方です)。そのため、呼び出し側が状態を持つオブジェクトを管理する必要はありません。

typescript
function voiceChangeRealtime(
  samples: Float32Array,
  sampleRate?: number, // デフォルト 48000
  preset?: RealtimeVoiceChangerConfigInput,
  options?: {
    channels?: 1 | 2;   // デフォルト 1(モノラル)。2 = インターリーブステレオ (L0,R0,L1,R1,...)
    /** @deprecated Ignored — the shared C-ABI renderer uses a fixed block size. */
    blockSize?: number;
  },
): Float32Array  // 入力と同じレイアウト・長さ

バッファ全体が手元にある場合はこれを使います。ブロック単位のライブ処理を手動で行う場合は RealtimeVoiceChanger を、フルのプリセットチェーンが不要で一度きりのピッチ/フォルマント変更だけが必要な場合は voiceChange(...) を使ってください。

StreamingMasteringChain

リアルタイム処理やメモリ制約のあるユースケース(AudioWorklet やストリーム 入力からのブロック単位処理など)向けに、WASM モジュールは StreamingMasteringChain を公開しています。受け取るのは StreamingMasteringChainConfig で、これは masteringChain()MasteringChainConfig に、ストリーミング専用の任意フィールドを 2 つ追加したものです。

  • loudnessStaticGainDb — 事前計算した静的ラウドネスゲイン(dB、例: targetLufs - measuredIntegratedLufs)。ブロックごとに適用され、loudness ステージを有効にしたプリセットのストリーミングプレビューがオフラインレンダリングと一致するようにします。
  • loudnessStaticGainPeakDb — オフラインで計測した音源の True Peak(dBFS)。指定すると静的ゲインが loudness.ceilingDb - loudnessStaticGainPeakDb にクランプされ、ストリーミングのリミッターへオフラインチェーンより大きい入力が入らないようにします。

それ以外は、固定ブロックサイズで内部状態を準備したうえで、入力ブロックに対してチェーンを順番に適用します。

typescript
import { init, StreamingMasteringChain } from '@libraz/libsonare';
await init();

const chain = new StreamingMasteringChain({
  eq: { tilt: { tiltDb: 0.5 } },
  dynamics: { compressor: { thresholdDb: -20 } },
  maximizer: { truePeakLimiter: { ceilingDb: -1, oversampleFactor: 4 } },
});

chain.prepare(48000, /*maxBlockSize=*/512, /*numChannels=*/2);

// Use the path that matches the prepared channel count: processMono() /
// flushMono() after prepare(..., 1), processStereo() / flushStereo() after
// prepare(..., 2). Mixing them throws a num_channels mismatch.
const { left, right } = chain.processStereo(leftBlock, rightBlock);

console.log(chain.stageNames());      // ['eq.tilt', 'dynamics.compressor', ...]
console.log(chain.latencySamples());  // 有効ステージの合計レイテンシ

// 入力の最終ブロックのあと、チェーンの遅延と有限のテールを吐き出す
let tail: { left: Float32Array; right: Float32Array };
while ((tail = chain.flushStereo()).left.length > 0) {
  write(tail.left, tail.right);
}

chain.reset();   // prepare し直さずに状態だけクリア
chain.delete();  // WASM ハンドルを解放(使い終わったら呼ぶ)

flushMono() / flushStereo() は、入力がもうない状態で遅延分の音声と有限のプロセッサ テールを吐き出します。空の結果が返るまで呼び続けてください。フラッシュしないと、 ストリーミングチェーンで作ったバウンスは末尾の latencySamples() サンプルと、 リバーブやリミッターのテールを失います。連結したストリームの先頭 latencySamples() サンプルはチェーンの遅延なので、時間を揃えるには捨ててください。

numChannels === 1 のときはステレオ専用ステージはスキップされます。チェーン設定のリペアステージ(repair.declickrepair.dereverbrepair.denoiserepair.decliprepair.decracklerepair.dehum)はオフライン専用で、streaming constructor で有効にすると例外を投げます。masteringChain* / masterAudio*、または単発の masteringRepair* ヘルパーで実行してください。loudness ステージも、ストリーミングチェーンが信号全体の積分 LUFS を計測できないため、loudnessStaticGainDb(任意で loudnessStaticGainPeakDb も)を指定しない限り例外を投げます。同じチェーンで複数曲を順に処理する場合は reset()、使い終わったら delete() を呼んでハンドルを解放してください。

名前付きマスタリング API は次の系統に分かれます。

目的関数
シンプルなラウドネスマスタリングを実行mastering()
組み込みプリセットの一覧masteringPresetNames()
プリセットをモノラルに適用masterAudio()
プリセットをステレオに適用masterAudioStereo()
プリセットをモノラルに適用(進捗付き)masterAudioWithProgress()
プリセットをステレオに適用(進捗付き)masterAudioStereoWithProgress()
フルチェーン実行(モノラル)masteringChain()
フルチェーン実行(ステレオ)masteringChainStereo()
ブロック単位の EQStreamingEqualizer
進捗付きフルチェーン実行(モノラル)masteringChainWithProgress()
進捗付きフルチェーン実行(ステレオ)masteringChainStereoWithProgress()
ストリーミング(ブロック単位)チェーンStreamingMasteringChain
マスタリング判断用の音源プロファイルを取得masteringAudioProfile()
ステレオペアの音源プロファイルを取得masteringAudioProfileStereo()
音源解析からマスタリングの提案を取得masteringAssistantSuggest()
ステレオペアからマスタリングの提案を取得masteringAssistantSuggestStereo()
配信先ごとのラウドネス見込みをプレビューmasteringStreamingPreview()
ステレオペアの配信ラウドネスをプレビューmasteringStreamingPreviewStereo()
名前付きプロセッサ一覧(モノラル/ステレオ)masteringProcessorNames()
プロセッサ分類カタログを取得masteringProcessorCatalog()
チェーンのインサートプロセッサ一覧masteringInsertNames()
インサートが受け付けるパラメータキー一覧masteringInsertParamNames(name)
リアルタイムオートメーション可能なインサートパラメータ一覧masteringInsertParamInfo(name)
モノラル音声を処理masteringProcess()
ステレオ音声を処理masteringProcessStereo()
ペアプロセッサ一覧masteringPairProcessorNames()
ソース/リファレンスのペアを処理masteringPairProcess()
ペア解析の一覧masteringPairAnalysisNames()
ソース/リファレンスのペアを解析masteringPairAnalyze()
ステレオ解析の一覧masteringStereoAnalysisNames()
ステレオチャンネルを解析masteringStereoAnalyze()

関連するマスタリングガイド: 処理チェーントーンと Airダイナミクスステレオ、リミッター、ラウドネスリファレンスマッチ

単体のダイナミクス/リペアプロセッサ

名前付きの各ステージは単発の関数としても使え、チェーンを組まずに 1 つのプロセッサだけを実行できます。ダイナミクス系は DynamicsResult(処理後の samples と、プロセッサの先読みレイテンシをサンプル数で表す latencySamples)を、リペア系は Float32Array を返します。

typescript
// オフラインのダイナミクス
function masteringDynamicsCompressor(samples: Float32Array, sampleRate: number, options?: CompressorOptions): DynamicsResult
function masteringDynamicsGate(samples: Float32Array, sampleRate: number, options?: GateOptions): DynamicsResult
function masteringDynamicsTransientShaper(samples: Float32Array, sampleRate: number, options?: TransientShaperOptions): DynamicsResult

// オフラインのリペア
function masteringRepairDeclick(samples: Float32Array, sampleRate: number, options?: DeclickOptions): Float32Array
function masteringRepairDeclip(samples: Float32Array, sampleRate: number, options?: DeclipOptions): Float32Array
function masteringRepairDecrackle(samples: Float32Array, sampleRate: number, options?: DecrackleOptions): Float32Array
function masteringRepairDehum(samples: Float32Array, sampleRate: number, options?: DehumOptions): Float32Array
function masteringRepairDenoiseClassical(samples: Float32Array, sampleRate: number, options?: DenoiseClassicalOptions): Float32Array
function masteringRepairDereverbClassical(samples: Float32Array, sampleRate: number, options?: DereverbClassicalOptions): Float32Array
function masteringRepairTrimSilence(samples: Float32Array, sampleRate: number, options?: TrimSilenceOptions): Float32Array

リペア系のステージはオフライン専用で、StreamingMasteringChain では拒否されます。これらの単発ヘルパー、または masteringChain*masterAudio* の中で実行してください。ダイナミクスリペアを参照してください。

MasteringChainConfig

masteringChain*StreamingMasteringChain は下のネスト構造の設定スキーマを使います。 各キーは任意で、指定されたステージだけが下の固定順で有効になります。

マスタリングチェーンの順序
リペアEQダイナミクスサチュレーションスペクトルステレオマキシマイザーラウドネス
有効化したステージだけが処理されますが、有効なステージは常にこの順で実行されます。

masterAudio* はプリセットから開始し、同じキー名を "dynamics.compressor.thresholdDb" のようなフラットなドット記法の overrides(上書き値)として受け取ります。

maximizer.truePeakLimiter.releaseMs はポストリミッターのリリース時間です。省略するとプリセット/設定の既定値 50 ms を保ちます。フラットな上書き値として渡した場合、その値がそのまま適用されます。maximizer.truePeakLimiter.applyGainAtInputRate を有効にすると、静的なラウドネスゲインをオーバーサンプリング前の入力サンプルレートで適用します。ホスト間でゲイン段の位置を揃えたい場合に使います。

インターフェース全文(クリックで展開)
typescript
interface MasteringChainConfig {
  repair?: {
    denoise?: boolean;
    nFft?: number; hopLength?: number; ddAlpha?: number; gainFloor?: number;
    declip?: { enabled?: boolean; clipThreshold?: number; lpcOrder?: number;
               iterations?: number; lpcBlend?: number; };
    decrackle?: { enabled?: boolean; threshold?: number;
                  /** 0 = メディアン、1 = ウェーブレット縮小 */
                  mode?: number; levels?: number; };
    dehum?: { enabled?: boolean; fundamentalHz?: number; harmonics?: number;
              q?: number; adaptive?: boolean; searchRangeHz?: number;
              adaptation?: number; frameSize?: number; pllBandwidth?: number; };
    declick?: { threshold?: number; neighborRatio?: number; maxClickSamples?: number;
                lpcOrder?: number; residualRatio?: number; };
    dereverb?: { threshold?: number; attenuation?: number; nFft?: number;
                 hopLength?: number; t60Sec?: number; lateDelayMs?: number;
                 overSubtraction?: number; spectralFloor?: number;
                 wpeEnabled?: boolean; wpeIterations?: number; wpeTaps?: number;
                 wpeStrength?: number; };
  };
  eq?: {
    /** 正規のネストされた tilt ステージ */
    tilt?: { enabled?: boolean; tiltDb?: number; pivotHz?: number };
    /** @deprecated `eq.tilt.tiltDb` を使用してください */
    tiltDb?: number;
    /** @deprecated `eq.tilt.pivotHz` を使用してください */
    pivotHz?: number;
  };
  dynamics?: {
    compressor?: { thresholdDb?: number; ratio?: number; attackMs?: number;
                   releaseMs?: number; kneeDb?: number; makeupGainDb?: number;
                   autoMakeup?: boolean; };
    deesser?: { frequencyHz?: number; thresholdDb?: number; ratio?: number;
                attackMs?: number; releaseMs?: number; rangeDb?: number;
                bandpassQ?: number; };
    transientShaper?: { attackGainDb?: number; sustainGainDb?: number;
                        fastAttackMs?: number; fastReleaseMs?: number;
                        slowAttackMs?: number; slowReleaseMs?: number;
                        sensitivity?: number; maxGainDb?: number;
                        gainSmoothingMs?: number; lookaheadMs?: number; };
    multibandComp?: { lowCutoffHz?: number; highCutoffHz?: number;
                      lowThresholdDb?: number;  lowRatio?: number;
                      lowAttackMs?: number;     lowReleaseMs?: number;
                      midThresholdDb?: number;  midRatio?: number;
                      midAttackMs?: number;     midReleaseMs?: number;
                      highThresholdDb?: number; highRatio?: number;
                      highAttackMs?: number;    highReleaseMs?: number; };
  };
  saturation?: {
    tape?: { driveDb?: number; saturation?: number; hysteresis?: number;
             outputGainDb?: number; speedIps?: number; headBumpDb?: number;
             bias?: number; gapLoss?: number; };
    exciter?: { frequencyHz?: number; driveDb?: number; amount?: number;
                q?: number; evenOddMix?: number; };
  };
  spectral?: {
    airBand?: { amount?: number; shelfFrequencyHz?: number;
                dynamicThresholdDb?: number; dynamicRangeDb?: number; };
  };
  stereo?: {
    imager?: { width?: number; outputGainDb?: number;
               decorrelationAmount?: number; preserveEnergy?: boolean; };
    monoMaker?: { amount?: number; frequencyHz?: number };
  };
  maximizer?: {
    truePeakLimiter?: { ceilingDb?: number; lookaheadMs?: number;
                        releaseMs?: number; oversampleFactor?: number;
                        applyGainAtInputRate?: boolean; };
  };
  loudness?: { targetLufs?: number; ceilingDb?: number;
               truePeakOversample?: number; };
}

interface MasteringResult {
  samples: Float32Array;
  sampleRate: number;
  inputLufs: number;
  outputLufs: number;
  appliedGainDb: number;
  loudnessTargetLimited?: boolean;
  latencySamples?: number;
}
interface MasteringChainResult extends MasteringResult {
  stages: string[];
  outputTruePeakDbtp: number;
  outputLra: number;
  loudnessTargetLimited: boolean;
  stageGainReductions: StageGainReduction[];
  report: MasteringReport;
}
interface MasteringStereoResult {
  left: Float32Array;
  right: Float32Array;
  sampleRate: number;
  inputLufs: number;
  outputLufs: number;
  appliedGainDb: number;
  latencySamples: number;
}
// masteringChainStereo / masterAudioStereo(および WithProgress 変種)の
// 戻り値。MasteringStereoResult は masteringProcessStereo の戻り値。
// latencySamples フィールドはない — オフラインチェーンの出力はすでに
// レイテンシ補正済み。
interface MasteringChainStereoResult {
  left: Float32Array;
  right: Float32Array;
  sampleRate: number;
  inputLufs: number;
  outputLufs: number;
  appliedGainDb: number;
  stages: string[];
  outputTruePeakDbtp: number;
  outputLra: number;
  loudnessTargetLimited: boolean;
  stageGainReductions: StageGainReduction[];
  report: MasteringReport;
}
// MasteringStereoChainResult は MasteringChainStereoResult の
// @deprecated エイリアス。Node/Python バインディングとのソース互換性のために
// 維持されている。

各ステージの使いどころは用語集の各ページに対応しています: リペアトーンと Airダイナミクスステレオ・リミッター・ラウドネス

ミキシング API

WASM パッケージから libsonare のミキシングエンジンを使えます。mixStereo(...) はステム配列を手早くレンダーする一括処理用の入口です。Mixer は、チャンネルストリップ、バス、センド、VCA グループ、オートメーション、ストリップメーター、ゴニオメーターバッファを持つ、シーンベースのミキサーです。

typescript
import {
  Mixer,
  mixStereo,
  mixingScenePresetJson,
  mixingScenePresetNames,
} from '@libraz/libsonare';

mixingScenePresetNames(); // ['vocalReverbSend', ...]

const offline = mixStereo([vocalL, musicL], [vocalR, musicR], sampleRate, {
  inputTrimDb: [3, 0],
  faderDb: [-3, -12],
  pan: [0, -0.2],
  width: [1, 0.9],
  muted: [false, false],
});

const mixer = Mixer.fromSceneJson(mixingScenePresetJson('vocalReverbSend'), sampleRate, 512);
mixer.sceneWarnings(); // シーン読み込み時の非致命的な警告(どのプロセッサも読まない insert パラメータ=タイプミス)
const latency = mixer.latencySamples(); // ドライ/ウェット整列用のコンパイル済みグラフ遅延
const block = mixer.processStereo([vocalBlockL, musicBlockL], [vocalBlockR, musicBlockR]);
const meter = mixer.stripMeter(0, 'postFader');

mixer.scheduleFaderAutomation(0, sampleRate * 8, -6, 's-curve');
mixer.schedulePanAutomation(0, sampleRate * 8, -0.25, 'linear');
mixer.scheduleSendAutomation(0, 0, sampleRate * 12, -12, 'hold');

const goniometer = mixer.readGoniometerLatest(0, 256);
const sceneJson = mixer.toSceneJson();
mixer.delete();

AudioWorklet のようにレンダーブロックごとのアロケーションを避けたいループでは、Mixer.createRealtimeBuffer()processStereoInto(...) を使います。シーンやルーティングの詳細は ミキシングエンジン を参照してください。

プロジェクト、楽器、ライブ MIDI

このパッケージは、MIDI/クリップのアレンジを音声に変換するための、プロジェクト・シンセシス・ライブ入力のインターフェースも公開しています。ここでは概要のみを示し、各トピックには個別のガイドがあります。

目的使う APIガイド
空のプロジェクトを作るProject.create()(または new Project()プロジェクト編集
クリップ+MIDI アレンジの作成・読み込み・編集ProjectProject.fromJsontoSceneJson、MIDI イベントヘルパー)プロジェクト編集
解析・補助メタデータを不透明なまま保持するproject.setAssistSidecar(...)assistSidecars()プロジェクト編集
オートメーションレーンの対象種別を付けるProjectAutomationTargetKindProjectAutomationLaneDesctargetKindプロジェクト編集
プロジェクトを音声にレンダーproject.bounceWithSynthInstrument(s)プロジェクトバウンス
内蔵シンセサイザー(NativeSynth)のボイスを選ぶsynthPresetNames()synthPresetPatch(name)engine.setSynthInstrument(...)内蔵シンセサイザー
SoundFont で再生project.loadSoundFont(bytes) / engine.loadSoundFont(bytes)SoundFont プレイヤー
ライブエンジンへ MIDI クリップをサンプル精度でスケジュールするengine.setMidiClips(...)engine.sampleAtPpq(ppq)リアルタイムエンジン
トラック単位のキューモニタリングを設定する`engine.setTrackMonitorMode(laneIndex, 'off''pfl'
エンジンのトラックをレーン・バス・センド・ストリップでライブミックスするengine.setTrackLanes(...)engine.setTrackBuses(...)、ストリップ JSON セッターリアルタイムエンジン
トラックを外部 MIDI ハードウェアへ送り、必要ならクロック/トランスポートも転送するengine.setMidiDestinationExternal(...)engine.setExternalMidiClockEnabled(...)engine.drainExternalMidi(...)。Worklet ファサードでは onMidiOut(...)リアルタイムエンジン
ハードウェア/Web MIDI デバイスからエンジンへ演奏イベントを送るbindWebMidi(engine, ...) ブラウザ専用MIDI 入力
ライブのマイク入力をエンジンに流すbindMicrophoneInput(context, engine, ...) ブラウザ専用録音とテイク
typescript
import { Project, synthPresetNames } from '@libraz/libsonare';

const project = Project.fromJson(projectJson);
const audio = project.bounceWithSynthInstrument(synthPresetNames()[0]);

bounceWithSynthInstrument(...) は単一の楽器、または出力先ごとに 1 つの楽器を並べた配列を受け取ります。各要素には、プリセット名("va:" ルーティングプレフィックス可)、明示的な SynthPatch、または初期パッチを表す null を指定できます。

bindWebMidi(...)bindMicrophoneInput(...) はブラウザ専用のヘルパーで、Web MIDI や MediaStream をライブの RealtimeEngine に接続します。エンジン本体は リアルタイムエンジン を参照してください。

型エクスポート索引

WASM パッケージは、関数やクラスに加えて TypeScript の補助型もエクスポートしています。オプション、リアルタイムバッファ、コールバックのペイロードを型付けするときは、アプリ側で再定義せずこれらを使えます。

分野エクスポートされる型/定数
環境とエンジンEXPECTED_ENGINE_ABI_VERSION, EXPECTED_PROJECT_ABI_VERSION, EngineCapabilities, ProgressCallback
エンジンのレーンミキサー、マーカー、MIDI クリップEngineTrackLane, EngineTrackSend, EngineBus, EngineMarker, EngineMidiClipSchedule, EngineMidiEvent, ExternalMidiEvent, MarkerKind, ProjectMarker
キー/コード/リズム/音色解析ChordDetectionOptions, KeyProfileName, RhythmAnalysisResult, TimbreAnalysisResult, TimbreFrame, DynamicsAnalysisResult
スペクトル/ピッチ/特徴量変換MelPowerResult, StftPowerResult, PitchCorrectOptions, VoicedFlags, SpectralRegionOp, SpectralEditOptions, TempogramMode
ページ式クリップストリーミングClipPageStreamerEngine, ClipPageStreamerOptions, ClipPageStreamSource, OpfsClipStream, OpfsClipStreamOptions, OpfsClipPageProviderOptions
マスタリングMasteringProcessorParams, MasteringProcessorCatalogEntry, MasteringInsertParamInfo, MasteringChannelPolicy, MasteringChainStereoResult, MasteringStereoParamsRequest, MasteringStreamingPreviewStereoRequest
メータリングのリクエストMeteringStereoRequest, MeteringStereoDecimatedRequest
ストリーミングリチューンStreamingRetuneConfig
ストリーミング EQStreamingEqualizerConfig, EqBandType, EqBandPhase, EqCoeffMode, EqMatchOptions, EqStereoPlacement
リアルタイム音声VoicePresetId, RealtimeVoiceChangerConfigInput, RealtimeVoiceChangerPodConfig, RealtimeVoiceChangerMonoBuffer, RealtimeVoiceChangerInterleavedBuffer, RealtimeVoiceChangerPlanarBuffer
ミキシング/Worklet 用リアルタイムバッファMixerRealtimeBuffer, SonareScopeRingBuffer, SonareScopeRingReadResult, SonareWorkletScopeSnapshot
プロジェクト/エンジンのオートメーションProjectAssistSidecar, ProjectAssistSidecarInput, ProjectAutomationTargetKind, EngineTrackMonitorMode, TrackMonitorMode
パン則の入力PanLaw, PanLawName, PanLawInput

SurroundPanMixer.setSurroundPan のパラメータ型)はパッケージの公開エクスポート一覧に含まれていません。インポートせず、インラインまたはローカルなエイリアスとして型付けしてください。

パフォーマンスサマリー

API負荷備考
StreamAnalyzerリアルタイムチャンクごとの処理、〜2ms/フレーム、更新される BPM/キー/コード推定
Mixerリアルタイムオートメーションとメーターを持つシーンベースのブロック処理
analyze / analyzeWithProgress高負荷総合解析パイプライン
hpss / harmonic / percussive高負荷STFT + メディアンフィルター
timeStretch高負荷フェーズボコーダー
pitchShift高負荷タイムストレッチ + リサンプル
stft / stftDb中負荷複数の FFT 演算
melSpectrogram / mfcc中負荷STFT + フィルターバンク
chroma中負荷STFT + クロマフィルターバンク
pitchYin / pitchPyin中負荷フレームごとのピッチ検出
resample中負荷高品質リサンプリング
detectBpm / detectKey低負荷単一結果
detectBeats / detectOnsets低負荷フレームベース検出
単位変換関数低負荷純粋な計算
normalize / trim低負荷シンプルな処理

バンドルサイズ

ファイルサイズGzip
sonare.js~58 KB~14 KB
index.js~254 KB~51 KB
sonare.wasm~4,059 KB~1,376 KB
合計~4,372 KB~1,442 KB

ブラウザサポート

ブラウザ最小バージョン
Chrome57+
Firefox52+
Safari11+
Edge16+

要件: WebAssembly、ES2017+ (async/await)、Web Audio API