Skip to content

スペクトログラムと STFT

libsonare のほぼすべての MIR 機能 — クロマ、メル、MFCC、オンセット強度、さらには BPM やキー — は、音声の時間-周波数表現から計算されます。この 1 つの土台を理解すれば、なぜ多くの関数が同じ nFfthopLength を共有するのかが分かります。本ページは MIR の全体像 の地図より 1 段深く掘り下げます。

波形から周波数へ: FFT

波形は時間に対する振幅であり、どの周波数が含まれるかは教えてくれません。フーリエ変換はそれに答えます — 信号を、それを合成する正弦波へ分解します。プリズムが光を色に分けるようなものです。FFT(高速フーリエ変換)は、それをサンプルのブロックに対して効率的に計算するアルゴリズムにすぎません。

問題は、1 回の FFT はブロック全体を、その周波数内容がまったく変化しないかのように記述する点です。音楽は絶えず変化するので、曲全体の単一 FFT はほとんど役に立ちません。

時間変化を追う: STFT

短時間フーリエ変換(STFT)は、音声を短く重なり合う窓に切り分け、それぞれに FFT をかけることでこれを解決します。結果は 2 次元のグリッド — 各時刻の周波数内容です。スペクトログラムはそのグリッドを画像として描いたもので、一方の軸が時間、もう一方が周波数、エネルギーが明るさです。

STFT · SPECTRALIDLE
STFT — 時間と周波数を同時に見る

220 Hz から 4 kHz へ上昇するトーン。各列が1つの短時間スペクトルで、明るいほどその周波数のエネルギーが大きい。

このグリッドを制御するため、2 つのパラメータがどこにでも現れます。

パラメータ設定するものトレードオフ
nFft窓サイズ(サンプル数。例 2048大きいほど周波数が細かく、時間は粗くなります
hopLength窓を進める量(例 512小さいほど 1 秒あたりのフレームが増え(動きが滑らか)、CPU 負荷も増えます

これが時間-周波数の分解能トレードオフです。完璧な周波数分解能と完璧な時間分解能を同時には得られません。これは物理であり、libsonare の制約ではありません。

窓掛け

各ブロックは FFT の前に、端をゼロへなめらかに落とす窓関数(Hann 窓など)と掛け合わされます。これがないと、ブロック境界の急な切れ目が周波数全体へエネルギーを漏らし(スペクトル漏れ)、結果がにじみます。窓掛けはフレームが重なる理由でもあります — テーパーした端は隣のフレームが補います。

音楽的な間隔: CQT と VQT

標準の STFT は周波数ビンを Hz で均等に並べます。しかし音名は対数的に並び — オクターブごとに周波数が倍になる — ため、均等なグリッドは高域で分解能を浪費し、低域で不足します。定 Q 変換(CQT)は音楽的な音程ごと(通常は半音ごと)にビンを並べ、オクターブあたり同じ分解能を与えます。可変 Q 変換(VQT)は CQT に似ていますが、低域では音名ごとの厳密な間隔をゆるめ、低い音が時間方向ににじまないようにします。CQT のような音高を意識したビンを使いつつ、ベースや低域の打撃成分の時間挙動をきれいに保ちたいときに使います。

libsonare が STFT をどう計算するか

libsonare の STFT・フレーミングユーティリティは、窓(既定で Hann)を適用し、hopLength ずつ進め、フレームごとに実数 FFT を実行して、メル・クロマ・オンセット・テンポグラムの各段が再利用する振幅/パワースペクトルを生成します。中間のスペクトログラムが共有されるため、1 つのソースに対して複数機能を求めても FFT を毎回計算し直しません。nFft/hopLength の既定値(2048/512)は一般的な librosa の使い方に合わせ、リファレンステストで出力を比較できるようにしています。CQT/VQT は同じフレーミング規約の上に対数周波数ビンを重ねます。

関連: MIR の全体像, クロマ特徴量, メル・MFCC・音色, オーディオ基礎