Skip to content

クロマ特徴量 ​

クロマは、ハーモニー解析の土台になる表現です。スペクトル全体を C、C♯、D、… B の 12 のピッチクラスビンへ畳み込み、各フレームで「C のエネルギーはどれだけ、C♯ はどれだけ」をオクターブによらず示します。キー検出もコード認識もここから読み取ります。本ページは MIR の全体像 のハーモニーの節を掘り下げます。

ピッチクラス: オクターブを忘れる ​

ピッチクラスは、ある音名のすべてのオクターブをひとまとめにします。C2、C3、C4 は別々の音高ですが、同じピッチクラス「C」です。西洋音楽には半音ごとに 12 のピッチクラスがあります。クロマは STFT フレーム内の全周波数に広がるエネルギーをその 12 ビンへ合算するので、どのオクターブで弾かれた C も同じビンに入ります。

ただし、すべてのオクターブが同じ重みで足されるわけではありません。libsonare のフィルターバンクは librosa のリファレンスに合わせ、A5(880 Hz)を中心とし、標準偏差 2 オクターブのガウス包絡線で各ビンの寄与に重みを付けます。包絡線の幅は広く、中低域から数 kHz までは強く数えられますが、それより下では減っていきます。中心からほぼ 4 オクターブ下の C2(65 Hz)付近の音は、重みが 5 分の 1 未満になります。はっきり聞こえているベースラインがクロマグラム上では薄く見えるのは、このためです。

この意図的な「忘却」が要点です。ハーモニーはどのオクターブではなくどの音の話です。C メジャーコードは、低く配置されても高く配置されても C メジャーコードです。オクターブを畳み込むと、各時点のハーモニーを表す 12 次元の小さな指紋が得られます。

たとえば低い C、中央の C、高い C が同時に鳴っていても、クロマでは全部 C のビンに足されます。一方で、C と E と G が強ければ C メジャーらしい、A と C と E が強ければ A マイナーらしい、という判断に使えます。つまりクロマは「音名の分布」を見る道具です。

クロマグラム: 時間軸上のクロマ ​

各フレームのクロマベクトルを積み重ねるとクロマグラムになります。ピッチクラスのエネルギーが曲の中をどう動くかを示す 12 行の画像です。持続するコードは安定した水平の帯として現れ、キーが変わると点灯し続けるビンが移ります。ビジュアライザーはこれを直接描き、アナライザーはここからパターンを読み出します。

フレームは「音声を短く切った 1 コマ」です。動画が静止画の連続でできているように、クロマグラムは短い時間ごとのクロマを横に並べたものです。横方向が時間、縦方向が 12 音名、と考えると読みやすくなります。

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

すべての周波数を12のピッチクラスへ畳み込むため、オクターブは消え、ハーモニーが残ります。このクリップは C–Am–F–G の三和音だけを小節ごとに鳴らし、コードの間に1拍の休符を置いています。点灯する行の移動を見てから、進行を再生してください。

NNLS クロマ: ビンを畳むのではなく音を当てはめる ​

通常の STFT クロマや CQT クロマは、各周波数ビンをそのままピッチクラスへ畳み込みます。そのため音の倍音が別のピッチクラスのビンにも入ります。C の第 3 倍音は G、第 5 倍音は E なので、低い C を 1 音鳴らしただけでも C メジャーの和音が少し点灯します。

NNLS クロマ(非負最小二乗法)は、フレームごとに別の問いを立てます。このスペクトルを最もよく説明する音の組み合わせは何か、という問いです。libsonare はピアノの鍵盤 1 つにつき 1 つ(A0 から C8 までの 88 音)のテンプレートを持つ固定の辞書を作ります。各テンプレートは最初の 6 つの部分音を重みを下げながら並べたもので、1 半音 3 ビンの定 Q スペクトル上に置かれます。CQT 振幅の各フレームをこれらのテンプレートの和として当てはめ、どの音の量も 0 以上に保ちます。得られた音の量を 12 のピッチクラスへ畳むので、当てはめで C に帰属した倍音は G や E ではなく C として数えられます。そのぶんコード用のプロファイルがきれいになり、特に強いベースの上で効きます。

既定では純粋な NNLS の出力ではありません。複数の低い音が 1 つの部分音を同じくらい説明できてしまう、まばらな素材や純音でも安定するように、結果を直接の CQT クロマと混ぜ(当てはめ 60 %、直接 40 %)、さらに通常の STFT クロマと stftBlendWeight 0.55 で混ぜます。当てはめた CQT ベースのプロファイルだけが欲しい場合は enableStftBlend: false を渡します。

nnlsChroma(...)(Python は nnls_chroma)は、これを 12 × フレーム数の行列として返し、各フレームは最大値が 1 になるよう正規化されています。detectChords(...) に chromaMethod: 'nnls' を渡すと、同じフロントエンドの軽量版(5 オクターブ、1 音あたり 4 つの部分音)を使います。

クロマがハーモニーに適し、メロディに不向きな理由 ​

問いクロマを使う?理由
キーは何か?はい全体のピッチクラス分布が調性の中心を示します
今鳴っているコードは?はいフレームのクロマがコードテンプレートと一致します
ベースのオクターブは?いいえオクターブは畳み込まれています
リードメロディの音は?いいえピッチ追跡を使います。クロマは旋律線を分離できません
どの楽器か?いいえ音色はスペクトル形状が必要なので MFCC を使います

表現を問いに合わせるのは、MIR(Music Information Retrieval、音楽情報検索)で繰り返し必要になる技能です。クロマはハーモニーを明確にするために、オクターブと音色の詳細をあえて手放します。

libsonare がクロマをどう構築するか

Chroma クラスは STFT のパワースペクトルにクロマフィルターバンクを適用し、各周波数ビンを(上記のオクターブ包絡で重み付けしながら)そのピッチクラスへ対応づけて 12 ビンへ累積し、フレームごとに最大値が 1.0 になるよう正規化します(L-infinity)。振幅ではなくパワーを入力とするため、強い倍音ほど大きく効きます。

項目内容
基本設定n_chroma = 12。fmin と n_octaves も設定に含まれますが、STFT クロマのフィルターバンクはこれらを参照しません(CQT クロマ側の概念で、指定しても解析範囲は変わりません)
解析窓n_fft = 2048/hop_length = 512、Hann 窓
チューニング12 ビン構成では、tuning に A440 からのずれを半音分数で指定します。既定は 0(A440)で、analyze・detectChords・detectKey に tuning: 'auto' を渡したときだけ信号から測定します
算出方式STFT ベース、CQT ベース(chromaCqt / chroma_cqt、ChromaCqtConfig。librosa.feature.chroma_cqt の直接の相当)、CENS(ChromaCensConfig)
コード向け変種NnlsChromaConfig(非負最小二乗)で倍音の影響を抑える

クロマは KeyAnalyzer(Krumhansl-Schmuckler 系)と ChordAnalyzer(テンプレートマッチング)で使われるため、クロマ段を改善すると下流の 2 機能が同時に良くなります。

チューニングは要求したときだけ測定されます

ChromaConfig.tuning の既定は 0、つまり A440 で、クロマ段が自分でこれを推定することはありません。librosa.feature.chroma_stft は既定の tuning=None でまず estimate_tuning() を実行するので、この点で挙動が異なります。A440 から半音の何分の一かずれた録音では、ピッチクラスの格子が実際の倍音列と合わなくなり、エネルギーが隣のビンへにじみ、キーやコードの結果が何の警告もないまま劣化します。

古い録音、テープ、生演奏、意図的に別の基準ピッチで演奏されたものなど、素材が A440 でない可能性がある場合は、analyze・detectChords・detectKey(Python では analyze・detect_chords・detect_key)に tuning: 'auto'(Python では tuning="auto")を渡してください。エンジンが先にずれを測定し、その値でクロマを作ります。estimateTuning()/estimate_tuning() が返す半音分数の値([-0.5, 0.5))を直接渡すこともでき、C++ では ChromaConfig.tuning にそのまま渡します。どの結果も、実際に使った値を返します(AnalysisResult・ChordAnalysisResult の tuning、detectKey の KeyDetection)。45 セント低く調律した合成のハ長調和音は、A440 のままだとホ短調と判定され、tuning: 'auto' ではハ長調と判定されて、約 -0.43 のチューニングを報告しました。単体の chroma は A440 固定で、チューニング引数を受け取りません。tuningToReferenceHz(tuning) と referenceHzToTuning(hz) で、この単位と Hz 単位の基準ピッチを相互に換算できます。ストリーミングは Hz をそのまま使い、作成時の tuningRefHz または処理中の setTuningRefHz() に A4 の基準周波数を指定します。ビジュアルプレイヤーは、読み込んだファイルごとにずれを推定して適用しています。

関連: MIR の全体像、キー検出、コード認識、スペクトログラムと STFT