...

ローパスフィルタの数理

by user

on
Category: Documents
10

views

Report

Comments

Transcript

ローパスフィルタの数理
ローパスフィルタの数理
有馬 啓晃
2014 年 3 月 10 日
5
目次
1
2
3
4
イントロ
1.1 研究の動機
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
重要単語の説明
2.1 サンプリング . . . . . . . . . . . . . . . . . . .
2.2 Z 変換 . . . . . . . . . . . . . . . . . . . . . . .
2.3 デジタルフィルタ . . . . . . . . . . . . . . . . .
2.3.1 線形定常システムとそのフィルタ係数 .
2.4 伝達関数 . . . . . . . . . . . . . . . . . . . . . .
2.5 ローパスフィルタ . . . . . . . . . . . . . . . . .
2.5.1 窓関数は何の為にあるのか . . . . . . . .
2.5.2 ハン窓(ハニング窓) . . . . . . . . . .
2.5.3 窓関数はなんのためにあるのか(続き)
プログラム ex6 1 の解読
3.1 ex6 1 を作るのに必要なソースプログラム .
3.2 ex6 1.c . . . . . . . . . . . . . . . . . . . .
3.3 エッジ周波数という言葉の解読 . . . . . .
3.4 sinc 関数 . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5
5
.
.
.
.
.
.
.
.
.
6
6
6
6
7
8
8
10
11
11
.
.
.
.
12
12
14
17
18
まとめ
19
A Fourier 変換
A.1 流儀 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A.2 流儀 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A.3 流儀 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
19
20
20
B Fourier 級数と離散 Fourier 変換
B.1 Fourier 級数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
B.2 離散 Fourier 変換 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
20
21
C 離散時間 Fourier 変換
23
D 参考文献
23
1
1.1
イントロ
研究の動機
私は音楽に興味があって、C 言語を使ったプログラムでなにか音を操作できないだろうかと
考えた。と言うのも、音楽の信号がデジタル処理されていることは知っていて、先輩も音のデ
6
ジタル処理を卒研のテーマにしていた、というのがあったためである。
青木 [1」の第 6 章にローパスフィルターのプログラム ex6 1.c が載っていた。ローパスフィ
ルターとは、ある一定の周波数より低い周波数は通し、高い周波数は通さない、というもの
で、もっとも基本的なエフェクトであると考えられる。この卒業研究では、このプログラムを
数学的に理解することを目標とする。
重要単語の説明
2
2.1
サンプリング
x : R → C という信号と、Ts > 0 があったとき、
xn := x(nTs ) (n ∈ Z)
で {xn }n∈Z ∈ CZ が定まる。
Ts は標本化周期(Sampling period)と呼ばれる。以下で周期関数を扱うことも多く、その周
期を T で表したいため、標本化周期には s という添字をつけて Ts という記号を用いる。
例.
Ω ∈ R とするとき、x(t) = eiΩt は正弦波と呼ばれる。Ts > 0 として、
xn := x(nTs )
とおく。
xn = eiΩnTs = einω .
ただし ω := ΩTs とおいた。{xn } は公比 eiΩ の等比数列である。|eiΩ | = 1 であることに注
意する。
2.2
Z 変換
∪
整数全体の集合を Z,1 以上の整数全体の集合を N, N0 := N {0} とする。
以下、数列 {xn } の話として説明するが、関数 x : R → C と、Ts > 0 に対して xn = x(nT )
とおくことで、関数のサンプリングデータの話と考えることもできる。
数列 {xn }n∈Z ∈ CZ に対して、
∑ xn
(z ∈ C, ただし収束する場合)
X(z) :=
zn
n∈Z
で定義される X = X(z) を {xn } の Z 変換と呼ぶ。
2.3
デジタルフィルタ
デジタルフィルタとは、数学的には、数列 {xn }n を数列 {yn } に写す写像 F : {xn } → {yn }
である。線型かつ時不変であるもの(線型定常システム)だけを考えることにする。
7
2.3.1
線形定常システムとそのフィルタ係数
デジタルフィルタ F が線型であるとは、
F ({xn } + {yn }) = F ({xn }) + F ({yn }),
F (c{xn }) = cF ({xn })
が成り立つことであり、時不変(定常)であるとは、
∀k ∈ Z F ({xn−k }) = {yn−k }
が成り立つことをいう。
添字 n の範囲が問題になるが、まずは n ∈ Z の場合を考えることにする。
X := CZ = {{xn }n∈Z ; ∀n ∈ Z xn ∈ C}
とおくとき、線型定常なデジタルフィルタ F : X → X に対して、
∃h ∈ CZ
s.t. ∀x ∈ CZ
F (x) = x ∗ h.
が成り立つ。実際、h として h = F (δ) をとれば良い。ここで δ = {δn }n∈Z は
δn := δn0 =
{
1 (n = 0)
0 (n ̸= 0)
で定められる数列で、単位インパルスと呼ばれる (Kronecker のデルタ δij を用いれば、δn = δn0
と書くこともできる)。h のことをデジタルフィルタ F のフィルタ係数と呼ぶが、h = F (δ) で
あることから、F の単位インパルス応答とよぶこともある。
青木 [1] では hn の代わりに bn と書いてある。
FIR フィルタとは、デジタルフィルタのうちで、
∃J ∈ N s.t. bn = 0 (n < 0 or n > J)
を満たすものである。bm (0 ≤ m ≤ J) をフィルタ係数と呼ぶ。このとき
yn =
J
∑
xn−k bk
(n ∈ Z)
k=0
プログラムでは、片側の信号 {xn }n≥0 , {yn }n≥0 しか扱っていないせいもあって、
∑
min{J,n}
yn =
m=0
となっている。
8
xn−m bm
2.4
伝達関数
デジタル・フィルタに正弦波を入力したときの出力について調べてみよう。
正弦波 x(t) = eiΩt をサンプリングして作った離散信号 {xn } を入力してみる。
xn = x(nTs ) = eiΩnTs = einω ,
ω := ΩTs
であるから、{xn } は公比 eiω の等比数列である。
h = {hn }, y = {yn }, y = x ∗ h とする。h の z 変換を H(z) とすると、∀n ∈ Z に対して
yn =
∑
∑
xn−k hk =
k∈Z
ei(n−k)ω hk = einω
∑
e−ikω hk = H(eiω )xn .
k∈Z
k∈Z
つまり y = H(eiω )x. ゆえにデジタルフィルタ h に正弦波を入力すると、出力はやはり正弦波
で、その周波数は入力と同じである。ただ周波数ごとに何倍されるかの係数が異なる、という
ことを表している。
デジタルフィルタ h の z 変換 H(z) に eiω を代入した H(eiω ) を ω の関数 ω 7→ H(eiω ) とみた
とき、これを伝達関数 (transfer function) と呼ぶ。
ω ∈ [0, 2π](あるいは ω ∈ [−π, π])に対して、
(1)
G(ω) := |H(eiω )|,
θ(ω) := arg H(eiω ) (arg でなく ∠ と書くこともある。)
とおき、G(ω) を利得 (gain),θ(ω) を位相シフト (phase shift) と呼ぶ。
2.5
ローパスフィルタ
正弦波 x(t) = eiΩt をサンプリング周期 Ts でサンプリングして、離散信号を作る。
xn := x(nTs ) = eiΩnTs = einω
(n ∈ Z),
ただし
ω := ΩTs .
この x = {xn } をデジタルフィルタに入力したときの、出力信号 y = {yn } は、フィルタ係数を
{hn } とすると、
)
(
∑
∑
∑ hk
einω = H(eiω )einω .
yn =
xn−k hk =
ei(n−k)ω hk =
eikω
k∈Z
k∈Z
k∈Z
ただし H は {hn } の z 変換である:
H(z) :=
∑ hk
k∈Z
zk
.
これはデジタルフィルタに正弦波を入力すると、出力は同じ周波数をもつ正弦波で、振幅が
X(ω) := |H(eiω )| 倍されることを意味する。ωe ∈ (0, π) に対して、
{
1 (|ω| ≤ ωe )
X(ω) = ([−ωe , ωe ] の特性関数) =
0 (|ω| > ωe )
9
1.0
0.8
0.6
0.4
0.2
-3
-2
1
-1
2
3
図 1: 上の式のグラフ
となるようなフィルタを求める。
X(ω) =
∑
hn e−inω
(ω ∈ R)
k∈Z
は、X が {hn } の離散時間 Fourier 変換であることを意味する。離散時間 Fourier 変換には反転
公式
∫ π
1
X(ω)einω dω (n ∈ R)
hn =
2π −π
がある。これは実は周期 2π の周期関数の Fourier 級数展開と同じである。
(次の公式の i と −i
を入れ替えるだけ)。
Fourier 級数展開(Fourier 係数と「反転公式」)
周期 2π の周期関数 x : R → C に対して、
∫ pi
1
x(θ)e−inθ dθ
cn :=
2π π
とおくと、
x(θ) =
∑
cn e−inθ
(n ∈ Z)
(θ ∈ R)
k∈Z
が成り立つ。
要するに、次のように {hn } を定めればよい。
∫ π
∫ ωe
1
ωe
1
inω
X(ω)e dω =
einω dω =
sinc nωe .
hn =
2π −π
2π −ωe
π
エッジ周波数 fe となるには、fe =
hn =
fe
ωe
fs とすれば良いので、ωe = 2π であり、
2π
fs
2πfe /fs
fe
2nπfe
fe
.
sinc 2nπ = 2 sinc
π
fs
fs
fs
10
bm = wm hm−J/2 であるので、窓関数の wm の部分を無視して bm ≒ hm−J/2 と見なすと、n ≥ J/2
に対して、
yn =
∑
xn−k hk ≒
xn−k hk ≒
|k|≤J/2
k∈Z
2.5.1
∑
∑
xn−k bk+J/2 =
|k|≤J/2
J
∑
xn−J/2−m bm = y[n − J/2].
m=0
窓関数は何の為にあるのか
hn =
ωe
sinc nωe
π
とするとき、
XJ (ω) :=
∑
hn e−inω
|n|≤J/2
とおき、そのグラフを Mathematica で描いてみる。
Clear[n, t, w, x];
w[x_]:=(1-Cos[2 Pi x])/2;
omega=0.5;
h[n_]:=omega/Pi Sinc[n omega];
draw[J_]:=Plot[Sum[h[n]Exp[-I n t], {n, -J/2, J/2}],{t, -Pi, Pi},
PlotRange -> All];
実際には無限和は計算できないので、有限和ですませることになる。
f (ω) :=
50
∑
hn e−inω
n=−50
f (ω) ≒ H(e ) と期待されるが
iω
1.0
0.8
0.6
0.4
0.2
-3
-2
1
-1
図 2: 窓関数なし (J = 100)
Gibbs の現象が生じて良い近似にはならない。
そこで、窓関数としてハン窓(ハニング窓)を使用する。
11
2
3
2.5.2
ハン窓(ハニング窓)
ハン窓 (hann window), von Hann window,2 乗余弦窓 (raised cosine window) とも呼ばれる。
一般化ハミング窓に分類されたので、ハニング窓 (hanging wndow) と呼ばれる。
w(x) =
1 − cos 2πx
2
(0 ≤ x ≤ 1).
1.0
0.8
0.6
0.4
0.2
0.2
0.4
0.6
図 3: hann 窓 w(x) =
0.8
1.0
1 − cos 2πx
2
void Hanning window(double w[], int N) という関数がある。これは、整数 N が与えら
れたとき
 (n)

(N が偶数)
w N
(n = 0, 1, ..., N − 1)
wn :=
)
(

w n + 1/2
(N が奇数)
N
−1
で定まる w = {wn }N
n=0 を返す。
N の偶奇で式を変えるのは、w の最大値 w(1/2) = 1 を数列中に含めたいからであろう。
Hanning window() の処理の Mathematica 訳
Clear[w];
w[x_]:=(1-Cos[2 Pi x])/2;
hanningWindow[N_]:=if[EvenQ[N],
Table[w[n/N], {n, 0, N-1}],
Table[w[(n+1/2)/N], {n, 0, N-1}]]
2.5.3
窓関数はなんのためにあるのか(続き)
hn の代わりに h̃n := hn w(n/100) をフィルタ係数に選ぶと
f˜(ω) =
50
∑
n=−50
12
h̃n e−inω
draw2[J_]:=Plot[Sum[w[n/J-1/2]h[n]Exp[-I n t],{n, -J/2, J/2}], {t,-Pi,Pi},
PlotRange -> All]
1.0
0.8
0.6
0.4
0.2
-3
-2
1
-1
2
3
図 4: 窓関数あり (J = 100)
H(eiω ) の良い近似が得られる。
プログラム ex6 1 の解読
3
青木 [1] に載っている ex6 1.c というプログラムを解読する。
ex6 1 がすること sine 500hz 3500hz.wav という WAVE ファイル(フォーマットは 16 ビッ
トモノラル PCM、内容は 500Hz, 3500Hz の正弦波を合成して作った音声信号)を読んで、エッ
ジ周波数 1000Hz, 遷移帯域幅 1000Hz のローパスフィルタで処理した結果を ex6 1.wav という
ファイルに出力する。
3.1
ex6 1 を作るのに必要なソースプログラム
• ex6 1.c — メインのプログラム
• wave.h — 音声ファイル(.wav 等)を読み書きするための関数群が定義されている。
関数名は wave {read | write} {8 | 16}bit {stereo | mono}() といったもの。
いずれの関数も返す型は void で、引数は 2 つあり、第 1 引数は PCM データへのポイン
ター、第 2 引数はファイルのパス名である。
• window function.h — いくつかの窓関数の関数値を計算する関数が定義されている。
1 − cos 2πx
ex6 1 で使っているのはハン窓(hann window)w(x) =
x
この関数の仕様は重要なので後で詳しく解説する。
13
• sinc.h — sinc を計算する関数が定義されている。
sin πx
sin x
いわゆる正規化 sinc(sinc x =
) ではなく、非正規化 sinc(sinc x =
)
πx
x
• fir filter.h — FIR フィルタを扱う関数が定義されている。
そのうち ex6 1 で使っているのは
(a) FIR filtering(x,y,L,b,J) — 畳み込み y = x ∗ b を計算する。
J
x = {x[n]}L−1
n=0 ,b = {b[m]}m=0 が入力として与えられたとき、
∑
minJ,n
(♢)
y[n] =
b[m]x[n − m] (n = 0, ..., L).
m=0
で定まる y =
{y[n]}L−1
n=0
を返す。
(b) FIR LPF(fe, J, b, w) — エッジ周波数 fe のローパスフィルタのフィルタ係数 {bm }Jm=0
を計算する。使用する窓関数は {wm }Jm=0 で与える。
14
3.2
ex6 1.c
ex6 1.c
#include
#include
#include
#include
#include
#include
#include
<stdio.h>
<stdlib.h>
<math.h>
"wave.h"
"window_function.h"
"sinc.h"
"fir_filter.h"
int main(void)
{
MONO_PCM pcm0, pcm1;
int n, m, J;
double fe, delta, *b, *w;
wave_read_16bit_mono(&pcm0, "sine_500hz_3500hz.wav");
pcm1.fs = pcm0.fs; /* 標本化周波数 */
pcm1.bits = pcm0.bits; /* 量子化精度 */
pcm1.length = pcm0.length; /* 音データの長さ */
pcm1.s = calloc(pcm1.length, sizeof(double)); /* 音データ */
fe = 1000.0 / pcm0.fs; /* エッジ周波数 */
delta = 1000.0 / pcm0.fs; /* 遷移帯域幅 */
J = (int)(3.1 / delta + 0.5) - 1; /* 遅延器の数 */
if (J % 2 == 1)
{
J++; /* J+1 が奇数になるように調整する */
}
b = calloc((J + 1), sizeof(double));
w = calloc((J + 1), sizeof(double));
Hanning_window(w, (J + 1)); /* ハニング窓 */
FIR_LPF(fe, J, b, w); /* FIR フィルタの設計 */
/* フィルタリング */
for (n = 0; n < pcm1.length; n++)
{
for (m = 0; m <= J; m++)
{
if (n - m >= 0)
{
pcm1.s[n] += b[m] * pcm0.s[n - m];
}
}
}
wave_write_16bit_mono(&pcm1, "ex6_1.wav");
free(pcm0.s);
free(pcm1.s);
free(b);
free(w);
return 0;
}
fe = 1000.0 / pcm0.fs; /* エッジ周波数 */
エッジ周波数を 1000Hz としている。fe はサンプリング周期 (1/8000s) あたりの振動数であり、
15
1/8 という値になる。
fs , fe をそれぞれサンプリング周波数、エッジ周波数として、fe には fe /fs という値がセットさ
れている、と考えることにする(つまり fe は、fe と似ている名前だけど別物である、fe= fe /fs
である、ということ)。
delta = 1000.0 / pcm0.fs; /* 遷移帯域幅 */
遷移帯域幅を 1000Hz としている。
これも上と同様に、fs , δ をそれぞれサンプリング周波数、遷移帯域幅として、delta= δ/fs
である、と考えることにする。
次はこれからつくるローパスフィルタの係数 {bm }Jm=0 の個数 J + 1 を定めている。
J = (int)(3.1 / delta + 0.5) - 1; /* 遅延器の数 */
if (J % 2 == 1)
{
J++; /* J+1 が奇数になるように調整する */
}
(3.1/delta を四捨五入して、奇数だったら 1 を足し戻す)
これは
J = round(3.1 / delta);
if(J % 2 == 1)
{
J--;
}
(3.1/delta を四捨五入して、奇数だったら 1 を引く)
と同価で、こう書くほうが自然である。
ハニング窓の場合は、
[
]
3.1
1
J=
fs + −p (p = 0, 1 は J が偶数になるように調節)
δ
2
で良いことが理論的に分かるらしい。J を偶数(J + 1 を奇数)に選ぶ理由は、関数の最大値
を与えるところを中心に対象にしたいためと考察するが、右に 1 つ 0 を補うだけで良いと思
う。細かいところはさておき、樋口・川又 [2] には、
6.2π
= ”遷移帯域幅”
N
という式がある。6.2π を 3.1 × 2π と見ると、よく似ている式である。
([2] は正規化して説明し
ていることを考慮すると、”遷移帯域幅”は δ/fs × 2π ということであろうか)。
このプログラム ex6 1 では、δ = 1000Hz,fs = 8000Hz であるから、J = 24 である。
16
Hanning_window(w, (J + 1)); /* ハニング窓 */
(3.1/delta を四捨五入して、奇数だったら 1 を引く)
1 − cos 2πx
Hanning window(w, N) は、hann 窓 w(x) :=
の関数値
2
 n
w( )
(N が偶数の場合)
N
wn :=
(n = 0, 1, ..., N − 1)
w( n + 1/2 ) (N が奇数の場合)
N
を計算する関数である。
次の関数呼び出しで、sinc と hann 窓を使ったローパスフィルタのフィルタ係数を求めている。
FIR_LPF(fe, J, b, w); /* FIR フィルタの設計 */
ここで入力は fe(= fe /fs , サンプリング周期単位のエッジ周波数), J(フィルタ係数の個数),
w(= {wm }Jm=0 は hann 窓の関数値) の 3 つで、出力は b(= {bm }Jm=0 , ローパスフィルタのフィル
タ係数) である。
この結果
fe
2πfe (m − J/2)
bm := wm × 2 sinc
(m = 0, 1, ..., J)
(♣)
fs
fs
となる。
fs=8000;
fe=1000;
delta=1000/fs;
J=Round[3.1/delta]; If[OddQ[J], J=J+1];
g=Plot[2*fe/fs*Sinc[2 Pi fe (m - J/2)/fs], {m, 0, J + 1}]
0.25
0.20
0.15
0.10
0.05
5
10
15
20
25
-0.05
図 5: hann 窓をかける前
g2 = Plot[w[m/(J + 1)]*2*fe/fs*Sinc[2 Pi fe (m - J/2)/fs], {m, 0, J + 1}]
17
0.25
0.20
0.15
0.10
0.05
5
10
15
20
25
図 6: hann 窓をかけた後 — ローパスフィルタの完成
3.3
エッジ周波数という言葉の解読
樋口・川又 [2] には「エッジ周波数」という語はない。
ローパスフィルタでは、fs より低い周波数の信号成分は通し、fe より高い周波数の信号成
分は通さない、そういう周波数 fe のことをローパスフィルタのエッジ周波数と呼んでいるら
しい。
実際には(連続的な観測など不可能なので)、そういう理想的なものを実現することは困難
である。
以下、[2] でやってみる。
M (ω) を振幅特性と呼ぶ。
1
|M (ω)|
=√
max|M (ω)|
2
となる ω を cutoff frequency と呼ぶ。
許容値と呼ばれる小さな正数 δp を定めておいて、
1 − δp ≤ |M (ω)| ≤ 1 + δp
を満たす ω の範囲が [0, ωp ] となるとき、[0, ωp ] を通過域、ωp を通過域端周波数と呼ぶ。
誤差と呼ばれる小さな数 δs を定めておいて、
|M (ω)| ≤ δs
となる ω の範囲が [ωs , π] となるとき、[ωs , π] を阻止域、ωp を阻止域端周波数と呼ぶ。
[ωp , ωs ] を遷移域と呼ぶ。
つまり、通過域、遷移域、阻止域は「分割」である。
青木 [1] と合わせるには、[ωp , ωs ] を遷移域、(ωp + ωs )/2 をエッジ周波数 fs 、ωs − ωp を遷移
帯域幅 δ と考えるべきだろうか。
(?) fe =
ωp + ωs
,
2
18
ω s − ωp = δ
3.4
sinc 関数
sinc.h では、sinc という関数の値を計算する sinc() という関数を定義してある。

 sin x (x ∈ R\{0})
x
sinc(x) :=
1
(x = 0)
実はこれは非正規化 sinc と呼ばれる。信号処理の分野では

 sin πx (x ∈ R\{0})
πx
正規化 sinc x :=
1
(x = 0)
で定義される正規化 sinc 関数も使われる([2] がそうなっている)。以下の Mathematica の
Sinc[] は非正規化 sinc である。この文書では一貫して非正規化 sinc を使うことにする。
Mathematica で sinc のグラフ描写
g = Plot[Sinc[x], x, -15, 15, PlotRange -> Full]
1.0
0.8
0.6
0.4
0.2
-15
-10
5
-5
10
15
-0.2
図 7: sinc x =
sin x
のグラフ
x
滑らかな偶関数で、x = nπ (n ∈ Z) が零点で、グラフは y = ±
1
で挟まれた部分を上下
|x|
している。
sinc が重要視される理由は次の事実にある。ωp ∈ (0, π) とするとき、区間 [−ωp , ωp ] の特性
ωp
関数 χ[−ωp ,ωp ] の逆 Fourier 変換は
sinc ωp t である。実際、
π
∫ ∞
∫ ωp
1
1
iωt
χ[−ωp ,ωp ] (ω)e dω =
eiωt dω
2π −∞
2π −ωp
[
]ω=ωp
1 eiωt
1 eiωp t − e−iωp t
1 sin ωp t
=
=
=
2π it ω=−ωp 2π
it
π t
ωp
=
sinc ωp t.
π
19
まとめ
4
最初に立てた目標である「音の低音、高音を自由に強めたり、弱めたりする」ことに対して
今回は、自分で指定した周波数のローパスフィルタの設計、実際の音データのフィルタリング
に成功した。
窓関数について、完全に理解することまでは時間切れでできなかった。
新たな課題として考えられることは、ある周波数より高い音を通すハイパスフィルタ、ある
周波数帯の音のみを通すフィルタ、これらも、ローパスフィルタの考え方を元に調べることが
できるということ、また、リアルタイムでのローパスフィルタを利用したフィルタリングにつ
いても、新たな課題として考えられる。
A
Fourier 変換
虚数単位は i で表す。
テキストによって定義が異なる。
A.1
流儀 1
f : Rn → C に対して、
1
g(ξ) :=
(2π)n/2
(2)
∫
Rn
f (x)e−ixξ dx (ξ ∈ Rn )
で定義される関数 g = g(ξ) を、f の Fourier 変換と呼び、Fg, fˆ などの記号で表す:
(3)
Ff (ξ) = fb(ξ) =
∫
1
(2π)n/2
Rn
f (x)e−ixξ dx (ξ ∈ Rn ).
多くの f に対して
1
f (x) =
(2π)n/2
(4)
∫
g(ξ)eixξ dξ
Rn
(x ∈ Rn )
が成り立つ。これを Fourier の反転公式と呼ぶ。
一般に、g : Rn → C に対して、(4) で定義される関数 f = f (x) を、g の逆 Fourier 変換
と呼び、F ∗ g, F −1 g, g̃ などの記号で表す:
(5)
1
F g = ge(x) =
(2π)n/2
∗
20
∫
g(ξ)eixξ dξ
Rn
(x ∈ Rn ).
A.2
流儀 2
(時刻 t と角周波数 ω を使う立場。)
x = x(t) に対して
∫
∞
X(ω) :=
−∞
x(t)e−iωt dt (ω ∈ R)
で定義される関数 X = X(ω) を、x の Fourier 変換と呼び、Fx, x̂ などと表す:
∫ ∞
b(ω) =
Fx(ω) = x
x(t)e−iωt dt (ω ∈ R).
−∞
X = X(ω) に対して
1
x(t) :=
2π
∫
∞
X(ω)eiωt dω
(t ∈ R)
inf ty
e などの記号で表す:
で定義される関数 x = x(t) を、X の逆 Fourier 変換と呼び、F ∗ X, F −1 X, X
∫ ∞
1
∗
e
F X(t) = X(t) :=
X(ω)eiωt dω (t ∈ R).
2π −∞
X(ω) のことを x(t) の角周波数領域での表現、などと呼ぶこともある。
A.3
流儀 3
x = x(t) に対して
∫
∞
X(f ) :=
−∞
x(t)e−2πif t dt (f ∈ R)
で定義される関数 X = X(ω) を、x の Fourier 変換と呼び、Fx, x̂ などの記号で表す:
∫ ∞
b(f ) =
Fx(f ) = x
x(t)e−2πif t dt (f ∈ R).
−∞
X = X(t) に対して
∫
∞
x(t) =
X(f )e2πif t df
−∞
(t ∈ R)
b などの記号で表す:
で定義される関数 x = x(t) を X の逆 Fourier 変換と呼び、F ∗ X, X
∫
∗
b =
F X(t) = X(t)
X(f )e2πif t df (t ∈ R).
R
B
B.1
Fourier 級数と離散 Fourier 変換
Fourier 級数
周期 T の関数 x = x(t) に対して、次の級数を x の Fourier 級数と呼ぶ:
)
∞ (
a0 ∑
2nπt
2nπt
+
+ bn sin
,
an cos
2
T
T
n=1
21
ただし
1
an :=
T
∫
T /2
2nπt
x(t) cos
dt,
T
−T /2
1
bn :=
T
∫
T /2
x(t) sin
−T /2
2nπt
dt.
T
ここまでは積分区間を [−T /2, T /2] としたが、周期関数であるから、[0, T ] としても同じこと
である。
また次の級数を x の複素 Fourier 級数と呼ぶ:
∑
n∈Z
exp
2πnit
,
T
ただし
cn
(
)
2πnit
x(t) exp −
dt.
T
−T /2
∫
1
:=
T
T /2
N
2πnit
1 ∑
exp
DN (t) :=
T n=−N
T
(N ∈ N, t ∈ R)
で定義される DN を Dirichlet 核と呼ぶ。
命題
周期 T の任意の周期関数 x = x(t), N ∈ N に対して、
N
∑
1πnit
,
xN (t) :=
cn exp
T
n=−N
1
cn :=
T
(
)
2πnit
x(t) exp −
dt
T
−T /2
∫
T /2
とおくとき、xN = x ∗ DN , すなわち
∫
xN (t) =
T /2
−T /2
x(t − τ )DN (τ )dτ
(t ∈ R)
が成り立つ。—「x の Fourier 級数の第 N 項までの部分和は、x と Dirichlet 核 DN との畳
み込みに等しい。」
B.2
離散 Fourier 変換
x = x(t) が周期 T の周期関数であるとする。周期区間 [0, T ] の N 等分点
tj = j
T
N
(j = 0, 1, ..., N = 1)
における値 xj = x(tj ) が得られたとき、Fourier 係数
1
cn =
T
∫
0
T
(
)
2nπit
x(t) exp −
dt
T
22
を近似計算することを考える。周期関数の1周期における積分は、台形公式で近似するのが有
効である。今の場合は
(
)
(
)
N −1
N =1
1 T ∑
2nπitj
1 ∑
2nπij
Cn := ·
xj exp −
=
xj exp −
.
T N j=0
T
N j=0
N
(
2πi
W := exp −
N
とおくと、
)
N −1
1 ∑
Cn =
xj W nj .
N j=0
W は 1 の原始 N 乗根であり、
W j ̸= 1 (j = 1, 2, ..., N − 1)
W N = 1,
を満たす。これから
N
−1
∑
W kj =
{
N
(k ≡ 0 (mod N ))
0
(k ̸≡ 0 (mod N ))
j=0
が導ける。
m ≡ n (mod N )
⇒
Cn = Cm
であることが分かるので、C0 , C1 , ..., CN −1 だけを考えれば十分である。
−1
数列 {xj }N
j=0 に対して、
Xk =
N
−1
∑
xj W kj
(k = 0, 1, ..., N = 1)
j=0
−1
N −1
で定まる数列 {Xk }N
k=0 を、{xj }j=0 の離散 Fourier 変換と呼ぶ。また写像 {xj } 7→ {Xk } を離
散 Fourier 変換と呼ぶこともある。(k, j) 成分が W kj である行列を W とすると、




x0
X0
 x1 
 X1 




 ..  = W  ..  .
 . 
 . 
xN =1
XN =1
言い換えると、離散 Fourier 変換の表現行列は W である。
W∗ W = WW∗ = N IN
が成り立つ。これから、
W−1 =
これから
1 ∗
1
W = (W −jk ).
N
N
N −1
1 ∑
xj =
Xk W −kj
N k=0
23
(j = 0, 1, ..., N − 1)
が得られる。
not 特に
1
U := √ W
N
1
とおくと、U ∗ = √ W∗ であるので、
N
U ∗ U = U U ∗ = IN .
ゆえに U は unitary 行列である
C
離散時間 Fourier 変換
{xn }n∈Z の離散時間 Fourier 変換 (discrete-time Fourier transform,DTFT) とは、
∑
(6)
X(ω) :=
xn e−inω (ω ∈ R; 実は周期 2π である).
n∈Z
xn について、有限エネルギー条件
∑
を課す、としたテキストがある。その場合、
n∈Z|xn |2 <∞
X ∈ L2 (0, 2π) であり、(6) は、L2 における等式と解釈することになる。
この関数 X は周期 2π である:
∀k ∈ Z X(ω + 2πk) = X(ω).
ゆえに ω ∈ [0, 2π](あるいは ω ∈ [−π, π]) で考えれば十分である。
xn は関数 X の第 (−n)Fourier 係数と見なせるので
∫ π
1
(7)
X(ω)einω dω (n ∈ Z).
xn =
2π −π
これが離散時間 Fourier 変換の反転公式である。
D
参考文献
[1] 青木直史 : サウンドプログラミング入門 — 音響合成の基本と C 言語による実装, 技術評
論社 (2013).
[2] 樋口龍雄, 川又政征 : MATLAB 対応 ディジタル信号処理, 昭晃堂 (2000).
24
Fly UP