@dsk_saito先生のSPTK講習のまとめ。
音声合成の基礎であるヴォコーダー周りを学ぼう。合成フィルタの詳しい話はSPTKのマニュアル等を参照で。3.5系では一部コマンドの仕様が変わっているので、3.4系準拠ということで。
ヴォコーダーは、pitchの系列と素性ベクトルの系列(LPCやMel-cepstrum)を元に音声を合成するもの。
Text to Speechシステムではヴォコーダーに与えるためのピッチ系列とスペクトルに関する素性ベクトル系列の生成はHMMなどで生成するけれど、まずは人間の生の音声から素性ベクトルとピッチ抽出して再合成をしてみる。このピッチ系列と素性ベクトル系列に対しての操作を行うことで、ヴォイスチェンジャーや話者変換を実現することができる。
とりあえずsoxとSPTKを利用して音声分析合成を行う方法をまとめる。音声は16k16bit。SPTKの実行ファイル群は名前が他のプログラムと被っているものがあるので、prefixに/usr/local/SPTKなどを指定してインストールするとよい。
f0(ピッチ)の系列を取り出す。
bcut +s -s 22 test.wav | x2x +sf | frame -l 400 -p 80 | window -l 400 | pitch -s 16 -l 400 -t 4.5 > test.pitch
bcutを使ってwavのヘッダを切る frame: 音声をフレームに分割 。-lでウィンドウサイズを指定。'-l 400'で400/16000の25ms 。-pでフレーム周期(スライド量)を決める。
excite -p 80 test.pitch|sopr -m 1000 | x2x +fs > pitchsignal.raw
exciteを利用してピッチファイルから音源波形を生成
soprでスカラ演算を実行 (-m 1000 千倍) し、ヴォーカルコードの抽出が完了
sox -t raw -r 16000 -s -2 pitchsignal.raw pitchsignal.wav
soxでraw形式に対してwaveヘッダを付与
bcut +s -s 22 test.wav | x2x +sf | frame -l 400 -p 80 | window -l 400 -L 512 | mcep -a 0.42 -m 20 -l 512 > test.mcep
windowに -L 512 をしてるのは、FFTのため。後ろをzero fill して2のべき乗にしている
mcepに-mで20を指定すると、20次元ではなく21次元のベクトルが生成 (0 origineのデータに対して、終端のindexの値を指定するから)
excite -p 80 test.pitch | mlsadf -m 20 -a 0.42 -p 80 test.mcep | clip -y -32000 32000 | x2x +fs > mcepresyn.raw sox -t raw -r 16000 -s -2 mcepresyn.raw mcepresyn.wav
ヴォーカルコードとケプストラムを組み合わせて波形の合成処理をする
clipを利用して、short値を超える値をクリッピングしておく。
bcut +s -s 22 test.wav | x2x +sf | frame -l 400 -p 80 | window -l 400 | lpc -l 400 -m 20 > test.lpc excite -p 80 test.pitch | poledf -m 20 -p 80 test.lpc | clip -y -32000 32000 | x2x +fs > lpcresyn.raw sox -t raw -r 16000 -s -2 lpcresyn.raw lpcresyn.wav
MSなどの音声合成はこれを用いている(音が良いと言われている)
lpc2lsp -m 20 -n 256 < test.lpc > test.lsp excite -p 80 test.pitch | lspdf -m 20 -p 80 test.lsp | clip -y -32000 32000 | x2x +fs > lspresyn.raw sox -t raw -r 16000 -s -2 lspresyn.raw lspresyn.wav
bcut +s -s 22 test.wav | x2x +sf | frame -l 400 -p 80 | window -l 400 -L 512 | mgcep -a 0.42 -m 20 -c 2 -l 512 > test.mgcep excite -p 80 test.pitch | mglsadf -m 20 -a 0.42 -p 80 -c 2 test.mgcep | clip -y -32000 32000 | x2x +fs > mgcepresyn.raw sox -t raw -r 16000 -s -2 gmcepresyn.raw mgcepresyn.wav
波形を直接いじると品質の劣化が激しい。しかし、パラメータ情報(f0と素性ベクトル)をいじるとかなり頑健に変換が出来る。 以降はメルケプストラムで実装
音源情報のみを変化させる 高くする。
sopr -m 0.4 test.pitch | excite -p 80 | mlsadf -m 20 -a 0.42 -p 80 test.mcep | clip -y -32000 32000 |x2x +fs > highpitch.raw sox -t raw -r 16000 -s -2 highpitch.raw highpitch.wav
低くする。
sopr -m 2 test.pitch | excite -p 80 | mlsadf -m 20 -a 0.42 -p 80 test.mcep | clip -y -32000 32000 |x2x +fs > lowpitch.raw sox -t raw -r 16000 -s -2 lowpitch.raw lowpitch.wav
音源の間隔を変化させる
sopr -m 1 test.pitch | excite -p 40 | mlsadf -m 20 -a 0.42 -p 40 test.mcep | clip -y -32000 32000 |x2x +fs > fast.raw sox -t raw -r 16000 -s -2 fast.raw fast.wav
80フレームごとにシフトしていたものを、無理やり40フレームでシフトしていたものであるとして合成すると、2倍の速度で合成される。
sopr -m 1 test.pitch | excite -p 160 | mlsadf -m 20 -a 0.42 -p 160 test.mcep | clip -y -32000 32000 |x2x +fs > slow.raw sox -t raw -r 16000 -s -2 slow.raw slow.wav
音源を無声化
sopr -m 0 test.pitch | excite -p 80 | mlsadf -m 20 -a 0.42 -p 80 test.mcep | clip -y -32000 32000 |x2x +fs > hoarse.raw sox -t raw -r 16000 -s -2 hoarse.raw hoarse.wav
音源を一定にする
train -p 200 -l -1 | mlsadf -m 20 -a 0.42 -p 80 test.mcep | clip -y -32000 32000 |x2x +fs > robot.raw sox -t raw -r 16000 -s -2 robot.raw robot.wav
プロソディックな情報を完全に消した物 -> 昔の音声合成のイメージ
スペクトル自体を伸縮
sopr -m 0.4 test.pitch | excite -p 80 | mlsadf -m 20 -a 0.1 -p 80 test.mcep | clip -y -32000 32000 |x2x +fs > child.raw sox -t raw -r 16000 -s -2 child.raw child.wav
スペクトル包絡を高い方にシフト(アルファのパラメータを小さくする) ピッチが高くなる
sopr -m 2 test.pitch | excite -p 80 | mlsadf -m 20 -a 0.6 -p 80 test.mcep | clip -y -32000 32000 |x2x +fs > deep.raw sox -t raw -r 16000 -s -2 deep.raw deep.wav
freqtというsptkのコマンドで同様のことが出来る。
ピッチだけを変化させても綺麗にならない。ヴォーカルトラクト側の情報(スペクトル包絡等)も変化させてより自然な変換が可能に
これをきちんと確率モデルで実現するものが、声質変換、話者適応と呼ばれる物。