Qt Qt调用windows TTS.docx
- 文档编号:30286110
- 上传时间:2023-08-13
- 格式:DOCX
- 页数:20
- 大小:18.04KB
Qt Qt调用windows TTS.docx
《Qt Qt调用windows TTS.docx》由会员分享,可在线阅读,更多相关《Qt Qt调用windows TTS.docx(20页珍藏版)》请在冰豆网上搜索。
QtQt调用windowsTTS
所使用的DLL:
/////////////////////////////////////////////////////////////////////////////////////////////////////
//TTSSpeaker.cpp:
Qt
/////////////////////////////////////////////////////////////////////////////////////////////////////
//调用sapi.dll,使用里面的三个函数来初始化,释放资源,发音函数
//在VS中使用TTSSpeaker.cpp生成DLL文件.因为如果在QtCreator中使用的话,有可能自带的mingw的不完全,而找不到
//某些结构的定义而出错题.
#include"stdafx.h"
#include
#ifdef_MANAGED
#pragmamanaged(push,off)
#endif
BOOLAPIENTRYDllMain(HMODULEhModule,
DWORDul_reason_for_call,
LPVOIDlpReserved
){
returnTRUE;
}
ISpVoice*pVoice;
HRESULThr;
extern"C"__declspec(dllexport)boolinitialize(){
pVoice=NULL;
if(FAILED(:
:
CoInitialize(NULL))){
returnfalse;
}
hr=CoCreateInstance(CLSID_SpVoice,NULL,CLSCTX_ALL,IID_ISpVoice,(void**)&pVoice);
returntrue;
}
extern"C"__declspec(dllexport)voidrelease(){
if(SUCCEEDED(hr)){
pVoice->Release();
pVoice=NULL;
}
:
:
CoUninitialize();
}
extern"C"__declspec(dllexport)voidspeak(char*szU8){
if(SUCCEEDED(hr)){
intwcsLen=:
:
MultiByteToWideChar(CP_UTF8,NULL,szU8,strlen(szU8),NULL,0);
wchar_t*wszString=newwchar_t[wcsLen+1];
:
:
MultiByteToWideChar(CP_UTF8,NULL,szU8,strlen(szU8),wszString,wcsLen);
wszString[wcsLen]='\0';
hr=pVoice->Speak(wszString,0,NULL);
}
}
#ifdef_MANAGED
#pragmamanaged(pop)
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////////
//Speaker.h:
Qt
//////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndefSPEAKER_H
#defineSPEAKER_H
#include
#include
#include
classSpeaker;
classTtsLoader;
classTtsRemover;
classSpeakThread;
//对应sapi.dll里的三个TTS函数,从DLL中得到的
typedefbool(*InitializeFunc)();
typedefvoid(*ReleaseFunc)();
typedefvoid(*SpeakFunc)(char*szU8);
/**
*管理TTS的类,对TTS进行加载,释放TTS占用的资源,调用TTS进行文本发音.
*/
classSpeaker:
publicQObject{
Q_OBJECT
public:
staticSpeaker&getInstance();
voidsetSpeakEnabled(boolenabled);
boolisSpeakEnabled()const;
boolisTtsLoaded()const;
voidspeak(constQString&str);//启动发音线程
voidinitializeTts();//启动TTS加载线程
voidreleaseTts();//启动释放TTS资源的线程
voidterminateAllThreads();
protected:
voidloadTts();//真正加载TTS的函数
voidremoveTts();//真正释放TTS占用资源的函数
voidspeakString(constQString&str);//真正发音的函数
privateslots:
voidcompleteLoadTts();//TTS加载线程结束的处理糟函数
voidcompleteRemoveTts();//释放TTS资源线程结束的处理糟函数
private:
Speaker();
~Speaker();
Speaker(constSpeaker&other);
Speaker&operator=(constSpeaker&other);
//TTS初始化,释放资源,发音函数
InitializeFuncinitializeFunc;
ReleaseFuncreleaseFunc;
SpeakFuncspeakFunc;
boolttsLoaded;//TTS加载成功
boolspeakEnabled;//启用语音功能
friendclassTtsLoader;
TtsLoader*ttsLoader;//TTS加载线程
friendclassTtsRemover;
TtsRemover*ttsRemover;
friendclassSpeakThread;
SpeakThread*speakThread;//发音线程
friendclassstd:
:
auto_ptr
staticstd:
:
auto_ptr
};
///////////////////////////////////////////////////////////////////////////////////
//加载TTS的线程
//如果不使用线程来加载,在加载的时候就会感觉到卡
classTtsLoader:
publicQThread{
public:
TtsLoader(Speaker*speaker);
virtualvoidrun();
voidstop();
private:
Speaker*speaker;
volatileboolstopped;
};
///////////////////////////////////////////////////////////////////////////////////
//释放TTS资源的线程
classTtsRemover:
publicQThread{
public:
TtsRemover(Speaker*speaker);
voidstop();
protected:
virtualvoidrun();
private:
Speaker*speaker;
volatileboolstopped;
};
///////////////////////////////////////////////////////////////////////////////////
//TTS发音线程,
classSpeakThread:
publicQThread{
public:
SpeakThread(Speaker*speaker);
voidstop();
voidsetSpeakingString(constQString&speakingString);
protected:
virtualvoidrun();
private:
Speaker*speaker;
volatileboolstopped;
QStringspeakingString;
};
#endif//SPEAKER_H
//////////////////////////////////////////////////////////////////////////////////////////////////////
//Speaker.cpp:
Qt
//////////////////////////////////////////////////////////////////////////////////////////////////////
#include"Speaker.h"
#include
#include
std:
:
auto_ptr
:
instance;
Speaker:
:
Speaker(){
ttsLoaded=false;
speakEnabled=true;
//Threads
ttsLoader=0;
ttsRemover=0;
speakThread=0;
//TTSfunctions
initializeFunc=0;
releaseFunc=0;
speakFunc=0;
}
Speaker:
:
~Speaker(){
terminateAllThreads();
deletettsLoader;
deletettsRemover;
deletespeakThread;
//这里释放不用线程,而是直接释放
if(ttsLoaded){
removeTts();
}
}
Speaker&Speaker:
:
getInstance(){
if(instance.get()==0){
instance.reset(newSpeaker());
}
return*(instance.get());
}
voidSpeaker:
:
setSpeakEnabled(boolenabled){
speakEnabled=enabled;
}
boolSpeaker:
:
isSpeakEnabled()const{
returnspeakEnabled;
}
boolSpeaker:
:
isTtsLoaded()const{
returnttsLoaded;
}
voidSpeaker:
:
speak(constQString&str){
if(ttsLoaded&&speakEnabled&&(0!
=speakThread)){
if(speakThread->isRunning()){
qDebug()<<"speakThreadisrunning";
speakThread->stop();
}
qDebug()<<"Speaking:
"< speakString("");//不加这一句,不知道为什么不行 speakThread->setSpeakingString(str); speakThread->start(); } } voidSpeaker: : speakString(constQString&str){ if(speakFunc! =0){ speakFunc(str.toUtf8().data()); } } voidSpeaker: : initializeTts(){ //Ifttsisloaded,don'tneedtoloadagain. if(ttsLoaded){ return; } //启动加载线程 //IfttsLoaderisnoteuqal0,thatmeansttsLoaderisrunning. //BecauseafterttsLoaderisfinished,itwillberemoved. if(ttsLoader==0){ ttsLoader=newTtsLoader(this); connect(ttsLoader,SIGNAL(finished()),this,SLOT(completeLoadTts())); ttsLoader->start(); } } voidSpeaker: : releaseTts(){ //Ifttsisnotloaded,removingprocessisnotneeded. if(! ttsLoaded){ return; } if(0==ttsRemover){ ttsRemover=newTtsRemover(this); connect(ttsRemover,SIGNAL(finished()),this,SLOT(completeRemoveTts())); ttsRemover->start(); } } voidSpeaker: : loadTts(){ //如果TTS引擎已经加载了,就不需要再次加载 if(ttsLoaded){ return; } QLibrarylib("TTSSpeaker"); if(lib.load()){ initializeFunc=(InitializeFunc)lib.resolve("initialize"); releaseFunc=(ReleaseFunc)lib.resolve("release"); speakFunc=(SpeakFunc)lib.resolve("speak"); if(initializeFunc&&releaseFunc&&speakFunc){ initializeFunc(); ttsLoaded=true; qDebug()<<"TTSisloaded."; //Whenttsisloaded,initializethespeakthread. speakThread=newSpeakThread(this); speak("");//加载完后说一下,准备好,因为第一次说都会很慢 } }else{ qDebug()< } } voidSpeaker: : removeTts(){ //Ifttsisnotloaded,removingprocessisnotneeded. if(! ttsLoaded){ return; } releaseFunc(); ttsLoaded=false; initializeFunc=0; releaseFunc=0; speakFunc=0; qDebug()<<"TTSisremoved."; //Afterttsisremoved,speakthreadisalsoneedtoberemoved. if(speakThread! =0){ speakThread->terminate(); } deletespeakThread; speakThread=0; } /** *Aftertheprocessthatloadsttsiscompleted,theloadthreadisnotneeded,thenremoveit. */ voidSpeaker: : completeLoadTts(){ deletettsLoader; ttsLoader=0; } /** *Aftertheprocessthatremovesttsiscompleted,theremovethreadisnotneeded,thenremoveit. */ voidSpeaker: : completeRemoveTts(){ deletettsRemover; ttsRemover=0; } /** *Terminatedallthreads. */ voidSpeaker: : terminateAllThreads(){ if(ttsLoader! =0){ ttsLoader->terminate(); } if(ttsRemover! =0){ ttsRemover->terminate(); } if(speakThread! =0){ speakThread->terminate(); } } /////////////////////////////////////////////////////////////////////////////////// TtsLoader: : TtsLoader(Speaker*speaker){ this->speaker=speaker; stopped=false; } voidTtsLoader: : run(){ if(! stopped){ speaker->loadTts(); } stopped=false;// } voidTtsLoader: : stop(){ stopped=true; } /////////////////////////////////////////////////////////////////////////////////// TtsRemover: : TtsRemover(Speaker*speaker){ this->speaker=speaker; stopped=false; } voidTtsRemover: : run(){ if(! stopped){ speaker->removeTts(); } stopped=false; } voidTtsRemover: : stop(){ stopped=true; } /////////////////////////////////////////////////////////////////////////////////// SpeakThread: : SpeakThread(Speaker*speaker){ this->speaker=speaker; stopped=false; } voidSpeakThread: : run(){ if(! stopped){ speaker->speakString(speakingString); } stopped=false; } voidSpeakThread: : stop(){ stopped=true; } voidSpeakThread: : setSpeakingString(constQString&speakingString){ this->speakingString=speakingString; } /* 很奇怪的问题: 如果直接使用loadTts()和removeTts()函数来初始化和释放TTS的资源,就不会存在内存泄漏问题.但是如果使用线程来处理,即调用initializeTts(),releaseTts(),在线程中调用loadTts(),removeTts()来初始化和释放TTS的资源,就会存在内存泄漏.泄漏的内存大小为初始化一次TTS的内存,没发现会叠加. 文本发音的使用过程: 由于使用的是单态模式,所以在使用发音函数speak前,初始化TTS一次就可以了,而TTS的资源释放是自动释放的,当然也可以手动释放. 1.Speaker: : getInstance().initializeTts();//最好程序启动的时候调用. 2.Speaker: : getInstance().speak(str); .................可以在程序的任何地方直接调用.(如果TTS没有被加载,或者不启用语音功能,这时调用了不起任何作用) [不需要自己手动释放TTS的资源,因为使用了智能指针实现单态模式]
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Qt Qt调用windows TTS 调用 windows
![提示](https://static.bdocx.com/images/bang_tan.gif)