Windows の SAPI・Speech Synthesizer で say コマンドもどきを作る
MacOS には say
コマンドというモノが標準搭載されている。OpenJTalk や espeak
コマンドと同じようなモノだ。
# どちらでも動く
$ say こんにちは Neo です
$ say 'こんにちは Neo です'
こんな風に引数に与えた文字列を全て連結して読み上げてくれる。利用できるボイスは $ say -v ?
で確認できるが、日本語が話せるのは Kyoko の1種類のみ。
そして、以前 PowerShell でも似たようなことができる、という記事も書いたことがある。
この時はよく分からないまま触っていたのだが、COM オブジェクトである SAPI (Windows Speech API)、もしくは .NET の Speech Synthesizer を使うことで、Windows でも MacOS の say
コマンドのように、任意のテキストを発話させられるワケだ。
今回はこの SAPI が VBScript・JScript からも呼べることを確認しつつ、最終的に PowerShell で say
もどきのコマンドを作ってみる。
- Neos21/shell-scripts: Bash・Windows Batch・WSH (VBScript・JScript)・PowerShell Scripts
- 今回掲載するコードはコチラの GitHub リポジトリにも上げてある
目次
WSH で SAPI を呼び出す
まずは WSH、つまり VBScript や JScript で SAPI を呼び出すコードを書いてみる。
- VBScript 版
Option Explicit
Dim sapi : Set sapi = WScript.CreateObject("SAPI.SpVoice")
sapi.Speak "どうも Neo です。お疲れ様です。VBScript です。"
- JScript 版
var sapi = WScript.CreateObject('SAPI.SpVoice');
sapi.Speak('どうも Neo です。お疲れ様です。JScript です。');
こんな感じでとっても簡単。
- 参考 : Windowsにしゃべらせるプログラム | 電脳産物
- 参考 : Windowsバッチで,手軽に日本語テキストを自動読み上げ(Text To Speech)する方法 …WSHでSAPIやSpeech.SpVoiceを使う音声合成の手順とサンプルコード - 主に言語とシステム開発に関して
- 参考 : SAPIを使ってパソコンに喋らせる - Qiita
PowerShell では SAPI と Speech Synthesizer 両方使える
SAPI は COM オブジェクトとして提供されているので、WScript.CreateObject()
で WSH から簡単に利用できたが、PowerShell では .NET に含まれる Speech Synthesizer というモノも呼び出せる。検証した限り、どちらでも出来ることやボイスの種類などは同じだったので、好きに使えば良さそう。
(ちなみに WSH から .NET の API を呼び出すことも可能ではあるようなので、VBScript から Speech Synthesizer を呼び出すようなコードを書くこともできそうではある)
- PowerShell で SAPI
$sapi = New-Object -ComObject SAPI.SpVoice;
$sapi.Speak("どうも Neo です。お疲れ様です。PowerShell です。");
- PowerShell で Speech Synthesizer
Add-Type -AssemblyName System.speech;
$speech = New-Object System.Speech.Synthesis.SpeechSynthesizer;
$speech.Speak("どうも Neo です。お疲れ様です。Speech Synthesizer です。");
こんな感じ。
- ASCII.jp : Windows 10は好きな文章を合成音声で簡単に喋らせることができる (1/2)
- PowerShellでMacのsayコマンドのように合成音声にテキストを読み上げさせてみる | 俺的備忘録 〜なんかいろいろ〜
- PowerShellで音声合成を試してみた - サーバーワークスエンジニアブログ
PowerShell で say
コマンドもどきを作る
というワケで、扱い方は分かったので、say
コマンドもどきを作ってみよう。以下のスクリプトを say.ps1
という名前で保存し、環境変数 PATH が通っているフォルダに配置する。そうすれば PowerShell を開いて PS> say ほげふが
と実行できるようになる。
# ================================================================================
# Windows 版・簡易 `say` コマンド
# ================================================================================
# 引数を文字列に連結する
$paramArray = $args[0..($args.Length - 1)];
$paramString = $paramArray -join ' ';
# 引数での文字列指定がなければ中断する
if([string]::IsNullOrEmpty($paramString)) {
Write-Host 'Please Input Text';
exit;
}
# 発話する
$sapi = New-Object -ComObject SAPI.SpVoice;
$sapi.Speak($paramString) | Out-Null;
引数を文字列に連結して SAPI に与えているだけ。細かいところで参考にした文献は以下のとおり。
- 参考 : 【Windows Powershell】スクリプトのコマンドライン引数の数を得る - Muni Bus
..
演算子を使って$args[0..($args.Length - 1)]
とすると全ての引数を配列で取得できる
- 参考 : PowerShell/配列内の文字列を連結し1つの変数に格納したい - Windowsと暮らす
$text = $array -join ''
といった形で配列を文字列に連結できる
- 参考 : 文字列が空文字や NULL であるかを判定する方法 PowerShell : バヤシタ
[string]::IsNullOrEmpty($value)
で Null や空文字を判定できる
- 参考 : PowerShell/PowerShellで/dev/null - Windowsと暮らす
> /dev/null
相当は| Out-Null
簡単にできて良き良き!