ディジタル信号処理のための Python 入門 第 5 回. フィルター 赤部 晃一 AHC Lab YYYY-MM-DD YYYY-MM-DD Koichi Akabe (AHC-Lab) 1 / 16 フィルター 信号から特定の範囲の周波数を除去 HPF 1.5 1.5 1.0 1.0 0.5 0.0 0 0.5 1000 4000 0.0 0 5000 1.5 1.5 1.0 1.0 0.5 YYYY-MM-DD 1000 2000 3000 Frequency [Hz] 4000 5000 4000 5000 BEF 2.0 H H 2000 3000 Frequency [Hz] BPF 2.0 0.0 0 LPF 2.0 H H 2.0 0.5 1000 2000 3000 Frequency [Hz] 4000 5000 Koichi Akabe 0.0 0 (AHC-Lab) 1000 2000 3000 Frequency [Hz] 2 / 16 理想的なフィルターのインパルス応答 遮断周波数 ωc の低域通過フィルターの場合 n = 0 のとき: ωc h[n] = π n ̸= 0 のとき: h[n] = = 1 2π ∫ ωc ejΩn dΩ −ωc [ ]ω 1 ejΩn c 2π jn −ωc 1 ejωc n − e−jωc n 2π jn sin(ωc n) = πn インパルス応答が無限に続き、かつ非因果的(n < 0 で値を持つ) なため、実現できない。 = YYYY-MM-DD Koichi Akabe (AHC-Lab) 3 / 16 インパルス応答の打ち切り(FIR フィルター) インパルス応答を 2N + 1 の長さで打ち切った場合 sin[ωc (n−N )] (0 ≤ n ≤ 2N, n ̸= N ) π(n−N ) ω c h[n] = (n = N ) π 0 (n > 2N ) 因果性を確保するため、中心を N とした。 YYYY-MM-DD Koichi Akabe (AHC-Lab) 4 / 16 インパルス応答の打ち切り結果 遮断周波数 3000Hz, 標本化周波数 10000Hz (ωc = 0.6π) N=8 0 20 H [dB] H [dB] 20 40 60 40 60 80 100 80 0 N=50 20 0 2000 4000 6000 Frequency [Hz] 8000 120 0 10000 2000 N=200 10 4000 6000 Frequency [Hz] 8000 10000 8000 10000 N=4000 0 0 10 20 30 H [dB] H [dB] 20 40 50 40 60 60 70 80 0 ▶ ▶ ▶ YYYY-MM-DD 80 2000 4000 6000 Frequency [Hz] 8000 10000 0 2000 4000 6000 Frequency [Hz] N が小さいほどリアルタイム性が高いが、周波数応答が理想 的なフィルターとは異なる。 N が大きくなると理想的なフィルターに近づくが、リアルタ イム性が低くなる。 遮断周波数付近にリップル(波)がある。 Koichi Akabe (AHC-Lab) 5 / 16 バタワースフィルター バタワース・ローパスフィルター 1 { ( H(s) = ∏ N −1 s − ωc exp 12 + k=0 (2k+1)π 2N )} 振幅特性 1 ( |H(jω)| = √ 1+ ω ωc )2N ここで、N はフィルターの次数 YYYY-MM-DD Koichi Akabe (AHC-Lab) 6 / 16 バタワース・ローパスフィルターの特性 wc = 1, N = 1, 2, 3, 4 0 H [dB] −20 −40 −60 −80 −100 -1 10 100 Frequency [rad/s] 101 通過域が平坦(リップルが無い)。傾斜は約 −6N [dB/oct] YYYY-MM-DD Koichi Akabe (AHC-Lab) 7 / 16 バタワースフィルターのディジタル化 1+sT /2 双一次変換による近似 z = esT ≈ 1−sT /2 を用いる。近似による誤 差を考慮して、遮断周波数の補正が行われることもある。 SciPy によるバタワースフィルターの実装 http://docs.scipy.org/doc/scipy/reference/generated/ scipy.signal.butter.html from scipy . signal import butter , lfilter # ::: # x : signal # n : order # fc : critical frequency # fs : sample frequency # low pass / high pass b , a = butter (n , fc / fs , " lowpass " ) # band pass / band stop b , a = butter (n , [ fc1 / fs , fc2 / fs ] , " bandpass " ) y = lfilter (b , a , x ) YYYY-MM-DD Koichi Akabe (AHC-Lab) 8 / 16 第一種チェビシェフ多項式 −1 ≤ x ≤ 1 の場合、 Tn (x) = cos(n cos−1 x) 漸化式に展開すると T0 (x) = 1 T1 (x) = 0 Tn (x) = 2xTn−1 (x) − Tn−2 (x) 展開された Tn の定義域を拡張し、x > 1 に対しても考える。(解 析接続) YYYY-MM-DD Koichi Akabe (AHC-Lab) 9 / 16 第一種チェビシェフ多項式の出力 10 8 C 6 4 2 0 −1.0 YYYY-MM-DD −0.5 0.0 Koichi Akabe 0.5 x (AHC-Lab) 1.0 1.5 2.0 10 / 16 第一種チェビシェフフィルター 第一種チェビシェフ多項式を利用したフィルター 第一種チェビシェフ・ローパスフィルター 振幅特性: 1 |H(jω)| = √ 1 + ϵ2 Tn2 ( ω ωc ) (伝達関数は割愛) YYYY-MM-DD Koichi Akabe (AHC-Lab) 11 / 16 第一種チェビシェフ・ローパスフィルターの特性 ϵ = 1, wc = 1, N = 2, 3, 4, 5 0 G [dB] −20 −40 −60 −80 −100 10 -1 10 0 10 1 Frequency [rad/s] バタワースフィルターに比べ勾配が急。通過域にリップルがある。 YYYY-MM-DD Koichi Akabe (AHC-Lab) 12 / 16 SciPy における IIR フィルターの実装 バタワースフィルター、第一種・第二種チェビシェフフィルター、 楕円フィルターなどがある。 詳細は SciPy のドキュメントを参照 http://docs.scipy.org/doc/scipy/reference/signal.html#matlabstyle-iir-filter-design YYYY-MM-DD Koichi Akabe (AHC-Lab) 13 / 16 音声ファイルへの書き出し 音声信号 y をチャンネル数: 1, 量子化ビット数: 16(2 バイト), 標本化周波数: 44100Hz で出力する例 wav = wave . open ( " ./ upsample . wav " , " wb " ) wav . setnchannels (1) wav . setsampwidth (2) wav . setframerate (44100) wavdata = [ min ( max ( int ( yy * 2**15) , -2**15) , 2**15 -1) for yy in y ] wav . writeframes ( struct . pack ( " h " * len ( wavdata ) , * wavdata ) ) wav . close () YYYY-MM-DD Koichi Akabe (AHC-Lab) 14 / 16 問題: 標本化周波数変換 11025Hz で標本化された音声信号 sample.wav の標本化周波数を 以下の手順によって 44100Hz に変換せよ。 1. sample.wav を読み込み、配列化せよ。 2. 配列の各要素を、インデックスが 44100/11025 倍となる位置 に移動し、空となった要素は 0 で埋めよ。 3. 遮断周波数 11025/2Hz(ナイキスト周波数)のローパスフィ ルターを設計し、上で作成した信号に対して適用せよ。 4. ローパスフィルター通過後の信号を標本化周波数 44100Hz の 音声ファイルとして upsample.wav に保存せよ。 5. 両者の音声を比較せよ。 6. この方法によって標本化周波数を変換できる理由を考察せよ。 YYYY-MM-DD Koichi Akabe (AHC-Lab) 15 / 16 付録: 配列インデックスの引き伸ばしと 0 埋め 配列 x の要素を、インデックスが scale 倍となる位置に移動し、 空となった要素は 0 で埋める。 y = [0.0] * int ( len ( x ) * scale ) ref_pref = -1 for i in range ( len ( y ) ) : ref = int ( i * scale ) if ref != ref_pref : ref_pref = ref y [ i ] = x [ ref ] YYYY-MM-DD Koichi Akabe (AHC-Lab) 16 / 16
© Copyright 2024 ExpyDoc