読者です 読者をやめる 読者になる 読者になる

人工知能に関する断創録

人工知能、認知科学、心理学、ロボティクス、生物学などに興味を持っています。このブログでは人工知能のさまざまな分野について調査したことをまとめています。最近は、機械学習・Deep Learningに関する記事が多いです。



SPTKの使い方 (10) ボコーダーで遊ぼう

音声信号処理 音声合成

SPTKの使い方 (9)(2013/3/2)の続き。

今回は、分析合成音のパラメータを変えることで、高い声、低い声、かすれ声、ロボット声、子供声、深い声などいろんな音声に変換してみます。この実験はSPTKのマニュアルの8章を参考にしています。

オリジナルの音声

今までは青い植木鉢を使ってきましたが、今回は別の音声を使いました。ピッチ抽出(2012/7/7)で使った「あらゆる現実を」の音声です。

これをいろんな声に変換して遊んでみましょう!

ピッチ抽出

まず今までと同様に音声からピッチを抽出します。

x2x +sf a01.raw| pitch -a 1 > a01.pitch
dmp +f a01.pitch > pitch.txt

gnuplotでピッチ軌跡のグラフを表示してみるときれいに抽出できていることが確認できます。

f:id:aidiary:20130309204134p:plain

メルケプストラム分析合成

今回はマニュアルにしたがって分析合成のパラメータとしてメルケプストラムを使います。コマンドの詳しい使い方はメルケプストラム分析合成(2013/1/19)を参照してください。

x2x +sf < a01.raw | frame -l 400 -p 80 | window -l 400 -L 512 | mcep -l 512 -m 20 -a 0.42 > a01.mcep
excite -p 80 a01.pitch | mlsadf -m 20 -a 0.42 -p 80 a01.mcep| clip -y -32000 32000 | x2x +fs > a01.syn.raw
sox -e signed-integer -c 1 -b 16 -r 16000 a01.syn.raw a01.syn.wav

分析合成音はこんな感じです。ちょっとノイジーな感じですが再現できています。

音声を高くする・低くする

音声を高くしたり低くしたりするには音源のピッチの値を変更します。ピッチは声の高さを表しているからです。pitchコマンドのデフォルトの出力値は、サンプリング周波数をHzで割った値が出力されます。そのためピッチの値が小さいほど高い音を意味します。soprコマンドを使うと値を変更することができます。たとえば、ピッチの値を0.5倍すると高い音になり、2倍すると低い音になります。オプションの-mはかけ算を意味しています。

sopr -m 0.5 a01.pitch | dmp +f > pitch.high.txt
sopr -m 2 a01.pitch | dmp +f > pitch.low.txt

f:id:aidiary:20130309205411p:plain

グラフでも0.5倍、2倍になっていることが確認できます。ではそれぞれのピッチファイルから分析合成音を出してみます。メルケプストラムパラメータはどちらも同じものを使います。変えるのは音源のピッチファイルだけです。

sopr -m 0.5 a01.pitch | excite -p 80 | mlsadf -m 20 -a 0.42 -p 80 a01.mcep | clip -y -32000 32000 | x2x +fs > a01.high.raw
sopr -m 2 a01.pitch | excite -p 80 | mlsadf -m 20 -a 0.42 -p 80 a01.mcep | clip -y -32000 32000 | x2x +fs > a01.low.raw

ちゃんと高い声、低い声に変換できました。

音声を速くする・遅くする

次に音声を早くしたり、遅くしたりしてみます。今度はピッチではなく、フレームシフトのパラメータをいじります。

excite -p 40 a01.pitch | mlsadf -m 20 -a 0.42 -p 40 a01.mcep | clip -y -32000 32000 | x2x +fs > a01.fast.raw
excite -p 160 a01.pitch | mlsadf -m 20 -a 0.42 -p 160 a01.mcep | clip -y -32000 32000 | x2x +fs > a01.slow.raw

元の音声は80フレームでシフトして分析していました。そのデータを異なるフレームシフトであるとみなして合成すると話速が変わるみたいです。ただどうしてフレームシフトと話速が関係するのかいまいち理解できていません。

かすれ声

人間の音声には有声音と無声音があります。有声音は喉が振るえる音(a i u e oなど)、無声音は喉が振るえない音(k sなど)です。無声音は喉が振るえないのでピッチが取れずpitchファイルでは0になっている区間に当たります。前に音源の生成(2013/1/19)で書きましたがSPTKのexciteコマンドが出力する音源は、有声音区間はパルス音源、無声音区間はホワイトノイズを出力していて、これを声道フィルターに通すことで合成音になります。有声音の区間もすべて無声音扱いすると独特のかすれた声(Hoarse Voice)が出せます。ピッチに0をかけて全部無声音にしてしまいましょう

sopr -m 0 a01.pitch | excite -p 80 | mlsadf -m 20 -a 0.42 -p 80 a01.mcep | clip -y -32000 32000 | x2x +fs > a01.hoarse.raw

ロボット声

肉声からピッチ抽出したピッチファイルを音源にするのではなく、一定値のパルス音源を使うと抑揚が全くないロボット声になります。パルス音源を出すコマンドはtrainです(何でtrainなんだろう?)サンプルでは-pオプションで200サンプルごとにパルスを出しています。この間隔を小さくすると高いロボット声、大きくすると低いロボット声になります。

train -p 200 -l -1 | mlsadf -m 20 -a 0.42 -p 80 a01.mcep | clip -y -32000 32000 | x2x +fs > a01.robot.raw

子供声・深い声

ピッチだけを高くしたり、低くすると変な声になってしまいますが、スペクトル包絡の方の\alphaパラメータに手を入れるとより自然な高い声・低い声になります。

sopr -m 0.5 a01.pitch | excite -p 80 | mlsadf -m 20 -a 0.1 -p 80 a01.mcep | clip -y -32000 32000 | x2x +fs > a01.child.raw
sopr -m 2 a01.pitch | excite -p 80 | mlsadf -m 20 -a 0.6 -p 80 a01.mcep | clip -y -32000 32000 | x2x +fs > a01.deep.raw

音声はこんな感じです。

高い方は子供っぽい声、低い方は何か犯罪者のモザイク(笑)みたいな声になりますね。ピッチだけ変えた音声と比べてみると違いがよくわかります。確かフィルタの\alphaパラメータは、メルスケールを導入するパラメータでサンプリング周波数によって値が決まっていました(16kHzのときは0.42)。これを変えるとどうして子供声や深い声になるのだろう?もう少しフィルタ理論を深めないとわからないです。

まとめ

この実験を通して音源とフィルタから合成音を作るソースフィルタモデルの理解が深まりました。次回はマイクで録音した声のパラメータを調整できる簡単なボイスチェンジャーを作りたいと思います。よく知らないんですがボイスチェンジャーって今回やった分析合成と同じ原理なんですかね?市販のソフトウェアもいくつか調べてみようと思います。