Qt中利用 MS Speech SDK5.1 实现文本朗读

3 篇文章 0 订阅

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

                                              



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值