音声知覚と音声合成と合唱

最近、どの道へ進んでも音に関連するものに出会ってる筆者が音声合成・知覚に関する研究するうえで勉強してきたことを備忘録として残していきます

波形とスペクトラム

こんばんは、4月13日、ハッピバースデートゥーミーです。
現在音声認識・合成・知覚など(具体的な分類はわかってない)に関する研究室に配属しまして、音の勉強に熱中し始めたころです。
早速、記事を書いていき、自分の頭の悪さを認識しながら勉強していきたいと思います。
基礎中の基礎から進んでいき、わかりやすいブログの書き方も学びたいと思っています。
よろしくお願いします。

波形からスペクトラム

 
早速ですが、音声知覚・合成を行ううえで重要な情報というのは、音の波形ではなく、スペクトラムにあります。まずは「スペクトラムとはなにか」という点から書いていきます。

スペクトラムとは


フーリエの定理

音声や地震波などの周期性のある信号は、どれだけ複雑な信号であっても、単純な波に分解できる


以上の定理にしたがって、複合波形から、周期性のある信号の周波数と振幅を取り出したものが周波数スペクトラムとなります。

複合波の生成

???よくわからないですね。少なくともこの説明じゃ私には理解できないです。() というわけで早速、数値計算ソフトであるMATLABを用いて信号を可視化しながら理解していきます。まずは、入力となるFig1,Fig2のような複数の異なる周波数・振幅を持つ波を複合した波を作ります。

f:id:Keropattyo:20150412222715p:plain:w300
Fig1 振幅1.2、周波数130[Hz]とした正弦波

f:id:Keropattyo:20150412222729p:plain:w300
Fig2 振幅0.9、周波数200[Hz]とした余弦


Fig3は、上記2つの波を複合させた波を出力した結果です。

f:id:Keropattyo:20150412223149p:plain
Fig3 Fig1, Fig2を複合させた波


MATLABによって以下のソースコードで上のような波を生成します。

Fs = 8820;  % サンプリング周波数 8820Hz
time = 0 : 1 / Fs : 0.05;
sinwav_1 = 1.2 * sin(2 * pi * 130 * time); %振幅1.2、周波数130[Hz]の正弦波 Fig1の波
coswav_1 = 0.9 * cos(2 * pi * 200 * time); %振幅0.9、周波数200[Hz]の余弦波 Fig2の波
wavdata = 1.4 + [sinwav_1 + coswav_1];
plot(time*1000, wavdata); xlabel('時間[ms]'); ylabel('振幅');

音声知覚などでは入力として、このような複数の信号が合わさった複合波を扱っていくことになります。


複合波の分析方法  ~フーリエ変換

さて、この波形(入力)に対して音声を情報として扱うための分析を行うには、この複合波が、どのような単純な波で構成されているのか(スペクトラム)を知る必要があります。そこでフーリエ変換を用います。授業でフーリエ変換、やった気がしなくもないです。復習します。
フーリエ変換の式は以下のようになっています。

f:id:Keropattyo:20150412231116p:plain

今回は式だけ示して、また別の機会に離散フーリエ変換高速フーリエ変換、その逆のパターンに関する記事をまとめようと思います。(どうせゼミのために勉強しなきゃいけない(ボソッ))

早速、Fig1の波Fig2の波で構成された複合波Fig3に対してフーリエ変換していきます。
MATLABにおいて以下のソースコードフーリエ変換を行うことができます。

fftsize = 2048;   %フーリエ変換の次数, 周波数ポイントの数
dft = fft(wavdata, fftsize); %wavdataは入力複合波

%振幅スペクトル(dftの絶対値、conj:複素共役)
Adft = sqrt(dft .* conj(dft));   %Adft = abs(dft); としても同じ

%パワースペクトル(dftの絶対値の二乗)
Pdft = abs(dft) .^ 2;

%周波数スケール(サンプリング定理より、OHzからサンプリング周波数まで)
fscale = linspace(0, Fs, fftsize);    %0Hz~8820Hzまでをfftsize個に分割

%プロット(表示するのはサンプリング周波数の半分まで)
subplot(2,1,1); plot(fscale(1:fftsize/2), Adft(1:fftsize/2)); 
xlabel('周波数[Hz]'); ylabel('振幅スペクトル'); xlim([0 1000]);
subplot(2,1,2); plot(fscale(1:fftsize/2), Pdft(1:fftsize/2)); 
xlabel('周波数[Hz]'); ylabel('パワースペクトル'); xlim([0 1000]);


さて、これを用いると複合波形はどのような出力となるのか、次の図に示します。
f:id:Keropattyo:20150412225937p:plain
Fig4 Fig3複合波形にフーリエ変換を用いた結果

以上の結果から、大体わかっていただけたかと思います。
今回生成した波は、振幅1.2、周波数130[Hz]の正弦波と、振幅0.9、周波数200[Hz]の余弦で構成された複合波です。横軸が周波数ですので、130Hzの場所と200Hzの場所でいい感じの振幅で波が立っていることがわかりますね。つまり複合波をフーリエ変換すると、どの周波数・振幅の単純な波で構成されているかが波として現れます。

まとめ

音声知覚・合成などの分野において、音声信号はただの波形であり、それらをどのような単純な波の構成で作られた複合波(スペクトラム)なのかを抽出することで初めて情報となる。(らしい)(あってる??)
そして、その方法の一つとして離散フーリエ変換を用いて、ちゃんと複合波を構成する単純な波を抽出できていることを実験を通して確認した。
次は離散フーリエ変換高速フーリエ変換についてまとめたいと思ってる(数学辛い)
記事書き始めだからこれから少しずつわかりやすい書き方へと成長していこう