EnsekiTT Blog

EnsekiTTが書くブログです。

STFT→iSTFTでちゃんと音がもとに戻るのか確認してみた話

つまりなにしたの?

音声データをSTFTして、スペクトログラムを用意してそのスペクトログラムからまた音声データに戻せるのか確認してみた。
一旦スペクトログラムにすればCNNとかと相性が良いから面白いかもなーと試してみた。

f:id:ensekitt:20171026224438j:plain

音声データとは

録音したデジタルの音声データ。今回は普通のモノラル音源を用意した。

フーリエ変換とは

時間領域表現の関数を周波数領域表現の関数に分解する。どんな周波数の成分の組み合わせで波が出来ているかを知る方法。
高速フーリエ変換を使うとそこそこリアルタイムな感じで周波数成分の値に変換できる。
今回はある時間の音声データをスペクトログラム(横軸に時間、縦軸に周波数、色に強さ)で表示して、
そのデータ*1から音声を復元することを目指す。
窓関数をかけてしまっているし、スペクトログラムから波形にも戻してどうなるか確認したい。

窓関数とは

フーリエ係数を求めるためには本来は無限長の波形に対して積分を行う。
しかし、そんなデータは実際にはないので、範囲を区切る必要がある。単純にぶった切ってしまうと、急に信号が始まって急に信号が止まるという信号になり連続な感じにならない。
そのために、窓関数として関数をかける。窓関数の特徴としては切り取った波形の真ん中あたりが1に近くて、端っこは0に近づく。そうすると無限と言いつつ真ん中あたりだけをうまく扱える。

STFTとiSTFT

STFTはshort-time Fourier transformの略で短時間フーリエ変換とかって訳す。ここで言う短時間は短い時間幅って意味で速度が早いフーリエ変換FFTとは別物。これを使って短い時間毎に周波数領域に変換していくことで時間軸をある程度維持しながら各時間に置ける周波数領域情報を得ることができる。
ドラマの声紋認証とかで出て来るこんな画。あとで示すけど、声紋認証のインタフェースにこんなの出しちゃうと写真撮られたらある程度音声が復元できちゃうから録音で突破できるようになっちゃうんじゃないですかねって思ってみたり。
f:id:ensekitt:20171026225302j:plain

iSTFTはフーリエ逆変換を同じく短時間フーリエ変換向けにたくさんやって元の時間領域表現に戻す。
f:id:ensekitt:20171026230901p:plain
今回は戻してWaveファイルに書き込んで聞くところまでやる。
正直波形の差は見てもわからないけど聞けば多少変になってたらわかると思ったため。
あと一応平均二乗誤差で短時間の範囲を変えたらどうなるか確認してみた。

Scipy.signal使って実装してみた。

Jupyter Notebookで実行できる。*2
github.com

評価

nperseg(時間の幅)の変更について評価した。(オーバーラップ率は標準の1/8)
nparseg: 平均二乗誤差
128: 0.638
256: 1.174
512: 2.365
1024: 4.059
2048: 5.785
だんだん誤差が大きくなっていった。けどもともとめっちゃ良くて耳じゃわからない!!

*1:JPEGなどの画像データではなく2次元配列データ

*2:githubってどのクライアントでもJupyter Notebook見られますよね