TadaoYamaokaの開発日記

個人開発しているスマホアプリや将棋AIの開発ネタを中心に書いていきます。

CQTでスペクトログラムを描く

個人メモ

音声信号をFFT短時間フーリエ変換を行うと、低周波数帯で周波数分解能が不足し、高周波数帯では必要以上の周波数分解能になる。

音楽の解析をする場合、周波数の対数スケールで、半音区間ごとのビンを扱うと都合がよい場合がある。

そのような場合、Constant-Q Transform(CQT)が使用される。

Constant-Q Transform(CQT)

Constant-Q Transform (CQT) とは、中心周波数に対する帯域幅の比(Q値)を一定に保ち、対数周波数スケールで信号を解析することで、人間の聴覚特性や音楽信号処理に適した時間–周波数変換手法である。

CQTは、信号 x(t) に対して以下のように定義される:

\displaystyle
X(k,n) = \sum_{m=0}^{N_k - 1} x[ n+m ] w_k[m] e^{-j 2 \pi Q m / N_k}

  • k: 周波数ビン(例えば半音階の各音)
  • n: 時間インデックス
  • N_k: k-番目の周波数ビンに対応する窓長
  • w_k[m]: 窓関数(例えばハニング窓)
  • Q: 定数値で、Q値と呼ばれる

\displaystyle
  Q = \frac{f_k}{\Delta f_k}

各周波数ビンごとに窓長 N_k が異なるという特徴がある。

\displaystyle
  N_k = \frac{Q \cdot f_s}{f_k}

定義通り計算すると、計算量が大きい。

CQTの高速化

FFTを使用して、CQTを高速化する手法に、「An efficient algorithm for the calculation of a constant Q transform」がある。

時間領域の逐次畳み込みではなく FFT を用いて周波数領域の疎なカーネルとの積和に置き換えることで、CQT を効率的に計算する手法である。

CQTを使用してリアルタイムにスペクトログラムを描画

C++でCQTを使用してリアルタイムにスペクトログラムを描画するWindowsプログラムを作成した。

特性

サンプリング周波数44.1kHzで、ギターの6弦の開放弦であるE2を含めるには、FFTの窓長(2のべき乗)は16384が必要になる。 FFTの窓長16384で、最低周波f_{min}は、F#1付近になる。

時間分解能は、約 372 msとなる。

スペクトログラムの上限の周波数は、4 kHzに制限した。

その場合、周波数領域カーネルの疎行列の要素数は、しきい値を論文の推奨値0.15とした場合、4178となった。 音声信号のFFTの結果に対する乗算回数は、実部と虚部の合計で、8356回になる。

まとめ

FFTでCQTを高速化する処理を実装し、リアルタイムにスペクトログラムを描くプログラムを作成した。 FFTと周波数領域カーネルの疎行列化により乗算回数が抑えられており、リアルタイムで十分に処理できる軽さになっている。