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