mirror of
https://github.com/Gigaslav/HL2Overcharged.git
synced 2026-01-02 17:48:11 +03:00
276 lines
7.6 KiB
C++
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;
|
|
}
|
|
|