转载: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文件中,添加以下代码
- INCLUDEPATH += -L"C:/Program Files/Microsoft Speech SDK 5.1/Include"
- LIBS += -L"C:/Program Files/Microsoft Speech SDK 5.1/Lib/i386"
以下是头文件 speechClass.h
- #ifndef SPEECHCLASS_H
- #define SPEECHCLASS_H
- #undef UNICODE
- #include <sapi.h>
- #include <sphelper.h>
- #include <comdef.h>
- #define UNICODE
- #include <windows.h>
- #include <windowsx.h>
- #include <commctrl.h>
- #include <QString>
- class speech{
- public:
- speech();
- ~speech();
- void speak(QString text);
- void setVolume(int volume);
- void setRate(int rate);
- void pause();
- void resume();
- void finish();
- int getVolume();
- int getRate();
- private:
- void sounding(QString s, int voice);
- void speak(QString s, int mode);
- HRESULT hr;
- CComPtr<ISpObjectToken> pToken;
- CComPtr<ISpVoice> pVoice;
- WCHAR *pChnToken;
- WCHAR *pEngToken;
- bool over;
- };
- #endif // SPEECHCLASS_H
以下是源文件 speechClass.cpp
- #include "speechClass.h"
- #define Eng 0x00
- #define Chn 0x01
- //构造函数
- speech::speech()
- {
- hr = S_OK;
- WCHAR *w1 = L"HKEY_LOCAL_MACHINE\Software\Microsoft\Speech\Voices\Tokens\MSSimplifiedChineseVoice";
- WCHAR *w2 = L"HKEY_LOCAL_MACHINE\Software\Microsoft\Speech\Voices\Tokens\MSMike";
- pChnToken = w1;
- pEngToken = w2;
- if (SUCCEEDED(hr))
- hr = pVoice.CoCreateInstance( CLSID_SpVoice );
- over = true;
- }
- speech::~speech()
- {
- pChnToken = NULL;
- pEngToken = NULL;
- }
- /**********************************************************************/
- //将文本text转化成语音,支持中英文混读
- /**********************************************************************/
- void speech::speak(QString text)
- {
- QChar curr;
- QString str;
- int flagCur;
- int flagPre(Chn);
- int cnt(0);
- int first(0);
- int len = text.length();
- for (int i = 0; i < len; ++i)
- {
- curr = text.at(i);//获取第i个位置的字符
- if ((curr >= 32 & curr <= 47) || (curr >= 58 && curr <= 64))
- flagCur = flagPre; //如果是空格或者标点符号,标志不变
- else
- {
- if ((curr >= 'A' && curr <= 'Z') || (curr>='a' && curr<='z'))
- flagCur = Eng;
- else
- flagCur = Chn;
- }
- if (flagCur == flagPre)
- cnt++;
- else
- {
- if (cnt != 0) //字符类型变化,读出前面的文本
- {
- str = text.mid(first, cnt);
- sounding(str, flagPre);
- }
- flagPre = flagCur;
- first = i;
- cnt = 1;
- }
- }
- //阅读最后一段内容
- str = text.mid(first, cnt);
- sounding(str, flagCur);
- }
- /**********************************************************************/
- //把文本s读出来,若voice = Eng, 读英文, 若voice = Chn, 读中文
- /**********************************************************************/
- void speech::sounding(QString s, int voice)
- {
- //把s转化为WCHAR类型的字符串
- WCHAR *w;
- w = new WCHAR[s.length()+1];
- s.toWCharArray(w);
- w[s.length()] = 0;
- //根据voice的值选择发音类型, 中文 or 英文
- if (SUCCEEDED(hr))
- {
- if (voice == Eng)
- hr = SpGetTokenFromId(pEngToken, &pToken);
- else if (voice == Chn)
- hr = SpGetTokenFromId(pChnToken, &pToken);
- }
- if (SUCCEEDED(hr))
- hr = pVoice->SetVoice(pToken);
- //发音
- if(SUCCEEDED(hr))
- hr = pVoice->Speak(w, SPF_DEFAULT | SVSFlagsAsync, NULL);
- //释放令牌
- pToken.Release();
- delete w;
- }
- /**********************************************************************/
- //获取当前语音音量大小
- /**********************************************************************/
- int speech::getVolume()
- {
- USHORT v;
- if(SUCCEEDED(hr))
- hr = pVoice->GetVolume(&v);
- return (int)v;
- }
- /**********************************************************************/
- //获取当前语音速度大小
- /**********************************************************************/
- int speech::getRate()
- {
- long r;
- if (SUCCEEDED(hr))
- hr = pVoice->GetRate(&r);
- return (int)r;
- }
- /**********************************************************************/
- //设置语音音量,大小为volume
- /**********************************************************************/
- void speech::setVolume(int volume)
- {
- if(SUCCEEDED(hr))
- hr = pVoice->SetVolume((USHORT)volume);
- }
- /**********************************************************************/
- //设置语音速度,大小为rate
- /**********************************************************************/
- void speech::setRate(int rate)
- {
- if(SUCCEEDED(hr))
- hr = pVoice->SetRate((long)rate);
- }
- /**********************************************************************/
- //暂停当前播放
- /**********************************************************************/
- void speech::pause()
- {
- over = false;
- if (SUCCEEDED(hr))
- hr = pVoice->Pause();
- }
- /**********************************************************************/
- //继续当前播放
- /**********************************************************************/
- void speech::resume()
- {
- over = true;
- if (SUCCEEDED(hr))
- hr = pVoice->Resume();
- }
- /**********************************************************************/
- //结束当前播放
- /**********************************************************************/
- void speech::finish()
- {
- over = true;
- if (SUCCEEDED(hr))
- hr = pVoice->Speak(NULL, SPF_PURGEBEFORESPEAK, 0);
- }
利用这个speech类做了一个小例子,通过这个小例子,来说明如何在Qt中使用speech类
下载地址:http://download.csdn.net/detail/qin_lin_sb/4462802