Qt下使用微软的TTS

来源:互联网 发布:cf36 2检测到数据异常 编辑:程序博客网 时间:2024/06/05 20:03

微软的sdk下载地址为:www.microsoft.com/en-us/download/details.aspx?id=10121

下载并安装上图勾选的两个,建议按默认的路径安装

安装完成后,接下来就是写程序了

首先在新建的.pro文件中添加

LIBS +=.\sapi.lib        lib在下载的文件中可以看到,也可以在你安装的SpeechSDK中找到     

LIBS +=-lole32

#include <windows.h>

#include <mmsystem.h>
#include <conio.h>
#include <iostream>
#include "sapi.h"
#include "sphelper.h"
using namespace std;
#pragma comment(lib,"winmm.lib")
ISpVoice *pVoice=NULL;
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //初始化COM接口
   if (FAILED(::CoInitialize(NULL)))
        return;
    //获取SpVoice接口
    HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void**)&pVoice);
    if (SUCCEEDED(hr))
    {
        pVoice->SetVolume((USHORT)100); //设置音量,范围是 0 -100
        pVoice->SetRate(0); //设置速度,范围是 -10 - 10
        hr = pVoice->Speak(L"你好", 0, NULL);
        pVoice->Release();
        pVoice = NULL;
    }
    //释放com资源
    ::CoUninitialize();
}

基本的代码就是这样,一定要加上#include <window.h>  否则会出现bug

接下来是借用别人写的类,直接调用即可

分别是speech.h 和speech.cpp文件

#ifndef SPEECH_H

#define SPEECH_H
#include <QThread>
#include <windows.h>
#include <windows.h>
#include <mmsystem.h>
#include <conio.h>
#include <iostream>
#include "sapi.h"
#include "sphelper.h"
using namespace std;
class Speech : public QThread       //用线程是为了防止一直按“speak”而导致挂掉
{
    Q_OBJECT
private:                //类为公共静态类,类构造由类内部自己调用,因此可直接用私有构造
    explicit Speech(QObject *parent = 0);
    ~Speech();
public:
    static Speech * getInstance();
    void speak(const QString & speakText);
    void setSpeechEnabled(bool speechEnable);
private:
    static Speech * pSpeech;
    ISpVoice * pSpVoice;
    ISpObjectToken * pSpObjectToken;
    QList<QString> speechList;
    bool isSpeechEnabled;
protected:
    void run();
signals:
    void sendMsg(QString);
public slots:
};
#endif // SPEECH_H

#include "speech.h"

Speech * Speech::pSpeech = NULL;
Speech::Speech(QObject *parent) :
    QThread(parent)
{
    CoInitialize(NULL);
    pSpVoice = NULL;
    isSpeechEnabled = true;
    if(FAILED(CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))
    {
        return;
    }
    else
    {
        emit sendMsg("ERROR!! Can not create instance!!");
    }
    pSpObjectToken = NULL;
    pSpVoice->SetVolume((USHORT)100); //设置音量,范围是 0 -100
    pSpVoice->SetRate(0); //设置速度,范围是 -10 - 10
  /* if(SUCCEEDED(
               SpFindBestToken(SPCAT_VOICES, L"language=405", NULL, &pSpObjectToken)))
    {
        pSpVoice->SetVoice(pSpObjectToken);
        pSpVoice->SetRate(8);
    }
    else
    {
        emit sendMsg("ERROR!! Can not find token!!");
    }*/
}
Speech * Speech::getInstance()
{
    if(!pSpeech)
    {
        pSpeech = new Speech();
    }
    return pSpeech;
}
void Speech::speak(const QString &speakText)
{
    if(!isSpeechEnabled)
    {
        return;
    }
    speechList.append(speakText);
    if(!isRunning())
    {
        start();
    }
}
void Speech::setSpeechEnabled(bool speechEnable)
{
    isSpeechEnabled = speechEnable;
}
void Speech::run()
{
    CoInitialize(NULL);
    while(!speechList.isEmpty())
    {
        QString speakText = speechList.first();
        speechList.pop_front();
        wchar_t * pBuf = new wchar_t[speakText.length()+1];
        memset(pBuf, 0, sizeof(wchar_t)*(speakText.length()+1));
        speakText.toWCharArray(pBuf);
        pSpVoice->Speak(pBuf, SPF_DEFAULT, NULL);
        delete pBuf;
    }
    CoUninitialize();
}
Speech::~Speech()
{
    pSpObjectToken->Release();
    CoUninitialize();
}

调用该类后,在MainWindows中直接用即可

MainWindow.h

#include "speech.h"

classSpeech;

Speech*speech;

MainWindow.cpp

   speech=Speech::getInstance();

voidMainWindow::on_pushButton_clicked()

{
    speech->speak(ui->plainTextEdit->toPlainText());
}

结果如图所示


在文本框中输入文本,点击speak按钮便可有声音发出

但该程序还是存在了问题,在初始化时,会出现如下的提醒,但不会影响使用 ,要是有大神知道解决办法,欢迎留言评论。

代码我已上传至  http://download.csdn.net/download/zhulichen/9991752


原创粉丝点击