Google Homeに任意のテキストをText-To-Speechでしゃべらせるgoogle-home-notifier、これの音声品質がイマイチってことで、HOYAのVoiceText Web APIを利用する方法が提案されています。我が家でもこちらのスクリプトを流用させていただいています(ありがとうございます)。
がじぇねこ Google Homeで好きな言葉を話してもらう その2(VoiceText)
VoiceTextのAPIにテキストを渡すと、WAVなりMP3なりの音声ファイルが帰ってくるので、それをHTTP参照可能な場所(OUT_PATHに定義)に保存し、URLとして返すということをするのがVoiceTextWriter.jsです。
さて、いつからかわかりませんが、音声再生前に鳴る「ディン!」という「これからメッセージを鳴らすよ!」的な警告音と音声がかぶってしまってメッセージ冒頭が聞き取りづらいという点に気付きました。どちらかというと鳴らされるより鳴らす立場の使い方が多く気付いてなかっただけかもですが、セットアップした頃はそんなことなかったと思うんですよね。
まぁ気になり出したら気になるので、
- APIに投げるテキストの最初にスペースやカンマ、ハイフンなどを入れて無音区間が作れないか?
- 音声再生のタイミングを指定するようなパラメーターを探す
- 「ディン」を消せないか?
など試行錯誤したものの不発。そもそもディンは誰が鳴らしてるのかもわからないし、なんと呼ぶのかもわからないのでググるのも難しい。少なくともVoiceTextWriter.jsやVoiceText Web APIではなく、google-home-notifierか、音声を流し込まれたGoogleHomeの規定動作なんでしょうけど、、
SoXで音声冒頭に無音区間を挿入する
ということでもっと簡単に指定できるパラメーターがあるかもとは思いましたが、思いつく方法として、生成された音声ファイルを音声ツールのSoXで加工して冒頭に無音区間を挿入する、という荒技で乗り切ってみました。
我が家はCentOSで運用していて、SoXは
yum install sox
でサクっと入りました。Raspbianでもapt-getなどですぐ入れられるんじゃないかと思います。
そしてVoiceTextWeiter.jsを以下のように改変します。
冒頭のパス定義にDELAYER_PATHを追加(2行目)。パスは環境にあわせていただき、ファイル名をOUT_PATHのものと違えておきます。ここでは「_temp2.wav」とします。OUTPUT_URLのファイル名はDELAYED_PATHのものに合わせます。そして一番最後のelseブロックのfs.writeFrileSync()(音声ファイル保存)とresolve()(URLを返す)の間にSoX実行コードを挿入します。
// ... 冒頭部分
var OUT_PATH = '/home/xxx/google-home/api-server/public/voice/_temp.wav'
var DELAYED_PATH = '/home/xxx/google-home/api-server/public/voice/_temp2.wav' //追加
var OUTPUT_URL = 'http://xxx.xxx.xxx.xxx:12345/googlehome/_temp2.wav'; //ファイル名を上記にあわせる
// ... 略
// ... 最後の方のelseブロックの中
}else{
fs.writeFileSync(OUT_PATH, buf, 'binary');
// SoXを実行するコード(ここから)
const exec = require('child_process').exec;
exec('/usr/bin/sox ' + OUT_PATH + ' ' + DELAYED_PATH + " delay 0.7", (err,stdout,stderr)=> {
if (err) { console.log(err); }
console.log(stdout);
});
// SoXを実行するコード(ここまで)
resolve(OUTPUT_URL);
}
ちなみに、ここで実行しているSoXのコマンドは、
sox (入力ファイル名) (出力ファイル名) delay 0.7
の形です。0.7が遅延時間なのでお好みで調整してください。
もっと簡単にどこかのパラメーター1ついじるだけで済むよ、など情報ありましたらお知らせいただければと思います。