{*******************************************************}
{                                                       }
{       nrCommLib Communication Library for Delphi      }
{       TextToSpeech API Declaration                    }
{       Copyright (c) 1997-2011 Roman Novgorodov        }
{       v9.27                                           }
{       last update: 22 Feb 2009                        }
{                                                       }
{       e-mail:noro@deepsoftware.com                    }
{       DeepSoftware                                    }
{       http://www.deepsoftware.com/                    }
{                                                       }
{*******************************************************}
{$I nrcommlib.inc}

unit nrsapi;

interface

Const
  CLASS_SpVoice: TGUID                  = '{96749377-3391-11D2-9EE3-00C04F797396}';
  CLASS_SpMemoryStream: TGUID           = '{5FB7EF7D-DFF4-468A-B6B7-2FCBD188F994}';
  IID_IEnumSpObjectTokens: TGUID        = '{06B64F9E-7FDA-11D2-B4F2-00C04F797396}';
  CLSID_SpObjectTokenCategory: TGUID    = '{A910187F-0C7A-45AC-92CC-59EDAFB77B53}';

  SPCAT_VOICES:WideString = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices';

  SPF_ASYNC = 1;

  {$IFNDEF GEN6}
  S_OK = 0;                             
  {$ENDIF}

Type

  {$IFDEF GEN3}
  Int64=array[0..1]of integer;
  HRESULT = type Longint;
  {$ENDIF}

  LongWord = longint;
  TOleEnum = type LongWord;

  SYSUINT = cardinal;
  UINT_PTR = cardinal;
  LONG_PTR = integer;
  PPPrivateAlias1 = ^Pointer; {*}
  Largeuint = int64;

  _LARGE_INTEGER = packed record
    QuadPart: Int64;
  end;

  _ULARGE_INTEGER = packed record
    QuadPart: Largeuint;
  end;

  PWord1 = ^Word; {*}
  PByte1 = ^Byte; {*}
  PUINT1 = ^LongWord; {*}
  PPWord1 = ^PWord1; {*}

  SpeechDataKeyLocation = TOleEnum;
  SpeechTokenContext    = TOleEnum;
  SpeechTokenShellFolder = TOleEnum;
  SPDATAKEYLOCATION = TOleEnum;
  SPVISEMES = TOleEnum;
  SPVPRIORITY = TOleEnum;
  SPEVENTENUM = TOleEnum;
  SpeechRunState = TOleEnum;
  SpeechVoiceEvents = TOleEnum;
  SpeechVoicePriority = TOleEnum;
  SpeechVoiceSpeakFlags = TOleEnum;

Type
  SpeechAudioFormatType = TOleEnum;
const
  SAFTDefault                   = $FFFFFFFF;
  SAFTNoAssignedFormat          = $00000000;
  SAFTText                      = $00000001;
  SAFTNonStandardFormat         = $00000002;
  SAFTExtendedAudioFormat       = $00000003;
  SAFT8kHz8BitMono              = $00000004;
  SAFT8kHz8BitStereo            = $00000005;
  SAFT8kHz16BitMono             = $00000006;
  SAFT8kHz16BitStereo           = $00000007;
  SAFT11kHz8BitMono             = $00000008;
  SAFT11kHz8BitStereo           = $00000009;
  SAFT11kHz16BitMono            = $0000000A;
  SAFT11kHz16BitStereo          = $0000000B;
  SAFT12kHz8BitMono             = $0000000C;
  SAFT12kHz8BitStereo           = $0000000D;
  SAFT12kHz16BitMono            = $0000000E;
  SAFT12kHz16BitStereo          = $0000000F;
  SAFT16kHz8BitMono             = $00000010;
  SAFT16kHz8BitStereo           = $00000011;
  SAFT16kHz16BitMono            = $00000012;
  SAFT16kHz16BitStereo          = $00000013;
  SAFT22kHz8BitMono             = $00000014;
  SAFT22kHz8BitStereo           = $00000015;
  SAFT22kHz16BitMono            = $00000016;
  SAFT22kHz16BitStereo          = $00000017;
  SAFT24kHz8BitMono             = $00000018;
  SAFT24kHz8BitStereo           = $00000019;
  SAFT24kHz16BitMono            = $0000001A;
  SAFT24kHz16BitStereo          = $0000001B;
  SAFT32kHz8BitMono             = $0000001C;
  SAFT32kHz8BitStereo           = $0000001D;
  SAFT32kHz16BitMono            = $0000001E;
  SAFT32kHz16BitStereo          = $0000001F;
  SAFT44kHz8BitMono             = $00000020;
  SAFT44kHz8BitStereo           = $00000021;
  SAFT44kHz16BitMono            = $00000022;
  SAFT44kHz16BitStereo          = $00000023;
  SAFT48kHz8BitMono             = $00000024;
  SAFT48kHz8BitStereo           = $00000025;
  SAFT48kHz16BitMono            = $00000026;
  SAFT48kHz16BitStereo          = $00000027;
  SAFTTrueSpeech_8kHz1BitMono   = $00000028;
  SAFTCCITT_ALaw_8kHzMono       = $00000029;
  SAFTCCITT_ALaw_8kHzStereo     = $0000002A;
  SAFTCCITT_ALaw_11kHzMono      = $0000002B;
  SAFTCCITT_ALaw_11kHzStereo    = $0000002C;
  SAFTCCITT_ALaw_22kHzMono      = $0000002D;
  SAFTCCITT_ALaw_22kHzStereo    = $0000002E;
  SAFTCCITT_ALaw_44kHzMono      = $0000002F;
  SAFTCCITT_ALaw_44kHzStereo    = $00000030;
  SAFTCCITT_uLaw_8kHzMono       = $00000031;
  SAFTCCITT_uLaw_8kHzStereo     = $00000032;
  SAFTCCITT_uLaw_11kHzMono      = $00000033;
  SAFTCCITT_uLaw_11kHzStereo    = $00000034;
  SAFTCCITT_uLaw_22kHzMono      = $00000035;
  SAFTCCITT_uLaw_22kHzStereo    = $00000036;
  SAFTCCITT_uLaw_44kHzMono      = $00000037;
  SAFTCCITT_uLaw_44kHzStereo    = $00000038;
  SAFTADPCM_8kHzMono            = $00000039;
  SAFTADPCM_8kHzStereo          = $0000003A;
  SAFTADPCM_11kHzMono           = $0000003B;
  SAFTADPCM_11kHzStereo         = $0000003C;
  SAFTADPCM_22kHzMono           = $0000003D;
  SAFTADPCM_22kHzStereo         = $0000003E;
  SAFTADPCM_44kHzMono           = $0000003F;
  SAFTADPCM_44kHzStereo         = $00000040;
  SAFTGSM610_8kHzMono           = $00000041;
  SAFTGSM610_11kHzMono          = $00000042;
  SAFTGSM610_22kHzMono          = $00000043;
  SAFTGSM610_44kHzMono          = $00000044;

Type
  SpeechStreamSeekPositionType  = TOleEnum;
Const
  SSSPTRelativeToStart                  = $00000000;
  SSSPTRelativeToCurrentPosition        = $00000001;
  SSSPTRelativeToEnd                    = $00000002;

Type
  WaveFormatEx = packed record
    wFormatTag: Word;
    nChannels: Word;
    nSamplesPerSec: LongWord;
    nAvgBytesPerSec: LongWord;
    nBlockAlign: Word;
    wBitsPerSample: Word;
    cbSize: Word;
  end;

  __MIDL_IWinTypes_0009 = record
    case Integer of
      0: (hInproc: Integer);
      1: (hRemote: Integer);
  end;

  _RemotableHandle = packed record
    fContext: Integer;
    u: __MIDL_IWinTypes_0009;
  end;

  SPEVENT = packed record
    eEventId: Word;
    elParamType: Word;
    ulStreamNum: LongWord;
    ullAudioStreamOffset: Largeuint;
    wParam: UINT_PTR;
    lParam: LONG_PTR;
  end;

  SPEVENTSOURCEINFO = packed record
    ullEventInterest: Largeuint;
    ullQueuedInterest: Largeuint;
    ulCount: LongWord;
  end;

  _FILETIME = packed record
    dwLowDateTime: LongWord;
    dwHighDateTime: LongWord;
  end;

  tagSTATSTG = packed record
    pwcsName: PWideChar;
    Type_: LongWord;
    cbSize: _ULARGE_INTEGER;
    mtime: _FILETIME;
    ctime: _FILETIME;
    atime: _FILETIME;
    grfMode: LongWord;
    grfLocksSupported: LongWord;
    clsid: TGUID;
    grfStateBits: LongWord;
    reserved: LongWord;
  end;

  SPVOICESTATUS = packed record
    ulCurrentStream: LongWord;
    ulLastStreamQueued: LongWord;
    hrLastResult: HResult;
    dwRunningState: LongWord;
    ulInputWordPos: LongWord;
    ulInputWordLen: LongWord;
    ulInputSentPos: LongWord;
    ulInputSentLen: LongWord;
    lBookmarkId: Integer;
    PhonemeId: Word;
    VisemeId: SPVISEMES;
    dwReserved1: LongWord;
    dwReserved2: LongWord;
  end;

  //===============================================
  IEnumSpObjectTokens = interface;

  ISpDataKey = interface(IUnknown)
    ['{14056581-E16C-11D2-BB90-00C04F8EE6C0}']
    function SetData(var pszValueName: Word; cbData: LongWord; var pData: Byte): HResult; stdcall;
    function GetData(var pszValueName: Word; var pcbData: LongWord; var pData: Byte): HResult; stdcall;
    function SetStringValue(pszValueName: PWideChar; var pszValue: WideString): HResult; stdcall;
    function GetStringValue(pszValueName: PWideChar; var ppszValue: PWideChar): HResult; stdcall;
    function SetDWORD(var pszValueName: Word; dwValue: LongWord): HResult; stdcall;
    function GetDWORD(var pszValueName: Word; var pdwValue: LongWord): HResult; stdcall;
    function OpenKey(var pszSubKeyName: Word; var ppSubKey: ISpDataKey): HResult; stdcall;
    function CreateKey(var pszSubKey: Word; var ppSubKey: ISpDataKey): HResult; stdcall;
    function DeleteKey(var pszSubKey: Word): HResult; stdcall;
    function DeleteValue(var pszValueName: Word): HResult; stdcall;
    function EnumKeys(Index: LongWord; ppszSubKeyName: PPWord1): HResult; stdcall;
    function EnumValues(Index: LongWord; ppszValueName: PPWord1): HResult; stdcall;
  end;

  ISpObjectTokenCategory = interface(ISpDataKey)
    ['{2D3D3845-39AF-4850-BBF9-40B49780011D}']
    function SetId(const pszCategoryId: PWideChar; fCreateIfNotExist: boolean): HResult; stdcall;
    function GetId(out ppszCoMemCategoryId: PWord1): HResult; stdcall;
    function GetDataKey(spdkl: SPDATAKEYLOCATION; var ppDataKey: ISpDataKey): HResult; stdcall;
    function EnumTokens(pzsReqAttribs: PWideChar; pszOptAttribs: PWideChar;
                        out ppEnum: IEnumSpObjectTokens): HResult; stdcall;
    function SetDefaultTokenId(var pszTokenId: Word): HResult; stdcall;
    function GetDefaultTokenId(out ppszCoMemTokenId: PWord1): HResult; stdcall;
  end;

  ISpObjectToken = interface(ISpDataKey)
    ['{14056589-E16C-11D2-BB90-00C04F8EE6C0}']
    function SetId(var pszCategoryId: Word; var pszTokenId: Word; fCreateIfNotExist: Integer): HResult; stdcall;
    function GetId(ppszCoMemTokenId: PPWord1): HResult; stdcall;
    function GetCategory(var ppTokenCategory: ISpObjectTokenCategory): HResult; stdcall;
    function CreateInstance(const pUnkOuter: IUnknown; dwClsContext: LongWord; var riid: TGUID;
                            out ppvObject: Pointer): HResult; stdcall;
    function GetStorageFileName(var clsidCaller: TGUID; var pszValueName: Word;
                                var pszFileNameSpecifier: Word; nFolder: LongWord;
                                out ppszFilePath: PWord1): HResult; stdcall;
    function RemoveStorageFileName(var clsidCaller: TGUID; var pszKeyName: Word;
                                   fDeleteFile: Integer): HResult; stdcall;
    function Remove(var pclsidCaller: TGUID): HResult; stdcall;
    function IsUISupported(var pszTypeOfUI: Word; var pvExtraData: Pointer; cbExtraData: LongWord;
                           const punkObject: IUnknown; out pfSupported: Integer): HResult; stdcall;
    function DisplayUI(var hWndParent: _RemotableHandle; var pszTitle: Word; var pszTypeOfUI: Word;
                       var pvExtraData: Pointer; cbExtraData: LongWord; const punkObject: IUnknown): HResult; stdcall;
    function MatchesAttributes(var pszAttributes: Word; out pfMatches: Integer): HResult; stdcall;
  end;

  IEnumSpObjectTokens = interface(IUnknown)
    ['{06B64F9E-7FDA-11D2-B4F2-00C04F797396}']
    function Next(celt: LongWord; out pelt: ISpObjectToken; out pceltFetched: LongWord): HResult; stdcall;
    function Skip(celt: LongWord): HResult; stdcall;
    function Reset: HResult; stdcall;
    function Clone(out ppEnum: IEnumSpObjectTokens): HResult; stdcall;
    function Item(Index: LongWord; out ppToken: ISpObjectToken): HResult; stdcall;
    function GetCount(out pCount: LongWord): HResult; stdcall;
  end;

  //===============================================

  ISpeechDataKey = interface(IDispatch)
    ['{CE17C09B-4EFA-44D5-A4C9-59D9585AB0CD}']
    procedure SetBinaryValue(const ValueName: WideString; Value: OleVariant); safecall;
    function GetBinaryValue(const ValueName: WideString): OleVariant; safecall;
    procedure SetStringValue(const ValueName: WideString; const Value: WideString); safecall;
    function GetStringValue(const ValueName: WideString): WideString; safecall;
    procedure SetLongValue(const ValueName: WideString; Value: Integer); safecall;
    function GetLongValue(const ValueName: WideString): Integer; safecall;
    function OpenKey(const SubKeyName: WideString): ISpeechDataKey; safecall;
    function CreateKey(const SubKeyName: WideString): ISpeechDataKey; safecall;
    procedure DeleteKey(const SubKeyName: WideString); safecall;
    procedure DeleteValue(const ValueName: WideString); safecall;
    function EnumKeys(Index: Integer): WideString; safecall;
    function EnumValues(Index: Integer): WideString; safecall;
  end;

  ISpeechObjectTokens = interface;

  ISpeechObjectTokenCategory = interface(IDispatch)
    ['{CA7EAC50-2D01-4145-86D4-5AE7D70F4469}']
    function Get_Id: WideString; safecall;
    procedure Set_Default(const TokenId: WideString); safecall;
    function Get_Default: WideString; safecall;
    procedure SetId(const Id: WideString; CreateIfNotExist: WordBool); safecall;
    function GetDataKey(Location: SpeechDataKeyLocation): ISpeechDataKey; safecall;
    function EnumerateTokens(const RequiredAttributes: WideString;
                             const OptionalAttributes: WideString): ISpeechObjectTokens; safecall;
    property Id: WideString read Get_Id;
    property Default: WideString read Get_Default write Set_Default;
  end;

  ISpeechObjectToken = interface(IDispatch)
    ['{C74A3ADC-B727-4500-A84A-B526721C8B8C}']
    function Get_Id: WideString; safecall;
    function Get_DataKey: ISpeechDataKey; safecall;
    function Get_Category: ISpeechObjectTokenCategory; safecall;
    function GetDescription(Locale: Integer): WideString; safecall;
    procedure SetId(const Id: WideString; const CategoryID: WideString; CreateIfNotExist: WordBool); safecall;
    function GetAttribute(const AttributeName: WideString): WideString; safecall;
    function CreateInstance(const pUnkOuter: IUnknown; ClsContext: SpeechTokenContext): IUnknown; safecall;
    procedure Remove(const ObjectStorageCLSID: WideString); safecall;
    function GetStorageFileName(const ObjectStorageCLSID: WideString; const KeyName: WideString;
                                const FileName: WideString; Folder: SpeechTokenShellFolder): WideString; safecall;
    procedure RemoveStorageFileName(const ObjectStorageCLSID: WideString;
                                    const KeyName: WideString; DeleteFile: WordBool); safecall;
    function IsUISupported(const TypeOfUI: WideString; var ExtraData: OleVariant;
                           const Object_: IUnknown): WordBool; safecall;
    procedure DisplayUI(hWnd: Integer; const Title: WideString; const TypeOfUI: WideString;
                        var ExtraData: OleVariant; const Object_: IUnknown); safecall;
    function MatchesAttributes(const Attributes: WideString): WordBool; safecall;
    property Id: WideString read Get_Id;
    property DataKey: ISpeechDataKey read Get_DataKey;
    property Category: ISpeechObjectTokenCategory read Get_Category;
  end;

  ISpeechObjectTokens = interface(IDispatch)
    ['{9285B776-2E7B-4BC0-B53E-580EB6FA967F}']
    function Get_Count: Integer; safecall;
    function Item(Index: Integer): ISpeechObjectToken; safecall;
    function Get__NewEnum: IUnknown; safecall;
    property Count: Integer read Get_Count;
    property _NewEnum: IUnknown read Get__NewEnum;
  end;

  ISequentialStream = interface(IUnknown)
    ['{0C733A30-2A1C-11CE-ADE5-00AA0044773D}']
    function RemoteRead(out pv: Byte; cb: LongWord; out pcbRead: LongWord): HResult; stdcall;
    function RemoteWrite(var pv: Byte; cb: LongWord; out pcbWritten: LongWord): HResult; stdcall;
  end;

  ISpStreamFormat = interface;

  IStream = interface(ISequentialStream)
    ['{0000000C-0000-0000-C000-000000000046}']
    function RemoteSeek(dlibMove: _LARGE_INTEGER; dwOrigin: LongWord;
                        out plibNewPosition: _ULARGE_INTEGER): HResult; stdcall;
    function SetSize(libNewSize: _ULARGE_INTEGER): HResult; stdcall;
    function RemoteCopyTo(const pstm: ISpStreamFormat; cb: _ULARGE_INTEGER;
                          out pcbRead: _ULARGE_INTEGER; out pcbWritten: _ULARGE_INTEGER): HResult; stdcall;
    function Commit(grfCommitFlags: LongWord): HResult; stdcall;
    function Revert: HResult; stdcall;
    function LockRegion(libOffset: _ULARGE_INTEGER; cb: _ULARGE_INTEGER; dwLockType: LongWord): HResult; stdcall;
    function UnlockRegion(libOffset: _ULARGE_INTEGER; cb: _ULARGE_INTEGER; dwLockType: LongWord): HResult; stdcall;
    function Stat(out pstatstg: tagSTATSTG; grfStatFlag: LongWord): HResult; stdcall;
    function Clone(out ppstm: ISpStreamFormat): HResult; stdcall;
  end;

  PUserType1 = ^TGUID; {*}
  PUserType2 = ^WaveFormatEx; {*}
  PPUserType3 = ^PUserType2; {*}

  ISpStreamFormat = interface(IStream)
    ['{BED530BE-2606-4F4D-A1C0-54C5CDA5566F}']
    function GetFormat(var pguidFormatId: TGUID; ppCoMemWaveFormatEx: PPUserType3): HResult; stdcall;
  end;

  ISpeechVoiceStatus = interface(IDispatch)
    ['{8BE47B07-57F6-11D2-9EEE-00C04F797396}']
    function Get_CurrentStreamNumber: Integer; safecall;
    function Get_LastStreamNumberQueued: Integer; safecall;
    function Get_LastHResult: Integer; safecall;
    function Get_RunningState: SpeechRunState; safecall;
    function Get_InputWordPosition: Integer; safecall;
    function Get_InputWordLength: Integer; safecall;
    function Get_InputSentencePosition: Integer; safecall;
    function Get_InputSentenceLength: Integer; safecall;
    function Get_LastBookmark: WideString; safecall;
    function Get_LastBookmarkId: Integer; safecall;
    function Get_PhonemeId: Smallint; safecall;
    function Get_VisemeId: Smallint; safecall;
    property CurrentStreamNumber: Integer read Get_CurrentStreamNumber;
    property LastStreamNumberQueued: Integer read Get_LastStreamNumberQueued;
    property LastHResult: Integer read Get_LastHResult;
    property RunningState: SpeechRunState read Get_RunningState;
    property InputWordPosition: Integer read Get_InputWordPosition;
    property InputWordLength: Integer read Get_InputWordLength;
    property InputSentencePosition: Integer read Get_InputSentencePosition;
    property InputSentenceLength: Integer read Get_InputSentenceLength;
    property LastBookmark: WideString read Get_LastBookmark;
    property LastBookmarkId: Integer read Get_LastBookmarkId;
    property PhonemeId: Smallint read Get_PhonemeId;
    property VisemeId: Smallint read Get_VisemeId;
  end;

  ISpeechWaveFormatEx = interface(IDispatch)
    ['{7A1EF0D5-1581-4741-88E4-209A49F11A10}']
    function Get_FormatTag: Smallint; safecall;
    procedure Set_FormatTag(FormatTag: Smallint); safecall;
    function Get_Channels: Smallint; safecall;
    procedure Set_Channels(Channels: Smallint); safecall;
    function Get_SamplesPerSec: Integer; safecall;
    procedure Set_SamplesPerSec(SamplesPerSec: Integer); safecall;
    function Get_AvgBytesPerSec: Integer; safecall;
    procedure Set_AvgBytesPerSec(AvgBytesPerSec: Integer); safecall;
    function Get_BlockAlign: Smallint; safecall;
    procedure Set_BlockAlign(BlockAlign: Smallint); safecall;
    function Get_BitsPerSample: Smallint; safecall;
    procedure Set_BitsPerSample(BitsPerSample: Smallint); safecall;
    function Get_ExtraData: OleVariant; safecall;
    procedure Set_ExtraData(ExtraData: OleVariant); safecall;
    property FormatTag: Smallint read Get_FormatTag write Set_FormatTag;
    property Channels: Smallint read Get_Channels write Set_Channels;
    property SamplesPerSec: Integer read Get_SamplesPerSec write Set_SamplesPerSec;
    property AvgBytesPerSec: Integer read Get_AvgBytesPerSec write Set_AvgBytesPerSec;
    property BlockAlign: Smallint read Get_BlockAlign write Set_BlockAlign;
    property BitsPerSample: Smallint read Get_BitsPerSample write Set_BitsPerSample;
    property ExtraData: OleVariant read Get_ExtraData write Set_ExtraData;
  end;

  ISpeechAudioFormat = interface(IDispatch)
    ['{E6E9C590-3E18-40E3-8299-061F98BDE7C7}']
    function Get_Type_: SpeechAudioFormatType; safecall;
    procedure Set_Type_(AudioFormat: SpeechAudioFormatType); safecall;
    function Get_Guid: WideString; safecall;
    procedure Set_Guid(const Guid: WideString); safecall;
    function GetWaveFormatEx: ISpeechWaveFormatEx; safecall;
    procedure SetWaveFormatEx(const WaveFormatEx: ISpeechWaveFormatEx); safecall;
    property Type_: SpeechAudioFormatType read Get_Type_ write Set_Type_;
    property Guid: WideString read Get_Guid write Set_Guid;
  end;

  ISpeechBaseStream = interface(IDispatch)
    ['{6450336F-7D49-4CED-8097-49D6DEE37294}']
    function Get_Format: ISpeechAudioFormat; safecall;
    procedure _Set_Format(const AudioFormat: ISpeechAudioFormat); safecall;
    function Read(out Buffer: OleVariant; NumberOfBytes: Integer): Integer; safecall;
    function Write(Buffer: OleVariant): Integer; safecall;
    function Seek(Position: OleVariant; Origin: SpeechStreamSeekPositionType): OleVariant; safecall;
    property Format: ISpeechAudioFormat read Get_Format write _Set_Format;
  end;

 ISpeechMemoryStream = interface(ISpeechBaseStream)
    ['{EEB14B68-808B-4ABE-A5EA-B51DA7588008}']
    procedure SetData(Data: OleVariant); safecall;
    function GetData: OleVariant; safecall;
  end;

  ISpeechVoice = interface(IDispatch)
    ['{269316D8-57BD-11D2-9EEE-00C04F797396}']
    function Get_Status: ISpeechVoiceStatus; safecall;
    function Get_Voice: ISpeechObjectToken; safecall;
    procedure _Set_Voice(const Voice: ISpeechObjectToken); safecall;
    function Get_AudioOutput: ISpeechObjectToken; safecall;
    procedure _Set_AudioOutput(const AudioOutput: ISpeechObjectToken); safecall;
    function Get_AudioOutputStream: ISpeechBaseStream; safecall;
    procedure _Set_AudioOutputStream(const AudioOutputStream: ISpeechBaseStream); safecall;
    function Get_Rate: Integer; safecall;
    procedure Set_Rate(Rate: Integer); safecall;
    function Get_Volume: Integer; safecall;
    procedure Set_Volume(Volume: Integer); safecall;
    procedure Set_AllowAudioOutputFormatChangesOnNextSet(Allow: WordBool); safecall;
    function Get_AllowAudioOutputFormatChangesOnNextSet: WordBool; safecall;
    function Get_EventInterests: SpeechVoiceEvents; safecall;
    procedure Set_EventInterests(EventInterestFlags: SpeechVoiceEvents); safecall;
    procedure Set_Priority(Priority: SpeechVoicePriority); safecall;
    function Get_Priority: SpeechVoicePriority; safecall;
    procedure Set_AlertBoundary(Boundary: SpeechVoiceEvents); safecall;
    function Get_AlertBoundary: SpeechVoiceEvents; safecall;
    procedure Set_SynchronousSpeakTimeout(msTimeout: Integer); safecall;
    function Get_SynchronousSpeakTimeout: Integer; safecall;
    function Speak(const Text: WideString; Flags: SpeechVoiceSpeakFlags): Integer; safecall;
    //function Speak(const Text: WideString; Flags: SpeechVoiceSpeakFlags; p:pointer): Integer; safecall;
    function SpeakStream(const Stream: ISpeechBaseStream; Flags: SpeechVoiceSpeakFlags): Integer; safecall;
    procedure Pause; safecall;
    procedure Resume; safecall;
    function Skip(const Type_: WideString; NumItems: Integer): Integer; safecall;
    function GetVoices(const RequiredAttributes: WideString; const OptionalAttributes: WideString): ISpeechObjectTokens; safecall;
    function GetAudioOutputs(const RequiredAttributes: WideString;
                             const OptionalAttributes: WideString): ISpeechObjectTokens; safecall;
    function WaitUntilDone(msTimeout: Integer): WordBool; safecall;
    function SpeakCompleteEvent: Integer; safecall;
    function IsUISupported(const TypeOfUI: WideString; var ExtraData: OleVariant): WordBool; safecall;
    procedure DisplayUI(hWndParent: Integer; const Title: WideString; const TypeOfUI: WideString;
                        var ExtraData: OleVariant); safecall;
    property Status: ISpeechVoiceStatus read Get_Status;
    property Voice: ISpeechObjectToken read Get_Voice write _Set_Voice;
    property AudioOutput: ISpeechObjectToken read Get_AudioOutput write _Set_AudioOutput;
    property AudioOutputStream: ISpeechBaseStream read Get_AudioOutputStream write _Set_AudioOutputStream;
    property Rate: Integer read Get_Rate write Set_Rate;
    property Volume: Integer read Get_Volume write Set_Volume;
    property AllowAudioOutputFormatChangesOnNextSet: WordBool read Get_AllowAudioOutputFormatChangesOnNextSet write Set_AllowAudioOutputFormatChangesOnNextSet;
    property EventInterests: SpeechVoiceEvents read Get_EventInterests write Set_EventInterests;
    property Priority: SpeechVoicePriority read Get_Priority write Set_Priority;
    property AlertBoundary: SpeechVoiceEvents read Get_AlertBoundary write Set_AlertBoundary;
    property SynchronousSpeakTimeout: Integer read Get_SynchronousSpeakTimeout write Set_SynchronousSpeakTimeout;
  end;
(*
  ISpNotifySource = interface(IUnknown)
    ['{5EFF4AEF-8487-11D2-961C-00C04F8EE628}']
    procedure SetNotifySink(pNotifySink:OleVariant); safecall;
    procedure SetNotifyWindowMessage(hWnd, Msg, wParam,lParam:cardinal); safecall;
    procedure SetNotifyCallbackFunction(pfnCallback:OleVariant; wParam, lParam:cardinal); safecall;
    procedure SetNotifyCallbackInterface(pSpCallback : OleVariant; wParam, lParam:cardinal); safecall;
    procedure SetNotifyWin32Event(); safecall;
    procedure WaitForNotifyEvent(dwMilliseconds:cardinal); safecall;
    function GetNotifyEventHandle():cardinal; safecall;
  end;

  ISpEventSource = interface(ISpNotifySource)
    ['{BE7A9CCE-5F9E-11D2-960F-00C04F8EE628}']
    procedure SetInterest(ullEventInterest, ullQueuedInterest:int64); safecall;
    function GetEvents(ulCount:cardinal; pEventArray, pulFetched:OleVariant):OleVariant; safecall;
    function GetInfo(pInfo:OleVariant):OleVariant; safecall;
  end;

  ISpVoice  = interface(ISpEventSource)
    ['{6C44DF74-72B9-4992-A1EC-EF996E0422D4}']
    procedure SetOutput(pUnkOutput:IUnknown;fAllowFormatChanges:WordBool); safecall;
    function GetOutputObjectToken(ppObjectToken:ISpObjectToken):OleVariant; safecall;
    function GetOutputStream(ppStream:ISpStreamFormat):OleVariant; safecall;
    procedure Pause(); safecall;
    procedure Resume(); safecall;
    procedure SetVoice(pToken:ISpObjectToken); safecall;
    procedure GetVoice(ppToken:ISpObjectToken); safecall;
    procedure Speak(pwcs:WideString; dwFlags:cardinal; pulStreamNumber:OleVariant); safecall;
    procedure SpeakStream(pStream:IStream; dwFlags:Cardinal; pulStreamNumber:OleVariant); safecall;
    procedure GetStatus(pStatus:OleVariant; ppszLastBookmark:WideString); safecall;
    procedure Skip(pItemType:WideString; lNumItems:integer;var pulNumSkipped:cardinal); safecall;
    procedure SetPriority(ePriority:OleVariant); safecall;
    procedure GetPriority(out pePriority:OleVariant); safecall;
    procedure SetAlertBoundary(eBoundary:OleVariant); safecall;
    procedure GetAlertBoundary(out peBoundary:OleVariant); safecall;
    procedure SetRate(RateAdjust:cardinal); safecall;
    procedure GetRate(out pRateAdjust:cardinal); safecall;
    procedure SetVolume(usVolume:word); safecall;
    procedure GetVolume(out pusVolume:word); safecall;
    procedure WaitUntilDone(msTimeout:cardinal); safecall;
    procedure SetSyncSpeakTimeout(msTimeout:cardinal); safecall;
    procedure GetSyncSpeakTimeout(out pmsTimeout:cardinal); safecall;
    procedure SpeakCompleteEvent(); safecall;
    procedure IsUISupported(pszTypeOfUI:WideString; pvExtraData:OleVariant; cbExtraData:cardinal; out pfSupported:WordBool); safecall;
    procedure DisplayUI(hwndParent:cardinal; pszTitle, pszTypeOfUI:WideString; pvExtraData:OleVariant; cbExtraData:cardinal); safecall;
  end;

  *)
  function SpEnumTokens(pszCategoryId,pszReqAttribs,pszOptAttribs:PWideChar;var ppEnum:IEnumSpObjectTokens):HRESULT;




implementation
uses ComObj;

function SpGetCategoryFromId(pszCategoryId:PWideChar;var ispCategory:ISpObjectTokenCategory; fCreateIfNotExist:boolean):HRESULT;
begin
   Result:=S_OK;
   ispCategory:=CreateComObject(CLSID_SpObjectTokenCategory)as ISpObjectTokenCategory;
   if ispCategory<>nil
     then Result:=ispCategory.SetId(pszCategoryId, fCreateIfNotExist);
end;

function SpEnumTokens(pszCategoryId,pszReqAttribs,pszOptAttribs:PWideChar;var ppEnum:IEnumSpObjectTokens):HRESULT;
var ispCategory:ISpObjectTokenCategory;
begin
  Result:=SpGetCategoryFromId(pszCategoryId,ispCategory,False);
  if Result=S_OK
    then Result:= ispCategory.EnumTokens(pszReqAttribs,pszOptAttribs,ppEnum);
end;

end.
