ATL COM组件 SPEECH5.0语音播放和识别(文本到语音、语音到文本)

来源:互联网 发布:淘宝云客服试题及答案 编辑:程序博客网 时间:2024/04/29 05:56

基于SPEECH5.0的语音组件,需要相应开发包联合编译
// speechX.h : CspeechX 的声明

#pragma once
#include "resource.h"       // 主符号


// IspeechX
[
 object,
 uuid("25246261-2CD8-4D9C-AC51-D5184D1572C4"),
 dual, helpstring("IspeechX 接口"),
 pointer_default(unique)
]
__interface IspeechX : IDispatch
{
 [id(1), helpstring("方法Read")] HRESULT Read(BSTR text);
 [propget, id(2), helpstring("属性 HearedWord")] HRESULT HearedWord([out, retval] BSTR* pVal);
 [id(3), helpstring("方法StartH")] HRESULT StartH(void);

 [propget, id(4), helpstring("属性 IsHearing")] HRESULT IsHearing([out, retval] BOOL* pVal);
};

 

// CspeechX

[
 coclass,
 threading("apartment"),
 vi_progid("speech.speechX"),
 progid("speech.speechX.1"),
 version(1.0),
 uuid("D72932F4-000C-4EF7-BAD4-FC5F616CD9E3"),
 helpstring("speechX Class")
]
class ATL_NO_VTABLE CspeechX :
 public IspeechX
{

private:
  //朗读
  CComPtr<ISpVoice>   m_cpVoice;
  //上下文 
  CComPtr<ISpRecoContext> cpRecoCtxt;
  //语法分析
     CComPtr<ISpRecoGrammar> cpGrammar;
   //语音结果  
     CComPtr<ISpRecoResult> cpResult;
    
  //听到的单词
  _bstr_t m_hear;
     //朗读的单词
  _bstr_t m_text;
  //退出接收标志
  BOOL m_quitflag;
  //结果
  HRESULT                 hr;
    public:
 CspeechX()
 {
     
 
      m_hear=L"对话开始";
      m_quitflag=false;

 }


 DECLARE_PROTECT_FINAL_CONSTRUCT()

 HRESULT FinalConstruct()
 {
  return S_OK;
 }
 
 void FinalRelease()
 {
     m_cpVoice.Release();
     cpRecoCtxt.Release();
     cpGrammar.Release();
     cpResult.Release();
 }
protected:
 inline HRESULT BlockForResult (ISpRecoContext * pRecoCtxt, ISpRecoResult ** ppResult);


public:

 STDMETHOD(Read)(BSTR text);
 HRESULT read(WCHAR* path);
 STDMETHOD(get_HearedWord)(BSTR* pVal);
 
 STDMETHOD(StartH)(void);

 STDMETHOD(get_IsHearing)(BOOL* pVal);
};
------------------------------------------
// speechX.cpp : CspeechX 的实现

#include "stdafx.h"
#include "speechX.h"
#include "sphelper.h"

// CspeechX


STDMETHODIMP CspeechX::Read(BSTR text)
{
   m_text=text;
      read( (WCHAR *)m_text );
      //释放BSTR,调试时误用
      SysFreeString(text);
  return S_OK;
}

STDMETHODIMP CspeechX::StartH(void)
{
   m_quitflag=true;
   hr = cpRecoCtxt.CoCreateInstance(CLSID_SpSharedRecoContext);
 
  //设置上下文      
            if (cpRecoCtxt &&
                SUCCEEDED(hr = cpRecoCtxt->SetNotifyWin32Event()) &&
                SUCCEEDED(hr = cpRecoCtxt->SetInterest(SPFEI(SPEI_RECOGNITION), SPFEI(SPEI_RECOGNITION))) &&
                SUCCEEDED(hr = cpRecoCtxt->SetAudioOptions(SPAO_RETAIN_AUDIO, NULL, NULL)) &&
                SUCCEEDED(hr = cpRecoCtxt->CreateGrammar(0, &cpGrammar)) &&
                SUCCEEDED(hr = cpGrammar->LoadDictation(NULL, SPLO_STATIC)) &&
                SUCCEEDED(hr = cpGrammar->SetDictationState(SPRS_ACTIVE)))
            {
                                           
            if (SUCCEEDED(hr = BlockForResult(cpRecoCtxt, &cpResult)))
            {
                    cpGrammar->SetDictationState( SPRS_INACTIVE );

                    WCHAR* dstrText;

                    if (SUCCEEDED(cpResult->GetText(SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE,
                                                    TRUE, &dstrText, NULL)))
                    {   m_hear= dstrText;
   
                        cpResult.Release();
                    }
                    
    cpGrammar->SetDictationState(SPRS_ACTIVE);

                }
           
     cpRecoCtxt.Release();
              cpGrammar.Release();
              cpResult.Release();
   }

    m_quitflag=false;
  
 return S_OK;
}


HRESULT CspeechX::read(WCHAR* path)
{
 

    hr = m_cpVoice.CoCreateInstance( CLSID_SpVoice );
    m_cpVoice->Speak(path, 0, NULL);
    m_cpVoice.Release();

 

 return S_OK;
}

//收到信息接口
STDMETHODIMP CspeechX::get_HearedWord(BSTR* pVal)
{
 * pVal=m_hear;

 return S_OK;
}

 


//将上下文填充进结果
inline HRESULT CspeechX::BlockForResult(ISpRecoContext * pRecoCtxt, ISpRecoResult ** ppResult)
{
    HRESULT hr = S_OK;
 CSpEvent event;

    while (SUCCEEDED(hr) &&
           SUCCEEDED(hr = event.GetFrom(pRecoCtxt)) &&
           hr == S_FALSE)
    {
        hr = pRecoCtxt->WaitForNotifyEvent(INFINITE);
    }

    *ppResult = event.RecoResult();
    if (*ppResult)
    {
        (*ppResult)->AddRef();
    }

    return hr;
}

 

 


STDMETHODIMP CspeechX::get_IsHearing(BOOL* pVal)
{
 * pVal=m_quitflag;

 return S_OK;
}