`

文本语音转换入门 使用微软语音 zz

阅读更多

zz sorry to 原作者 这篇帖子网上太多,出处我已无法考证 :)

最近项目需要这个,zz如下:


内容简介
     文本语音(Text-to-Speech,以下简称TTS),它的作用就是把通过TTS引擎把文本转化为语音输出。本文不是讲述如何建立自己的TTS引擎,而是简单介绍如何运用Microsoft Speech SDK 建立自己的文本语音转换应用程序。

Microsoft Speech SDK简介
     Microsoft Speech SDK是微软提供的软件开发包,提供的Speech API (SAPI)主要包含两大方面:  

  • 1. API for Text-to-Speech  
  • 2. API for Speech Recognition  

     其中API for Text-to-Speech,就是微软TTS引擎的接口,通过它我们可以很容易地建立功能强大的文本语音程序,金山词霸的单词朗读功能就用到了这写 API,而目前几乎所有的文本朗读工具都是用这个SDK开发的。至于API for Speech Recognition就是与TTS相对应的语音识别,语音技术是一种令人振奋的技术,但由于目前语音识别技术准确度和识别速度不太理想,还未达到广泛应 用的要求。
     Microsoft Speech SDK可以在微软的网站免费下载,目前的版本是5.1,为了支持中文,还要把附加的语言包(LangPack)一起下载。
     为了在VC中使用这SDK,必需在工程中添加SDK的include和lib目录,为免每个工程都添加目录,最好的办法是在VC的
Option->Directoris立加上SDK的include和lib目录。

一个最简单的例子
     先看一个入门的例子:  

#include <sapi.h>

#pragma comment(lib,"ole32.lib")   //CoInitialize CoCreateInstance需要调用ole32.dll
#pragma comment(lib,"sapi.lib")    //sapi.lib在SDK的lib目录,必需正确配置

int main(int argc, char* argv[])
{
 ISpVoice * pVoice = NULL;

//COM初始化:
 if (FAILED(::CoInitialize(NULL)))
   return FALSE;

//获取ISpVoice接口:
 HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
 if( SUCCEEDED( hr ) )
 {
   hr = pVoice->Speak(L"Hello world", 0, NULL);
   pVoice->Release();
   pVoice = NULL;
 }

//千万不要忘记:
 ::CoUninitialize();   
 return TRUE;
}

     短短20几行代码就实现了文本语音转换,够神奇吧。SDK提供的SAPI是基于COM封装的,无论你是否熟悉COM,只要按部就班地用 CoInitialize(), CoCreateInstance()获取IspVoice接口就够了,需要注意的是初始化COM后,程序结束前一定要用 CoUninitialize()释放资源。

IspVoice接口主要函数

   上述程序的流程是获取IspVoice接口,然后用ISpVoice::Speak()把文本输出为语音,可见,程序的核心就是IspVoice接口。除 了Speak外IspVoice接口还有许多成员函数,具体用法请参考SDK的文档。下面择要说一下几个主要函数的用法:  

HRESULT Speak(const WCHAR *pwcs,DWORD dwFlags,ULONG *pulStreamNumber);       
       
功能:就是speak了
参数:
      *pwcs 输入的文本字符串,必需为Unicode,如果是ansi字符串必需先转换为Unicode。
      dwFlags 用来标志Speak的方式,其中SPF_IS_XML 表示输入文本含有XML标签,这个下文会讲到。
      PulStreamNumber 输出,用来获取去当前文本输入的等候播放队列的位置,只有在异步模式才有用。 
 
HRESULT Pause ( void );
HRESULT Resume ( void );

功能:一看就知道了。

HRESULT SetRate(long RateAdjust );
HRESULT GetRate(long *pRateAdjust);

功能:设置/获取播放速度,范围:-10 to 10
      
HRESULT SetVolume(USHORT usVolume);
HRESULT GetVolume(USHORT *pusVolume);

功能:设置/获取播放音量,范围:0 to 100
      
HRESULT SetSyncSpeakTimeout(ULONG msTimeout);
HRESULT GetSyncSpeakTimeout(ULONG *pmsTimeout);

功能:设置/获取同步超时时间。由于在同步模式中,电泳Speak后程序就会进入阻塞状态等待Speak返回,为免程序长时间没相应,应该设置超时时间,
      msTimeout单位为毫秒。
      
       HRESULT SetOutput(IUnknown *pUnkOutput,BOOL fAllowFormatChanges);

功能:设置输出,下文会讲到用SetOutput把Speak输出问WAV文件。      

这些函数的返回类型都是HRESULT,如果成功则返回S_OK,错误有各自不同的错误码。

使用XML
     个人认为这个TTS api功能最强大之处在于能够分析XML标签,通过XML标签设置音量、音调、延长、停顿,几乎可以使输出达到自然语音效果。前面已经提过,把Speak 参数dwFlags设为SPF_IS_XML,TTS引擎就会分析XML文本,输入文本并不需要严格遵守W3C的标准,只要含有XML标签就行了,下面举 个例子:  

……
pVoice->Speak(L"<VOICE REQUIRED=''NAME=Microsoft Mary''/>volume<VOLUME LEVEL=''100''>turn up</VOLUME>", SPF_IS_XML, NULL);
……
<VOICE REQUIRED=''NAME=Microsoft Mary''/>

标签把声音设为Microsoft Mary,英文版SDK中一共含有3种声音,另外两种是Microsoft Sam和Microsoft Mike。  

……
<VOLUME LEVEL=''100''> 

把音量设为100,音量范围是0~100。

另外:标志音调(-10~10):  

<PITCH MIDDLE="10">text</PITCH> 

注意:" 号在C/C++中前面要加 \ ,否则会出错。 标志语速(-10~10):  

<RATE SPEED="-10">text</RATE>

逐个字母读:  

<SPELL>text</SPELL>

强调:  

<EMPH>text</EMPH>

停顿200毫秒(最长为65,536毫秒):  

<SILENCE MSEC="200" />

控制发音:  

<PRON SYM = ''h eh - l ow 1''/>

     这个标签的功能比较强,重点讲一下:所有的语言发音都是由基本的音素组成,拿中文发音来说,拼音是组成发音的最基本的元素,只要知道汉字的拼音,即使不知 道怎么写,我们可知道这个字怎么都,对于TTS引擎来说,它不一定认识所有字,但是你把拼音对应的符号(SYM)给它,它就一定能够读出来,而英语发音则 可以用音标表示,''h eh - l ow 1''就是hello这个单词对应的语素。至于发音与符号SYM具体对应关系请看SDK文档中的Phoneme Table。
     再另外,数字、日期、时间的读法也有一套规则,SDK中有详细的说明,这里不说了(懒得翻译了),下面随便抛个例子:  

<context ID = "date_ ymd">1999.12.21</context> 

会读成  

"December twenty first nineteen ninety nine"

XML标签可以嵌套使用,但是一定要遵守XML标准。XML标签确实好用,效果也不错,但是……缺点:一个字―――"烦",如果给一大段文字加标签,简直痛不欲生。

把文本语音输出为WAV文件  

#include <sapi.h>
#include <sphelper.h>

#pragma comment(lib,"ole32.lib")
#pragma comment(lib,"sapi.lib")

int main(int argc, char* argv[])
{
 ISpVoice * pVoice = NULL;
 if (FAILED(::CoInitialize(NULL)))
   return FALSE;
 
 HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, 
   IID_ISpVoice, (void **)&pVoice);
 if( SUCCEEDED( hr ) )
 {
   CComPtr<ISpStream>    cpWavStream;
   CComPtr<ISpStreamFormat> cpOldStream;
   CSpStreamFormat OriginalFmt;
   pVoice->GetOutputStream( &cpOldStream );
   OriginalFmt.AssignFormat(cpOldStream);
   hr = SPBindToFile( L"D:\\output.wav",SPFM_CREATE_ALWAYS,
    &cpWavStream,&OriginalFmt.FormatId(),
    OriginalFmt.WaveFormatExPtr() );
   if( SUCCEEDED( hr ) )
   {
    pVoice->SetOutput(cpWavStream,TRUE);
    WCHAR WTX[] = L"<VOICE REQUIRED=''NAME=Microsoft Mary''/>text to wave";
    pVoice->Speak(WTX, SPF_IS_XML, NULL);
    pVoice->Release();
    pVoice = NULL;
   }
 }
 
 ::CoUninitialize();   
 return TRUE;
}

SPBindToFile把文件绑定到输出流上,而SetOutput把输出设为绑定文件的流上。

最后
     看完本文后,是不是觉得很简单,微软把强大的功能封装的太好了。其实SDK中另外一个API,SR(语音识别)更有趣,有兴趣不妨试试,你会有意外的收获的。

分享到:
评论

相关推荐

    base zz zz zz zz

    base zz zz zz zz zz base zz zz zz zz zz base zz zz zz zz zz base zz zz zz zz zz

    Linux文本编辑器vi的使用

    ### Linux文本编辑器vi的使用 #### 一、vi编辑器概述 vi是Linux乃至UNIX中最常用且功能强大的文本编辑器之一。对于Linux系统管理员来说,掌握vi编辑器的使用至关重要,因为它几乎适用于所有类型的文本文件编辑,...

    pdf转换成word转换器(转转大师)v4.8.1.0官方安装版

    【pdf转换成word转换器 转转大师】Zz PDF convert是一款PDF转换为word转换器,并且是完全免费的。它体积小,转换快速,界面简洁方便,1秒钟就能上手。有了它,你可以轻松地将PDF转换成office word软件可编辑的doc...

    VB字符转换:转换迅雷、快车、旋风下载地址.rar

     迅雷就在地址前后分别加上“AA”和“ZZ”,然后进行Base64编码,转换前为:AA地址ZZ  转换后的地址再加上 thunder://  快车是在地址前后分别加上了“[FLASHGET]”,然后Base64编码,转换前为:[FLASHGET]地址...

    统计多个文本长度

    在IT领域,文本处理是一项基础且重要的任务,特别是在大数据分析、自然语言处理和信息检索等应用中。"统计多个文本长度"是一个典型的文本处理问题,它涉及到读取文件、处理文本内容以及进行数据统计和分类。这个任务...

    Linux下最基本的文本编辑器vi使用方法

    Linux 下最基本的文本编辑器 vi 使用方法 vi 编辑器是 Unix 和 Linux 操作系统下最基本的文本编辑器,具有三种工作模式:指令模式、输入模式、末行模式。用户可以通过输入特定的命令在不同模式之间切换。下面是 vi ...

    ZZ561401.CAB

    ZZ561401.CAB ZZ561401.CAB ZZ561401.CAB

    wincc AX NF ZZ

    wincc SIMATIC WinCC是第一个使用最新的32位技术的过程监视系统,具有良好的开放性和灵活性。 从面市伊始,用户就对SIMATIC WinCC印象深刻。

    超出NLO QCD的高横向动量的ZZ产生

    使用LoopSim方法,我们合并ZZ和ZZ + jet的NLO QCD结果,并获得ZZ产生的近似NNLO预测。 还包括对ZZ过程的精确胶子融合环平方的贡献。 最重要的是,我们将来自胶子-胶子通道的胶子-融合ZZ + jet贡献添加到我们的合并...

    GIZA++运行报告zz

    统计机器翻译是计算机科学与语言学交叉领域的一门技术,旨在使用统计模型自动翻译文本或语音从一种自然语言到另一种自然语言。GIZA++是一款在统计机器翻译领域内常用的工具,主要用于词语对齐任务。词语对齐是翻译...

    matlab算法源码Matlab语音信号滤波源码

    值得注意的是,虽然Matlab提供了强大的工具箱支持信号处理,但在某些情况下,为了获得更高的处理效率或更小的资源占用,人们可能会选择将Matlab算法转换为C/C++等更接近硬件的语言实现,或者使用专门的硬件设备来...

    发电系统simulink仿真模型风力光伏发电太阳能电池发电系统MP3语音播报程序(含杜洋录制语音文件)

    在这个案例中,可能是指在发电系统监控或控制过程中使用了MP3语音播报技术来播放相关信息。例如,可以通过预先录制的声音文件(如杜洋录制的语音文件),在特定条件下自动播放系统状态或报警信息。 #### 3.1 语音...

    电子通信设计资料单片机控制语音芯片的录放音系统的设计资料

    ### 电子通信设计资料:单片机控制...从单片机的选择与编程到语音芯片的选型与使用,再到整个系统的集成与调试,每一步都需要细致入微地考虑各种细节问题。希望本文能够为广大电子爱好者及专业人士提供一定的参考价值。

    vi编辑器的使用,linux快速入门

    掌握vi编辑器的使用对于Linux用户来说至关重要,它不仅能够提高文本编辑效率,也是许多系统管理任务中不可或缺的工具。通过熟练运用vi的各种命令,用户可以在没有图形界面的环境中高效地处理文本文件,进一步提升...

    zz CAD快速计算长度插件

    在CAD中想要快速测量长度,在CAD工具栏找到加载应用程序,再点击加载 加载成功后在输入栏输入“zz”(不分大小写)在选择你需要测量的线段即可。

    ZZ超级画板教程.pdf

    ZZ超级画板教程.pdf 是一个功能强大且实用的绘图软件教程,旨在帮助用户快速掌握 ZZ 超级画板的使用方法和技巧。该教程涵盖了 ZZ 超级画板的主要特点和功能,包括: 1. 学科工具整合:ZZ 超级画板将不同的学科工具...

    stm32 DAC语音播放源码

    本文将详细讨论如何使用STM32的数字模拟转换器(DAC)来实现语音播放,特别是针对描述中提到的“小狗叫声”音频的播放。 首先,了解DAC的基本原理。DAC是Digital-to-Analog Converter的缩写,它的作用是将数字信号...

    zz.FindStr.rar_搜索_搜索文件_文件搜索_文本搜索_查找文件

    【标题】"zz.FindStr.rar" 是一个压缩包文件,主要功能是提供一个文本查找工具。这个工具能够帮助用户在指定的根目录及其所有子目录下进行文件搜索,特别是针对包含特定文本的文件进行高效定位。 【描述】该工具的...

Global site tag (gtag.js) - Google Analytics