SPTKの使い方 (10) ボコーダーで遊ぼう
SPTKの使い方 (9)(2013/3/2)の続き。
今回は、分析合成音のパラメータを変えることで、高い声、低い声、かすれ声、ロボット声、子供声、深い声などいろんな音声に変換してみます。この実験はSPTKのマニュアルの8章を参考にしています。
ピッチ抽出
まず今までと同様に音声からピッチを抽出します。
x2x +sf a01.raw| pitch -a 1 > a01.pitch dmp +f a01.pitch > pitch.txt
gnuplotでピッチ軌跡のグラフを表示してみるときれいに抽出できていることが確認できます。
メルケプストラム分析合成
今回はマニュアルにしたがって分析合成のパラメータとしてメルケプストラムを使います。コマンドの詳しい使い方はメルケプストラム分析合成(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
グラフでも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
子供声・深い声
ピッチだけを高くしたり、低くすると変な声になってしまいますが、スペクトル包絡の方のパラメータに手を入れるとより自然な高い声・低い声になります。
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
音声はこんな感じです。
高い方は子供っぽい声、低い方は何か犯罪者のモザイク(笑)みたいな声になりますね。ピッチだけ変えた音声と比べてみると違いがよくわかります。確かフィルタのパラメータは、メルスケールを導入するパラメータでサンプリング周波数によって値が決まっていました(16kHzのときは0.42)。これを変えるとどうして子供声や深い声になるのだろう?もう少しフィルタ理論を深めないとわからないです。
まとめ
この実験を通して音源とフィルタから合成音を作るソースフィルタモデルの理解が深まりました。次回はマイクで録音した声のパラメータを調整できる簡単なボイスチェンジャーを作りたいと思います。よく知らないんですがボイスチェンジャーって今回やった分析合成と同じ原理なんですかね?市販のソフトウェアもいくつか調べてみようと思います。