音声ファイルから動画ファイルを生成する(34) - スペアナ表示を作る

公開:2014-02-02 18:10
更新:2020-02-15 04:37
カテゴリ:音声動画出力プログラム,windows,c++,audio

少し問題というか

FFTによる表示も少し手慣れてきたところで、ちょっと問題が発生した。たんなる知識不足のせいかもしれないけれども。

いまどうやっているかというと、曲を1470サンプル(1/30秒)ずつずらしながら4096サンプルごとにFFTを実施して、その結果をスペアナ風表示をしている。

44100Hzの波形データを4096サンプルでFFTをかけると、2048段階の周波数スペクトルが得られる。これは約10Hz単位の周波数精度である。これをそのまま横軸を周波数、縦軸を振幅という形で表示すると左端に表示が偏る。これは楽音の周波数帯域が、20Hz~5KHz位だからである。

視覚的にはこれでは面白くないので、横軸は楽音の周波数帯域を中心に表示するようにする。横軸をどうとるかであるが、私はMIDIノートナンバー(音階)で表示することにした。つまり横軸はMIDIノートナンバーの36から127に対応した周波数を画面に表示すれば、楽音の周波数帯域をだいたいカバーするはずだと考えたからである。ノートナンバーから周波数を変換す数式は「MIDI Tuning Standard」の数式をそのまま使用している。

これを横軸にして表示してみた結果が下の動画である。

しかしこうすると、低い周波数帯域の粒度が粗くなってしまう。低域ではノートごとの周波数の刻みが細かく10Hz単位以下の動きとなってしまい、丸められてしまうからである。これをできる限り回避するためにはFFTに渡すサンプル数を増やす必要がある。1回のFFTに渡すサンプル数が多くすると周波数の分解能が上がるからである。試しに16384サンプル単位で行った結果が下の動画である。

確かに低域での粒度は細かくなったのが、サンプル数を増やすと今度は時間分解能が粗くなってしまい楽曲に動画が追従しなくなるようである。このあたりの調整がフーリエ変換を使ってスペアナを表示する上で難しい部分かもしれない。