ldjhust

工欲善其事 必先利其器

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

转载:http://blog.csdn.net/qin_lin_sb/article/details/7799451

 

1. 首先说下自己的环境配置,不确保该代码对所有配置都适用

操作系统:windows xp sp3

编译环境:Qt SDK1.2.1,MSVC2008编译

既然是利用了Microsoft Speech SDK,那么首先就要安装它,其下载地址为:

http://www.microsoft.com/en-us/download/details.aspx?id=10121

下载图中红色框内的两部分,下载完成后先安装SpeechSDK51.exe,再安装SpeechSDK51LangPack.exe,

按照其默认安装路径安装,代码中要用到其路径。

由于代码中用到了其sphelper.h头文件,编译的时候有可能出现错误,解决办法请参考以下链接:

http://blog.csdn.net/wangyangtao/article/details/5933734

 

2. 我们把对MS Speech SDK5.1  API的调用封装在speech类中,然后再调用该类提供的接口来实现文本朗读。

     下面就重点介绍怎么实现 speech 类。废话不多说了,直接上代码

首先在pro文件中,添加以下代码

[cpp] view plaincopy
 
  1. INCLUDEPATH += -L"C:/Program Files/Microsoft Speech SDK 5.1/Include"  
  2.   
  3. LIBS += -L"C:/Program Files/Microsoft Speech SDK 5.1/Lib/i386"  

 

以下是头文件 speechClass.h

 

[cpp] view plaincopy
 
  1. #ifndef SPEECHCLASS_H  
  2. #define SPEECHCLASS_H  
  3.   
  4. #undef UNICODE  
  5. #include <sapi.h>  
  6. #include <sphelper.h>  
  7. #include <comdef.h>  
  8. #define UNICODE  
  9.   
  10. #include <windows.h>  
  11. #include <windowsx.h>  
  12. #include <commctrl.h>  
  13.   
  14. #include <QString>  
  15.   
  16. class speech{  
  17.   
  18. public:  
  19.     speech();  
  20.     ~speech();  
  21.     void speak(QString text);  
  22.     void setVolume(int volume);  
  23.     void setRate(int rate);  
  24.     void pause();  
  25.     void resume();  
  26.     void finish();  
  27.     int  getVolume();  
  28.     int  getRate();  
  29.   
  30. private:  
  31.     void sounding(QString s, int voice);  
  32.     void speak(QString s, int mode);  
  33.     HRESULT                   hr;  
  34.     CComPtr<ISpObjectToken>   pToken;  
  35.     CComPtr<ISpVoice>         pVoice;  
  36.     WCHAR *pChnToken;  
  37.     WCHAR *pEngToken;  
  38.     bool   over;  
  39.   
  40. };  
  41.   
  42. #endif // SPEECHCLASS_H  

 


以下是源文件 speechClass.cpp

 

 

[cpp] view plaincopy
 
  1. #include "speechClass.h"  
  2.   
  3. #define Eng 0x00  
  4. #define Chn 0x01  
  5.   
  6. //构造函数  
  7. speech::speech()  
  8. {  
  9.     hr        = S_OK;  
  10.     WCHAR *w1 = L"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Speech\\Voices\\Tokens\\MSSimplifiedChineseVoice";  
  11.     WCHAR *w2 = L"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Speech\\Voices\\Tokens\\MSMike";  
  12.     pChnToken = w1;  
  13.     pEngToken = w2;  
  14.   
  15.     if (SUCCEEDED(hr))  
  16.         hr = pVoice.CoCreateInstance( CLSID_SpVoice );  
  17.   
  18.     over = true;  
  19. }  
  20.   
  21. speech::~speech()  
  22. {  
  23.     pChnToken = NULL;  
  24.     pEngToken = NULL;  
  25. }  
  26.   
  27.   
  28. /**********************************************************************/  
  29. //将文本text转化成语音,支持中英文混读  
  30. /**********************************************************************/  
  31. void speech::speak(QString text)  
  32. {  
  33.     QChar curr;  
  34.     QString str;  
  35.     int flagCur;  
  36.     int flagPre(Chn);  
  37.     int cnt(0);  
  38.     int first(0);  
  39.     int len = text.length();  
  40.   
  41.     for (int i = 0; i < len; ++i)  
  42.     {  
  43.         curr = text.at(i);//获取第i个位置的字符  
  44.         if ((curr >= 32 & curr <= 47) || (curr >= 58 && curr <= 64))  
  45.             flagCur = flagPre; //如果是空格或者标点符号,标志不变  
  46.         else  
  47.         {  
  48.             if ((curr >= 'A' && curr <= 'Z') || (curr>='a' && curr<='z'))  
  49.                 flagCur = Eng;  
  50.             else  
  51.                 flagCur = Chn;  
  52.         }  
  53.         if (flagCur == flagPre)  
  54.             cnt++;  
  55.         else  
  56.         {  
  57.             if (cnt != 0) //字符类型变化,读出前面的文本  
  58.             {  
  59.                 str = text.mid(first, cnt);  
  60.                 sounding(str, flagPre);  
  61.             }  
  62.             flagPre = flagCur;  
  63.             first = i;  
  64.             cnt  = 1;  
  65.         }  
  66.     }  
  67.     //阅读最后一段内容  
  68.     str = text.mid(first, cnt);  
  69.     sounding(str, flagCur);  
  70. }  
  71.   
  72.   
  73.   
  74. /**********************************************************************/  
  75. //把文本s读出来,若voice = Eng, 读英文, 若voice = Chn, 读中文  
  76. /**********************************************************************/  
  77. void speech::sounding(QString s, int voice)  
  78. {  
  79.     //把s转化为WCHAR类型的字符串  
  80.     WCHAR *w;  
  81.     w = new WCHAR[s.length()+1];  
  82.     s.toWCharArray(w);  
  83.     w[s.length()] = 0;  
  84.   
  85.     //根据voice的值选择发音类型, 中文 or 英文  
  86.     if (SUCCEEDED(hr))  
  87.     {  
  88.         if (voice == Eng)  
  89.             hr = SpGetTokenFromId(pEngToken, &pToken);  
  90.         else if (voice == Chn)  
  91.             hr = SpGetTokenFromId(pChnToken, &pToken);  
  92.     }  
  93.     if (SUCCEEDED(hr))  
  94.         hr = pVoice->SetVoice(pToken);  
  95.     //发音  
  96.     if(SUCCEEDED(hr))  
  97.         hr = pVoice->Speak(w, SPF_DEFAULT | SVSFlagsAsync, NULL);  
  98.     //释放令牌  
  99.     pToken.Release();  
  100.     delete w;  
  101. }  
  102.   
  103. /**********************************************************************/  
  104. //获取当前语音音量大小  
  105. /**********************************************************************/  
  106. int speech::getVolume()  
  107. {  
  108.     USHORT v;  
  109.     if(SUCCEEDED(hr))  
  110.         hr = pVoice->GetVolume(&v);  
  111.   
  112.     return (int)v;  
  113. }  
  114.   
  115. /**********************************************************************/  
  116. //获取当前语音速度大小  
  117. /**********************************************************************/  
  118. int speech::getRate()  
  119. {  
  120.     long r;  
  121.     if (SUCCEEDED(hr))  
  122.         hr = pVoice->GetRate(&r);  
  123.   
  124.     return (int)r;  
  125. }  
  126.   
  127. /**********************************************************************/  
  128. //设置语音音量,大小为volume  
  129. /**********************************************************************/  
  130. void speech::setVolume(int volume)  
  131. {  
  132.     if(SUCCEEDED(hr))  
  133.         hr = pVoice->SetVolume((USHORT)volume);  
  134. }  
  135.   
  136. /**********************************************************************/  
  137. //设置语音速度,大小为rate  
  138. /**********************************************************************/  
  139. void speech::setRate(int rate)  
  140. {  
  141.     if(SUCCEEDED(hr))  
  142.         hr = pVoice->SetRate((long)rate);  
  143. }  
  144.   
  145. /**********************************************************************/  
  146. //暂停当前播放  
  147. /**********************************************************************/  
  148. void speech::pause()  
  149. {  
  150.     over = false;  
  151.     if (SUCCEEDED(hr))  
  152.         hr = pVoice->Pause();  
  153. }  
  154.   
  155. /**********************************************************************/  
  156. //继续当前播放  
  157. /**********************************************************************/  
  158. void speech::resume()  
  159. {  
  160.     over = true;  
  161.     if (SUCCEEDED(hr))  
  162.         hr = pVoice->Resume();  
  163. }  
  164.   
  165. /**********************************************************************/  
  166. //结束当前播放  
  167. /**********************************************************************/  
  168. void speech::finish()  
  169. {  
  170.     over = true;  
  171.     if (SUCCEEDED(hr))  
  172.         hr = pVoice->Speak(NULL, SPF_PURGEBEFORESPEAK, 0);  
  173. }  

 

利用这个speech类做了一个小例子,通过这个小例子,来说明如何在Qt中使用speech类

下载地址:http://download.csdn.net/detail/qin_lin_sb/4462802

                                              

posted on 2013-08-10 15:10  ldjhust  阅读(842)  评论(0编辑  收藏  举报