Windows 10は好きな文章を合成音声で簡単に喋らせることができる

文●塩田紳二 編集● ASCII

2021年05月23日 10時00分

こんな簡単なコマンドで、Windowsは「しゃべって」くれる。画面キャプチャーでは声をお聞かせすることはできないが、お手元のWindows PowerShellで試してほしい

 スクリプトを作るとき、ちょっとユーザーの気を引きたくなることがある。たとえば、少し時間のかかる処理をするときに、終わったことを通知したい場合などだ。あるいは、実行後にすこし時間が経過してからエラーを通知するような場合にも、気を引きたくなることがある。

 こんなとき昔のコンピューターならベル音やビープ音を鳴らすのが一般的だった。端末装置からコンピューターを使っていた頃、Ctrl+Gを出力するとベル音が鳴った。マイクロプロセッサが使われ始め、パソコンの原型ができあがった頃、BEEPと呼ばれる機能ができた。プログラムでビットをオンオフし、これをスピーカーに接続することで音を出していた。今もマザーボード上には、そのための小さなスピーカーがあるはずだ。しかしWindowsが普及するとともに、PCにサウンド機能が標準となり、簡単に音を鳴らせるようになった。

 コントロールパネルの「サウンド」プロパティで開く、「サウンド」ダイアログボックスの「サウンド」タブには、Windowsがあらかじめ持っている「イベントサウンド」の定義がある。PlaySound APIなどを使うことで、こうしたシステム定義の音を鳴らすことができる。ただ、“ありもの”のサウンドは案外区別がつきにくい。しかし、独自のサウンドを鳴らすには音源ファイルを作る必要がある。それは面倒だ。

 こうしたとき、Windowsの音声合成機能を使うと、音源の必要なく、適切な「音声によるメッセージ」を出すことができるようになる。

Windowsに用意されているSpeech API

 Windowsには、Speach API(SAPI)があり、これを使うことで音声合成ができる。音声合成というと、なんか面倒くさそうな感じがしてしまうが、お手元のPCでPowerShell(Windows PowerShellを想定してあるが、PowerShell Coreでも確認済み)を開き、以下の2行のコマンドを実行してみてほしい。

$x=New-Object -ComObject SAPI.SpVoice
$x.Speak("早く人間に成りたい")

 ちゃんと音が出るように設定されていれば、女性の声が聞こえるはずだ。これがSpeach APIの音声合成機能だ。喋らせるテキストは、普通のテキストそのままでいい。しかも、日本語の音声の場合、英単語が混じっていてもいい。

$x.Speak("ここにFile Nameを入れてEnter keyを押してください")

 句読点を入れると、そこで一呼吸入れてくれる。

$x.Speak("早く,人間に,成りたい。早く人間に成りたい")

 Speakメソッドを繰り返し使えば、ずっと話し続けてくれる。なおデフォルトでは、同期呼び出しなので、発声が終わるまでSpeakメソッドは戻ってこない。これだとスクリプトの実行に差し障るというのであれば、非同期呼び出しとして発声が終わる前に制御を戻すこともできる。それには、後ろにもう1つ引数を追加して1(SVSFlagsAsync)をつける。

$x.Speak("ここにFile Nameを入れてEnter keyを押してください",1)

 なお、このSpeakメソッドに関しては、Microsoftの以下のページに情報がある。

●SpVoice Speak method (SAPI 5.4)
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee125647(v=vs.85)
●SpeechVoiceSpeakFlags (SAPI 5.4) 2つ目の引数の指定
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee125223(v=vs.85)

音量や声のキャラクターなど、ちょっと変化をつける

 まずは、音量を変えてみる。

$x.Speak("お出かけですか")
$x.Volume=50
$x.Speak("お出かけですか")
$x.Volume=100

 Volumeプロパティは、0~100の範囲で指定する。これは、Speech API側の出力を0~100%に設定するものなので、他の音との相対値である。最終的な音量はWindowsの設定で決まる。この値を低くすると、他のアプリよりも相対的に小さな音にすることができる。

 次は、読み上げ速度だ。これは、rateプロパティで設定する。値は-10から10の範囲で、-10が最も遅く、デフォルト値は0である。

$x.rate=-10
$x.Speak("早く人間に成りたい",1)
$x.rate=0

 次に声を変えてみる。日本語版Windowsでは、

Haruka(日本語、女性):0
Zira(英語、女性):1
David(英語、男性):2

の3つの声が利用できる。英語を話してほしいときには、ZiraかDavidを選ぶ。Davidなら

$x.Voice=$x.GetVoices().item(2)
$x.Speak("all works and no play makes jack a dull boy.",1)

とする。「item(2)」を「item(1)」にすればZiraが、「item(0)」にすればHarukaが選択できる。たとえば、

$x.Voice=$x.GetVoices().item(0);$x.Speak("裏に塀ができたんだってねぇ",1);$x.Voice=$x.GetVoices().item(2);$x.Speak("Hey",1)

とする。

発声をWAVファイルにして保存する

 ときどき、ちょっとした実験をしていて、短い音声ファイルが欲しくなることもある。しかし、簡単に録音できるからといって、自分の声を聞くのはなにか妙に恥ずかしい。そういうときには、Speech APIで喋らせた声を音声ファイルにすれば簡単に音声ファイルを作ることができる。

 まずは、音声ファイルを保存できるフォルダーを用意する。適当なフォルダーでよい。ここでは、「C:\temp」フォルダーに「output.wav」という音声ファイルを保存することにする。そこに音声ファイルを保存するのが以下のリストのコマンドだ。なお、すでに存在するファイルを上書きしようとするとエラーになるので、存在しないファイル名を「フルパス」で指定する。

$x=New-Object -ComObject SAPI.SpVoice
$vs=New-Object -ComObject SAPI.SpFileStream
$vs.Open("c:\temp\output.wav",3)
$x.AudioOutputStream=$vs
$x.Speak("裏に塀ができたんだってねぇ")
$vs.Close()

 音声ファイルは、メディアプレーヤーなどで再生が可能だが、コマンドラインからなら、

start "c:\temp\output.wav"

で再生が可能だ。

 Windowsには、Speech APIのほかにも.NET frameworkのSystem.Speechなど、いろいろとあるのだが、SAPIを使うのに比べると一手間かかってしまう。なので、スクリプトからすぐに使うには、この方法が一番楽。他の言語でもCOMコンポーネントを扱えるなら同様のことは簡単にできる。発声を普通のテキストで指定できるので、複数のサウンドを使い分けて鳴らすのと比べても簡単だ。

■関連記事