qt 操作tts
更新时间:2023-09-17 10:16:01 阅读量: 幼儿教育 文档下载
- 球探比分推荐度:
- 相关推荐
所使用的DLL: http://www.cppblog.com/Files/biao/TTSSpeaker.dll.zip ///////////////////////////////////////////////////////////////////////////////////////////////////// // TTSSpeaker.cpp: Qt
///////////////////////////////////////////////////////////////////////////////////////////////////// // 调用sapi.dll, 使用里面的三个函数来初始化, 释放资源, 发音函数
// 在VS中使用TTSSpeaker.cpp生成DLL文件. 因为如果在QtCreator中使用的话, 有可能自带的mingw的不完全, 而找不到
// 某些结构的定义而出错题.
#include \
#include
#ifdef _MANAGED #pragma managed(push, off) #endif
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) {
return TRUE;
}
ISpVoice *pVoice; HRESULT hr;
extern \ __declspec(dllexport) bool initialize() {
pVoice = NULL;
if (FAILED(::CoInitialize(NULL))) {
return false; }
hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void**)&pVoice);
return true; }
extern \ __declspec(dllexport) void release() { if (SUCCEEDED(hr)) {
pVoice->Release(); pVoice = NULL; }
::CoUninitialize(); }
extern \ __declspec(dllexport) void speak(char *szU8) { if (SUCCEEDED(hr)) {
int wcsLen = ::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), NULL, 0); wchar_t* wszString = new wchar_t[wcsLen + 1];
::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), wszString, wcsLen); wszString[wcsLen] = '\\0';
hr = pVoice->Speak(wszString, 0, NULL); } }
#ifdef _MANAGED #pragma managed(pop) #endif
////////////////////////////////////////////////////////////////////////////////////////////////////// // Speaker.h: Qt
////////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef SPEAKER_H #define SPEAKER_H
#include
class Speaker; class TtsLoader; class TtsRemover; class SpeakThread;
// 对应sapi.dll里的三个TTS函数, 从DLL中得到的
typedef bool (*InitializeFunc)(); typedef void (*ReleaseFunc)();
typedef void (*SpeakFunc)(char *szU8);
/**
* 管理TTS的类, 对TTS进行加载, 释放TTS占用的资源, 调用TTS进行文本发音. */
class Speaker : public QObject {
Q_OBJECT public:
static Speaker& getInstance(); void setSpeakEnabled(bool enabled);
bool isSpeakEnabled() const; bool isTtsLoaded() const;
void speak(const QString &str); // 启动发音线程 void initializeTts(); // 启动TTS加载线程 void releaseTts(); // 启动释放TTS资源的线程
void terminateAllThreads();
protected:
void loadTts(); // 真正加载TTS的函数
void removeTts(); // 真正释放TTS占用资源的函数 void speakString(const QString &str); // 真正发音的函数
private slots:
void completeLoadTts(); // TTS加载线程结束的处理糟函数 void completeRemoveTts(); // 释放TTS资源线程结束的处理糟函数 private: Speaker(); ~Speaker();
Speaker(const Speaker &other);
Speaker& operator=(const Speaker &other);
// TTS 初始化, 释放资源, 发音函数
InitializeFunc initializeFunc; ReleaseFunc releaseFunc; SpeakFunc speakFunc;
bool ttsLoaded; // TTS 加载成功 bool speakEnabled; // 启用语音功能
friend class TtsLoader;
TtsLoader *ttsLoader; // TTS 加载线程 friend class TtsRemover; TtsRemover *ttsRemover; friend class SpeakThread;
SpeakThread *speakThread; // 发音线程
friend class std::auto_ptr
/////////////////////////////////////////////////////////////////////////////////// // 加载TTS的线程
// 如果不使用线程来加载, 在加载的时候就会感觉到卡
class TtsLoader : public QThread {
public:
TtsLoader(Speaker *speaker); virtual void run(); void stop();
private:
Speaker *speaker; volatile bool stopped; };
/////////////////////////////////////////////////////////////////////////////////// // 释放TTS资源的线程
class TtsRemover : public QThread {
public:
TtsRemover(Speaker *speaker); void stop();
protected:
virtual void run(); private:
Speaker *speaker; volatile bool stopped; };
/////////////////////////////////////////////////////////////////////////////////// // TTS发音线程,
class SpeakThread : public QThread {
public:
SpeakThread(Speaker *speaker); void stop();
void setSpeakingString(const QString &speakingString);
protected:
virtual void run(); private:
Speaker *speaker; volatile bool stopped; QString speakingString; };
#endif // SPEAKER_H
////////////////////////////////////////////////////////////////////////////////////////////////////// // Speaker.cpp: Qt
//////////////////////////////////////////////////////////////////////////////////////////////////////
#include \
#include
#include
std::auto_ptr
Speaker::Speaker() { ttsLoaded = false; speakEnabled = true;
// Threads
ttsLoader = 0; ttsRemover = 0; speakThread = 0;
// TTS functions
initializeFunc = 0; releaseFunc = 0; speakFunc = 0; }
Speaker::~Speaker() { terminateAllThreads();
delete ttsLoader; delete ttsRemover; delete speakThread;
//这里释放不用线程,而是直接释放 if (ttsLoaded) { removeTts(); } }
Speaker& Speaker::getInstance() { if (instance.get() == 0) {
instance.reset(new Speaker()); }
return *(instance.get()); }
void Speaker::setSpeakEnabled(bool enabled) {
speakEnabled = enabled; }
bool Speaker::isSpeakEnabled() const {
return speakEnabled; }
bool Speaker::isTtsLoaded() const {
return ttsLoaded; }
void Speaker::speak(const QString &str) {
if (ttsLoaded && speakEnabled && (0 != speakThread)) { if (speakThread->isRunning()) {
qDebug() << \; speakThread->stop(); }
qDebug() << \ << str;
speakString(\); // 不加这一句, 不知道为什么不行 speakThread->setSpeakingString(str); speakThread->start(); } }
void Speaker::speakString(const QString &str) {
if (speakFunc != 0) {
speakFunc(str.toUtf8().data()); } }
void Speaker::initializeTts() {
// If tts is loaded, don't need to load again.
if (ttsLoaded) { return; }
// 启动加载线程
// If ttsLoader is not euqal 0, that means ttsLoader is running. // Because after ttsLoader is finished, it will be removed.
if (ttsLoader == 0) {
ttsLoader = new TtsLoader(this);
connect(ttsLoader, SIGNAL(finished()), this, SLOT(completeLoadTts()));
ttsLoader->start(); } }
void Speaker::releaseTts() {
// If tts is not loaded, removing process is not needed.
if (!ttsLoaded) { return; }
if (0 == ttsRemover) {
ttsRemover = new TtsRemover(this);
connect(ttsRemover, SIGNAL(finished()), this, SLOT(completeRemoveTts()));
ttsRemover->start(); } }
void Speaker::loadTts() {
// 如果TTS引擎已经加载了, 就不需要再次加载 if (ttsLoaded) { return; }
QLibrary lib(\); if (lib.load()) {
initializeFunc = (InitializeFunc)lib.resolve(\);
releaseFunc = (ReleaseFunc)lib.resolve(\); speakFunc = (SpeakFunc)lib.resolve(\);
if (initializeFunc && releaseFunc && speakFunc) { initializeFunc(); ttsLoaded = true;
qDebug() << \;
// When tts is loaded, initialize the speak thread.
speakThread = new SpeakThread(this);
speak(\); // 加载完后说一下,准备好,因为第一次说都会很慢
} } else {
qDebug() << lib.errorString(); } }
void Speaker::removeTts() {
// If tts is not loaded, removing process is not needed.
if (!ttsLoaded) { return; }
releaseFunc();
ttsLoaded = false; initializeFunc = 0; releaseFunc = 0; speakFunc = 0;
qDebug() << \;
// After tts is removed, speak thread is also need to be removed.
if (speakThread != 0) { speakThread->terminate(); }
delete speakThread; speakThread = 0; } /**
* After the process that loads tts is completed, the load thread is not needed, then remove it. */
void Speaker::completeLoadTts() {
delete ttsLoader; ttsLoader = 0; } /**
* After the process that removes tts is completed, the remove thread is not needed, then remove it. */
void Speaker::completeRemoveTts() {
delete ttsRemover; ttsRemover = 0; } /**
* Terminated all threads. */
void Speaker::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; }
void TtsLoader::run() {
if (!stopped) { speaker->loadTts(); }
stopped = false; // }
void TtsLoader::stop() {
stopped = true;
}
/////////////////////////////////////////////////////////////////////////////////// TtsRemover::TtsRemover(Speaker *speaker) { this->speaker = speaker; stopped = false; }
void TtsRemover::run() {
if (!stopped) {
speaker->removeTts(); }
stopped = false; }
void TtsRemover::stop() {
stopped = true; }
/////////////////////////////////////////////////////////////////////////////////// SpeakThread::SpeakThread(Speaker *speaker) { this->speaker = speaker; stopped = false; }
void SpeakThread::run() {
if (!stopped) {
speaker->speakString(speakingString); }
stopped = false; }
void SpeakThread::stop() {
stopped = true; }
void SpeakThread::setSpeakingString(const QString &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的资源, 因为使用了智能指针实现单态模式] */
正在阅读:
qt 操作tts09-17
剑八 Test2--Task1 作文范文11-05
普天综合布线技术参数06-28
小学升旗仪式作文06-15
预防医学总结复习05-23
实习小结10-26
SKC9800数控地面测井仪的简介及其与变密度仪器的配接应用 - 图文10-17
GEDO CE 轨检小车使用流程_CH_v1.6.409-01
生产工具领用管理规定05-25
2017感动中国观后感04-02
- 一、优秀运动员、教练员、裁判员名单
- 2012年咨询师项目决策分析与评价真题及答案
- 设备安装施工安全保证措施
- 鸦鹊岭镇红土完全小学(双效)
- 国际贸易地理论文
- 2013-2014学年石滩二中八年级物理第一学期期中复习专题—实验与探究
- 实验二 控制系统的动态响应及其稳定性分析
- 浮沉子实验报告
- 中美日常交际中的文化差异
- 买方变更协议书
- 宝鸡在关中—天水经济区率先崛起的战略思考
- 金属工艺考题
- 2010年高考数学压轴题跟踪演练(7+9+8+6+7+7)
- 南京大学禚金吉:即时通讯软件能实现互联互通吗 - 基于网络经济学的分析
- 5.3.1 平行线的性质(集体备课) - 图文
- WH市110kV降压变电所电气二次部分设计任务书
- 校园绿地景观环境设计调查报告
- IGBT 吸收电容
- JRC电子海图要点
- 危险化学品生产单位主要负责人、安全生产管理人员初训、复训考试题110