Files
HL2Overcharged/utils/sapi51/Tools/Comp/TTS/audiostate.cpp
2025-05-21 21:20:08 +03:00

276 lines
7.6 KiB
C++

//******************************************************************************
// Copyright (c) Microsoft Corporation. All rights reserved.
// audiostate.cpp
//
//******************************************************************************
#include "TTSComp.h"
//******************************************************************************
//***** Internal Functions
//******************************************************************************
inline HRESULT SpGetLanguageFromVoiceToken(ISpObjectToken * pToken, LANGID * plangid)
{
HRESULT hr = S_OK;
CComPtr<ISpDataKey> cpDataKeyAttribs;
hr = pToken->OpenKey(L"Attributes", &cpDataKeyAttribs);
CSpDynamicString dstrLanguage;
if (SUCCEEDED(hr))
{
hr = cpDataKeyAttribs->GetStringValue(L"Language", &dstrLanguage);
}
LANGID langid;
if (SUCCEEDED(hr))
{
if (!swscanf(dstrLanguage, L"%hx", &langid))
{
hr = E_UNEXPECTED;
}
}
if (SUCCEEDED(hr))
{
*plangid = langid;
}
SPDBG_REPORT_ON_FAIL(hr);
return hr;
} /* SpGetLanguageFromVoiceToken */
HRESULT SpGetLanguageIdFromDefaultVoice(LANGID *plangid)
{
HRESULT hr = S_OK;
CComPtr<ISpObjectToken> cpVoiceToken;
LANGID langid;
// Find the best voice
if( SUCCEEDED( hr ) )
{
hr = SpGetDefaultTokenFromCategoryId( SPCAT_VOICES, &cpVoiceToken );
}
if( SUCCEEDED( hr ) )
{
hr = SpGetLanguageFromVoiceToken(cpVoiceToken, &langid);
}
*plangid = langid;
return hr;
}
HRESULT GetWStrFromRes( UINT id, WCHAR* szwStr, int cchBufferMax )
{
HRSRC hResInfo = NULL;
HANDLE hStringSeg = NULL;
LPWSTR lpsz = NULL;
int cch = 0;
HRESULT hr = S_OK;
LANGID Language;
hr = SpGetLanguageIdFromDefaultVoice(&Language);
if (FAILED (hr ) )
return hr;
// String Tables are broken up into 16 string segments. Find the segment
// containing the string we are interested in.
if (hResInfo = FindResourceExW( g_pShellInfo->hLib, (LPCWSTR)RT_STRING,
MAKEINTRESOURCEW(((USHORT)id >> 4) + 1),
Language) )
{
// Load that segment.
hStringSeg = LoadResource( g_pShellInfo->hLib, hResInfo );
// Lock the resource.
if( lpsz = (LPWSTR)LockResource(hStringSeg) )
{
// Move past the other strings in this segment.
// (16 strings in a segment -> & 0x0F)
id &= 0x0F;
while( TRUE )
{
cch = *((WORD *)lpsz++); // PASCAL like string count
// first UTCHAR is count if TCHARs
if (id-- == 0) break;
lpsz += cch; // Step to start if next string
}
// Account for the NULL
cchBufferMax--;
// Don't copy more than the max allowed.
if (cch > cchBufferMax)
cch = cchBufferMax-1;
// Copy the string into the buffer.
CopyMemory( szwStr, lpsz, cch*sizeof(WCHAR) );
// Attach Null terminator.
szwStr[cch] = 0;
}
}
return cch ? S_OK : HRESULT_FROM_WIN32(ERROR_RESOURCE_NAME_NOT_FOUND);
}
//******************************************************************************
//***** TestProc()'s
//******************************************************************************
/*****************************************************************************/
//*************************************************************************************
TESTPROCAPI t_SpeakStop(UINT uMsg, TPPARAM tpParam, LPFUNCTION_TABLE_ENTRY lpFTE)
{
// This test uses the default audio object to speak pause and speak a stream. It checks
// to make sure a TTS engine is paying attention to these states by stopping the stream
// part way through and counting the number of word events ( these must be less than the
// total number in the string.
// Message check
if (uMsg != TPM_EXECUTE)
{
return TPR_NOT_HANDLED;
}
HRESULT hr = S_OK;
int tpr = TPR_PASS;
CComPtr<ISpVoice> cpLocalVoice;
// Create the SAPI voice
DOCHECKHRGOTO (hr = cpLocalVoice.CoCreateInstance( CLSID_SpVoice ););
tpr = t_SpeakStop_Test(uMsg, tpParam, lpFTE, cpLocalVoice, false);
EXIT:
return tpr;
}
/*****************************************************************************/
TESTPROCAPI t_SpeakStop_Test(UINT uMsg,
TPPARAM tpParam,
LPFUNCTION_TABLE_ENTRY lpFTE,
ISpVoice *cpVoice,
bool bCalledByMulti)
{
// Message check
if (uMsg != TPM_EXECUTE)
{
return TPR_NOT_HANDLED;
}
HRESULT hr = S_OK;
int tpr = TPR_PASS;
int cEventsReceived = 0;
WCHAR szwSpeakStr[MAX_PATH]=L"";
CSpEvent Event;
hr = cpVoice->SetOutput(NULL, TRUE);
CHECKHRGOTOId( hr, tpr, IDS_STRING60);
//clean up the event queue.
while (Event.GetFrom(cpVoice) == S_OK);
DOCHECKHRGOTO (hr = cpVoice->SetNotifyWin32Event(););
DOCHECKHRGOTO ( hr = cpVoice->SetInterest( SPFEI(SPEI_WORD_BOUNDARY), SPFEI(SPEI_WORD_BOUNDARY) ); );
DOCHECKHRGOTO ( hr = GetWStrFromRes( IDS_STRING1, szwSpeakStr ););
hr = cpVoice->Speak( szwSpeakStr, SPF_ASYNC, NULL );
CHECKHRGOTOId( hr, tpr, IDS_STRING13);
//wait for the first word boundry event
hr = cpVoice->WaitForNotifyEvent(TTS_WAITTIME);
if (bCalledByMulti )
{
//In Multi threaded case
CHECKHRGOTOIdEx( hr, tpr, IDS_STRING62, " t_SpeakStop_Test");
}
else
{
//normal case
CHECKASSERTGOTOIdEx( (hr == S_OK), tpr, IDS_STRING62, " t_SpeakStop_Test");
}
Sleep (500);
//purges all data, close the audio and set action flag to SPVES_ABORT
hr = cpVoice->Speak( NULL, SPF_PURGEBEFORESPEAK, 0 );
CHECKHRGOTOId( hr, tpr, IDS_STRING13);
hr = cpVoice->WaitUntilDone( TTS_WAITTIME_LONG );
if (!bCalledByMulti )
{
CHECKASSERTGOTOIdEx( (hr == S_OK), tpr, IDS_STRING61, " t_SpeakStop_Test");
}
else
{
CHECKHRIdEx( hr, tpr, IDS_STRING61, " t_SpeakStop_Test");
}
while (S_OK == hr )
{
hr = Event.GetFrom(cpVoice);
if( hr == S_OK )
{
// count how many word boundry events we got
cEventsReceived++;
}
}
//Make sure the entire first speak call did not finish
//Note - The sentence contains 20 words, so normally we can receive 20 word
//boundary events.
CHECKASSERTId(( cEventsReceived < 20 ), tpr, IDS_STRING5);
// Logging info
CHECKHRId( hr, tpr, IDS_STRING5 );
EXIT:
return tpr;
}
//*************************************************************************************
TESTPROCAPI t_SpeakDestroy(UINT uMsg, TPPARAM tpParam, LPFUNCTION_TABLE_ENTRY lpFTE)
{
// This test starts a long Speak call and destroys the stream before completion. It
// expects engines to clean-up correctly and not fault.
// Message check
if (uMsg != TPM_EXECUTE)
{
return TPR_NOT_HANDLED;
}
HRESULT hr = S_OK;
int tpr = TPR_PASS;
CComPtr<ISpVoice> cpVoice;
WCHAR szwSpeakStr[MAX_PATH]=L"";
WCHAR szwDebug[MAX_PATH]=L"";
// Create the SAPI voice
DOCHECKHRGOTO (hr = cpVoice.CoCreateInstance( CLSID_SpVoice ););
//get the bookmark string
DOCHECKHRGOTO (hr = GetWStrFromRes( IDS_STRING6, szwSpeakStr ););
hr = cpVoice->Speak( szwSpeakStr, SPF_ASYNC, NULL );
CHECKHRGOTOId( hr, tpr, IDS_STRING13);
cpVoice.Release();
// Logging info
CHECKHRId( hr, tpr, IDS_STRING7 );
EXIT:
return tpr;
}