那里有mstts的详细资料 兄弟们请支援一下下

c20000c 2003-09-12 11:01:41
mstts 即
microsoft text to speech
...全文
73 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
cymlife 2003-09-18
  • 打赏
  • 举报
回复
格式看起来很烂,可是在VC的编辑器里很好的。
cymlife 2003-09-18
  • 打赏
  • 举报
回复
实现部分:

// This is the constructor of a class that has been exported.
// see CMTTSEngine.h for the class definition
CCMTTSEngine::CCMTTSEngine()
{
m_bPause = FALSE; // pause audio?
m_bStop = TRUE; // stop audio?

m_uVolume = 0; // default volume
m_lRate = 0; // default rate
m_nFormatIndex = 0; // default output format

m_nTotolTTSEngine = 0;
m_nCurrentEngine = 0;
memset(m_TTSEngine, 0, sizeof(TTSEngine)*NUM_OUTPUTFORMATS);
}

CCMTTSEngine::~CCMTTSEngine()
{
}

HRESULT CCMTTSEngine::Init()
{
HRESULT hr = S_OK;

// Load COM
if (FAILED(CoInitialize(NULL)))
return hr;

hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&m_cpVoice);

// Get default output format index
if (SUCCEEDED(hr))
{
CComPtr<ISpStreamFormat> cpStream;
HRESULT hrOutputStream = m_cpVoice->GetOutputStream(&cpStream);

if (hrOutputStream == S_OK)
{
CSpStreamFormat Fmt;
hr = Fmt.AssignFormat(cpStream);
if (SUCCEEDED(hr))
{
SPSTREAMFORMAT eFmt = Fmt.ComputeFormatEnum();
for (int i = 0; i<NUM_OUTPUTFORMATS; i++ )
{
if (g_aOutputFormat[i] == eFmt )
{
m_nFormatIndex = i;
break;
}
}
}
}
}

// Get all token engine
if (SUCCEEDED(hr))
{
ISpObjectToken * pToken; // NOTE: Not a CComPtr! Be Careful.
CComPtr<IEnumSpObjectTokens> cpEnum;
hr = SpEnumTokens(SPCAT_VOICES, NULL, NULL, &cpEnum);
if (hr == S_OK)
{
bool fSetDefault = false;
while (cpEnum->Next(1, &pToken, NULL) == S_OK)
{
CSpDynamicString dstrDesc;
hr = SpGetDescription(pToken, &dstrDesc);
if (SUCCEEDED(hr))
{
USES_CONVERSION;

if (m_nTotolTTSEngine < NUM_OUTPUTFORMATS)
{
m_TTSEngine[m_nTotolTTSEngine].pSpObjectToken = pToken;
strcpy(m_TTSEngine[m_nTotolTTSEngine].chEngineName, W2T(dstrDesc));
m_nTotolTTSEngine++;
}
else
hr = E_OUTOFMEMORY;
}

if (FAILED(hr))
{
pToken->Release();
}
}
}
else
{
hr = SPERR_NO_MORE_ITEMS;
}
}

// Get default output format
if (SUCCEEDED(hr))
SpCreateDefaultObjectFromCategoryId(SPCAT_AUDIOOUT, &m_cpOutAudio);

// set current voice
VoiceChange();

// Get default rate
if (SUCCEEDED(hr))
hr = m_cpVoice->GetRate(&m_lRate);

// Get default volume
if (SUCCEEDED(hr))
hr = m_cpVoice->GetVolume(&m_uVolume);

return hr;
}

HRESULT CCMTTSEngine::Cleanup()
{
HRESULT hr = S_OK;

for (int i = 0; i < m_nTotolTTSEngine; i++)
{
if (m_TTSEngine[i].pSpObjectToken != NULL)
m_TTSEngine[i].pSpObjectToken->Release();
}

if (m_cpVoice)
m_cpVoice->Release();

if (m_cpOutAudio)
m_cpOutAudio->Release();

// Unload COM
CoUninitialize();

return hr;
}

void CCMTTSEngine::Stop()
{
HRESULT hr = S_OK;
if (m_cpVoice == NULL)
return;

// Stop current rendering with a PURGEBEFORESPEAK...
hr = m_cpVoice->Speak( NULL, SPF_PURGEBEFORESPEAK, 0 );

if( FAILED( hr ) )
{
}

m_bPause = FALSE;
m_bStop = TRUE;
}

HRESULT CCMTTSEngine::VoiceChange()
{
HRESULT hr = S_OK;
if (m_nCurrentEngine >= m_nTotolTTSEngine)
return hr;

if (m_cpVoice == NULL)
return hr;

GUID* pguidAudioFormat = NULL;
int iFormat = 0;

// Get the token associated with the selected voice

ISpObjectToken* pToken = m_TTSEngine[m_nCurrentEngine].pSpObjectToken;

//Determine if it is the current voice
CComPtr<ISpObjectToken> pOldToken;
hr = m_cpVoice->GetVoice( &pOldToken );

if (SUCCEEDED(hr))
{
if (pOldToken != pToken)
{
// Stop speaking. This is not necesary, for the next call to work,
// but just to show that we are changing voices.
hr = m_cpVoice->Speak( NULL, SPF_PURGEBEFORESPEAK, 0);
// And set the new voice on the global voice object
if (SUCCEEDED (hr) )
{
hr = m_cpVoice->SetVoice( pToken );
}
}
}

return hr;
}

void CCMTTSEngine::SetEngine(int nIndex)
{
if (m_cpVoice == NULL)
return;

if (nIndex < 0 || nIndex >= m_nTotolTTSEngine)
return;

if (m_nCurrentEngine == nIndex)
return;

m_nCurrentEngine = nIndex;

VoiceChange();
}

void CCMTTSEngine::SetVolume(USHORT uVolume)
{
if (m_cpVoice == NULL)
return;

if (uVolume < SPMIN_VOLUME || uVolume > SPMAX_VOLUME)
return;

if (m_uVolume == uVolume)
return;

m_uVolume = uVolume;

HRESULT hr = S_OK;
hr = m_cpVoice->SetVolume(m_uVolume);
}

void CCMTTSEngine::SetRate(long lRate)
{
if (m_cpVoice == NULL)
return;

if (lRate < SPMIN_RATE || lRate > SPMAX_RATE)
return;

if (m_lRate == lRate)
return;

m_lRate = lRate;

HRESULT hr = S_OK;
hr = m_cpVoice->SetRate(m_lRate);
}

void CCMTTSEngine::SetFormatIndex(int nFormatIndex)
{
if (nFormatIndex < 0 || nFormatIndex >= NUM_OUTPUTFORMATS)
return;

if (m_nFormatIndex == nFormatIndex)
return;

if (m_cpVoice == NULL || m_cpOutAudio == NULL)
return;

m_nFormatIndex = nFormatIndex;

HRESULT hr = S_OK;

SPSTREAMFORMAT eFmt = g_aOutputFormat[m_nFormatIndex];

CSpStreamFormat Fmt;
Fmt.AssignFormat(eFmt);
if ( m_cpOutAudio )
hr = m_cpOutAudio->SetFormat( Fmt.FormatId(), Fmt.WaveFormatExPtr() );

if( SUCCEEDED( hr ) )
{
hr = m_cpVoice->SetOutput( m_cpOutAudio, FALSE );
}
}

void CCMTTSEngine::SpeakText(char* pText)
{
if (m_cpVoice == NULL)
return;

Stop();

if (strlen(pText) <= 0)
return;

HRESULT hr = S_OK;
m_bStop = FALSE;

// only get the string if we're not paused
if( !m_bPause )
{
memset(m_szWTextString, 0, sizeof(WCHAR)*MAX_TEXTLEN);

MultiByteToWideChar( CP_ACP, 0, pText, strlen(pText), m_szWTextString, MAX_TEXTLEN);

// do we speak or interpret the XML
hr = m_cpVoice->Speak(m_szWTextString, SPF_ASYNC | SPF_IS_NOT_XML, 0);

if( FAILED( hr ) )
{
}
}
m_bPause = FALSE;
// Set state to run
hr = m_cpVoice->Resume();
}

/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
cymlife 2003-09-18
  • 打赏
  • 举报
回复
我写的,不知道有没有用:

#ifndef __CMTTSENGINE_H
#define __CMTTSENGINE_H

#include <atlbase.h> // ATL
extern CComModule _Module;
#include <atlcom.h>
#include <sapi.h> // SAPI includes
#include <sphelper.h>
#include <spuihelp.h>

////////////////////////////////////////////////////////////////
#pragma comment(lib, "sapi.lib")

////////////////////////////////////////////////////////////////
#define NUM_OUTPUTFORMATS 36
#define MAX_TEXTLEN 64*1024 // 64K
////////////////////////////////////////////////////////////////
// for get all Engine
struct TTSEngine{
ISpObjectToken* pSpObjectToken;
char chEngineName[MAX_PATH];
};

////////////////////////////////////////////////////////////////
class CCMTTSEngine {
public:
CCMTTSEngine();
~CCMTTSEngine();

public:
HRESULT Init();
HRESULT Cleanup();
void Stop();
HRESULT VoiceChange();

int GetEnginesCount() { return m_nTotolTTSEngine; }

char* GetEngine(int nIndex)
{
if (nIndex < m_nTotolTTSEngine)
return m_TTSEngine[nIndex].chEngineName;

return NULL;
}

USHORT GetVolume() { return m_uVolume; }
long GetRate() { return m_lRate; }
int GetFormatIndex() { return m_nFormatIndex; }

void SetEngine(int nIndex);
void SetVolume(USHORT uVolume);
void SetRate(long lRate);
void SetFormatIndex(int nFormatIndex);

void SpeakText(char* pText);

protected:
ISpVoice* m_cpVoice;
ISpAudio* m_cpOutAudio;
BOOL m_bPause;
BOOL m_bStop;

USHORT m_uVolume;
long m_lRate;
int m_nFormatIndex;

WCHAR m_szWTextString[MAX_TEXTLEN];

protected:
TTSEngine m_TTSEngine[NUM_OUTPUTFORMATS];
int m_nTotolTTSEngine;

int m_nCurrentEngine;
};
#endif
c20000c 2003-09-12
  • 打赏
  • 举报
回复
谢谢 弥弥兄
看过了 没有提供更详细的函数之类的东东 :(
比如说速度,角色等..
akiko 2003-09-12
  • 打赏
  • 举报
回复
http://www.ctiforum.com/forum/2003/08/forum03_0812.htm

2,586

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 资源
社区管理员
  • 资源
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧