Qt Qt调用windows TTS.docx

上传人:b****8 文档编号:30286110 上传时间:2023-08-13 格式:DOCX 页数:20 大小:18.04KB
下载 相关 举报
Qt Qt调用windows TTS.docx_第1页
第1页 / 共20页
Qt Qt调用windows TTS.docx_第2页
第2页 / 共20页
Qt Qt调用windows TTS.docx_第3页
第3页 / 共20页
Qt Qt调用windows TTS.docx_第4页
第4页 / 共20页
Qt Qt调用windows TTS.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

Qt Qt调用windows TTS.docx

《Qt Qt调用windows TTS.docx》由会员分享,可在线阅读,更多相关《Qt Qt调用windows TTS.docx(20页珍藏版)》请在冰豆网上搜索。

Qt Qt调用windows TTS.docx

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_ptrinstance;

};

///////////////////////////////////////////////////////////////////////////////////

//加载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_ptrSpeaker:

:

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的资源,因为使用了智能指针实现单态模式]

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 人力资源管理

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1