Category Archives: スピーチプラットフォーム

Speech API (SAPI)からCeVIO AI Voiceで読み上げ C++ 実装編 (COM SDKからのSpeakで失敗する)

タイトルの通りWin32 COM C++では、SAPIの音声リストからCeVIOのボイスの選択はS_OKで成功するが、Speakで “REGDB_E_CLASSNOTREG Class not registerd” エラーが出る。

Win32 COMではCeVIO AIのボイスを選択し、SAPIのSpeakでREGDB_E_CLASSNOTREG Class not registerd エラーが出る

OSにバンドルされているSAPIのボイスのSelect, Speakではエラーにはならない(正しい動作)ので、エラー処理でCeVIOを除外するしかない。(SpeakがFailした場合、最後にS_OKだったボイスをセット)今のところ、”CeVIO”がボイス名に含まれているか、Initializeの時の第一声テスト時にFailするボイスを自動選択しないようにするコードを追加。

このコードは、デスクトップ上に時刻を表示するアプリで、Win32 C++ COMでUIがD2Dベース。かれこれ5年くらいコードは触っていなかった。最近、CeVIOをインストールしたときから、Speechできなくなっていた。D2DはWindows Animationで画像表示やエフェクト、移動等ができビジュアル面では高機能。コードはWin32 C++ なのでメモリアドレス、メモリのコピペ等の操作のコード直書きなのでパフォーマンスがいいけれど、CeVIOがこれでは対応できない。

多分、CeVIOのC++コードをDLLインポートすると、2つのアプリではAPIは呼べないはずだし。

とりあえず今回は、CeVIO AIのボイスを除外する方向で修正済み。

TimeSignalアプリの時間表示。TimeSignal.exeにSpeechする言葉をオプションで起動することで、バックグラウンドで走る。画像は右クリックでExitメニューが表示されているところ

CeVIO AI コントローラー .NET アプリページを公開

CeVIO AIのコードが使えそうになってきたのでページを公開しました。コードを公開する予定はありませんが、コードの使い方はこのブログで書いていこうと思います。

パッケージはアプリの完成度をみながら公開。あえてインストーラーは作りません。

UIはまだまだ改良の余地があるのでデザイン的なものも含めて今後アップデートしていきます。

ウェブスクレイピングが出来ると用途が増えると思うけど。どんな使い方ができるか今後追ってアップする。リアルタイムでTwitch上でアップできると編集とかしなくて時短できていいかな。

CeVIO AI コントローラー(開発中)

ご意見、用途のご相談お待ちしております。お仕事としても依頼受け付けております。よろしくお願いします。

追伸:最近はゲーム配信が出来ていない。夜中に起きてやるしかない。しかし、Twitchのチャットの自動音声返信まではまだ先が長い。

Speech API (SAPI)からCeVIO AI Voiceで読み上げ .NET C# 実装編

前回、CeVIO AIがSAPIではSelectVoiceした時点でエラーが出る件の続き。(SAPIでの読み上げは断念)

仕組みとしては、CeVIO AIでインストールされるDLL (CeVIO.Talk.RemoteService2.dll)から.NETアセンブリとしてAPIをコールする。APIコールからCeVIO トークエディタをプロパティ付きで起動してアプリから読み上げ(Speak)をする。できればDLLのAPIからアプリの起動なしで読み上げしてほしかった。(UIとか.NETとかメモリ食いでCPUパワーを使ってしまう)

さて置き、実装は単純なのでSAPIの部分を置き換えて、両方使えるようにするのがメインの作業。

CeVIO AIをC#から読み上げるサンプル

インストールされているボイスはSAPI経由でGetInstalledVoicesで取ってくるサンプルがあるけれど、レジストリに登録されているボイス名とCastに設定する名前は一致していない。

SAPIに登録されるボイス名は、弦巻マキ、スターターパック(日本語、英語)の場合、CeVIO-AI-弦巻マキ(英語)とCeVIO-AI-弦巻マキ(日本語)(SAPI用レジストリ)。Castに設定する名前は、弦巻マキ(英)と弦巻マキ(日)。setting.cfgファイルに記述あり。しかし英語のsetting.cfgファイルは英語表記されていて、CeVIO DLLに含まれるAPI AvailableCastsのリストも一致しない。

.NETアセンブリとして登録する、dllの参照の追加元はC:\Program Files\CeVIO\CeVIO AI\CeVIO.Talk.RemoteService2.dllから。(CeVIOのサイトでは再配布はしないでねと書かれているので注意)

やってみて思い出した。メインにしたアプリが.NET COREで、CeVIOのサイトには明確にサポート外。これで30分くらい悩む。(参考にさせて頂いたサイトのコードのActivateでエラーが消えず)

結局.NETアプリで常駐するコマンドアプリにする。CMDバージョンと、Formバージョンで試作。すでに起動中の時にはIPC経由でイベントを発生させて文字列を渡してプログラムを抜ける。FormバージョンはUIにテキストを設定して読み上げボタンイベントを発生させる。

しかし、CeVIO自身の実装はいたって簡単。一度に読み上げる文字列の長さが200文字の制限以外はSAPIほど初期化の処理がすくなくて快適。逆に.exeにアセンブリを実装する前にファイルチェックをしたうえでAssemblyをコード上からインポートして実行する必要がある。これをやらないと、トークエディタがインストールされていないマシンではアプリは走らない。。。マイクロソフトのSAPIとも共存したい。

twitch, YouTube チャットを読み込んで自動応答してBotに使用。マイクロソフトの音声認識はもうちょっと制度を上げてほしい。認識精度悪すぎ。登録単語モードはほぼほぼつかえない。フリーワードモードは自由度高すぎで発音した単語が正しく認識されることはまずない。

とりあえず、SAPIでCeVIOがインストールされている時はVoiceCallCmd.exe、VoiceCallForm.exeを読み上げ文章をつけて実行する。今のところメールチェック、メールのタイトルの読み上げ、処理状況の読み上げはいつも通り読めている。

読み上げ中の場合は、読み上げテキストをキューに設定して、キューがなくなるまで繰り返す。

VoiceCallForm.exeには各種パラメータをつけて感情表現をできるようにする。その前に参考にさせてもらったサイトのコードは他のボイスエンジンとの互換性の為に、クラスにはAPIがすべて網羅されていないのでパラメータの数値(0-100)、感情値の設定をそのまま使えるようにクラスを作り直すことにする。

(コードは完成するまでは未公開)

Speech API (SAPI)からCeVIO AI Voiceで読み上げ APIでボイスのインストールは確認できるけど、SAPIでSpeechできず

CeVIO AIをSAPIから使ってみる。マイクロソフトのボイスから卒業できるか検証してみる。

CeVIO AIのユーザーガイドページ

CeVIO AIインストール前のSAPI VOICEのリスト。英語Zira、Davidと、日本語Harukaがインストールされている。

CeVIO AIインストール前のSAPI VOICEのリスト。英語Zira、Davidと、日本語Harukaがインストールされている。

今回は、お買い得なスターターパック、エディタと日本語、英語がセットになった弦巻マキのダウンロード版を購入してみました。セットアップは簡単。だけどマイクロソフトにダウンロードしたExeの起動をブロックされたけれど無視(レポートも送らないよ)。許可してZipを自動展開して起動。MSIが起動されインストールされる。

CeVIO AIのインストール画面

インストールのステップは省きます。

日本語のボイスをインストールした状態で、SAPIのインストールは以下の通り。

CeVIO AI 弦巻マキ 日本語 をインストールした状態 エディタはインストールしていない

エディタをインストールしていない状況ではExceptionがでる。(補足。結果から言うと、エディタをインストールしても結局同じエラーがでます)

CeVIO AI トークエディタをインストールしていない状況ではExceptionがでる。

スターターパックを購入した後、トークエディタのダウンロードは別でライセンスキーのみ提供される。トークディタ、ボイス、日本語、英語のライセンス認証しても、SelectVoiceで同じエラーがでる。

そして、コントロールパネルから音声合成のテストでエラーが出る。やっぱりプロテクトがかけられているのか。トークエディタでは使えている。

CeVIOはWindows10でOSの音声合成に使えない

このままでは、マイクロソフトのボイスと共存もさせられないし。

こちらでは、CeVIOのdllからアセンブリ経由でAPIを呼ぶように推奨されている。SAPI5では動くみたいだけれど、Win10でSAPI5はもうないだろう。

多分SpeechSynthesizer.GetInstalledVoices APIに対応してVoiceリストを返せるようにしたけれど、TTSエンジンのDLLは提供しないということなのだろう。マイクロソフトのSpeechボイスのCLSIDはTTSエンジンのDLLが定義されている。CeVIOのCLSIDはダミー。SelectVoiceをCallした時点でエラーがでる。

あきらめて、.NET DLL API に変更。共存する時にはCeVIOのボイスは選択をスキップするしかない。

CeVIOのサンプルコードを使った結果は次回。

PS:記事には、Officeは32Bitだから動かないとかSAPI5のアプリだったら動くようなことが書かれているけれど今は、64Bit主流でSAPI5に戻りようがないし。Officeから使うのかは疑問だなぁ。

Windows 10 に搭載されているSAPI(音声合成)とCortanaについて

今回はWindows 10の音声合成の環境のアップデート。

Win7, 8, 8.1にはSAPIが搭載されており、sapi.hにOS標準の音声合成APIが含まれていました。Windows10も同様、標準のボイスの情報はSPCAT_VOICESに定義されているレジストリキー(HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\Voices)にあり、バージョンは11.0となっています。

SAPI_REG1

さらに、Speech Platform Language Packでインストールされるボイスは”Speech Server”下に定義されます。このレジストリキーはSpEnumTokens関数でTokenを取得するときに第一引数として使用できます。(ただしSpeech Serverは Speech Platfrom Runtimeをインストールしないと、登録されていないボイスというエラーが返ってきます)

さらに、Windows10で話題のCortana(コルタナ)ですが、同じフォーマットでSpeech_OneCoreに定義されています。このボイスはSpEnumTokens関数で指定可能です。

SpEnumTokensでCortanaのボイスを指定する例)

hr = SpEnumTokens(L”HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech_OneCore\\Voices”, strReqAttribute, NULL, &pEnum);

CortanaにはパラメータがSAPIよりも用意されていますが、公開されているかは不明です。今のところ、SAPIから使用可能ということだけでしょうか。あと、日本語Cortanaのボイス名は”Ichiro”と”Ayumi”となっています。

SAPI_REG2

誰を使って、AI作ろうか。

今回作った。SAPIの関数(COMのHRESULTのエラー処理は省略)

HRESULT speak(LPWSTR strSpeakString)
{
	HRESULT hr = S_OK;

	//ISpVoice * pVoice = NULL;
	ISpVoice *pVoice = 0; 
	ISpObjectToken *pToken = 0;
	IEnumSpObjectTokens *pEnum = 0;

	if (FAILED(CoInitialize(NULL)))
	{
		::MessageBoxW(NULL, L"Error to intiliaze COM", L"DBG", MB_OK);
		return S_OK;
	}	

	hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
	if (SUCCEEDED(hr))
	{

		hr = SpEnumTokens(SPCAT_VOICES, L"Language = 411", NULL, &pEnum); //SAPI default voice (OS language pack) 411:Japanese
		//hr = SpEnumTokens(L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech Server\\v11.0\\Voices", L"Language = 411", NULL, &pEnum); //Speech Platform v11.0 (Required runtime)
		//hr = SpEnumTokens(L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech_OneCore\\Voices", L"Language = 411", NULL, &pEnum); //Cortana voice

		ULONG ulCount = 0;
		USHORT usVolume = 0;
		
		long lRate = 0;


		hr = pEnum->GetCount(&ulCount);
		pEnum->Item(0, &pToken);
			
		hr = pVoice->SetVoice(pToken);
		hr = pVoice->GetVolume(&usVolume);
		hr = pVoice->SetVolume(100); //0 - 100

		hr = pVoice->GetRate(&lRate);
		hr = pVoice->SetRate(0); // -10 to 10


		hr = pVoice->Speak(NULL, SPF_PURGEBEFORESPEAK, 0);
		hr = pVoice->Speak(strSpeakString, SPF_IS_XML | SPF_DEFAULT, NULL);
		hr = pVoice->WaitUntilDone(INFINITE);

		if(pToken)
		{
			hr = pToken->Release();
			pToken = 0;
		}

		if (pVoice)
		{
			hr = pVoice->Release();
			pVoice = 0;
		}

		if (pEnum)
		{
			hr = pEnum->Release();
			pEnum = 0;
		}
	}

	if (pToken)
	{
		hr = pToken->Release();
		pToken = 0;
	}

	CoUninitialize();
	return S_OK;
}