高精度HPFをJavaで作る

HPF(ハイパスフィルター)は何かと必須だと思えて、AudacityのHPFやらEQやらVSTを試してみる。HPFは違いが音として分かりにくい側面があるのだけど、ミックスなどでは確かに質が変化してくる。目立たないけどめちゃくちゃ重要じゃないか?HPFって。

AudacityのHPFはIIRのButterworthタイプで高速に処理できるのはよいのだが、位相が変化してしまう欠点があるのと、効き方がどうしてもゆるくなってしまう。

次にVSTのHPFもいくつか試してみるがAudacityとの相性の問題も出てしまう。VSTのFIRタイプだと音が遅れてしまうのが普通なので、使えないという判断。

Audacity標準のEqualizationをHPFとして使う手もあると思って試してみる。フィルタータイプはおそらくFrequency Sampling MethodでFFTを使って高速処理しているようだ。直線位相なので、位相問題もなく、かなり高精度という印象。タップ数は選択可能で最大で8191使える。これで効き方なども調整できる。なかなか素晴らしいHPFという結論。ただ微妙な誤差が出ているように思うのは設定値の誤差なのか、FFTの計算上のものなのか分からない。量子化ノイズ程度なので、測定しないと分からない範囲ではあるが。

ということで、勉強も含めて精度優先でDFTを使ったHPFを作ってみた。速度を無視すれば楽に精度を上げられる。はっきり言って実用性はあまりない。リアルタイム処理なんて絶対無理。ただ試したかっただけ。処理時間は数分の入力信号でも、数十秒から分単位で計算する・・・。FFTで高速処理させないと実用にはならないと判断。FFTは原理のところからちゃんと勉強して誤差を最小にしたいところ。実現するには、それなりに勉強が必要そう。

現状では遅いのだが、floatの音声ファイルの処理なら、バイナリーレベルでチェックしても誤差0となった。またFIRの遅れもリアルタイムではないので、レイテンシー0に細工した。あと窓関数の種類でHPFのかかり方が大きく変化するので、その辺りもいろいろ試した方がよさそう。hammingはカットがあまくなるのでHPFには向いてない。hanningは結構鋭くかかるという印象でHPFには適していると思う。自分でHPFに最適な窓関数を考えてみるのも面白い。

公開できるレベルで最適化していないので、まだ非公開。誤差が出ない範囲で効率化を実現したら公開しようかと思う。

sound programming 目次はこちら