フィルタのうち一番手軽に使えそうなIIRローパスフィルターをJavaで実装します。前回説明したがIIRローパスフィルターはIIRという方式で作成する低い周波数のみ通過させるフィルターです。あとでオプティマイズは必要でしょうがひとまず動くものを作ります。
必要なパラメーター
フィルターを作るにあたって必要な要素が3つあります。
サンプルレート sample rate
同じ機能のフィルターであってもサンプルレートが違うと計算が異なります。デジタル信号で過去のサンプルを利用するということは一つ前のサンプルの時間はサンプルレートによって変わって来てしまうからです。
例えばサンプルレート20kHzでの一つ前のサンプルが入力された時間はサンプルレートが40kHzの場合よりも2倍前の時間になります。
このことはフィルターの係数を計算する上で考慮しなければいけません。今まで通りサンプル変数は48kHzとして計算します。
遮断周波数 cutoff frequency
どの周波数を通過と遮断の境目にするかを表します。実際にはこの周波数の前後でなだらかに変化し少し高い周波数のところでは遮断され、少し低いところでは通過するようになります。このなだらかさはフィルタの次数によって変えることができますが品質と処理時間のトレードオフになります。
デジタルフィルターの場合は計算に使えるための遮断変数は以下の式で求めます。目的の遮断周波数は変数名cutoff、デジタルフィルターで使うための変数はfcとしておきます。
遮断変数fc = tan( π * cutoff / sample_rate) / 2π
クオリティファクタ quality factor
遮断周波数での増幅率として使われます。遮断周波数前後でなだらかに通過から遮断に変化するため1と0の間の数字を使うのが妥当です。一般的には
1 / √2
とされています。この値は後々使うので変化させられるように実装するようにします。
係数について
サンプルに対して変化させるために使う係数を計算します。まずどのような係数が必要か整理します。
前係数
読み込んだ入力サンプルに対して掛け合わせる係数です。bはbeforeの略です。
係数名 | 対象の入力 |
---|---|
b0 | read0 : 今回入力されたサンプル |
b1 | read1 : 前回入力されたサンプル |
b2 | read2 : 前々回入力されたサンプル |
後係数
過去に計算した後出力したサンプルに対して掛け合わせる係数です。aはafterの略です。今回出力するサンプルをまさに計算中であるため前係数のように0番目はありません。
係数名 | 対象の入力 |
---|---|
a1 | return1 : 前回出力されたサンプル |
a2 | return2 : 前々回出力されたサンプル |
フィルターの計算の概要
今回入力された値read0が与えられた時出力値return0は以下のように計算します。
double return0 = 0; return0 += b0 * read0; return0 += b1 * read1; return0 += b2 * read2; return0 -= a1 * return1; return0 -= a2 * return2;
後係数による計算の時は減算しているのに注意してください。
次回係数の計算をします。