[dasher: 98/217] Quick and dirty way to speak non default language



commit 89f299c31ebff8d4d2249d2d453288d2f6e7923b
Author: ipomoena <amajorek google com>
Date:   Fri Oct 23 17:34:20 2015 -0700

    Quick and dirty way to speak non default language

 Src/Win32/Dasher.cpp |   75 ++++++++++++++++++++++++++++++++------------------
 Src/Win32/Dasher.h   |    4 ++-
 2 files changed, 51 insertions(+), 28 deletions(-)
---
diff --git a/Src/Win32/Dasher.cpp b/Src/Win32/Dasher.cpp
index 933b1af..5e341c9 100644
--- a/Src/Win32/Dasher.cpp
+++ b/Src/Win32/Dasher.cpp
@@ -15,7 +15,7 @@
 #include "Sockets/SocketInput.h"
 #include "BTSocketInput.h"
 #endif
-
+#include <Sphelper.h>
 #include "Common/WinOptions.h"
 
 #ifndef _WIN32_WCE
@@ -41,7 +41,6 @@ CDasher::CDasher(HWND Parent, CDasherWindow *pWindow, CEdit *pEdit)
   CoInitialize(NULL);
 #endif
 #ifdef WIN32_SPEECH
-  pVoice = 0;
   m_bAttemptedSpeech = false;
 #endif
 
@@ -61,13 +60,6 @@ CDasher::CDasher(HWND Parent, CDasherWindow *pWindow, CEdit *pEdit)
 CDasher::~CDasher(void) {
   WriteTrainFileFull();
   delete m_pCanvas;
-#ifdef WIN32_SPEECH
-  if (pVoice) {
-         pVoice->Release();
-         pVoice = 0; 
-         m_bAttemptedSpeech = false;
-  }
-#endif
 }
 
 void CDasher::CreateModules() {
@@ -280,30 +272,59 @@ void CDasher::TakeFocus() {
 bool CDasher::SupportsSpeech() {
   if (!m_bAttemptedSpeech) {
     //try to create speech synthesizer lazily, saving resources if no speech req'd.
-    HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
-    
-    if(hr!=S_OK)
-      pVoice=0;
-    else if (pVoice) {
-      //ACL Do we need to check pVoice? copying old code again, previous comment said:
-      // TODO: Why is this needed?
-      pVoice->Speak(L"",SPF_ASYNC,NULL);
+    HRESULT hr = m_pDefaultVoice.CoCreateInstance(CLSID_SpVoice);
+    if (SUCCEEDED(hr)) {
+      // First speak takes long time. 
+      m_pDefaultVoice->Speak(L"",SPF_ASYNC,NULL);
+      m_voicesByLangCode[""] = m_pDefaultVoice;
     }
     m_bAttemptedSpeech = true;
+    // TODO find language code and add entry to map
+  }
+  return m_pDefaultVoice != 0;
+}
+
+ISpVoice* CDasher::getVoice(string lang)
+{
+  auto it = m_voicesByLangCode.find(lang);
+  if (it != m_voicesByLangCode.end())
+    return it->second;
+  // temporary hack to see how language selection works 
+  if (lang=="pl")
+  {
+    CComPtr<IEnumSpObjectTokens> cpEnum;
+    HRESULT hr = SpEnumTokens(SPCAT_VOICES, L"", L"Language=415", &cpEnum);
+    if (SUCCEEDED(hr)) {
+      CComPtr<ISpObjectToken> cpToken;
+      hr = cpEnum->Next(1, &cpToken, NULL);
+      if (SUCCEEDED(hr)) {
+        CComPtr<ISpVoice> pVoice;
+        HRESULT hr = pVoice.CoCreateInstance(CLSID_SpVoice);
+        if (SUCCEEDED(hr)) {
+          hr = pVoice->SetVoice(cpToken);
+          if (SUCCEEDED(hr)) {
+            m_voicesByLangCode[lang] = pVoice;
+            return pVoice;
+          }
+        }
+      }
+    }
   }
-  return pVoice != 0;
+  m_voicesByLangCode[lang] = m_pDefaultVoice;
+  return m_pDefaultVoice;
 }
 
 void CDasher::Speak(const string &strText, bool bInterrupt) {
-  //ACL TODO - take account of bInterrupt
-       if (pVoice) {
-               Tstring wideText;
-               UTF8string_to_wstring(strText, wideText);
-    int flags = SPF_ASYNC;
-    if (bInterrupt)
-      flags |= SPF_PURGEBEFORESPEAK;
-               pVoice->Speak(wideText.c_str(), flags, NULL);
-       }
+  if (!m_pDefaultVoice)
+    return;
+
+  string lang = GetActiveAlphabet()->GetLanguageCode();
+  Tstring wideText;
+  UTF8string_to_wstring(strText, wideText);
+  int flags = SPF_ASYNC;
+  if (bInterrupt)
+    flags |= SPF_PURGEBEFORESPEAK;
+  getVoice(lang)->Speak(wideText.c_str(), flags, NULL);
 }
 #endif
 
diff --git a/Src/Win32/Dasher.h b/Src/Win32/Dasher.h
index 50fe4e0..a45aa60 100644
--- a/Src/Win32/Dasher.h
+++ b/Src/Win32/Dasher.h
@@ -77,8 +77,10 @@ private:
   CDasherWindow *m_pWindow;
   CEdit *m_pEdit;
 #ifdef WIN32_SPEECH
-  ISpVoice *pVoice;
+  ISpVoice* getVoice(string lang);
+  CComPtr<ISpVoice> m_pDefaultVoice;
   bool m_bAttemptedSpeech;
+  map<string, CComPtr<ISpVoice> > m_voicesByLangCode;
 #endif
 };
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]