www.pudn.com > HMRspeech.rar > TextToSpeech.cpp, change:2009-11-02,size:5265b


// TextToSpeech.cpp: implementation of the TextToSpeech class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "speech.h" 
#include "TextToSpeech.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CTextToSpeech::CTextToSpeech() 
{ 
	m_IpVoice = NULL; 
	m_sError=_T(""); 
} 
 
CTextToSpeech::~CTextToSpeech() 
{ 
	Destroy(); 
} 
 
BOOL CTextToSpeech::Initialize(HWND hWnd) 
{ 
	if (FAILED(CoInitialize(NULL))) 
	{ 
		m_sError=_T("Error intialization COM"); 
		return FALSE; 
	} 
 
	HRESULT hr = m_IpVoice.CoCreateInstance(CLSID_SpVoice); 
	if (FAILED(hr)) 
	{ 
		m_sError=_T("Error creating voice"); 
		return FALSE; 
	} 
	hr = m_IpVoice->SetInterest(SPFEI(SPEI_VISEME), SPFEI(SPEI_VISEME)); 
	if (FAILED(hr)) 
	{ 
		m_sError=_T("Error creating interest...seriously"); 
		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; 
		} 
	} 
	return TRUE; 
} 
 
void CTextToSpeech::Destroy() 
{ 
	if (m_IpVoice) 
		m_IpVoice.Release(); 
	CoUninitialize(); 
} 
 
HRESULT CTextToSpeech::Speak(const WCHAR *pwcs, DWORD dwFlags) 
{ 
	return m_IpVoice->Speak(pwcs, dwFlags, NULL); 
} 
 
HRESULT CTextToSpeech::Pause() 
{ 
	return m_IpVoice->Pause(); 
} 
 
HRESULT CTextToSpeech::Resume() 
{ 
	return m_IpVoice->Resume(); 
} 
 
// rate 
HRESULT CTextToSpeech::SetRate(long lRateAdjust) 
{ 
	return m_IpVoice->SetRate(lRateAdjust); 
} 
 
HRESULT CTextToSpeech::GetRate(long* plRateAdjust) 
{ 
	return m_IpVoice->GetRate(plRateAdjust); 
} 
 
// volume 
HRESULT CTextToSpeech::SetVolume(USHORT usVolume) 
{ 
	return m_IpVoice->SetVolume(usVolume); 
} 
 
HRESULT CTextToSpeech::GetVolume(USHORT* pusVolume) 
{ 
	return m_IpVoice->GetVolume(pusVolume); 
} 
 
ULONG CTextToSpeech::GetVoiceCount() 
{ 
	HRESULT hr = S_OK; 
	CComPtr<ISpObjectToken> cpVoiceToken; 
	CComPtr<IEnumSpObjectTokens> cpEnum; 
	ULONG ulCount = -1; 
	//Enumerate the available voices 
	hr = SpEnumTokens(SPCAT_VOICES, NULL, NULL, &cpEnum); 
	if(FAILED(hr)) 
	{ 
		m_sError = _T("Error to enumerate voices"); 
		return -1; 
	} 
	//Get the number of voices 
	hr = cpEnum->GetCount(&ulCount); 
	if(FAILED(hr)) 
	{m_sError = _T("Error to get voice count"); 
	return -1; 
	} 
	return ulCount; 
} 
HRESULT CTextToSpeech::GetVoice(WCHAR **ppszDescription, ULONG lIndex) 
{ 
	HRESULT hr = S_OK; 
	CComPtr<ISpObjectToken> cpVoiceToken; 
	CComPtr<IEnumSpObjectTokens> cpEnum; 
	ULONG ulCount = 0; 
	if (lIndex == -1) 
	{ 
		// current voice 
		// 
		hr = m_IpVoice->GetVoice(&cpVoiceToken); 
		if(FAILED(hr)) 
		{ 
			m_sError = _T("Error to get current voice"); 
			return hr; 
		} 
		SpGetDescription(cpVoiceToken, ppszDescription); 
		if(FAILED(hr)) 
		{ 
			m_sError = _T("Error to get current voice description"); 
			return hr; 
		} 
	} 
	else 
	{ 
		// else other voices, we should enumerate the voice list first 
		// 
		//Enumerate the available voices 
		hr = SpEnumTokens(SPCAT_VOICES, NULL, NULL, &cpEnum); 
		if(FAILED(hr)) 
		{ 
			m_sError = _T("Error to enumerate voices"); 
			return hr; 
		} 
		//Get the number of voices 
		hr = cpEnum->GetCount(&ulCount); 
		if(FAILED(hr)) 
		{ 
			m_sError = _T("Error to voice count"); 
			return hr; 
		} 
		// range control 
		ASSERT(lIndex >= 0); 
		ASSERT(lIndex < ulCount); 
		// Obtain specified voice id 
		ULONG l = 0; 
		while (SUCCEEDED(hr)) 
		{ 
			cpVoiceToken.Release(); 
			hr = cpEnum->Next( 1, &cpVoiceToken, NULL ); 
			if(FAILED(hr)) 
			{ 
				m_sError = _T("Error to get voice token"); 
				return hr; 
			} 
			if (l == lIndex) 
			{ 
				hr = SpGetDescription(cpVoiceToken, ppszDescription); 
				if(FAILED(hr)) 
				{ 
					m_sError = _T("Error to get voice description"); 
					return hr; 
				} 
				break; 
			} 
			l++; 
		} 
	} 
	return hr; 
} 
HRESULT CTextToSpeech::SetVoice(WCHAR **ppszDescription) 
{ 
	HRESULT hr = S_OK; 
	CComPtr<ISpObjectToken> cpVoiceToken; 
	CComPtr<IEnumSpObjectTokens> cpEnum; 
	ULONG ulCount = 0; 
	//Enumerate the available voices 
	hr = SpEnumTokens(SPCAT_VOICES, NULL, NULL, &cpEnum); 
	if(FAILED(hr)) 
	{ 
		m_sError = _T("Error to enumerate voices"); 
		return hr; 
	} 
	//Get the number of voices 
	hr = cpEnum->GetCount(&ulCount); 
	if(FAILED(hr)) 
	{ 
		m_sError = _T("Error to voice count"); 
		return hr; 
	} 
	// Obtain specified voice id 
	while (SUCCEEDED(hr) && ulCount--) 
	{ 
		cpVoiceToken.Release(); 
		hr = cpEnum->Next( 1, &cpVoiceToken, NULL ); 
		if(FAILED(hr)) 
		{ 
			m_sError = _T("Error to voice token"); 
			return hr; 
		} 
		WCHAR *pszDescription1; 
		hr = SpGetDescription(cpVoiceToken, &pszDescription1); 
		if(FAILED(hr)) 
		{ 
			m_sError = _T("Error to get voice description"); 
			return hr; 
		} 
		if (! wcsicmp(pszDescription1, *ppszDescription)) 
		{ 
			hr = m_IpVoice->SetVoice(cpVoiceToken); 
			if(FAILED(hr)) 
			{ 
				m_sError = _T("Error to set voice"); 
				return hr; 
			} 
			break; 
		} 
	} 
	return hr; 
}