Tweet


* サンプリングレート変換 その5 [#m1d97e28]

前回はトランスバーサルフィルタの動作について説明しました.
今回はその設計法について説明します.

** 設計パラメータ [#f6b1922c]

トランスバーサルフィルタにおいて,設計時にいじるところは
- タップ数
- タップ係数
-- 前回の図での a(0) … です

の2つになります.

大雑把なところではこれらのパラメータは
- タップ係数はフィルタ特性
-- 係数によってフィルタの(おおまかな)特性が決まる
- タップ数はフィルタの精度
-- たとえば実験結果を近似式で表す場合,1次式よりも2次式のほうがより結果に近い曲線になります.それと同じようなことです.

という点に影響します.

** トランスバーサルフィルタの性質 [#i5e4d47b]

実は,トランスバーサルフィルタには
> タップ係数 a(0) … をフーリエ変換した周波数特性はフィルタの周波数特性になる

という性質があります.

ということは
> 実現したい周波数特性を逆フーリエ変換してタップ係数に割り当てれば,欲しいフィルタを作れる

ということになります.

** 例題 [#caa26149]

実際にやってみましょう.
お題は「16 kHz -> 8 kHz ダウンコンバート用フィルタ」です.
サンプル点を間引きする前に 4 kHz 以上の周波数成分を除去するフィルタになります.

設計要件としては
- サンプリング周波数は 16 kHz
- 0 〜 4 kHz まではなるべくフラット
- 4 kHz 〜 はなるべくカット

です.
理想的な特性をグラフにするとこんな感じかな.
#ref(lpf_ideal.png,center)

12000 Hz 以上の部分は,サンプリングによる鏡像です.
設計時にこの鏡像部分がないと,逆フーリエ変換したときに変なことになるので注意.

** もう少し煮詰める [#d90896aa]

タップ数を決めましょう.
えいや,ということで 16 とします.

で,フーリエ変換・逆変換には
> n 点のサンプル点を変換すると n 点の周波数特性になる.逆も同じ

という性質があります.
というわけで 16 個の周波数に対する振幅を指定します.

で,周波数の刻みは 0 Hz からサンプリング周波数間を n 等分した周波数になります.
つまり,0 Hz, 1000 Hz, 2000 Hz, ... 15000 Hz での振幅を設定します.

|周波数 [Hz]|振幅|h
|0|1|
|1000|1|
|2000|1|
|3000|1|
|4000|0|
|5000|0|
|6000|0|
|7000|0|
|8000|0|
|9000|0|
|10000|0|
|11000|0|
|12000|0|
|13000|1|
|14000|1|
|15000|1|

というわけで,指定しました.

こいつを逆フーリエ変換してみます.
今回は逆フーリエ変換を計算するに [http://www.gnu.org/software/octave/ octave] というプログラムを使います.
今回は逆フーリエ変換を計算するのに [http://www.gnu.org/software/octave/ octave] というプログラムを使います.

 sh-3.2$ octave
 GNU Octave, version 3.0.1
 Copyright (C) 2008 John W. Eaton and others.
 This is free software; see the source code for copying conditions.
 There is ABSOLUTELY NO WARRANTY; not even for MERCHANTIBILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  For details, type `warranty'.
 
 Octave was configured for "i486-pc-linux-gnu".
 
 Additional information about Octave is available at http://www.octave.org.
 
 Please contribute if you find this software useful.
 For more information, visit http://www.octave.org/help-wanted.html
 
 Report bugs to <bug@octave.org> (but first, please read
 http://www.octave.org/bugs.html to learn how to write a helpful report).
 
 For information about changes from previous versions, type `news'.
 
 octave:1> af = [ 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 ]'
 af =
 
    1
    1
    1
    1
    0
    0
    0
    0
    0
    0
    0
    0
    0
    1
    1
    1
 
 octave:2> at = ifft ( af )
 at =
 
    0.43750 + 0.00000i
    0.31421 + 0.00000i
    0.06250 + 0.00000i
   -0.09354 + 0.00000i
   -0.06250 + 0.00000i
    0.04176 + 0.00000i
    0.06250 + 0.00000i
   -0.01243 + 0.00000i
   -0.06250 + 0.00000i
   -0.01243 + 0.00000i
    0.06250 + 0.00000i
    0.04176 + 0.00000i
   -0.06250 + 0.00000i
   -0.09354 - 0.00000i
    0.06250 + 0.00000i
    0.31421 + 0.00000i
 
 octave:3> 

計算できました.
グラフにしてみます.
#ref(tap0.png,center)

実際にタップ係数に割り当てるときは,この係数列の後ろ半分を前に持ってきます.
つまり,( 8ばんめ, 9ばんめ, ... 15ばんめ, 0ばんめ, 1ばんめ, … 7ばんめ ) と並び替えます(番号が 0 ばんめから始まっているところに注意).

#ref(tap1.png,center)

** 設計時に指定しなかった周波数での挙動を見る [#vd44c6e0]

今回は 0 Hz, 1000 Hz, 2000 Hz ... の周波数に対する特性を指定して設計しました.
が,例えば「1500 Hz の信号を入力した場合の挙動」はどうなってるのでしょうか?

ここで「n サンプルをフーリエ変換した結果も n サンプルになる」ということを踏まえ,トンチを働かせます.
- 今設計したフィルタの後ろに 16 タップ追加して合計 32 タップにする
- 追加した 16 タップ分のタップ係数は 0 とする

追加した部分のタップ係数は 0 なので,出力には影響しません.
つまり,挙動は元のフィルタと同じはずです.

が,タップ係数は 32 個あるので,フーリエ変換した後の点も 32 点出てきます.
で,周波数の範囲は 0 <= f < 16000 Hz のままです.
しかし,32 点あるので,元の設計よりも周波数軸で詳しい特性が出ていることになります.
やってみましょう.

 octave:12> at = real(at);                 # 実数部だけ取り出して
 octave:13> at2 = [ at(9:16)' at(1:8)' ]'; # 前後を入れ替え
 octave:18> at2 = [ at2' zeros(1,16)]';    # 後ろに 0 を追加
 octave:21> af2 = fft(at2);                # フーリエ変換
 octave:30> a2 = abs(af2);                 # 振幅成分だけ取り出す

グラフにしてみましょう.
#ref(hires.png,center)

確かに 0 Hz, 1000 Hz, … の設計時に指定した周波数では,その通りの振幅特性になっています.
が,設計時に指定しなかった周波数では思ったとおりになってませんね.
指定せずに「よきに計らえ」とした結果なので,これはしかたのないことです.

もちろん,設計時に 1500 Hz 等の特性を指定すれば,指定した点に置いてはその通りの特性になります.
が,細かく指定するにはタップ数を増やさなくてはなりません.
で,タップを増やせば回路規模や計算量などのコストが増えるので,やたらに増やすわけには行かない.

トランスバーサルフィルタの設計は,そういうジレンマの中での闘いなのです.



トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS