Short Time Fourier Transform って、何?
windows内のtown.midを再生して、spectrum analysis から逆FFTして得た、オシロの波形 ( 34 frame/sec )
input wave と output waveは、殆ど、同じと思います。
0. 追加記事 無駄骨だったわ
結論として、徒労に終わりました。
理由は、
簡単な理由で、ございました....なはは (^_^;; 汗。
ですので、
短時間フーリエ変換( Short Time Fourier Transform )は、実際に、時間差を持って、captureしなければ、意味がないようです...
では、どうするか?
実際のcaptureを、そのまま、使います。この場合は
captureしたデータを、窓を掛けてFFTしたのですから、逆FFTして、窓関数で割ってやれば、
それだけで、うまく波形が再生されます。(繋ぎ目は、繋がっていると、信じて...)
プログラムの一部です。
-------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------
FFT関係と、Filter関係を、クラス化してみましたが、ただ、クラス化しただけの、しょうもないクラスです。
captureしたデータを入れると、窓関数を掛けて、FFTし、IFFTして、窓関数で割ったデータが戻ってくる関数
public short[] get_windowed_IFFTed_windowed_FFTed_capture_data(int selected_windowFunc, short[] d)
こんなもん、作ってどないすんねん... (^_^;;
以下は、midファイル内の、同じシーンを使って、窓関数による差を、見てみたものです。
Rectangular
Hanning
Hamming
Blackman
Blackman-Harris
追加記事、ここまでです。
----------------------------------------------------------------------------------------------------
5KHz 1000tap LPFirを通した波形の復元(Hanning窓)
入力波形です。出力波形と、殆ど同じ。
1.spectrumからの、波形の復元は難しい...
上図は、復元波形が、1番きれいに見える状態の時を、表しています。
実は、波形及びspectrumの、表示は、非常に不安定なんで、頭が痛いですわ。
以下は、上図のように、きれいに見えた時を使って、窓関数の違いを調べてみます。
まず、rectangular 窓
復元した波形の、振幅が、一定では、なくなりました。
次に、Hamming 窓
振幅は、まあ、一定です。
次は、Blackman 窓
振幅は、少し、うねりますね....
沢山の計算を、通過した後なので、こうなるのかも知れませんね。
つまり、Short Time Fourier Tramsoform について、解った事は、後ほど書きますが、
現在Captureしたデータ( current_CaptureData )と、それから、
一つ前にCaptureしたデータの後半の半分と、現在のデータの前半の半分を、この順序で合わせた、新しい( new_CaptureData )を得て
new_CaptureData = second_half_of_former_CaptureData + first_half_of_current_CaptureData
それぞれ( new_CaptureData , current_CaptureData )
に付いて、窓関数を掛けて、 FFTします。
current_CaptureData ---> FFTed current_CaptureData (windowed)
new_CaptureData ---> FFTed new_CaptureData (windowed)
そして、FFTを使った直線たたみ込みを使用して、Low pass filterを通すのですから
Low pass filterをFFTしたものと、 FFTed_LPFir_coefと、掛け算します。
new_CaptureData ---> FFTed new_CaptureData x FFTed_LPFir_coef --->mixed_FFTed new_CaptureData
current_CaptureData ---> FFTed current_CaptureData x FFTed_LPFir_coef ---> mixed_FFTed current_CaptureData
この2つを使って、逆FFTして、波形データを復元します。
それぞれに付いて 逆FFTします。
mixed_FFTed new_CaptureData ---> IFFTed_mixed_FFTed new_CaptureData
mixed_FFTed current_CaptureData ---> IFFTed_mixed_FFTed current_CaptureData
ここで、得られた両者を、それぞれ、逆Windowする。(窓関数を掛けたから、窓関数で、割って、元にもどす。)
IFFTed_mixed_FFTed new_CaptureDataの後半の半分 second_half_of_IFFTed_mixed_FFTed new_CaptureData を得る
IFFTed_mixed_FFTed current_CaptureDataの前半の半分 first_half_of_IFFTed_mixed_FFTed current_CaptureData を得る
得られた両者について、なめらかになるような関数w1,w2を掛けます。
second_half_of_IFFTed_mixed_FFTed new_CaptureData x w1
first_half_of_IFFTed_mixed_FFTed current_CaptureData x w2
そして、最後に、この両者を、足して、Low pass filter通過後の信号の、半分が、復元できた事になります... ああ、しんど (^_^;;
計算の過程を書くと、ややこしいですね...間違っとるかも、知れん。
ぎょうさん、書いてしもた.....ごめんなさい。
ここ と、
「フーリエ変換,逆変換をして元の波形に戻るか?」を、ご覧になって下さい。
貴重な資料を公開して下さっておられる、御両名に、御礼申し上げます。
プログラムも複雑になってきましたので、この辺りで、クラス化を考えた方が、よい気がしてきました、
クラスの知識は、少ないのですが....例によって、書きながら、調べて行けば、なんとかなるかも....
2.結局 Short Time Fourier Transform って、何なんよ...
だらだらと、書いてしまって、 お怒りごもっともです、すみません。
私は、以下の様に解釈しました。
この場合、CaptureDataの半分を、重なるようにして、時間的に繋いで行くようです。
まだ、実験がうまく行ってないのは、この解釈が間違っているからかも、知れません...涙、涙
2回目のデータをcaptureしたら、
前のデータと、前のデータの後半と現在のデータの前半を合わせたものとで、FFT、IFFTし
次に、前のデータの後半と現在のデータの前半を合わせたものと、今回captureしたデータで、FFT,及びIFFTする
と、言う訳ですから、
1度のcaptureで、2回計算することになります....1粒で、2度おいしい、グリコみたいやな、なはは (^_^;;
これの繰り返しに、なると思います。
FFTする時、窓関数を掛けて、滑らかにします。
まだまだ、うまく行ってません......
何かが、間違っているようです... 「線路は続くーよー どこまでもー ♪」....
H.18.10.26