コード認識
コード認識は、時間ごとに鳴っているハーモニーを推定し、開始/終了時刻と信頼度を持つコード区間を返します。キー検出と違い、「今鳴っているコードは何か」を見る局所的なハーモニー解析です。
コンピュータにとってのコードとは
コードは複数の音が 1 つのまとまりとして鳴るものです — C メジャーは C + E + G です。認識で重要なのは、オクターブや楽器ではなく、含まれるピッチクラスの集合で、これはまさにクロマが捉えるものです。C メジャーコードはどう配置されても C・E・G のビンを点灯させます。認識が生のスペクトルではなくクロマ上で動くのはこのためです。
クロマとテンプレート
libsonare はフレーム単位、またはビート同期したクロマ要約をコードテンプレート集合と比較します。テンプレートには、3 つの音からなる素朴なコード(三和音。たとえば C メジャー)に加え、音を足したり変化させたりするより豊かな品質 — 7th、9th、add9、diminished、half-diminished、sus 系 — が含まれます。各区間で最も合うルートと品質が選ばれます。
既定では、拡張コードは単純な三和音より一定以上よく一致しない限り採用されません。これにより、ノイズの多いクロマで普通の三和音が不安定な拡張コードに化けるのを抑えます。
イメージとしては、各フレームのクロマという「12 音の点灯パターン」を、あらかじめ用意したコードごとの理想パターン(テンプレート)と重ね、最もよく重なるものを選ぶ作業です。これを時間方向に並べるとコード進行になります。
タイミングとスムージング
コード検出はフレームレベルのクロマでも、ビート同期クロマでも実行できます。コード変化はビートにそろうことが多いため、通常はビート同期のほうが音楽的に整理された変化になります。スムージングと最小長のマージにより、ごく短いラベルのちらつきを避けます。
必要に応じて HMM スムージング(隠れマルコフモデル。各区間を単独で判定するのではなく、つながりとして自然なコード列を優先する手法)をコード候補にかけ、キーコンテキストを併用してちらつきをさらに抑えられます。ストリーミングでは推定が逐次更新されるため、十分な文脈がたまるまでは暫定値として扱います。
よくある混同
ハーモニー的に近いコードは音を共有するため、置き換えが起きます。C メジャーと A マイナー 7 は 3 つのピッチクラスを共有し、コードに経過メロディ音が加わるとより豊かな拡張に見えます。隣接コード間のときどきの入れ替わりは想定してください。清潔で持続する素材で最も強く、密で歪んだミックスでは倍音がテンプレートの読むクロマをぼかすため最も弱くなります。信頼度の低い区間は UI で淡く表示するなど、確定ではなく候補として扱うと実態に合います。
libsonare がどう計算するか
ChordAnalyzer は STFT または NNLS クロマを作り、テンプレート相関で候補を採点します。拡張コードは設定された余裕を超えた場合だけ三和音より優先され、minDuration 未満の短い区間はマージされます。既定値は minDuration = 0.3、smoothingWindow = 2.0、threshold = 0.5、nFft = 2048、hopLength = 512、useBeatSync = true です。公開バインディングでは、コードのルート、品質、時刻、信頼度に加え、バインディングに応じて inversion、key、HMM オプションを扱えます。
関連: クロマ特徴量, キー検出, ビートとダウンビート