ギター用チューナーを作る① フーリエ変換

ふとギター用チューナーが作りたくなりました。プログラムを書いてコンピュータ上で実行させるつもりです。あわよくば複数弦を同時にチューニングを確認できるようにしたり、Webブラウザ上で動作できるようにしたいなと思ってます。

まずはもととなるアルゴリズムから。周波数解析と言えばフーリエ変換ですね。多分。
いろいろ調べたことをここにまとめます。自分のための備忘録。

フーリエ変換

フーリエ変換とは

フランスの科学者 J.Fourier が熱伝導に関する論文において、任意の関数が三角級数で表現可能であることを主張し、導入された。

フーリエ級数

フーリエ級数(Fourier series)とは、任意の周期関数を三角関数の(無限)和で表す方法のこと。その式は、周期 Tの周期関数 x(t)に対して

  {\displaystyle \frac{a_0}{2} +  \sum_{n=1}^{\infty}( a_n cos \frac{2\pi n}{T}t + b_n sin \frac{2\pi n}{T}t ) }

と表される。 a_nb_n x(t)フーリエ係数(Fourier coefficient)と呼び、これらはそれぞれ

 {\displaystyle a_n = \frac{2}{T} \int_0^T x(t) cos \frac{2\pi n}{T}t dt }

 {\displaystyle b_n = \frac{2}{T} \int_0^T x(t) sin \frac{2\pi n}{T}t dt }

この定義から、 a_{-n} = a_n, b_{-n} = -b_nとわかる。
( cos(-x) = cosx , sin(-x) = -sinxより)

さらに、オイラーの公式から

 {\displaystyle cos \frac{2 \pi n}{T}t = \frac{e^{i \frac{2\pi n}{T}t} + e^{-i \frac{2\pi n}{T}t}}{2}}

 {\displaystyle sin \frac{2 \pi n}{T}t = \frac{e^{i \frac{2\pi n}{T}t} - e^{-i \frac{2\pi n}{T}t}}{2i}}

これをフーリエ級数の式に代入して整理すると

  {\displaystyle \frac{a_0}{2} +  \sum_{n=1}^{\infty}( a_n \frac{e^{i \frac{2\pi n}{T}t} + e^{-i \frac{2\pi n}{T}t}}{2} + b_n \frac{e^{i \frac{2\pi n}{T}t} - e^{-i \frac{2\pi n}{T}t}}{2i}) }
 {\displaystyle = \frac{a_0}{2} +  \sum_{n=1}^{\infty}( \frac{a_n - i b_n}{2} e^{i \frac{2\pi n}{T}t} + \frac{a_n + i b_n}{2} e^{-i \frac{2\pi n}{T}t}) }
{\displaystyle = \frac{a_0}{2} +  \sum_{n=1}^{\infty} \frac{a_n - i b_n}{2} e^{i \frac{2\pi n}{T}t} + \sum_{n=-1}^{-\infty} \frac{a_n - i b_n}{2} e^{i \frac{2\pi n}{T}t} }
 {\displaystyle = \sum_{n=-\infty}^{\infty} c_n e^{i \frac{2\pi n}{T}t}}

ただし、 {\displaystyle c_n = \frac{a_n - i b_n}{2}} と定める。
この級数複素フーリエ級数といい、 c_n複素フーリエ係数という。

フーリエ変換

フーリエ級数は、周期関数あるいは有限区間で与えられた関数を三角級数で表すものであった。これに対し、無限区間で定義された周期を持たない関数は、周期が無限大の関数として考えることによって、フーリエ級数を形式的に適応する。

ここからは、区間 [0,T]を [- \frac{T}{2} , \frac{T}{2}]に取り直す。

 {\displaystyle c_n = \frac{1}{T} \int_{- \frac{T}{2}}^{\frac{T}{2}} x(\tau) e^{-i \frac{2\pi n}{T} \tau} d\tau }

を複素フーリエ級数の式に代入すると

 {\displaystyle \sum_{n=-\infty}^{\infty} \frac{1}{T} (\int_{- \frac{T}{2}}^{\frac{T}{2}} x(\tau) e^{-i \frac{2\pi n}{T} \tau} d\tau ) e^{i \frac{2\pi n}{T}t} }

 無限区間に拡張するため、 T \rightarrow \inftyを考える。
ここで、周期 Tと基本各周波数 \omega _0 {\displaystyle \omega_0 = \frac{2\pi}{T}}の関係があるから
 {\displaystyle \lim_{T \to \infty} \omega_0 \to d\omega}
さらに、 n\omega_0 は微小量の整数倍で、連続量(実数)と捉えることができる。 n\omega_0 =: \omega \in \mathcal{R} のように \omegaを定めると、

 {\displaystyle \lim_{T \to \infty} \sum_{n=-\infty}^{\infty} \frac{\omega_0}{2\pi} (\int_{- \frac{T}{2}}^{\frac{T}{2}} x(\tau) e^{-i n \omega_0 \tau} d\tau ) e^{i n \omega_0 t} }

 {\displaystyle = \frac{1}{2\pi} \int_{-\infty}^{\infty} d\omega (\int_{- \infty}^{\infty} x(\tau) e^{-i \omega \tau} d\tau ) e^{i \omega t} }

この式は元々、 x(t)を変換したものであるから、

 {\displaystyle x(t) = \frac{1}{2\pi} \int_{-\infty}^{\infty} (\int_{- \infty}^{\infty} x(\tau) e^{-i \omega \tau} d\tau ) e^{i \omega t} d\omega}

と表すことができる。ここで両辺の x(t)に注目すると、右辺の x(t)が2回の変換を経て元の式に戻っていることがわかる。すなわち、括弧内が x(t)の変換で、外側が変換した x(t)の復元と考えることが出来る。ここで変換した関数を X(\omega)とおく。

上式の括弧内の部分
 {\displaystyle X(\omega) = \int_{- \infty}^{\infty} x(t) e^{-i \omega t} dt }

この x(t)から X(\omega)への変換の過程をフーリエ変換と呼ぶ。

括弧内を X(\omega)と置いた式

 {\displaystyle x(t) = \frac{1}{2\pi} \int_{- \infty}^{\infty} X(\omega) e^{i \omega t} d\omega }

この X(\omega)から x(t)への変換の過程をフーリエ逆変換と呼ぶ。

結局何がどうなったの?

フーリエ級数フーリエ変換はどちらも「時間関数」を「周波数関数」に変換している。ということは、音声入力から周波数分布を知ることが出来るようになった。

フーリエ級数は、基本角周波数{\displaystyle \omega = \frac{2\pi}{T}} の整数倍の正弦波の無限和で元の関数を表現する。それに対してフーリエ変換は、基本各周波数 {\displaystyle \omega = lim_{T \to \infty} \frac{2\pi}{T} }の整数倍の正弦波の無限和で元の関数を表現している。

すなわち、たとえば時間変数の信号(音声など)をそれぞれの方法で処理する時、フーリエ級数では、周波数成分を離散的に取り出すが、フーリエ変換では連続的に取り出すことが可能。

問題点

フーリエ変換は連続な関数を積分しているため、計算機上では厳密な計算ができない。ということは離散化する必要がありそう。

あとがき

次は本題の離散フーリエ変換高速フーリエ変換(FFT)について書きます。それはいつになるのだろうか…
かなり曖昧な理由付けによって式変形しているところがいくつかあってモヤモヤしてるので、ちゃんと理解したらこっそり書き直します。