裏目小僧の部屋

フィルタIIR一次

一次のIIRフィルターで出来る事

  • LPF 低周波成分は普通に通し高周波成分程にカットする
  • HPF 高周波成分は普通に通し低周波成分程にカットする
  • APF 周波数成分には影響なく位相にだけ影響を与える

一次のIIRフィルターの音声処理での使い道

  • LPF 音声帯では距離が離れてゆくと高域から減衰するので、その表現程度でしょうか
  • HPF 直流カットとして使われます
  • APF 人は位相特性だけが違っても同じ音と感じるのですが波形は違ってくる
  • HPFとLPFを組み合わせて高域と低域の強度調整も出来ます

一次のフィルタではあまり音が変わったと思われないので、それを逆に利用した使い方が多くなるでしょう。例えば信号に尖った部分(パルスのような)があるとフルスケールを下げなければならなくなりますが位相を崩したりすれば 尖った部分が収まるという事もあり、結果音量感を大きく出来るというような使い方ですね。他に動的に係数を変更しても破綻しないので位相を動的に回すという事も。

アナログでの特性

グラフ上マウス等でf0付近をドラッグすればf0を変更可
HPF/LPFのカット側は周波数比例 
このことは

  • -6dB/oct (周波数が2倍になったら強度も半分になる)
  • -20dB/dec(周波数が10倍になったら強度も1/10)

というふうに表現されます。

HPF/LPFのカット側は最大90度に向けて回転する
符号は反対です
APFは周波数が高い程最大180度に向けて回転する
180度ということは符号反転という事であり、最初から符号反転してDCで位相180度、周波数が高くなると0度に戻るものもAPF

アナログCR LPFの特性 実際の数値

アナログ一次フィルターの特性を確認します

  • 周波数とゲイン
    • カットオフ周波数 f0=1/(2*PI*R*C) = 1/(2*PI*時定数)
    • gain = 1/(1+(f/f0)^2)^0.5 逆関数 f= f0/((gain^2-1))^0.5
    • 位相 =atan(frq/f0)
gain 周波数f 位相
1 0 0
1-1/f f0/√(2/f) 180*√(2/f)/pi
1-1/1000 f0/22.3 2.56
1-1/802 f0/20 2.86
1-1/201 f0/10 5.71
1-1/100 f0/7 8.13
1-1/80 f0/2PI 9.04 1/(時定数)
1-2.9857% f0/4 14.0
1-5.1317% f0/3 18.4
1-10.557% f0/2 26.6
0.7071 f0 45.0 -3dB
0.5 √3*f0 60.0 -6dB=0.5
0.4472 2*f0 63.4 -7dB
0.3162 3*f0 71.6
0.2425 4*f0 76.0 以後は概算式f0=f*gainで
0.2 4.9*f0 78.5
0.1 9.95*f0 84.3
gain f0/gain 90-180/pi*gain
  • HPFはf0の位置で上下 逆になる
  • ゲインが下がるにつれ位相も90度にむけ回る事に注意

 デジタルフィルターの周波数特性

一次IIRフィルタの構成Z=1/z fsサンプリング周波数 

  • Z変換でDC[1]の時Z=1 fs/2の時 Z=-1を代入
A+B*Z       DC   (A+B)/(1-C) ゲインが1であるには A+B+C=1
-----  -->  fs/2 (A-B)/(1+C) ゲインが1であるには A-B-C=1 A-B=1+C
1-C*Z

C=1-w とすると

LPF (DCゲイン=1 Highゲイン=0)
    A= B=(1-C)/2 = w/2
HPF (DCゲイン=0 Highゲイン=1)
    A=-B=(1+C)/2 = 1-w/2
APF(DCゲイン=1 Highゲイン=-1)
    A=-C B=1  
   (DCゲイン=-1 Highゲイン=1){{fn 定義的に1次APFはこちらのものある}}
    A=C B=-1  

動かないフィルタ

周波数特性がマトモに表示されても実際には動かないフィルタは1次フィルタでも作れます

  • Z変換した結果から実装する式を考えてみましょう。
分母が
1-C*Z
の時は
y=C*y
 という繰り返し演算をするわけですが、Cの絶対値が1を超えたら小さな入力が延々大きくなるのは式を見れば判りますよね
 C=1-w と変形すれば 
 y=(1-w)*y
 wが0〜2までは使えるという事です

wは2πf0/fsの近似[2]となります

  • Highゲインはfs/2でのゲインの事になります。アナログフィルターの∞とは違います
  • 先にキッチリゼロにならない簡易型の説明をします

 簡易型 1次フィルタ

実用ではメモリー1変数だけで実現出来る簡易型が良く使われます

簡易型周波数特性

1次LPF 簡易型
(高域が0にならない)
    w      DC   =1
 --------  fs/2 = w/(2-w)
(1-(1-w)Z)

  • f0を変更してみて下さい(f0が3Khzを超えたあたりからアナログとの差が大きくなります)
  • w=sin(2PI*f0/fs)とすれば多少はマシになりますが、あまり意味がないですね
  • 高域の位相がアナログと離れているのに注意して下さい
  • 実用的な実装では 1遅延された w*Z/(1-(1-w)Z) となるので、その場合の位相特性も見て下さい
    • 1遅延した事によりfs/2では180度回転する事になります
1次HPF 簡易型
(高域が1より大きいゲインを持つ)
   1-Z      DC   =0
 --------  fs/2  = 2/(2-w)
(1-(1-w)Z)

  • やはりf0が3Khzを超えたあたりからアナログとの差が大きくなります
  • 高域にゲインを持つようになるので、f0>fs/(4PI)あたりから使うのは厳しいですね
1次CTL 簡易型
低域高域のゲイン制御
 (w*Z*L1 +(1-Z)*H1)  DC  =  gL
 ----------------- fs/2= (2*H1-w*L1)/(2-w)
   (1-(1-w)Z)

LPFの1遅延結果とHPFを按分加算すれば、L1=H1の時にフラットとなりますが

  • 低域だけ強くしようとすると特性が崩れる
  • f0を変更すれば特性は移動はするが位相等の最大変異場所がズレている

のような特性がありますが、実現が容易なので特性を把握すれば便利に使えます。

1次APF
DCで0度 fs/2で180度回転します
  -(1-w)+Z    DC   =1
 --------    fs/2  = -1
(1-(1-w)Z)

  • ((1-w)-Z)/(1-(1-w)Z)とすればDCで180度となります
  • 簡易型でもキッチリ型でも分母が 1-b1*Zであれば分子は-b1+Zなので形は同じになります

違いはf0に対するb1の求め方だけですから

簡易型実現方法

xを入力 sum をメモリ上のレジスタ L,Hを一時変数として 1サンプルあたり
L:=sum*w ;LはLPF結果の1遅延が得られる
H:=(x-L) ;HはHPF結果が得られる
sum:=sum+H

と非常に簡易でHPF LPF同時に得られるので良く使われるのです。高域低域CTRL調整にも都合が良い

順番を入れ替え、Lとsumをメモリ上のレジスタとすれば
H:=(x-L) ;HはHPF結果
sum:=sum+H
L:=sum*w ;LはLPF結果

Lの1遅延も解消されます(もっとも、この場合L+Hはフラットになりません)

注意すべき事
f0が小さい程 wが小さくなると,結果sumの桁数が入力xよりもより多く(x最大/w)だけ必要になります。

  • 簡易型は整数演算でも使えます
wを1/8 1/16のように2のべき乗とすれば
L=sum >> n;LはLPF結果の1遅延が得られる
H=(x-L)   ;HはHPF結果が得られる
sum+=H ;
となりますから

 キッチリ型 1次フィルタ

z変換した場合簡易型と分母は同じです。

周波数特性

1次LPF
(高域が0になる)
 w/2*(1+Z) DC   =1
 --------  fs/2 =0
(1-(1-w)Z)

  • fs/2でカットされるのでアナログよりも高域では急峻となります。
  • やはりf0>3KHzでアナログより高くなるので
    • w=2PI*f0/fs;をw=sin(2PI*f0/fs)とすれば若干改善しますがf0<fs/4までです

もっと良い補正方法は

双一次変換については調べてみて下さい
1次HPF
(高域がゲインが1)

(1-w/2)*(1-Z)   DC   =0
 -----------    fs/2 =1
(1-(1-w)Z)

  • やはりf0>3KHzでは双一次変換を使わないと厳しいですね
1次CTL

きっちり型 

 w/2*(1+Z)*L0 +(1-w/2)*(1-Z)*H0
 -----------------------         DC  =L0
    (1-(1-w)Z)                   fs/2=H0

これでも簡易型よりは綺麗にゆきますが、これを使うなら双一次変換したものが多少の面倒はあっても使われます

w =tan(w/ 2);
b1=(1 - w) / (1 + w);
k1=(1 - b1) / 2;
a0=k1*(L0+H0/w);
a1=k1*(L0-H0/w);
    (a0+a1Z)
 -----------------------    
    (1-b1Z)                  

  • 簡易型に比べるとマシだが、まだ若干変更点が設定したf0とズレている
さらにそれらしく周波数特性をあわせるなら
w =w * sqrt(H0/L0);
と補正する。(挿入してみて下さい)
正確には
 位相が最大に振れる周波数は
 tan(2πf/f0) =√(H0*L0)*(2-w)*w*2 / ( (4-4*w+w^2)*H0-w^2*L0)

キッチリ型 実現方法

1サンプル周期毎に LPFy HPFy ox をメモリ xを入力として
 LPFy := (1-w)*LPFy +w/2*(x+ox)
 HPFy := (1-w)*HPFy +(1-w/2)*(x-ox)
 ox:=x
  w は低周波の場合 w=2*π*f0/fs

wが1/4より大きくなるなら双一次変換を使う

   w =tan(w/ 2);
   b1=(1 - w) / (1 + w);
   k1=(1 - b1) / 2;
 と係数を求めておいて
 LPFy := b1*LPFy + k1*(x+ox)
 HPFy := b1*HPFy + k1/w*(x-ox)
 ox:=x
注意すべき事
f0が小さい程 wが小さくなり、(1-w)が1に近くなると,結果 LPFy/HPFyの有効桁数(少数点以下)が入力xよりも多く必要になります。

 まとめ

一次フィルタの実現方法として
簡易型 キッチリ型 双一次変換 の3つを説明しました。
  • 内部の係数を含めた計算の面倒さは簡易型<キッチリ型<双一次変換となります。
  • フィルタの特性そのものはキッチリ型と双一次変換はf0を調整してるだけで同じ形です
  • 特にAPFはキッチリ型と簡易型も同じになります
  • 1次フィルタは動的にwを変更しても有効範囲なら破綻しないのですが、 双一次変換となると係数変更にコストがかかるので、3種類の特性を把握して使い分けましょう
w b1
簡易型 w=2PI*f0/fs; b1=1-w;
キッチリ型 w=2PI*f0/fs; b1=1-w;
双一次変換 w=tan(PI*f0/fs); b1=(1-w)/(1+w);
キッチリ型 Z変換(Z=1/z) 実現式y出力 x入力 ox:メモリ 簡易型Z変換
LPF1 a1=(1-b1)/2 ;a1*(1+Z)/(1-b1Z) y := b1*y +a1*(x+ox);ox:=x; w/(1-(1-w)*Z)
HPF1 a1=(1-b1)/2/w;a1*(1-Z)/(1-b1Z) y := b1*y +a1*(x-ox);ox:=x; (1-Z)/(1-(1-w)Z)
APF1 (-b1+Z)/(1-b1Z) y := b1*y -b1*x+ox ;ox:=x;

簡易型の実現式は

H,L出力 x入力 sum:メモリ
L:=sum*w ;LはLPF結果の1遅延が得られる
H:=(x-L) ;HはHPF結果が得られる
sum:=sum+H

 音声処理以外での使い道

  • マイコンのADCでサンプルする時、LPFを入れるとADCの分解能より高く測定する事が出来ます。
    • 入力にある程度のノイズが入っているか、そうでなければ分解能レベルの三角波などの入力が必要ですが
    • 処理に必要な周期より、より高いサンプルレートである事も必要です
  • [1]DCはDirect Currentの略で直流の事 f=0の時の値を示します
  • [2]そもそもデジタルフィルタなので高域ではアナログフィルタとの乖離が大きくなります

プライバシーポリシー本文は日本語以外に翻訳禁止