投稿日: Jun 03, 2018 7:42:51 AM
なんだか難しげではあるけど、使い道としては周波数の特性を調べるとか、あとはボコーダー作ったりノイズリデュースしたり。
ぶっちゃけた話何をするためのものかというと音を周波数毎に分解するもの。
で、分解出来ただけでは意味があんまり無いので元に戻すための逆フーリエ変換ってのもあるわけです。
フーリエ変換後なにやらの処理をして逆変換して、という流れでデータを加工したりするわけですネ。
コンピュータではよく高速フーリエ変換(FFT)というのが使われています。
これは計算するパターンを制限することで速度を稼ぐためのもの。
速度を気にせず制限を取り払って使う場合は離散フーリエ変換(DFT)ってのを使います。
bareAudioの場合はじっくりしっかり、簡単に処理したいので当然こっちを選択します。
あちこちでフェーズのとり方がビミョーに違ったりしていて、違ったらダメだろうと思いつつも動いちゃうから困りもので。
わたしは昔に作ったソースを元にPythonに書き直してみました。
import math as m class DFT: def __init__(self): pass def dft(self,data): N = len(data) real = [0] * N image = [0] * N for i in range(N): for j in range(N): phase = 2*m.pi*i*j/N real[i] += data[j] * m.cos(phase) - data[j] * m.sin(phase) image[i]+= data[j] * m.sin(phase) + data[j] * m.cos(phase) real[i] /= N image[i] /= N return(real,image) def idft(self,data): N = len(data[0]) sr = data[0] si = data[1] data = [0] * N for i in range(N): for j in range(N): phase = 2*m.pi*i*j/N data[j] += sr[i]*m.cos(phase) + si[i]*m.sin(phase) return data
d = DFT() data = [1.2, 1.5, 2, 3, 4, 5, 6, 7.5] #dft (real,image) = d.dft(data) for i in range(len(real)): print(real[i] , " / " , image[i] ) print("-----") #idft data = d.idft((real,image)) for i in range(len(data)): print(data[i])
データを離散フーリエ変換して逆変換するというもの。
でまあ、実行するわけです。
3.775 / 3.7750.9454951288348655 / -1.46871843353822970.14999999999999947 / -0.8500000000000001 -0.23128156646177034 / -0.6454951288348667 -0.4750000000000004 / -0.4749999999999996 -0.6454951288348683 / -0.23128156646177067 -0.8500000000000024 / 0.14999999999999858 -1.4687184335382244 / 0.9454951288348677 ----- 1.19999999999999881.50000000000000442.00000000000000132.9999999999999923.9999999999999955.0000000000000026.0000000000000067.499999999999996
元のデータと見比べるとなんだか誤差が気になりますが。
これはコンピュータの数字の扱い上仕方がないというか、こんなもんなんです。
いちおうPythonにはこういう誤差を減らすためのモジュールがあるんですがmicroPythonだとかその他Python環境を考慮して使わないことにしておきます。のでこれで一旦妥協。
16bitオーディオにした時点で結構誤差がでるし、DFTのこの誤差はオーディオを耳で聴いて感じ取れるような差は生み出さないだろうってことで。
ひとまずフーリエ変換を用意できましたってことで、次はこれをbareAudioで便利に使う方法を考えましょうねぇ。