解説
stacksize(1000000) スタックを10Mバイトにする。
fs=8000; サンプリングレート8000で以後の計算を行うため、変数fsに8000を代入しておく。 ここまでのステップでは、後で使うために各種の定数を設定し、またxrには50Hzの励起用波形が作られている。
次の計算は、計算は簡単だが、若干巧妙な仕組みになっている。
x=int(modulo((1:fs)*100,fs) / fs * 1.1);
100Hzでデxユーティ比約10%のパルス波を作る。 xr=convol([1,-0.6,0.35,-0.2,0.1],x); 100Hzの成分が少なくなるようなフィルターをかける。 最初に100Hzのパルス列を作っている。このままでもよいが、このままだと100Hzの基音成分が大きくなりすぎて耳障りなので、フィルタで100Hz成分を削除した。
x=loadwave("a.wav"); "あ"の波形をファイルからロードする。
a=armax(50,50,x(l+1),x(l)); 50次のARMAモデルを作成する。 ここまででARモデルが作成される。次数はNで、作成されたARMAモデルは変数aに記録される。
ya=arsimul(a,xr); "あ"の音を合成し、変数yaに保存する。 以上で、「あ」という声が合成されて変数yaに保存される。
この後は、「い」、「お」、も同様に計算する。
もちろん、このプログラムは原理が判りやすいように、非常に簡単な計算だけで行ったので、音質はあまり良くない。実際の音声合成では、モデルをより精密にすることで、本文の人間の音声とほぼ聞き分けがつかないほど、品質の高い声を合成することができる。
b=3000;
aoi(1:b)=ya(1:b);
aoi(b+1:2*b)=yo(1:b);
aoi(2*b+1:3*b)=yi(1:b);"あ、お、い"の音をそれぞれ0.4秒ずつ切り出し、接続した波形を作り、変数aoiに保存する。 sound(aoi*0.1,fs); "あおい"と聞こえれば成功だ。 "あおい"という発音は、元となるxrという音に"あおい"という発音のフィルターをつけてつくられている。だから、元となるxrにはいろいろな音を使うことができる。以下に示すように、ノイズのような音、ピアノのような音でもだいじょうぶだ。
xr=(rand(1:fs)-0.5)*0.2;
xr=loadwave("x2.wav");
さらにbを12000にすることもできる。
機械的にやればこういうこと
声道模型を使って母音を合成することもできる
声道形状 -その2 - (上智大学 理工学部 情報理工学科 荒井研究室 研究分野:音声コミュニケーション)