音楽信号の音高分析に便利な定Q変換 (CQT)。
これまでにいくつか計算アルゴリズムや実装方法の種類を紹介してきました。
おそらく再帰的ダウンサンプリング法が速いと思っていたのですが、条件によっては疎行列計算と変わらないことがあったりと、実環境での処理速度の違いが気になっていました。
そこで、3つのリアルタイム向け定Q変換の Python 実装と、オフライン向けであるLibROSA の定Q変換とSTFTの処理速度を比較してみました
比較環境
- OS: Win10
- Python環境: Anaconda
比較する手法と条件
冒頭に書いたように、比較手法は以下の5つとします。
- スペクトルカーネル
- スペクトルカーネル+疎行列計算
- 再帰的ダウンサンプリング法
- LibROSA CQT(再帰的ダウンサンプリング法+バッチ処理特化)
- LibROSA STFT (
n_fft=8192
)
1~3はリアルタイム用の実装,4, 5はバッチ処理用の実装となっています*1。
1, 2 の実装は以下になります。
3の実装は以下になります
その他の条件は以下のように設定しました。
- 分析する信号は90秒のJPOP楽曲
- サンプリング周波数 44.1 kHz
- 各手法,5回計測
hop_length=256
- オクターブ数
n_octave
- 1オクターブのビン数
n_bins_per_octave
- 一番低い音高の周波数
fmin
比較1: 基本設定
良く使われる設定を試してみました。
- 最も低い周波数を22.5 Hz (A0)
- オクターブの数 8
- 1オクターブのビン数 12
(2)疎行列計算と(3)ダウンサンプリング法であまり差がでませんでした。
この条件での疎行列計算と比べると、オクターブ分割+ローパスフィルタリングにそれなりの計算が必要なのかなという印象です。
比較2: 1オクターブあたりの周波数ビン数を増やす
1オクターブあたり24ビンにしてみました。
(1)スペクトルカーネルで疎行列計算使わないと、信号が90秒なのに処理に250秒近くかかってしまってます。。
この条件では(2)疎行列計算と(3)ダウンサンプリング法で2倍くらい差がでました。
比較3: 低周波数を分析しない場合
メロディやコード分析の場合,中~高音域のみの分析でよいケースもあります。
そこで,fmin
を22.5 Hzから110Hzに変え,分析するオクターブ数を8から6に変更した場合の計算量をみてみます。
こちらはどれも10秒以内に終わります。
リアルタイム向けとバッチ処理向け実装で差があまりありません。
まとめ
リアルタイム/オフライン向け定Q変換のアルゴリズム・実装の処理速度を比較してみました。
計算機、プログラミング言語、処理系で結果は変わると思いますが、Pythonでの定Q変換の処理速度の比較結果は以下のようになりました