HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2014
0107
seasalt音声合成の終了を取得したいのですが…3解決


seasalt

リンク

2014/1/7(Tue) 00:32:06|NO.59219

以前、こちら(http://www.hsp.tv/play/pforum.php?mode=all&num=58994)で教えて頂いた者です。
音声合成でまた分からない点が出てきたので質問させて頂きます。

VoiceSpeakが再生処理中か、再生終了したかをHSPから取得することは可能でしょうか。
もし可能なら、その方法を教えて頂けないでしょうか…

以前教えて頂いたモジュールなども参考にして、テキスト読み上げソフトが形になって来ました。
そこで実際に長文を読ませてテストをしているのですが、
同期再生(再生終了まで待つ)で長文を読みあげようとすると、その間、自ウィンドウが操作を受け付けなくなってしまうという問題が出てきました。
自ウィンドウのドラッグなどができず、ボタンも反応しなくなります。
(そういうモードなので当然ですし、たいした実害もないのですが)

非同期再生モードにして、一文づつVoiceSpeakに渡してやれば改善されるのではないかと考えましたが、そのためにはVoiceSpeakが前の文を再生終了したかどうか知る必要があります。
自分なりに調べてみたのですが、ISpVoice::GetStatusというのがそれっぽいのかな、というのがわかったくらいで…この先が分かりません(´・ω・`)
ご教示いただければ幸いです…



この記事に返信する


inovia

リンク

2014/1/7(Tue) 02:13:14|NO.59221

GetVoiceStatus関数を追加しました。


#module SAPI_Speech_Voices #define global ctype SUCCEEDED(%1) ((%1) >= 0) /* #define global SafeRelease(%1) if ((varuse@(%1)) && (vartype@(%1) == 6)){ \ delcom@ %1: \ %1 = 0 \ } */ #define IID_ISpVoice "{6C44DF74-72B9-4992-A1EC-EF996E0422D4}" #define IID_IEnumSpObjectTokens "{06B64F9E-7FDA-11D2-B4F2-00C04F797396}" #define IID_ISpObjectToken "{14056589-E16C-11D2-BB90-00C04F8EE6C0}" #define IID_ISpObjectTokenCategory "{2D3D3845-39AF-4850-BBF9-40B49780011D}" #define CLSID_SpVoice "{96749377-3391-11D2-9EE3-00C04F797396}" #define CLSID_SpMMAudioEnum "{AB1890A0-E91F-11D2-BB91-00C04F8EE6C0}" #define CLSID_SpObjectToken "{EF411752-3736-4CB4-9C8C-8EF4CCB58EFE}" #define CLSID_SpObjectTokenCategory "{A910187F-0C7A-45AC-92CC-59EDAFB77B53}" #define SPCAT_VOICES "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\Voices" #usecom ISpVoice IID_ISpVoice CLSID_SpVoice // IUnknown(3)->ISpNotifySource(7)->ISpEventSource(3)->ISpVoice #comfunc ISpVoice_Pause 16 #comfunc ISpVoice_Resume 17 #comfunc ISpVoice_SetVoice 18 int #comfunc ISpVoice_GetVoice 19 var #comfunc ISpVoice_Speak 20 wstr, int, int #comfunc ISpVoice_GetStatus 22 sptr, wstr #comfunc ISpVoice_SetRate 28 int #comfunc ISpVoice_GetRate 29 var #comfunc ISpVoice_SetVolume 30 int #comfunc ISpVoice_GetVolume 31 var #usecom ISpObjectTokenCategory IID_ISpObjectTokenCategory CLSID_SpObjectTokenCategory //IUnknown(3)->ISpDataKey(12)->ISpObjectTokenCategory #comfunc ISpObjectTokenCategory_SetId 15 wstr, int #comfunc ISpObjectTokenCategory_EnumTokens 18 wstr, wstr, sptr #usecom IEnumSpObjectTokens IID_IEnumSpObjectTokens CLSID_SpMMAudioEnum // IUnknown(3)->IEnumSpObjectTokens #comfunc IEnumSpObjectTokens_Next 3 int, sptr, sptr #comfunc IEnumSpObjectTokens_Reset 5 #comfunc IEnumSpObjectTokens_Clone 6 sptr #comfunc IEnumSpObjectTokens_Item 7 int, sptr #comfunc IEnumSpObjectTokens_GetCount 8 var #usecom ISpObjectToken IID_ISpObjectToken CLSID_SpObjectToken // IUnknown(3)->ISpDataKey(12)->ISpObjectToken #comfunc ISpObjectToken_GetStringValue 6 wstr, sptr #deffunc SafeRelease var p1 if ((varuse(p1)) && (vartype(p1) == 6)){ delcom p1 p1 = 0 } return #deffunc CreateVoice var pSpVoice newcom pSpVoice, ISpVoice return #deffunc GetVoicesList var list sdim list, 1024 // 話者一覧取得 newcom pSpOTC, ISpObjectTokenCategory if varuse(pSpOTC){ ISpObjectTokenCategory_SetId pSpOTC, SPCAT_VOICES, 0 : hr = stat if SUCCEEDED(hr){ ptr = 0 ISpObjectTokenCategory_EnumTokens pSpOTC, "", "", varptr(ptr) : hr = stat if SUCCEEDED(hr) && ptr != 0{ newcom pSpOTs, IEnumSpObjectTokens, -1, ptr if varuse(pSpOTs){ Num = 0 IEnumSpObjectTokens_GetCount pSpOTs, Num : hr = stat if SUCCEEDED(hr){ repeat Num ptr = 0 IEnumSpObjectTokens_Item pSpOTs, cnt, varptr(ptr) : hr = stat if SUCCEEDED(hr) && ptr != 0{ newcom pSpT, ISpObjectToken, -1, ptr ISpObjectToken_GetStringValue pSpT, "", varptr(ptr) : hr = stat if SUCCEEDED(hr){ dupptr wStr, ptr, 1024, 2 list += cnvwtos(wStr) + "\n" } SafeRelease pSpT } loop } SafeRelease pSpOTs } } } SafeRelease pSpOTC } return hr #deffunc SetVoice var pSpVoice, int idx newcom pSpOTC, ISpObjectTokenCategory if varuse(pSpOTC){ ISpObjectTokenCategory_SetId pSpOTC, SPCAT_VOICES, 0 : hr = stat if SUCCEEDED(hr){ ptr = 0 ISpObjectTokenCategory_EnumTokens pSpOTC, "", "", varptr(ptr) : hr = stat if SUCCEEDED(hr) && ptr != 0{ newcom pSpOTs, IEnumSpObjectTokens, -1, ptr if varuse(pSpOTs){ ptr = 0 IEnumSpObjectTokens_Item pSpOTs, idx, varptr(ptr) : hr = stat if SUCCEEDED(hr){ ISpVoice_SetVoice pSpVoice, ptr } SafeRelease pSpOTs } } } SafeRelease pSpOTC } return hr #deffunc VoiceSpeek var pSpVoice, str s, int f ISpVoice_Speak pSpVoice, s, f, 0 return stat #deffunc DestoryVoice var pSpVoice SafeRelease pSpVoice return stat #defcfunc GetVoiceVolume var pSpVoice Volume = 0 ISpVoice_GetVolume pSpVoice, Volume return Volume #deffunc SetVoiceVolume var pSpVoice, int vol ISpVoice_SetVolume pSpVoice, vol return stat #defcfunc GetVoiceRate var pSpVoice, local Rate Rate = 0 ISpVoice_GetRate pSpVoice, Rate return Rate #deffunc SetVoiceRate var pSpVoice, int rate ISpVoice_SetRate pSpVoice, rate return stat #deffunc VoicePause var pSpVoice ISpVoice_Pause pSpVoice return stat #deffunc VoiceResume var pSpVoice ISpVoice_Resume pSpVoice return stat #defcfunc GetVoiceStatus var pSpVoice dim SPVOICESTATUS, 13 ISpVoice_GetStatus pSpVoice, varptr(SPVOICESTATUS), "" return SPVOICESTATUS.3 #global // 以下サンプル pSpVoice = 0 // ComObj作成 CreateVoice pSpVoice if varuse(pSpVoice){ onexit gosub *exit // 一覧取得 GetVoicesList list idx = 0 objsize 420, 20 combox idx, 100, list mes "▼ 文章" sdim s, 1024 : s = "Hello this is H.S.P. for windows." input s mes "▼ 音量(0〜100)" Volume = 100 input Volume mes "▼ 速度(-10〜10)" Rate = 0 input Rate Async = 1 chkbox "再生終了まで待たない", Async button gosub "再生", *speak }else{ dialog "呼び出し失敗" } stop *speak // 音量設定(0〜100) SetVoiceVolume pSpVoice, Volume // 再生速度設定(-10〜10) SetVoiceRate pSpVoice, Rate title "音量:"+GetVoiceVolume(pSpVoice)+", 速度"+GetVoiceRate(pSpVoice) // 音声選択 SetVoice pSpVoice, idx if stat{ dialog "音声選択に失敗しました" } // 同期再生(再生終了まで待つ) // 1にすると非同期 VoiceSpeek pSpVoice, s, Async if stat{ dialog "再生失敗しました" } // 再生終了までループ repeat // 再生終了している場合 // (再生開始時は0, 再生完了の場合は1, 再生中は2を返す様子) title "Status: "+GetVoiceStatus(pSpVoice) if GetVoiceStatus(pSpVoice) == 1 : break wait 12 loop dialog "再生終了!" return *exit // 終了時にでも破棄する DestoryVoice pSpVoice end : end return



inovia

リンク

2014/1/7(Tue) 02:59:18|NO.59222

もう1つの方法。
comeventを使ったやり方。


#module SAPI_Speech_Voices #define global ctype SUCCEEDED(%1) ((%1) >= 0) /* #define global SafeRelease(%1) if ((varuse@(%1)) && (vartype@(%1) == 6)){ \ delcom@ %1: \ %1 = 0 \ } */ #define IID_ISpVoice "{6C44DF74-72B9-4992-A1EC-EF996E0422D4}" #define IID_IEnumSpObjectTokens "{06B64F9E-7FDA-11D2-B4F2-00C04F797396}" #define IID_ISpObjectToken "{14056589-E16C-11D2-BB90-00C04F8EE6C0}" #define IID_ISpObjectTokenCategory "{2D3D3845-39AF-4850-BBF9-40B49780011D}" #define IID_ISpNotifySource "{5EFF4AEF-8487-11D2-961C-00C04F8EE628}" #define IID_ISpNotifySink "{259684DC-37C3-11D2-9603-00C04F8EE628}" #define CLSID_SpVoice "{96749377-3391-11D2-9EE3-00C04F797396}" #define CLSID_SpMMAudioEnum "{AB1890A0-E91F-11D2-BB91-00C04F8EE6C0}" #define CLSID_SpObjectToken "{EF411752-3736-4CB4-9C8C-8EF4CCB58EFE}" #define CLSID_SpObjectTokenCategory "{A910187F-0C7A-45AC-92CC-59EDAFB77B53}" #define SPCAT_VOICES "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\Voices" #usecom ISpVoice IID_ISpVoice CLSID_SpVoice // IUnknown(3)->ISpNotifySource(7)->ISpEventSource(3)->ISpVoice #comfunc ISpVoice_Pause 16 #comfunc ISpVoice_Resume 17 #comfunc ISpVoice_SetVoice 18 int #comfunc ISpVoice_GetVoice 19 var #comfunc ISpVoice_Speak 20 wstr, int, int #comfunc ISpVoice_GetStatus 22 sptr, wstr #comfunc ISpVoice_SetRate 28 int #comfunc ISpVoice_GetRate 29 var #comfunc ISpVoice_SetVolume 30 int #comfunc ISpVoice_GetVolume 31 var #usecom ISpObjectTokenCategory IID_ISpObjectTokenCategory CLSID_SpObjectTokenCategory //IUnknown(3)->ISpDataKey(12)->ISpObjectTokenCategory #comfunc ISpObjectTokenCategory_SetId 15 wstr, int #comfunc ISpObjectTokenCategory_EnumTokens 18 wstr, wstr, sptr #usecom IEnumSpObjectTokens IID_IEnumSpObjectTokens CLSID_SpMMAudioEnum // IUnknown(3)->IEnumSpObjectTokens #comfunc IEnumSpObjectTokens_Next 3 int, sptr, sptr #comfunc IEnumSpObjectTokens_Reset 5 #comfunc IEnumSpObjectTokens_Clone 6 sptr #comfunc IEnumSpObjectTokens_Item 7 int, sptr #comfunc IEnumSpObjectTokens_GetCount 8 var #usecom ISpObjectToken IID_ISpObjectToken CLSID_SpObjectToken // IUnknown(3)->ISpDataKey(12)->ISpObjectToken #comfunc ISpObjectToken_GetStringValue 6 wstr, sptr #deffunc SafeRelease var p1 if ((varuse(p1)) && (vartype(p1) == 6)){ delcom p1 p1 = 0 } return #deffunc CreateVoice var pSpVoice newcom pSpVoice, ISpVoice return #deffunc GetVoicesList var list sdim list, 1024 // 話者一覧取得 newcom pSpOTC, ISpObjectTokenCategory if varuse(pSpOTC){ ISpObjectTokenCategory_SetId pSpOTC, SPCAT_VOICES, 0 : hr = stat if SUCCEEDED(hr){ ptr = 0 ISpObjectTokenCategory_EnumTokens pSpOTC, "", "", varptr(ptr) : hr = stat if SUCCEEDED(hr) && ptr != 0{ newcom pSpOTs, IEnumSpObjectTokens, -1, ptr if varuse(pSpOTs){ Num = 0 IEnumSpObjectTokens_GetCount pSpOTs, Num : hr = stat if SUCCEEDED(hr){ repeat Num ptr = 0 IEnumSpObjectTokens_Item pSpOTs, cnt, varptr(ptr) : hr = stat if SUCCEEDED(hr) && ptr != 0{ newcom pSpT, ISpObjectToken, -1, ptr ISpObjectToken_GetStringValue pSpT, "", varptr(ptr) : hr = stat if SUCCEEDED(hr){ dupptr wStr, ptr, 1024, 2 list += cnvwtos(wStr) + "\n" } SafeRelease pSpT } loop } SafeRelease pSpOTs } } } SafeRelease pSpOTC } return hr #deffunc SetVoice var pSpVoice, int idx newcom pSpOTC, ISpObjectTokenCategory if varuse(pSpOTC){ ISpObjectTokenCategory_SetId pSpOTC, SPCAT_VOICES, 0 : hr = stat if SUCCEEDED(hr){ ptr = 0 ISpObjectTokenCategory_EnumTokens pSpOTC, "", "", varptr(ptr) : hr = stat if SUCCEEDED(hr) && ptr != 0{ newcom pSpOTs, IEnumSpObjectTokens, -1, ptr if varuse(pSpOTs){ ptr = 0 IEnumSpObjectTokens_Item pSpOTs, idx, varptr(ptr) : hr = stat if SUCCEEDED(hr){ ISpVoice_SetVoice pSpVoice, ptr } SafeRelease pSpOTs } } } SafeRelease pSpOTC } return hr #deffunc VoiceSpeek var pSpVoice, str s, int f ISpVoice_Speak pSpVoice, s, f, 0 return stat #deffunc DestoryVoice var pSpVoice SafeRelease pSpVoice return stat #defcfunc GetVoiceVolume var pSpVoice Volume = 0 ISpVoice_GetVolume pSpVoice, Volume return Volume #deffunc SetVoiceVolume var pSpVoice, int vol ISpVoice_SetVolume pSpVoice, vol return stat #defcfunc GetVoiceRate var pSpVoice, local Rate Rate = 0 ISpVoice_GetRate pSpVoice, Rate return Rate #deffunc SetVoiceRate var pSpVoice, int rate ISpVoice_SetRate pSpVoice, rate return stat #deffunc VoicePause var pSpVoice ISpVoice_Pause pSpVoice return stat #deffunc VoiceResume var pSpVoice ISpVoice_Resume pSpVoice return stat #defcfunc GetVoiceStatus var pSpVoice dim SPVOICESTATUS, 13 ISpVoice_GetStatus pSpVoice, varptr(SPVOICESTATUS), "" return SPVOICESTATUS.3 #global #define DIID_ISpeechVoiceEvents "{A372ACD1-3BEF-4BBD-8FFB-CB3E2B416AF8}" #define DISPID_SVEStreamStart 0x00000001 #define DISPID_SVEStreamEnd 0x00000002 #define DISPID_SVEVoiceChange 0x00000003 #define DISPID_SVEBookmark 0x00000004 #define DISPID_SVEWord 0x00000005 #define DISPID_SVEPhoneme 0x00000006 #define DISPID_SVESentenceBoundary 0x00000007 #define DISPID_SVEViseme 0x00000008 #define DISPID_SVEAudioLevel 0x00000009 #define DISPID_SVEEnginePrivate 0x0000000A // 以下サンプル pSpVoice = 0 // ComObj作成 CreateVoice pSpVoice if varuse(pSpVoice){ comevent pSpVEvent, pSpVoice, DIID_ISpeechVoiceEvents, *SpVEvent onexit gosub *exit // 一覧取得 GetVoicesList list idx = 0 objsize 420, 20 combox idx, 100, list mes "▼ 文章" sdim s, 1024 : s = "Hello this is H.S.P. for windows." input s mes "▼ 音量(0〜100)" Volume = 100 input Volume mes "▼ 速度(-10〜10)" Rate = 0 input Rate Async = 1 chkbox "再生終了まで待たない", Async button gosub "再生", *speak }else{ dialog "呼び出し失敗" } stop *SpVEvent dispid = comevdisp(pSpVEvent) if dispid == DISPID_SVEStreamStart{ title "再生開始" } if dispid == DISPID_SVEStreamEnd{ title "再生終了" dialog "再生終了" } return *speak // 音量設定(0〜100) SetVoiceVolume pSpVoice, Volume // 再生速度設定(-10〜10) SetVoiceRate pSpVoice, Rate title "音量:"+GetVoiceVolume(pSpVoice)+", 速度"+GetVoiceRate(pSpVoice) // 音声選択 SetVoice pSpVoice, idx if stat{ dialog "音声選択に失敗しました" } // 同期再生(再生終了まで待つ) // 1にすると非同期 VoiceSpeek pSpVoice, s, Async if stat{ dialog "再生失敗しました" } ;wait 50 : VoicePause pSpVoice // 再生終了までループ ;repeat // 再生終了している場合 // (再生開始時は0, 再生完了の場合は1, 再生中は2を返す様子) ; title "Status: "+GetVoiceStatus(pSpVoice) ; if GetVoiceStatus(pSpVoice) == 1 : break ; wait 12 ;loop ;dialog "再生終了!" return *exit // 終了時にでも破棄する DestoryVoice pSpVoice end : end return



seasalt

リンク

2014/1/7(Tue) 09:48:56|NO.59226

素早い回答をありがとうございます!なるほど、こうやるんですか…

おかげさまで、自ウィンドウの操作が改善できました。
想定していたのは一つ目のやり方ですが、ふたつ目のやり方も興味深いですね。
どちらがいいかもうすこし吟味してみたいと思います。

何度も回答していただき、ありがとうございましたm(_ _)m



ONION software Copyright 1997-2023(c) All rights reserved.