がれすたさんのDIY日記

電子回路、Python、組み込みシステム開発、自作エフェクターを語るblog

Python:scipy.signal.iirdesignを使ってIIRフィルタを設計する



今回はscipy.signal.iirdesignメソッドを使ってIIRフィルタを設計してみる。
ScipyのVerは1.2を使用している前提で進める

google colabの場合は

!pip install --upgrade scipy

をしてからランタイムのリセットをする

API仕様としては以下に示す通り

  • scipy.signal.iirdesign(wp, ws, gpass, gstop, analog=False, ftype='ellip', output='ba', fs=None)


Ver1.2からfsパラメータが増えていることに注目してほしい。
これを指定することでfsスケールで計算結果が返ってくる。


次に引数の説明を軽くしておく。

ftypeはフィルタの特性を指定できる。

  • Butterworth : ‘butter’
  • Chebyshev I : ‘cheby1’
  • Chebyshev II : ‘cheby2’
  • Cauer/elliptic: ‘ellip’
  • Bessel/Thomson: ‘bessel’

outputはどういう形で返り値を返すかの指定ができる。
零点、極、gain形式やバイクアッド型式が選択可能だが基本的にはbaを選んでおけばよいだろう。

fsはシステムのサンプリング周波数を指定する。
今回の例では48000Hz

フィルタの設計

フィルタ詳細は

  • 通過域周波数 : 100[Hz]
  • 遮断域周波数 : 1000[Hz]
  • 通過域ゲイン : 1.0[dB]
  • 遮断域ゲイン : 20[dB]

上記のようにパラメータを設計する。
パラメータは以下の図を参考に設計するといいと思う

f:id:gsmcustomeffects:20190116224910p:plain
フィルタ説明[Python scipy.signal IIR Filter Design]

ソースコード

from scipy import signal
import matplotlib.pyplot as plt
import numpy as np

fs = 48000
fpass = 100.0
fstop = 1000.0
gpass = 1
gstop = 20.0

#IIRフィルタの係数計算(fsパラメータはScipy Ver1.2から使える)
b,a = signal.iirdesign(fpass, fstop,gpass,gstop,analog=False, ftype='butter', output='ba', fs=fs)

#周波数応答の計算(fsパラメータはScipy Ver1.2から使える)
fs, h = signal.freqz(b,a,fs=fs)


fig, ax1 = plt.subplots()
plt.grid(which="both")
ax1.set_title('Digital filter frequency response')
ax1.semilogx(fs, 20 * np.log10(abs(h)))
ax1.axis((10, 10000, -100, 10))
ax1.set_ylabel('Amplitude [dB]')
ax1.set_xlabel('Frequency [Hz]')

plt.show()

f:id:gsmcustomeffects:20190116225250p:plain
設計したIIRフィルタの周波数応答

※freqzメソッドも同様にfsパラメータが付与されている。