「信号処理に欠かせないオールパスフィルタ―の概要・使い方・利用例」では、オールパスフィルタによって低演算量で様々な周波数特性のフィルタを作成できることを紹介しました。
この記事では、その具体例として1次IIRオールパスフィルタの並列回路でローパス/ハイパスフィルタを作成します。
1次IIRオールパスフィルタ
1次IIRオールパスフィルタの詳細はこちらの記事を参考にしてください。
今回は位相が90度遅れる周波数 fc
を4つ用意し、それぞれのフィルタ係数用パラメタ λ
を算出しました。
sr = 44100 worN = 4096 # 0.3, 2.8, 11.0, 17.6 kHz fc_list = (sr/128, sr/16, sr/4, sr/2.5) fr_list = [] for fc in fc_list: lam = -(np.tan(np.pi*fc/sr)-1)/(np.tan(np.pi*fc/sr)+1) b = np.array([-lam, 1.0]) a = np.array([1.0, -lam]) label=f"lam={lam:0.3f}, fc={fc:.0f} Hz" w, h = freqz(b, a=a, worN=worN) freqs = w / np.pi * (sr//2) angle = np.angle(h)/np.pi*180 angle[angle>0] = -180 - (180 - angle[angle>0]) angle = -angle
各オールパスフィルタの位相特性は以下のようになります。
なお、今回はプロット用に手動で位相アンラッピングをしていますが、numpy.unwrap
が便利です*1。
ローパスフィルタ
以下は1次IIRオールパスフィルタを使ったローパスフィルタのブロック図と伝達関数です。
入力信号とオールパスフィルタ出力を足し合わせることで、最終的な出力信号となります。
h = 0.5*(h+1)
オールパスフィルタによって高周波では位相が逆相波に近づくため、この回路全体の振幅特性は以下のようなローパスフィルタの特性となります。
以下は回路全体の振幅特性のプロットです。なお、下図は横軸(周波数)を対数軸にしたバージョンです。
ハイパスフィルタ
以下は1次IIRオールパスフィルタを使ったハイパスフィルタのブロック図と伝達関数です。
結局のところ、オールパスフィルタ出力は符号を変えることで低周波になるほど逆位相に近づき、高周波になるほど入力信号と同位相に近づきます。
h = 0.5*(h-1)
従って、回路全体の出力では高周波が残るためハイパスフィルタの特性となります。
まとめ
Pythonで1次IIRオールパスフィルタを使った並列回路でローパス/ハイパスフィルタを作りました。
なお、今回のフィルタは1次FIRフィルタの遅延素子を1次IIRオールパスフィルタに置き換えることで周波数特性の伸縮(周波数ワープ)をしているとも考えられます。
周波数ワープの詳細については以下の記事をご覧ください。
*1:使用可能な numpyのバージョンは 1.21.0 以上