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