マエカワの備忘録的な何か

思い立ったが吉日

音声音響情報処理 其の二 20180417

はじめに

 今回は,scilabを使って音声どうしの畳み込みまでやっていきました.理論的なことはあまり出てきませんでしたので,コードばかりのノートになると思いますが,悪しからず.

scilab操作

 一応,今回の講義で使ったプログラムは以下の通り.

音の出力

t=(1:8000)/8000; //サンプリング周波数8kHz
x=0.3*sin(2*%pi*1000*t); //角周波数1kHzのsin波を生成
plot(x(1:100)); //時刻100までの波形を出力
sound(x,8000); //サンプリングレート8kHzで再生

 これなんですが,サンプリングレートを低くしたら低速で,高くしたら高速で再生されるようになります.

フーリエ変換

 scilabには,fftという関数があります.これを使うと,離散フーリエ変換をしてくれるという仕組みになっています.ちなみに,離散フーリエ変換は以下のように記述できます.

   \displaystyle 
X\left(\omega_k\right)=\sum_{n=0}^{N-1}x\left(n\right)\exp\left(-j\frac{2\pi}{N}nk\right) , 0\le k\le N-1

ただし,離散フーリエ変換ではサンプル数(ここでは Nのこと)が異なれば,1メモリが表す数が異なることにも注意したい.不確定性というらしい.
 ということで,コードを書いていきましょう.

fx=fft(x);
plot(20.*log10(abs(fx)));

人間の感覚は対数に対応しているので,このような式でプロット.また,単純な大きさ(絶対値)でプロットしているのは,虚数空間を無視するためです.
 これでプロットされたのが次のグラフ.

f:id:maekawa_yoshimiki_1119:20180419013725p:plain

さっきの「1メモリが変わる」というのもやってみましょうか.

fx=fft(x(1:4000));
plot(20.*log10(abs(fx)));

サンプル数を8000個から4000個に落とします.そうして出てきたのが次のグラフ.

f:id:maekawa_yoshimiki_1119:20180419013918p:plain

どちらも,角周波数に設定した1kHzにスペクトルのピークが出ているのですが,前者は横軸が8000,後者は横軸が4000であることが分かります.サンプル数を半分に落とした分,横軸の1メモリに対応する値が2倍になったことがここからも確認できますね.
 そのほか,グラフにピーク値が二つあるのはサンプリング定理によるもの.サンプリング周波数の半分(エイリアス)で折り返されるというあれですね.

音の足し合わせ

 音は線形なので,足し合わすことができます.ということでコードを.

t=(1:8000)/8000; //サンプリング周波数8kHz

x1=0.3*sin(2*%pi*1000*t);
x2=0.3*sin(2*%pi*3000*t);

x3=x1+x2; //足し合わせる
sound(x3,8000); //音を聞く

fx=fft(x3); //フーリエ変換
plot(20.*log10(abs(fx))); //プロット

出てきたグラフは次の通り.

f:id:maekawa_yoshimiki_1119:20180419015502p:plain

きれいに1kHzと3kHzの場所にピークが来てますね.面白い.今度は,x2の方を半分にして足し合わせてみます.

x3=x1+0.5*x2; //足し合わせる
sound(x3,8000); //音を聞く

fx=fft(x3); //フーリエ変換
plot(20.*log10(abs(fx))); //プロット

出てきたグラフはこんな感じ.

f:id:maekawa_yoshimiki_1119:20180419020125p:plain

3kHzの方だけピーク値が低いです.分かりにくいという人のために拡大画像を.

f:id:maekawa_yoshimiki_1119:20180419020233p:plain

こんな感じ.音の大きさが半分になると,大体6dBだけピークが低くなることが分かっています.これは,デシベルの計算をみても理解できます.

   \displaystyle 
\begin{eqnarray}
20\log_{10}\frac{1}{2}&=&-20\times 0.301\\
&=&-6.02
\end{eqnarray}