Obtain an ISpVoice
//
// 2003 Glenn Slayden
// Obtain an ISpVoice corresponding to a given multimedia output device id. Uses SAPI subsystem. Works on
// Windows XP. Microsoft documentation tries to force your to use the higher-level Agent API for
// text-to-speech (only Windows CE docs remain on MSDN for SAPI), but you don't need it. For header
// files, install SAPI 5.1 SDK, or... required files are included with Visual Studio .NET
//
// typical caller usage:
//
// HRESULT hr = GetDeviceVoice(0,&pVoice);
// if (SUCCEEDED(hr))
// {
// pVoice->SetRate(-2);
//
// BSTR bs = SysAllocString(L"Who ever heard of a computer which speaks?");
// hr = pVoice->Speak(bs, 0, NULL);
// SysFreeString(bs);
// pVoice->Release();
// }
//
#define _UNICODE
#include "windows.h"
#include "sapi.h"
#include "sphelper.h"
HRESULT GetDeviceVoice(UINT dev,ISpVoice **ppout)
{
if (!ppout)
return E_POINTER;
*ppout = NULL;
ISpVoice *pVoice = NULL;
HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
if (FAILED(hr))
return hr;
ISpObjectTokenCategory *cpSpCategory;
if (SUCCEEDED(hr = SpGetCategoryFromId(SPCAT_AUDIOOUT, &cpSpCategory)))
{
IEnumSpObjectTokens *cpSpEnumTokens;
if (SUCCEEDED(hr = cpSpCategory->EnumTokens(NULL, NULL, &cpSpEnumTokens)))
{
ISpObjectToken *pSpTok;
if (SUCCEEDED(hr = cpSpEnumTokens->Item(dev,&pSpTok)))
{
pVoice->SetOutput(pSpTok,FALSE);
pSpTok->Release();
}
cpSpEnumTokens->Release();
}
cpSpCategory->Release();
}
if (hr==NOERROR)
*ppout = pVoice;
return hr;
}