头文件定义(CSpeechSpeekImpl.h):
#pragma once
#include "sphelper.h"
class CSpeechSpeekImpl
{
public:
CSpeechSpeekImpl(void);
~CSpeechSpeekImpl(void);
HRESULT SpeechVoice(LPCSTR lpszVoiceText, UINT bSyn=TRUE);
HRESULT SetVolume(USHORT usVolume);
HRESULT MakeWavFile(LPCTSTR lpszVoiceText, LPCTSTR lpszWaveFile);
private:
ISpVoice* m_pVoice;
BOOL Inited();
void EnumVoicePackage();
};
源码实现(CSpeechSpeekImpl.cpp):
#include "StdAfx.h"
#include "SpeechSpeekImpl.h"
#include "sapi.h"
#pragma comment(lib,"sapi.lib")
CSpeechSpeekImpl::CSpeechSpeekImpl(void)
{
m_pVoice = NULL;
CoInitialize(NULL);
Inited();
}
CSpeechSpeekImpl::~CSpeechSpeekImpl(void)
{
if ( m_pVoice )
m_pVoice->Release();
CoUninitialize();
}
BOOL CSpeechSpeekImpl::Inited()
{
//初始化COM
if ( m_pVoice == NULL )
{
//初始化SAPI
HRESULT hr = CoCreateInstance(CLSID_SpVoice,
NULL,
CLSCTX_ALL,
IID_ISpVoice,
(void **)&m_pVoice);
ISpObjectToken * pSpObjectToken = NULL;
if (SUCCEEDED(SpFindBestToken(SPCAT_VOICES,
L"language=804",
NULL,
&pSpObjectToken)))//804代表中文
{
m_pVoice->SetVoice(pSpObjectToken);//声音大小
m_pVoice->SetRate(-8);//设置朗读速度(取值范围:-10到10)
pSpObjectToken->Release();
}
else
{
return FALSE;
}
}
if ( m_pVoice == NULL )
return FALSE;
return TRUE;
}
HRESULT CSpeechSpeekImpl::SpeechVoice(LPCSTR lpszVoiceText, UINT bSyn/*=TRUE*/)
{
if ( !Inited() )
return E_FAIL;
//朗读文字
CString strText = __T(lpszVoiceText);
BSTR lpwszVoiceText = strText.AllocSysString();
m_pVoice->SetRate(2); //设置朗读速度(取值范围:-10到10)
HRESULT hr = m_pVoice->Speak(lpwszVoiceText, SPF_ASYNC, NULL);
SysFreeString(lpwszVoiceText);
return S_OK;
}
HRESULT CSpeechSpeekImpl::SetVolume(USHORT usVolume)
{
if ( !Inited() )
return E_FAIL;
return m_pVoice->SetVolume(usVolume);// m_pVoice->SetVolume(usVolume);
}
//生成WAV文件
HRESULT CSpeechSpeekImpl::MakeWavFile(LPCTSTR lpszVoiceText, LPCTSTR lpszWaveFile)
{
if ( !Inited() )
return E_FAIL;
CComPtr<ISpStream> cpISpStream;
CComPtr<ISpStreamFormat> cpISpStreamFormat;
CSpStreamFormat spStreamFormat;
m_pVoice->GetOutputStream(&cpISpStreamFormat);
spStreamFormat.AssignFormat(cpISpStreamFormat);
HRESULT hResult = SPBindToFile(lpszWaveFile,
SPFM_CREATE_ALWAYS,
&cpISpStream,
&spStreamFormat.FormatId(),
spStreamFormat.WaveFormatExPtr());
if(SUCCEEDED(hResult))
{
m_pVoice->SetOutput(cpISpStream, TRUE);
CString strText = __T(lpszVoiceText);
BSTR lpwszVoiceText = strText.AllocSysString();
m_pVoice->SetRate(2);
m_pVoice->Speak(lpwszVoiceText, SPF_DEFAULT, NULL);
SysFreeString(lpwszVoiceText);
return S_OK;
}
else
{
return E_FAIL;
}
}
void CSpeechSpeekImpl::EnumVoicePackage()
{
//初始化COM组件
if (FAILED(::CoInitialize(NULL)))
return;
//枚举所有语音Token
IEnumSpObjectTokens* pIEnumSpObjectTokens = NULL;
if(SUCCEEDED(SpEnumTokens(SPCAT_VOICES, NULL, NULL, &pIEnumSpObjectTokens)))
{
//得到所有语音Token的个数
ULONG ulTokensNumber = 0;
pIEnumSpObjectTokens->GetCount(&ulTokensNumber);
//检测该机器是否安装有语音包
if (ulTokensNumber == 0)
return;
//将语音包的名字加入组合框控件
CString strVoicePackageName = _T("");
CString strTokenPrefixText = _T("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\Voices\\Tokens\\");
for(ULONG i=0; i<ulTokensNumber; i++)
{
ISpObjectToken* pISpObjectToken = NULL;
pIEnumSpObjectTokens->Item(i, &pISpObjectToken);
WCHAR* pChar;
pISpObjectToken->GetId(&pChar);
strVoicePackageName = pChar;
strVoicePackageName.Delete(0, strTokenPrefixText.GetLength());
}
//设置语言
// ISpObjectToken *pISpObjectToken = NULL;
// pIEnumSpObjectTokens->Item(1, &pISpObjectToken);
// m_pVoice->SetVoice(pISpObjectToken);
// pISpObjectToken->Release();
pIEnumSpObjectTokens->Release();
}
}