mirror of
https://github.com/cheat-engine/cheat-engine
synced 2026-08-15 02:26:08 -04:00
382 lines
13 KiB
ObjectPascal
Executable file
382 lines
13 KiB
ObjectPascal
Executable file
unit winsapi;
|
|
|
|
{
|
|
partial sapi.h conversion for the syntesized voice functions
|
|
|
|
https://www.w3.org/TR/speech-synthesis/
|
|
|
|
works:
|
|
<?xml version="1.0"?>
|
|
<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:schemaLocation="http://www.w3.org/2001/10/synthesis
|
|
http://www.w3.org/TR/speech-synthesis/synthesis.xsd"
|
|
xml:lang="en-US">
|
|
|
|
hello
|
|
</speak>
|
|
|
|
this wil freeze it(for a too long time)
|
|
<?xml version="1.0"?>
|
|
<!DOCTYPE speak PUBLIC "-//W3C//DTD SYNTHESIS 1.0//EN"
|
|
"http://www.w3.org/TR/speech-synthesis/synthesis.dtd">
|
|
<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis"
|
|
xml:lang="en-US">
|
|
|
|
hello
|
|
</speak>
|
|
|
|
}
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
{$ifdef windows}
|
|
|
|
uses
|
|
windows, Classes, SysUtils, ole2, variants, ActiveX, comobj;
|
|
|
|
function speak(s: widestring; waittilldone: boolean=false): HRESULT; overload;
|
|
function speak(s: widestring; flags: dword): HRESULT; overload;
|
|
|
|
const
|
|
CLSID_SpVoice: TGUID = (D1:$96749377;D2:$3391;D3:$11D2;D4:($9e,$e3,$00,$c0,$4f,$79,$73,$96));
|
|
|
|
SPF_DEFAULT = 0;
|
|
SPF_ASYNC = ( 1 shl 0 );
|
|
SPF_PURGEBEFORESPEAK = ( 1 shl 1 );
|
|
SPF_IS_FILENAME = ( 1 shl 2 ) ;
|
|
SPF_IS_XML = ( 1 shl 3 ) ;
|
|
SPF_IS_NOT_XML = ( 1 shl 4 );
|
|
SPF_PERSIST_XML = ( 1 shl 5 );
|
|
SPF_NLP_SPEAK_PUNC = ( 1 shl 6 );
|
|
SPF_PARSE_SAPI = ( 1 shl 7 );
|
|
SPF_PARSE_SSML = ( 1 shl 8 );
|
|
SPF_PARSE_AUTODETECT = 0;
|
|
SPF_NLP_MASK = SPF_NLP_SPEAK_PUNC;
|
|
SPF_PARSE_MASK = ( SPF_PARSE_SAPI or SPF_PARSE_SSML );
|
|
SPF_VOICE_MASK = ( ( ( ( ( ( ( SPF_ASYNC or SPF_PURGEBEFORESPEAK ) or SPF_IS_FILENAME ) or SPF_IS_XML ) or SPF_IS_NOT_XML ) or SPF_NLP_MASK ) or SPF_PERSIST_XML ) or SPF_PARSE_MASK );
|
|
SPF_UNUSED_FLAGS = not SPF_VOICE_MASK;
|
|
|
|
|
|
|
|
|
|
type
|
|
SPVPRIORITY=(SPVPRI_NORMAL=0, SPVPRI_ALERT=1, SPVPRI_OVER=2);
|
|
SPEVENTENUM=(SPEI_UNDEFINED = 0,
|
|
SPEI_START_INPUT_STREAM = 1,
|
|
SPEI_END_INPUT_STREAM = 2,
|
|
SPEI_VOICE_CHANGE = 3,
|
|
SPEI_TTS_BOOKMARK = 4,
|
|
SPEI_WORD_BOUNDARY = 5,
|
|
SPEI_PHONEME = 6,
|
|
SPEI_SENTENCE_BOUNDARY = 7,
|
|
SPEI_VISEME = 8,
|
|
SPEI_TTS_AUDIO_LEVEL = 9,
|
|
SPEI_TTS_PRIVATE = 15,
|
|
SPEI_MIN_TTS = 1,
|
|
SPEI_MAX_TTS = 15,
|
|
SPEI_END_SR_STREAM = 34,
|
|
SPEI_SOUND_START = 35,
|
|
SPEI_SOUND_END = 36,
|
|
SPEI_PHRASE_START = 37,
|
|
SPEI_RECOGNITION = 38,
|
|
SPEI_HYPOTHESIS = 39,
|
|
SPEI_SR_BOOKMARK = 40,
|
|
SPEI_PROPERTY_NUM_CHANGE = 41,
|
|
SPEI_PROPERTY_STRING_CHANGE = 42,
|
|
SPEI_FALSE_RECOGNITION = 43,
|
|
SPEI_INTERFERENCE = 44,
|
|
SPEI_REQUEST_UI = 45,
|
|
SPEI_RECO_STATE_CHANGE = 46,
|
|
SPEI_ADAPTATION = 47,
|
|
SPEI_START_SR_STREAM = 48,
|
|
SPEI_RECO_OTHER_CONTEXT = 49,
|
|
SPEI_SR_AUDIO_LEVEL = 50,
|
|
SPEI_SR_RETAINEDAUDIO = 51,
|
|
SPEI_SR_PRIVATE = 52,
|
|
SPEI_ACTIVE_CATEGORY_CHANGED = 53,
|
|
SPEI_RESERVED5 = 54,
|
|
SPEI_RESERVED6 = 55,
|
|
SPEI_MIN_SR = 34,
|
|
SPEI_MAX_SR = 55,
|
|
SPEI_RESERVED1 = 30,
|
|
SPEI_RESERVED2 = 33,
|
|
SPEI_RESERVED3 = 63);
|
|
|
|
|
|
|
|
SPEVENT=record
|
|
eEventId: WORD;
|
|
elParamType: WORD;
|
|
ulStreamNum: ULONG;
|
|
ullAudioStreamOffset: ULONGLONG;
|
|
wParam: wParam;
|
|
lParam: lParam;
|
|
end;
|
|
PSPEVENT=^SPEVENT;
|
|
|
|
SPEVENTSOURCEINFO=record
|
|
ullEventInterest: ULONGLONG;
|
|
ullQueuedInterest: ULONGLONG;
|
|
ulCount: ULONG;
|
|
end;
|
|
PSPEVENTSOURCEINFO=^SPEVENTSOURCEINFO;
|
|
|
|
SPVOICESTATUS = record
|
|
ulCurrentStream: ULONG;
|
|
ulLastStreamQueued: ULONG;
|
|
hrLastResult: HRESULT;
|
|
dwRunningState: DWORD;
|
|
ulInputWordPos: ULONG;
|
|
ulInputWordLen: ULONG;
|
|
ulInputSentPos: ULONG;
|
|
ulInputSentLen: ULONG;
|
|
lBookmarkId: LONG;
|
|
PhonemeId: WORD;
|
|
VisemeId: WORD;
|
|
dwReserved1: DWORD;
|
|
dwReserved2: DWORD;
|
|
end;
|
|
|
|
|
|
SPNOTIFYCALLBACK=procedure(wParam: WPARAM; lParam: LPARAM); stdcall;
|
|
|
|
ISpDataKey = interface (IUnknown)
|
|
['{14056581-E16C-11D2-BB90-00C04F8EE6C0}']
|
|
{
|
|
virtual HRESULT STDMETHODCALLTYPE SetData(
|
|
/* [in] */ LPCWSTR pszValueName,
|
|
/* [in] */ ULONG cbData,
|
|
/* [in] */ const BYTE *pData) = 0;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetData(
|
|
/* [in] */ LPCWSTR pszValueName,
|
|
/* [in] */ ULONG *pcbData,
|
|
/* [out] */ BYTE *pData) = 0;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE SetStringValue(
|
|
/* [in][annotation] */
|
|
_In_opt_ LPCWSTR pszValueName,
|
|
/* [in] */ LPCWSTR pszValue) = 0;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetStringValue(
|
|
/* [in][annotation] */
|
|
_In_opt_ LPCWSTR pszValueName,
|
|
/* [out][annotation] */
|
|
_Outptr_ LPWSTR *ppszValue) = 0;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE SetDWORD(
|
|
/* [in] */ LPCWSTR pszValueName,
|
|
/* [in] */ DWORD dwValue) = 0;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetDWORD(
|
|
/* [in] */ LPCWSTR pszValueName,
|
|
/* [out] */ DWORD *pdwValue) = 0;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE OpenKey(
|
|
/* [in] */ LPCWSTR pszSubKeyName,
|
|
/* [out][annotation] */
|
|
_Outptr_ ISpDataKey **ppSubKey) = 0;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE CreateKey(
|
|
/* [in] */ LPCWSTR pszSubKey,
|
|
/* [out][annotation] */
|
|
_Outptr_ ISpDataKey **ppSubKey) = 0;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE DeleteKey(
|
|
/* [in] */ LPCWSTR pszSubKey) = 0;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE DeleteValue(
|
|
/* [in] */ LPCWSTR pszValueName) = 0;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE EnumKeys(
|
|
/* [in] */ ULONG Index,
|
|
/* [out][annotation] */
|
|
_Outptr_ LPWSTR *ppszSubKeyName) = 0;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE EnumValues(
|
|
/* [in] */ ULONG Index,
|
|
/* [out][annotation] */
|
|
_Outptr_ LPWSTR *ppszValueName) = 0;
|
|
}
|
|
end;
|
|
|
|
ISpObjectToken = interface (ISpDataKey)
|
|
['{14056589-E16C-11D2-BB90-00C04F8EE6C0}']
|
|
{
|
|
virtual HRESULT STDMETHODCALLTYPE SetId(
|
|
/* [annotation] */
|
|
_In_opt_ LPCWSTR pszCategoryId,
|
|
/* [in] */ LPCWSTR pszTokenId,
|
|
/* [in] */ BOOL fCreateIfNotExist) = 0;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetId(
|
|
/* [out][annotation] */
|
|
_Outptr_ LPWSTR *ppszCoMemTokenId) = 0;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetCategory(
|
|
/* [out][annotation] */
|
|
_Outptr_ ISpObjectTokenCategory **ppTokenCategory) = 0;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE CreateInstance(
|
|
/* [in] */ IUnknown *pUnkOuter,
|
|
/* [in] */ DWORD dwClsContext,
|
|
/* [in] */ REFIID riid,
|
|
/* [iid_is][out] */ void **ppvObject) = 0;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetStorageFileName(
|
|
/* [in] */ REFCLSID clsidCaller,
|
|
/* [annotation][in] */
|
|
_In_ LPCWSTR pszValueName,
|
|
/* [string][in][annotation] */
|
|
_In_opt_ LPCWSTR pszFileNameSpecifier,
|
|
/* [in] */ ULONG nFolder,
|
|
/* [out][annotation] */
|
|
_Outptr_ LPWSTR *ppszFilePath) = 0;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE RemoveStorageFileName(
|
|
/* [in] */ REFCLSID clsidCaller,
|
|
/* [in][annotation] */
|
|
_In_ LPCWSTR pszKeyName,
|
|
/* [in] */ BOOL fDeleteFile) = 0;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE Remove(
|
|
/* [annotation] */
|
|
_In_opt_ const CLSID *pclsidCaller) = 0;
|
|
|
|
virtual /* [local] */ HRESULT STDMETHODCALLTYPE IsUISupported(
|
|
/* [in] */ LPCWSTR pszTypeOfUI,
|
|
/* [in] */ void *pvExtraData,
|
|
/* [in] */ ULONG cbExtraData,
|
|
/* [in] */ IUnknown *punkObject,
|
|
/* [out] */ BOOL *pfSupported) = 0;
|
|
|
|
virtual /* [local] */ HRESULT STDMETHODCALLTYPE DisplayUI(
|
|
/* [in] */ HWND hwndParent,
|
|
/* [in] */ LPCWSTR pszTitle,
|
|
/* [in] */ LPCWSTR pszTypeOfUI,
|
|
/* [in] */ void *pvExtraData,
|
|
/* [in] */ ULONG cbExtraData,
|
|
/* [in] */ IUnknown *punkObject) = 0;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE MatchesAttributes(
|
|
/* [in] */ LPCWSTR pszAttributes,
|
|
/* [out] */ BOOL *pfMatches) = 0;
|
|
|
|
}
|
|
end;
|
|
|
|
PISpObjectToken = ^ISpObjectToken;
|
|
|
|
ISpStreamFormat = interface(IStream)
|
|
['{BED530BE-2606-4F4D-A1C0-54C5CDA5566F}']
|
|
function GetFormat(pguidFormatId: GUID; out ppCoMemWaveFormatEx: TWAVEFORMATEX): HRESULT; stdcall;
|
|
end;
|
|
|
|
PISpStreamFormat = ^ISpStreamFormat;
|
|
|
|
ISpNotifySink = interface (IUnknown)
|
|
['{259684DC-37C3-11D2-9603-00C04F8EE628}']
|
|
function Notify: HRESULT; stdcall;
|
|
end;
|
|
|
|
ISpNotifySource = interface (IUnknown)
|
|
['{5EFF4AEF-8487-11D2-961C-00C04F8EE628}']
|
|
function SetNotifySink(NotifySink: ISpNotifySink): HRESULT; stdcall;
|
|
function SetNotifyWindowMessage(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): HRESULT; stdcall;
|
|
function SetNotifyCallbackFunction(pfnCallback: SPNOTIFYCALLBACK; wParam: WPARAM; lParam: LPARAM): HRESULT; stdcall;
|
|
function SetNotifyCallbackInterface(pSpCallback: pointer; wParam: WPARAM; lParam: LPARAM): HRESULT; stdcall;
|
|
function SetNotifyWin32Event: HRESULT; stdcall;
|
|
function WaitForNotifyEvent(dwMilliseconds: DWORD): HRESULT; stdcall;
|
|
function GetNotifyEventHandle: HANDLE; stdcall;
|
|
end;
|
|
|
|
ISpEventSource = interface (ISpNotifySource)
|
|
['{BE7A9CCE-5F9E-11D2-960F-00C04F8EE628}']
|
|
function SetInterest(ullEventInterest: ULONGLONG; ullQueuedInterest: ULONGLONG): HRESULT; stdcall;
|
|
function GetEvents(ulCount: ULONG; pEventArray: PSPEVENT; out pulFetched: ULONG): HRESULT; stdcall;
|
|
function GetInfo(pInfo: PSPEVENTSOURCEINFO): HRESULT; stdcall;
|
|
end;
|
|
|
|
ISpVoice = Interface (ISpEventSource)
|
|
['{6C44DF74-72B9-4992-A1EC-EF996E0422D4}']
|
|
function SetOutput(pUnkOutput: IUnknown; fAllowFormatChanges: BOOL): HRESULT; stdcall;
|
|
function GetOutputObjectToken(out ppObjectToken: ISpObjectToken): HRESULT; stdcall;
|
|
function GetOutputStream(out ppStream: ISpStreamFormat): HRESULT; stdcall;
|
|
function Pause: HRESULT; stdcall;
|
|
function Resume: HRESULT; stdcall;
|
|
function SetVoice(pToken: ISpObjectToken): HRESULT; stdcall;
|
|
function GetVoice(out pToken: ISpObjectToken): HRESULT; stdcall;
|
|
function Speak(pwcs: PWCHAR; dwFlags: DWORD; pulStreamNumber: PULONG): HRESULT; stdcall;
|
|
function SpeakStream(pStream: IStream; dwFlags: DWORD; pulStreamNumber: PULONG): HRESULT; stdcall;
|
|
|
|
function GetStatus(out pStatus: SPVOICESTATUS; out ppszLastBookmark: pwchar): HRESULT; stdcall;
|
|
function Skip(pItemType: LPCWSTR; lNumItems: long; out ulNumSkipped: ULONG): HRESULT; stdcall;
|
|
|
|
function SetPriority(ePriority: SPVPRIORITY): HRESULT; stdcall;
|
|
function GetPriority(out ePriority: SPVPRIORITY): HRESULT; stdcall;
|
|
|
|
function SetAlertBoundary(ePriority: SPEVENTENUM): HRESULT; stdcall;
|
|
function GetAlertBoundary(out ePriority: SPEVENTENUM): HRESULT; stdcall;
|
|
|
|
function SetRate(RateAdjust: long): HRESULT; stdcall;
|
|
function GetRate(out RateAdjust: long): HRESULT; stdcall;
|
|
|
|
function SetVolume(RateAdjust: USHORT): HRESULT; stdcall;
|
|
function GetVolume(out RateAdjust: USHORT): HRESULT; stdcall;
|
|
|
|
function WaitUntilDone(msTimeout: ULONG): HRESULT; stdcall;
|
|
function SetSyncSpeakTimeout(msTimeout: ULONG): HRESULT; stdcall;
|
|
function GetSyncSpeakTimeout(out msTimeout: ULONG): HRESULT; stdcall;
|
|
|
|
function SpeakCompleteEvent: HRESULT; stdcall;
|
|
function IsUISupported(pszTypeOfUI: LPCWSTR; pvExtraData: pointer; cbExtraData: ULONG; out fSupported: BOOL): HRESULT; stdcall;
|
|
function DisplayUI(hwndParent: HWND; pszTitle: LPCWSTR; pszTypeOfUI: LPCWSTR; pvExtraData: pointer; cbExtraData: ULONG): HRESULT; stdcall;
|
|
end;
|
|
|
|
{$endif}
|
|
|
|
implementation
|
|
{$ifdef windows}
|
|
var
|
|
voice: ISpVoice;
|
|
novoice: boolean=false;
|
|
|
|
function speak(s: widestring; flags: dword): HRESULT;
|
|
var
|
|
sn: ulong;
|
|
begin
|
|
{
|
|
for c users reading this code, and wondering why I don't call _release.
|
|
FPC will call _Release automatically when the reference count is nil
|
|
}
|
|
if not assigned(voice) then
|
|
begin
|
|
try
|
|
voice:=CreateComObject(CLSID_SpVoice) as ISpVoice;
|
|
except
|
|
exit(-1);
|
|
end;
|
|
end;
|
|
|
|
if assigned(voice) then
|
|
result:=voice.Speak(pwchar(s), flags, nil);
|
|
end;
|
|
|
|
|
|
function speak(s: widestring; waitTillDone: boolean=false): HRESULT; overload;
|
|
var flags: dword;
|
|
begin
|
|
flags:=SPF_PURGEBEFORESPEAK;
|
|
if not waittilldone then
|
|
flags:=flags or SPF_ASYNC;
|
|
|
|
result:=speak(s, flags);
|
|
end;
|
|
|
|
{$endif}
|
|
|
|
end.
|
|
|