微软Windows Speech SDK编程入门
2009-02-24 13:33
一、SAPI简介
软件中的语音技术包括两方面的内容,一个是语音识别(speech recognition) 和语音合成(speech synthesis)。这两个技术都需要语音引擎的支持。微软推出的应用编程接口API,虽然现在不是业界标准,但是应用比较广泛。
SAPI全称 The Microsoft Speech API.相关的SRSS引擎位于Speech SDK开发包中。这个语音引擎支持多种语言的识别和朗读,包括英文、中文、日文等。
SAPI包括以下组件对象(接口):
1Voice Commands API。对应用程序进行控制,一般用于语音识别系统中。识别某个命令后,会调用相关接口是应用程序完成对应的功能。如果程序想实现语音控制,必须使用此组对象。
2Voice Dictation API。听写输入,即语音识别接口。
3Voice Text API。完成从文字到语音的转换,即语音合成。
4Voice Telephone API。语音识别和语音合成综合运用到电话系统之上,利用此接口可以建立一个电话应答系统,甚至可以通过电话控制计算机。
5Audio Objects API。封装了计算机发音系统。
SAPI是架构在COM基础上的,微软还提供了ActiveX控件,所以不仅可用于一般的windows程序,还可以用于网页、VBA甚至EXCEL的图表中。如果对COM感到陌生,还可以使用微软的C++ WRAPPERS,它用C++类封装了语音SDK COM对象。
二、安装SAPI SDK
首先从这个站点下载开发包:www.microsoft/speech/download/sdk51
Microsoft Speech SDK 5.1添加了Automation支持。所以可以在VB,ECMAScript等支持Automation的语言中使用。
版本说明:
Version: 5.1
发布日期: 8/8/2001
语音: English
下载尺寸: 2.0 MB - 288.8 MB
这个SDK开发包还包括了可以随便发布的英文和中文的语音合成引擎(TTS),和英文、中文、日文的语音识别引擎(SR)
系统要求98以上版本。编译开发包中的例子程序需要vc6以上环境。
******下载说明******
1)如果要下载例子程序,说明文档,SAPI以及用于开发的美国英语语音引擎,需要下载,大约68M
2)如果想要使用简体中文和日文的语音引擎,需要下载。大约82M
3)如果想要和自己的软件一起发布语音引擎,需要下载,大约132M
    (在这个地址,我未能成功下载)。
4)如果要获取XP下的 Mike Mary 语音,下载。大约3.5M
5)如果要获取开发包的文档说明,请下载sapi.chm。大约2.3M。这个在sdk51里面已经包含。
下载完毕后,首先安装,然后安装中文语言补丁包SpeechSDK51LangPack,然后展开
msttss22l,自动将所需dll安装到系统目录。
三、配置vc环境
vc6.0的环境下编译语音工程,首先要配置编译环境。假设sdk安装在d:\Microsoft Speech SDK 5.1\路径下,打开工程设置对话框,在c/c++栏中选择Preprocessor分类,然后在"附加包含路径"中输入
d:\Microsoft Speech SDK 5.1\include
告诉vc编译程序所需的SAPI头文件的位置。
然后切换到LINK栏,在Input分类下的附加库路径中输入:
d:\Microsoft Speech SDK 5.1\lib\i386
使vc在链接的时候能够到sapi.lib
四、语音合成的应用。即使用SAPI实现TTS(Text to Speech)
1、首先要初始化语音接口,一般有两种方式:
  ISpVoice* pVoice;
  ::CoInitialize(NULL);
  HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice,
              (void **)&pVoice);
  然后就可以使用这个指针调用SAPI函数了,例如
  pVoice->SetVolume(50);//设置音量
  pVoice->Speak(str.AllocSysString(),SPF_ASYNC,NULL);
  另外也可以使用如下方式:
    CComPtr<ISpVoice>  m_cpVoice;
    HRESULT hr = m_cpVoice.CoCreateInstance( CLSID_SpVoice );
  在下面的例子中都用这个m_cpVoice变量。
  CLSID_SpVoice的定义位于SPAI.H中。
2、获取/设置输出频率。
  SAPI朗读文字的时候,可以采用多种频率方式输出声音,比如:
  8kHz 8Bit Mono8kHz 8Bit Stereo44kHz 16Bit Mono44kHz 16Bit Stereo等。在音调上有所差别。具体可以参考sapi.h
  可以使用如下代码获取当前的配置:
  CComPtr<ISpStreamFormat> cpStream;
  HRESULT hrOutputStream = m_cpVoice->GetOutputStream(&cpStream);
  if (hrOutputStream == S_OK)
  {
      CSpStreamFormat Fmt;
      hr = Fmt.AssignFormat(cpStream);
      if (SUCCEEDED(hr))
      {sdk
          SPSTREAMFORMAT eFmt = Fmt.ComputeFormatEnum();
      }
  }
    SPSTREAMFORMAT 是一个ENUM类型,定义位于SPAI.H中。每一个值对应了不同的频率设置。例如 SPSF_8kHz8BitStereo = 5
    通过如下代码设置当前朗读频率:
    CComPtr<ISpAudio>  m_cpOutAudio; //声音输出接口
    SpCreateDefaultObjectFromCategoryId( SPCAT_AUDIOOUT, &m_cpOutAudio ); //创建接口
    SPSTREAMFORMAT eFmt = 21; //SPSF_22kHz 8Bit Stereo
    CSpStreamFormat Fmt;
    Fmt.AssignFormat(eFmt);
    if ( m_cpOutAudio )
    {
hr = m_cpOutAudio->SetFormat( Fmt.FormatId(), Fmt.WaveFormatExPtr() );
    }
    else hr = E_FAIL;
    if( SUCCEEDED( hr ) )
  {
      m_cpVoice->SetOutput( m_cpOutAudio, FALSE );
  }
3、获取/设置播放所用语音。
  引擎中所用的语音数据文件一般保存在SpeechEngines下的spd或者vce文件中。安装sdk后,在注册表中保存了可用的语音,比如英文的男/女,简体中文的男音等。位置是:
  HKEY_LOCAL_MACHINE\Software\Microsoft\Speech\Voices\Tokens
如果安装在中文操作系统下,则缺省所用的朗读语音是简体中文。SAPI的缺点是不能支持
中英文混读,在朗读中文的时候,遇到英文,只能逐个字母读出。所以需要程序自己进行语音切换。
(1) 可以采用如下的函数把当前SDK支持的语音填充在一个组合框中:
    // SAPI5 helper function in sphelper.h
    HWND hWndCombo = GetDlgItem( hWnd, IDC_COMBO_VOICES ); //组合框句柄
    HRESULT hr = SpInitTokenComboBox( hWndCombo , SPCAT_VOICES );
    这个函数是通过IEnumSpObjectTokens接口枚举当前可用的语音接口,把接口的说明文字添加到组合框中,并且把接口的指针作为LPARAM
    保存在组合框中。
    一定要记住最后程序退出的时候,释放组合框中保存的接口:
    SpDestroyTokenComboBox( hWndCombo );
    这个函数的原理就是逐个取得combo里面每一项的LPARAM数据,转换成IUnknown接口指针,然后调用Release函数。
(2) 当组合框选择变化的时候,可以用下面的函数获取用户选择的语音:
    ISpObjectToken* pToken = SpGetCurSelComboBoxToken( hWndCombo );
(3) 用下面的函数获取当前正在使用的语音:
    CComPtr<ISpObjectToken> pOldToken;
    HRESULT hr = m_cpVoice->GetVoice( &pOldToken );
(4) 当用户选择的语音和当前正在使用的不一致的时候,用下面的函数修改:
    if (pOldToken != pToken)
    {       
        // 首先结束当前的朗读,这个不是必须的。
        HRESULT hr = m_cpVoice->Speak( NULL, SPF_PURGEBEFORESPEAK, 0);
        if (SUCCEEDED (hr) )
        {
            hr = m_cpVoice->SetVoice( pToken );
        }
    }
(5) 也可以直接使用函数SpGetTokenFromId获取指定voiceToken指针,例如:
      WCHAR pszTokenId[] = L"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Speech\\V
oices\\Tokens\\MSSimplifiedChineseVoice";
    SpGetTokenFromId(pszTokenID , &pChineseToken);
4、开始/暂停/恢复/结束当前的朗读
 
  要朗读的文字必须位于宽字符串中,假设位于szWTextString中,则:
  开始朗读的代码:
  hr = m_cpVoice->Speak( szWTextString, SPF_ASYNC | SPF_IS_NOT_XML, 0 );
  如果要解读一个XML文本,用:
  hr = m_cpVoice->Speak( szWTextString, SPF_ASYNC | SPF_IS_XML, 0 );

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。