実装検証
このページは、libsonare の実装がどのように検証されているかをまとめたものです。ベンチマークの主張ではなく、機能領域とリポジトリ内のテスト根拠を対応付けるための地図です。
各実装領域の背後にある標準規格、アルゴリズム、互換性参照は アルゴリズム根拠 を参照してください。
検証は根拠であって万能保証ではない
テストに通っているということは、対象範囲が参照値、不変条件、回帰出力などで確認されているという意味です。
あらゆる入力、部屋、楽曲、コーデック、ホスト環境で完全な答えを保証するものではありません。
このページは「何が確認済みで、どこから推定値として扱うべきか」を読むために使ってください。
このページで身につくこと
このページを読むと、次のことを判断・説明できるようになります。
- 解析、特徴量、マスタリング、ミキシング、リアルタイム、バインディング、CLI、性能のテスト根拠を探せる。
- 参照テスト、ゴールデンハッシュ、プロパティチェック、ノーアロケーションチェックの違いを理解できる。
- リアルタイム用途として設計された範囲と、オフライン用ヘルパーとして残る範囲を説明できる。
- 互換性や精度を過大に主張せず、境界を明確に伝えられる。
このページの読み方
| 知りたいこと | セクション |
|---|---|
| 機能領域ごとのテスト根拠 | 検証マトリクス |
| リアルタイム用途として検証されている範囲 | リアルタイム安全性 |
| 「1 つのエンジンをどのランタイムからも」は計測されているか | サーフェスカバレッジ |
| 互換性や精度をどう解釈すべきか | 精度の境界 |
検証マトリクス
| 領域 | リポジトリ内の根拠 |
|---|---|
| librosa 互換特徴量 | tests/librosa/*_test.cpp と tests/librosa/reference/ の JSON 参照値で、STFT、メル、MFCC、クロマ/CQT、オンセット、ビート/テンポ、PCEN、tonnetz、無音処理、frame/pad/fix、peak pick、変換ヘルパーを検証 |
| コア DSP の基礎部品 | tests/core/*_test.cpp、tests/util/*_test.cpp、tests/filters/*_test.cpp、tests/rt/*_test.cpp で FFT、窓関数、リサンプリング、padding、sequence、filter、oversampling、True Peak フィルター、queue、リアルタイム用の基礎部品を検証 |
| 解析 | tests/analysis/*_test.cpp、tests/fixtures/music_eval/ の任意 music fixture manifest、合成 key/chord matrix で BPM、キー、コード、ビート、ダウンビート、拍子、メロディ、音色、リズム、セクション、境界、長尺境界のプーリング、音響解析を検証 |
| 幾何ベースのルーム音響 | tests/acoustic/*_test.cpp、tests/effects/room_morph_test.cpp、tests/api/sonare_c_acoustic_test.cpp、tests/fixtures/acoustic/ の任意 fixture、バインディングテストでルームモデル/マテリアル、鏡像音源法、後期残響、RIR 合成、等価ルーム推定、ルームモーフィング、C ABI 挙動を検証 |
| マスタリング | tests/mastering/*_test.cpp でチェーン設定、レイテンシ、EQ、ダイナミクス、マルチバンド、サチュレーション、リペア、スペクトラル、ステレオ、マッチ、マキシマイザー、EBU R128、ラウドネス上限、プリセット、ゴールデンハッシュ、性質ベースの確認、アシスタント出力を検証 |
| ミキシング | tests/mixing/*_test.cpp、bindings/node/tests/mixing.test.ts、bindings/python/tests/test_mixing.py、WASM テストでルーティング、インサートオートメーション、処理中にアロケーションしないこと、シーンプリセット、メーター、ゴニオメーター、バインディングのスモークテストを検証 |
| リアルタイムエンジン | tests/engine/*_test.cpp、bindings/python/tests/test_engine.py、WASM worklet テストでトランスポート、テンポ同期、メトロノーム、キャプチャ、グラフ実行、モニター実行、モノラルのモニターとバウンスの同等性、テレメトリ、オフラインバウンス、並行処理、AudioWorklet 実行を検証 |
| 内蔵シンセサイザー(NativeSynth)のボイス調整 | tools/voicematch/ がGM フォールバックボイスと、ドライな FluidSynth/SoundFont 側の参照音をレンダーして音色指標を比較。autofit.py は隔離されたビルドディレクトリで、指定した数値定数を自動調整できる。これは調整用ハーネスであり、ボイスが完成した楽器シミュレーションであることの証明ではない。各エンジンの状態は NativeSynth を参照 |
| バインディング | bindings/wasm/tests/*.test.ts、bindings/node/tests/*.test.ts、bindings/python/tests/*.py、型検査用のスモークテストで、公開 API の形、structuredClone 可能な WASM 戻り値、入力検証ガード、バインディング間の挙動を検証 |
| クロスバインディング parity | tools/parity で C++、C ABI、Python、Node、WASM 間の既定値、定数/enum、パラメータ名のずれを検出し、サーフェスカバレッジで説明するランタイム別の対応表も生成 |
| 再生レンダラー | tests/playback/*_test.cpp でスピーカーレイアウトとレイアウト変換、バイノーラルレンダリング、HRTF セットの形式、ナイトモードのダイナミクス、ラウドネス計測、レイテンシとサンプルレートの扱いを検証し、ノーアロケーションの処理チェックも含む |
| コンポジションアシスト | tests/assist/*_test.cpp でアシストモジュール、それらが差し込まれるシーム、音楽理論ヘルパーを検証 |
| CLI | tests/cli/cli_{analysis,effects,mastering,project,contract}_test.cpp と Python CLI パーサーのカバレッジで、ターミナルから使う入口を検証 |
| 公開契約 | make conformance が tools/conformance/ と tests/conformance/ のチェックを実行し、公開入力のコーパス、cli_contract_v2.json に記録した CLI コマンド契約、バインディング間の規約を検証します。文書化された契約が変わるとリリース前に失敗します |
| パフォーマンス | benchmarks/*.cpp、benchmarks/results.json、benchmarks/results_cpp.json でスペクトル処理、ストリーミングメル/クロマ、マスタリング補助処理、サンプル間ピーク(ISP)検出、ステレオ処理、ミキシング、EQ、リサンプリング周辺のホットパスを確認 |
「ゴールデンハッシュ」「プロパティチェック」「ノーアロケーションチェック」とは?
上で挙げたテストの種類です。
- 参照/回帰テスト: 現在の出力を保存済みの既知の正解値と比較します。数値が予期せずずれるとテストが失敗し、誤った変更を検出します。
- ゴールデンハッシュ: 既知の正解レンダリングのコンパクトなチェックサム。同じ入力を同じ設定で再処理すると同じハッシュが再現されるはずで、出力音の変化を即座に検出します。
- プロパティチェック: どんな入力でも成り立つべき不変条件を検証します(例「出力はシーリングを超えない」「モノラル合算したイメージャーは極性を反転しない」)。1 つの固定ケースではなく多数のランダム入力で確認します。
- ノーアロケーションチェック: リアルタイムコードが音声コールバック内でメモリ確保(
new/malloc)を一切しないことを検証します。確保が起きると停止してドロップアウトを招く恐れがあるためです。
リアルタイム安全性
リアルタイム向けコードは、複数の観点で検証されています。
| 検証 | 守っていること |
|---|---|
| ノーアロケーションチェック | 音声コールバック内でメモリ確保しないこと。 |
| ロックフリーなコマンド/テレメトリキュー | 制御メッセージが音声スレッドを止めないこと。 |
| グラフ実行時テスト、AudioWorklet スモークテスト、ブロック単位同等性テスト、ボイスチェンジャー品質ゲート | リアルタイム経路が、対応するオフライン参照と同じ意味で動くこと。 |
一方で libsonare では、リアルタイム安全なブロック処理とオフライン用ヘルパーを区別しています。重いリペア処理やファイル全体のラウドネス最適化は、意図的にオフライン処理として設計されています。
サーフェスカバレッジ
「1 つの C++ コアをどのランタイムからも呼べる」という主張は、DSP については正しく、「C の入口がすべてのランタイムに存在する」と読むと誤りです。そのためリポジトリは、推測に任せるのではなく実際の到達範囲を公開しています。その根拠が tools/parity/surface-coverage.md です。公開 C ヘッダーごと(これがドメイン)に 1 行、ランタイムごと(Python、Node、WASM、そして 2 つのコマンドラインフロントエンドはそれぞれ別の列)に 1 列を持つ生成表で、各セルはそのドメインの C ABI 入口のうち、ランタイムが到達できる本数です。
これが主張ではなく根拠と言える理由は 3 つあります。
- 手書きではなく、ソースから生成されたものです。
tools/parity/surface_coverage.pyは parity チェッカー自身の抽出器と到達判定規則(クラスのメソッド、ハンドル接頭辞の付け替え、検証済みの別名はいずれも解決されます)を再利用するので、「公開されている」の定義が 2 つあってずれる余地がありません。make surface-coverageがファイルを書き直します。 - 古いコピーは CI で失敗します。
make surface-coverage-checkは表を再生成して追跡中のものと比較するので、表が追いつかないままヘッダーが増えると、楽観的な数値が黙って残るのではなくビルドが失敗します。 - 検討済みの欠落も見えたままです。 検討済みの差を parity チェックに通す許可リストは、その機能をランタイムに戻すわけではありません。許可リストに載った差も差として数えるので、検討だけで表を完成しているように見せることはできません。
したがって、表にある差は計測された欠落です。それが欠陥かどうかは別の問いで、バインディング対応表がランタイムごとに答えます。どちらの CLI も設計上絞り込まれた部分集合ですし、WASM はホストのファイルシステムにもスレッドにもアクセスできません。
精度の境界
librosa 互換性は、対象ヘルパーが生成済み参照値と比較されていることを意味します。高レベルの音楽解析結果がすべて librosa と同一という意味ではありません。
マスタリング検証では、DSP の不変条件、ラウドネス/True Peak 挙動、ゴールデンハッシュ、必要に応じた公開アルゴリズム上の前提を確認します。
ルーム音響のブラインド推定や楽曲構造解析は、ヒューリスティックな特徴量です。結果は、信頼度付きの推定値として扱ってください。
自分の素材で音楽解析の精度を測る
上の「推定値」は定性的な表現です。リポジトリには、fixture 駆動の精度レポートが同梱されています(tools/eval/summarize_accuracy.py、make accuracy-report で一括実行)。コーパスを実行した結果を、キー精度と MIREX 加重スコア、4% 許容誤差での BPM 精度、ビートとダウンビートの F 値、拍子の精度、メジャー/マイナーと厳密クオリティ両方の語彙でのコード再現率にまとめます。データセットごとに内訳が出て、各数値には fixture 件数が添えられます。
計測対象のデータセットは研究利用限定のライセンスで再配布できないため、マニフェストは空の状態で同梱されており、レポートは手元に用意したコーパスに対して実行します。
出力を読んだり自動化したりする前に知っておくべき挙動が 2 つあります。観測値がない次元は unmeasured として報告され、点数にはなりません。使えないデータ点を黙って読み飛ばし残りだけを平均する指標だと、空集合を満点として扱ってしまうためで、fixture ランナーは音声が見つからない行を意図的にスキップします。もう 1 つは --require <dimension> で、期待した次元が 1 件も観測値を出さなかった場合に実行を失敗させ、パスの誤りが一見「通過」に見えてしまう事態を防ぎます。
手順は FAQ: 自分の素材で精度を測るには? を参照してください。