www.pudn.com > ruier_TTS_SR(vc6).rar > Text2Speech.cpp


// Text2Speech.cpp : 实现文件 
// 
 
#include "stdafx.h" 
#include "TTS_SR.h" 
#include "Text2Speech.h" 
#include "TTDLG.h" 
 
// CText2Speech 
 
CText2Speech::CText2Speech() 
{ 
    m_IpVoice = NULL; 
    m_sError=_T(""); 
} 
 
CText2Speech::~CText2Speech() 
{ 
    Destroy(); 
} 
 
 
 
// CText2Speech 成员函数 
CString CText2Speech::GetErrorString() 
{ 
	return m_sError; 
} 
//初始化函数Initialize首先初始化COM库,并调用CoCreateInstance方法初始化语音引擎。然后设置必须响应的引擎事件,并指定响应事件消息的窗口句柄。该窗口句柄是作为函数的参数传入的,此方法应在初始化窗口之后再调用 
bool CText2Speech::Initialize(HWND hWnd,int nIDDlgItem) 
{ 
   if (FAILED(CoInitialize(NULL)))  
   { 
          m_sError=_T("Error intialization COM"); 
          return false; 
	   } 
   HRESULT hr;   
   hr = m_IpVoice.CoCreateInstance(CLSID_SpVoice); 
   if (FAILED(hr))  
	   { 
          m_sError=_T("Error creating voice"); 
          return false; 
   } 
   hr = m_IpVoice->SetInterest(SPFEI(SPEI_WORD_BOUNDARY), SPFEI(SPEI_WORD_BOUNDARY));  
   if (FAILED(hr))  
   { 
         m_sError=_T("Error creating interest"); 
         return false; 
   } 
   if (::IsWindow(hWnd)) 
   { 
       hr = m_IpVoice->SetNotifyWindowMessage(hWnd, WM_TTSEVENT, 0, 0); 
       if (FAILED(hr))  
       { 
        m_sError=_T("Error setting notification window"); 
        return false; 
       } 
	   hr =initVoiceList(hWnd,nIDDlgItem); 
	    if (FAILED(hr))  
       { 
        m_sError=_T("Error init comboBox for window"); 
        return false; 
       } 
   } 
   hw=hWnd; 
   return true; 
} 
 
//释放函数则释放语音引擎接口和COM库 
 
void CText2Speech::Destroy() 
{ 
    if (m_IpVoice)  
            m_IpVoice.Release(); 
			SpDestroyTokenComboBox(hw); 
    CoUninitialize(); 
} 
 
//语音、语速、音量函数都是通过m_IpVoice成员直接调用ISpVoice接口的相关方法来实现的 
 
HRESULT CText2Speech::Speak(const  WCHAR *pwcs, DWORD dwFlags) 
{ 
    return m_IpVoice->Speak(pwcs, dwFlags, NULL); 
} 
 
HRESULT CText2Speech::Stop() 
{ 
	return m_IpVoice->Speak( NULL, SPF_PURGEBEFORESPEAK, 0); 
} 
 
HRESULT CText2Speech::Pause() 
{ 
    return m_IpVoice->Pause(); 
} 
 
  
 
HRESULT CText2Speech::Resume() 
{ 
    return m_IpVoice->Resume(); 
} 
 
  
 
// 设置播放速率 
 
HRESULT CText2Speech::SetRate(long lRateAdjust) 
{ 
    return m_IpVoice->SetRate(lRateAdjust); 
} 
 
  
 
HRESULT CText2Speech::GetRate(long* plRateAdjust) 
{ 
    return m_IpVoice->GetRate(plRateAdjust); 
} 
 
  
 
//设置音量 
 
HRESULT CText2Speech::SetVolume(USHORT usVolume) 
{ 
    return m_IpVoice->SetVolume(usVolume); 
} 
 
  
 
HRESULT CText2Speech::GetVolume(USHORT* pusVolume) 
{ 
    return m_IpVoice->GetVolume(pusVolume); 
} 
 
HRESULT CText2Speech::initVoiceList(HWND hWnd,int nIDDlgItem) 
{ 
	HRESULT hr = 0; 
 
 
	// Use the SAPI5 helper function in sphelper.h to initialize the Voice combo box. 
    if ( SUCCEEDED( hr ) ) 
    { 
        hr = SpInitTokenComboBox(GetDlgItem(hWnd,nIDDlgItem),SPCAT_VOICES); 
    } 
	return hr; 
} 
 
ULONG CText2Speech::GetVoiceCount() 
 
{ 
 
    HRESULT hr = S_OK; 
    CComPtr cpVoiceToken; 
    CComPtr cpEnum; 
    ULONG ulCount = -1; 
    //枚举已有的发音者 
    hr = SpEnumTokens(SPCAT_VOICES, NULL, NULL, &cpEnum); 
    if(FAILED(hr)) 
    { 
        m_sError = _T("Error to enumerate voices"); 
        return -1; 
    } 
    //获得已有的发音者数 
    hr = cpEnum->GetCount(&ulCount); 
    if(FAILED(hr)) 
    { 
        m_sError = _T("Error to get voice count"); 
        return -1; 
    } 
    return ulCount; 
} 
 
HRESULT CText2Speech::SetVoice(HWND hWnd,int nIDDlgItem) 
{ 
    HRESULT hr = S_OK; 
 
	hr = m_IpVoice->SetVoice(SpGetCurSelComboBoxToken(GetDlgItem(hWnd,nIDDlgItem))); 
    if(FAILED(hr)) 
    { 
        m_sError = _T("Error to set voice"); 
        return hr; 
    } 
    return hr; 
} 
 
 
 
 
LRESULT CText2Speech::PrcEvent(WPARAM wParam, LPARAM lParam,CWnd* cw,int len) 
{ 
	WPARAM	nStart; 
    LPARAM	nEnd; 
	CSpEvent event;   
    while (event.GetFrom(m_IpVoice) == S_OK) { 
        switch (event.eEventId) { 
            case SPEI_WORD_BOUNDARY: 
				{ 
					HRESULT hr = m_IpVoice->GetStatus( &Stat, NULL ); 
					if( FAILED( hr ) ) 
				 { 
                		m_sError=_T("Error getting Status"); 
					} 
				     nStart = (LPARAM)( Stat.ulInputWordPos / sizeof(char) ); 
					 nEnd = nStart + Stat.ulInputWordLen; 
					 if(nEnd>=(len+1)) 	{((CTTDLG*)cw)->OnButtonStartTt() ;return 0;}; 
					 SendDlgItemMessage( cw->m_hWnd, IDC_EDIT_TT, EM_SETSEL, nStart, nEnd ); 
					 break; 
				} 
			case SPEI_END_INPUT_STREAM:  
			    
				break; 
 
        } 
    } 
	return 0; 
}