/*
 * Speech API (SAPI) IDL file.
 *
 * Copyright (C) 2017 Huw Davies
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

import "oaidl.idl";
import "ocidl.idl";

#ifndef __WIDL__
#define threading(model)
#define progid(str)
#define vi_progid(str)
#endif

cpp_quote("#if 0")
typedef [restricted, hidden] struct WAVEFORMATEX
{
    WORD  wFormatTag;
    WORD  nChannels;
    DWORD nSamplesPerSec;
    DWORD nAvgBytesPerSec;
    WORD  nBlockAlign;
    WORD  wBitsPerSample;
    WORD  cbSize;
} WAVEFORMATEX;
cpp_quote("#else")
cpp_quote("#include <mmsystem.h>")
cpp_quote("#endif")

cpp_quote("#if defined(__cplusplus)")
cpp_quote("interface ISpNotifyCallback")
cpp_quote("{")
cpp_quote("virtual HRESULT STDMETHODCALLTYPE NotifyCallback(WPARAM wParam, LPARAM lParam) = 0;")
cpp_quote("};")
cpp_quote("#else")
typedef void * ISpNotifyCallback;
cpp_quote("#endif")

cpp_quote("#if 0")
typedef void * SPNOTIFYCALLBACK;
typedef void * SPSTATEHANDLE;
cpp_quote("#endif")

typedef [restricted, hidden] struct SPEVENT
{
    WORD      eEventId;
    WORD      elParamType;
    ULONG     ulStreamNum;
    ULONGLONG ullAudioStreamOffset;
    WPARAM    wParam;
    LPARAM    lParam;
} SPEVENT;

cpp_quote("typedef void __stdcall SPNOTIFYCALLBACK(WPARAM wParam, LPARAM lParam);")
cpp_quote("DECLARE_HANDLE(SPSTATEHANDLE);")

const ULONG SP_MAX_LANGIDS = 20;

typedef [restricted, hidden] struct SPEVENTSOURCEINFO
{
    ULONGLONG   ullEventInterest;
    ULONGLONG   ullQueuedInterest;
    ULONG       ulCount;
} SPEVENTSOURCEINFO;

typedef [hidden] enum SPGRAMMARWORDTYPE
{
    SPWT_DISPLAY,
    SPWT_LEXICAL,
    SPWT_PRONUNCIATION,
    SPWT_LEXICAL_NO_SPECIAL_CHARS
} SPGRAMMARWORDTYPE;

typedef [hidden] struct tagSPPROPERTYINFO
{
    const WCHAR *pszName;
    ULONG        ulId;
    const WCHAR *pszValue;
    VARIANT      vValue;
} SPPROPERTYINFO;

typedef [hidden] enum SPDATAKEYLOCATION
{
    SPDKL_DefaultLocation = 0,
    SPDKL_CurrentUser     = 1,
    SPDKL_LocalMachine    = 2,
    SPDKL_CurrentConfig   = 5
} SPDATAKEYLOCATION;

typedef [hidden] enum SPLOADOPTIONS
{
    SPLO_STATIC,
    SPLO_DYNAMIC
} SPLOADOPTIONS;

typedef [hidden] enum SPRULESTATE
{
    SPRS_INACTIVE               = 0,
    SPRS_ACTIVE                 = 1,
    SPRS_ACTIVE_WITH_AUTO_PAUSE = 3,
    SPRS_ACTIVE_USER_DELIMITED  = 4
} SPRULESTATE;

typedef [hidden] enum SPGRAMMARSTATE
{
    SPGS_DISABLED  = 0,
    SPGS_ENABLED   = 1,
    SPGS_EXCLUSIVE = 3
} SPGRAMMARSTATE;

typedef [hidden] struct SPBINARYGRAMMAR
{
    ULONG ulTotalSerializedSize;
} SPBINARYGRAMMAR;

typedef [hidden] struct tagSPTEXTSELECTIONINFO
{
    ULONG ulStartActiveOffset;
    ULONG cchActiveChars;
    ULONG ulStartSelection;
    ULONG cchSelection;
} SPTEXTSELECTIONINFO;

typedef [hidden] enum SPWORDPRONOUNCEABLE
{
    SPWP_UNKNOWN_WORD_UNPRONOUNCEABLE,
    SPWP_UNKNOWN_WORD_PRONOUNCEABLE,
    SPWP_KNOWN_WORD_PRONOUNCEABLE
} SPWORDPRONOUNCEABLE;

typedef [hidden] enum SPINTERFERENCE
{
    SPINTERFERENCE_NONE,
    SPINTERFERENCE_NOISE,
    SPINTERFERENCE_NOSIGNAL,
    SPINTERFERENCE_TOOLOUD,
    SPINTERFERENCE_TOOQUIET,
    SPINTERFERENCE_TOOFAST,
    SPINTERFERENCE_TOOSLOW
} SPINTERFERENCE;

typedef [hidden] enum SPVISEMES
{
    SP_VISEME_0 = 0,
    SP_VISEME_1,
    SP_VISEME_2,
    SP_VISEME_3,
    SP_VISEME_4,
    SP_VISEME_5,
    SP_VISEME_6,
    SP_VISEME_7,
    SP_VISEME_8,
    SP_VISEME_9,
    SP_VISEME_10,
    SP_VISEME_11,
    SP_VISEME_12,
    SP_VISEME_13,
    SP_VISEME_14,
    SP_VISEME_15,
    SP_VISEME_16,
    SP_VISEME_17,
    SP_VISEME_18,
    SP_VISEME_19,
    SP_VISEME_20,
    SP_VISEME_21,
} SPVISEMES;

typedef [hidden] enum 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_MIN_SR              = 34,
    SPEI_MAX_SR              = 55,

    SPEI_RESERVED1           = 30,
    SPEI_RESERVED2           = 33,
    SPEI_RESERVED3           = 63
} SPEVENTENUM;

typedef [hidden] enum SPCONTEXTSTATE
{
    SPCS_DISABLED = 0,
    SPCS_ENABLED  = 1,
} SPCONTEXTSTATE;

typedef [hidden] enum SPVPRIORITY
{
    SPVPRI_NORMAL = 0,
    SPVPRI_ALERT  = 1,
    SPVPRI_OVER   = 2
} SPVPRIORITY;

typedef [hidden] enum SPRECOSTATE
{
    SPRST_INACTIVE,
    SPRST_ACTIVE,
    SPRST_ACTIVE_ALWAYS,
    SPRST_INACTIVE_WITH_PURGE,
    SPRST_NUM_STATES
} SPRECOSTATE;

typedef [hidden] enum SPWAVEFORMATTYPE
{
    SPWF_INPUT,
    SPWF_SRENGINE
} SPSTREAMFORMATTYPE;

typedef [restricted, hidden] struct SPRECOCONTEXTSTATUS
{
    SPINTERFERENCE  eInterference;
    WCHAR           szRequestTypeOfUI[255];
    DWORD           dwReserved1;
    DWORD           dwReserved2;
} SPRECOCONTEXTSTATUS;

typedef [hidden] enum SPAUDIOOPTIONS
{
    SPAO_NONE,
    SPAO_RETAIN_AUDIO
} SPAUDIOOPTIONS;

typedef [hidden] struct SPSERIALIZEDRESULT
{
    ULONG ulSerializedSize;
} SPSERIALIZEDRESULT;

typedef [hidden] enum SPDISPLYATTRIBUTES
{
    SPAF_ONE_TRAILING_SPACE     = 0x02,
    SPAF_TWO_TRAILING_SPACES    = 0x04,
    SPAF_CONSUME_LEADING_SPACES = 0x08,
    SPAF_ALL                    = 0x0f
} SPDISPLAYATTRIBUTES;

typedef [hidden] enum SPBOOKMARKOPTIONS
{
    SPBO_NONE,
    SPBO_PAUSE
} SPBOOKMARKOPTIONS;

typedef [hidden] enum _SPAUDIOSTATE
{
    SPAS_CLOSED,
    SPAS_STOP,
    SPAS_PAUSE,
    SPAS_RUN
} SPAUDIOSTATE;

typedef [hidden] enum SPRUNSTATE
{
    SPRS_DONE        = (1L << 0),
    SPRS_IS_SPEAKING = (1L << 1)
} SPRUNSTATE;

typedef [hidden] enum SPEAKFLAGS
{
    SPF_DEFAULT            = 0,
    SPF_ASYNC              = (1L << 0),
    SPF_PURGEBEFORESPEAK   = (1L << 1),
    SPF_IS_FILENAME        = (1L << 2),
    SPF_IS_XML             = (1L << 3),
    SPF_IS_NOT_XML         = (1L << 4),
    SPF_PERSIST_XML        = (1L << 5),
    SPF_NLP_SPEAK_PUNC     = (1L << 6),
    SPF_PARSE_SAPI         = (1L << 7),
    SPF_PARSE_SSML         = (1L << 8),
    SPF_PARSE_AUTODETECT   = 0,
    SPF_NLP_MASK           = (SPF_NLP_SPEAK_PUNC),
    SPF_PARSE_MASK         = (SPF_PARSE_SAPI|SPF_PARSE_SSML),
    SPF_VOICE_MASK         = (SPF_ASYNC|SPF_PURGEBEFORESPEAK|SPF_IS_FILENAME|SPF_IS_XML|SPF_IS_NOT_XML|SPF_NLP_MASK|SPF_PERSIST_XML|SPF_PARSE_MASK),
    SPF_UNUSED_FLAGS       = ~(SPF_VOICE_MASK)
} SPEAKFLAGS;

typedef [hidden] enum SPCFGRULEATTRIBUTES
{
    SPRAF_TopLevel      = (1 << 0),
    SPRAF_Active        = (1 << 1),
    SPRAF_Export        = (1 << 2),
    SPRAF_Import        = (1 << 3),
    SPRAF_Interpreter   = (1 << 4),
    SPRAF_Dynamic       = (1 << 5),
    SPRAF_Root          = (1 << 6),
    SPRAF_AutoPause     = (1 << 16),
    SPRAF_UserDelimited = (1 << 17)
} SPCFGRULEATTRIBUTES;

typedef [hidden] enum SPPHRASERNG
{
    SPPR_ALL_ELEMENTS = -1
} SPPHRASERNG;

typedef [hidden] enum SPVALUETYPE
{
    SPDF_PROPERTY      = 0x00000001,
    SPDF_REPLACEMENT   = 0x00000002,
    SPDF_RULE          = 0x00000004,
    SPDF_DISPLAYTEXT   = 0x00000008,
    SPDF_LEXICALFORM   = 0x00000010,
    SPDF_PRONUNCIATION = 0x00000020,
    SPDF_AUDIO         = 0x00000040,
    SPDF_ALTERNATES    = 0x00000080,
    SPDF_ALL           = 0x000000ff
} SPVALUETYPE;

typedef unsigned short SPPHONEID;

typedef [restricted, hidden] struct SPPHRASEELEMENT
{
    ULONG           ulAudioTimeOffset;
    ULONG           ulAudioSizeTime;
    ULONG           ulAudioStreamOffset;
    ULONG           ulAudioSizeBytes;
    ULONG           ulRetainedStreamOffset;
    ULONG           ulRetainedSizeBytes;
    const WCHAR     *pszDisplayText;
    const WCHAR     *pszLexicalForm;
    const SPPHONEID *pszPronunciation;
    BYTE            bDisplayAttributes;
    signed char     RequiredConfidence;
    signed char     ActualConfidence;
    BYTE            Reserved;
    float           SREngineConfidence;
} SPPHRASEELEMENT;

typedef [restricted, hidden] struct SPVOICESTATUS
{
    ULONG     ulCurrentStream;
    ULONG     ulLastStreamQueued;
    HRESULT   hrLastResult;
    DWORD     dwRunningState;
    ULONG     ulInputWordPos;
    ULONG     ulInputWordLen;
    ULONG     ulInputSentPos;
    ULONG     ulInputSentLen;
    LONG      lBookmarkId;
    SPPHONEID PhonemeId;
    SPVISEMES VisemeId;
    DWORD     dwReserved1;
    DWORD     dwReserved2;
} SPVOICESTATUS;

typedef [restricted, hidden] struct SPAUDIOSTATUS
{
    long         cbFreeBuffSpace;
    ULONG        cbNonBlockingIO;
    SPAUDIOSTATE State;
    ULONGLONG    CurSeekPos;
    ULONGLONG    CurDevicePos;
    DWORD        dwAudioLevel;
    DWORD        dwReserved2;
} SPAUDIOSTATUS;

typedef [restricted, hidden] struct SPRECOGNIZERSTATUS
{
    SPAUDIOSTATUS AudioStatus;
    ULONGLONG     ullRecognitionStreamPos;
    ULONG         ulStreamNumber;
    ULONG         ulNumActive;
    CLSID         clsidEngine;
    ULONG         cLangIDs;
    LANGID        aLangID[SP_MAX_LANGIDS];
    ULONGLONG     ullRecognitionStreamTime;
} SPRECOGNIZERSTATUS;

typedef [restricted, hidden] struct SPPHRASERULE SPPHRASERULE;

struct SPPHRASERULE
{
    LPCWSTR                 pszName;
    ULONG                   ulId;
    ULONG                   ulFirstElement;
    ULONG                   ulCountOfElements;
    const SPPHRASERULE*     pNextSibling;
    const SPPHRASERULE*     pFirstChild;
    float                   SREngineConfidence;
    signed char             Confidence;
};

typedef [restricted, hidden] struct SPPHRASEPROPERTY SPPHRASEPROPERTY;

struct SPPHRASEPROPERTY
{
    const WCHAR            *pszName;
    ULONG                   ulId;
    const WCHAR            *pszValue;
    VARIANT                 vValue;
    ULONG                   ulFirstElement;
    ULONG                   ulCountOfElements;
    const SPPHRASEPROPERTY *pNextSibling;
    const SPPHRASEPROPERTY *pFirstChild;
    float                   SREngineConfidence;
    signed char             Confidence;
};

typedef [restricted, hidden] struct SPPHRASEREPLACEMENT
{
    BYTE         bDisplayAttributes;
    const WCHAR *pszReplacementText;
    ULONG        ulFirstElement;
    ULONG        ulCountOfElements;
} SPPHRASEREPLACEMENT;

typedef [restricted, hidden] struct SPPHRASE
{
    ULONG                   cbSize;
    LANGID                  LangID;
    WORD                    wReserved;
    ULONGLONG               ullGrammarID;
    ULONGLONG               ftStartTime;
    ULONGLONG               ullAudioStreamPosition;
    ULONG                   ulAudioSizeBytes;
    ULONG                   ulRetainedSizeBytes;
    ULONG                   ulAudioSizeTime;
    SPPHRASERULE            Rule;
    const SPPHRASEPROPERTY *pProperties;
    const SPPHRASEELEMENT  *pElements;
    ULONG                   cReplacements;
    const SPPHRASEREPLACEMENT *pReplacements;
    GUID                    SREngineID;
    ULONG                   ulSREnginePrivateDataSize;
    const BYTE             *pSREnginePrivateData;
} SPPHRASE;

typedef [restricted, hidden] struct SPSERIALIZEDPHRASE
{
    ULONG ulSerializedSize;
} SPSERIALIZEDPHRASE;

typedef [restricted, hidden] struct SPRECORESULTTIMES
{
    FILETIME  ftStreamTime;
    ULONGLONG ullLength;
    DWORD     dwTickCount;
    ULONGLONG ullStart;
} SPRECORESULTTIMES;

typedef [hidden] enum SPFILEMODE
{
    SPFM_OPEN_READONLY,
    SPFM_OPEN_READWRITE,
    SPFM_CREATE,
    SPFM_CREATE_ALWAYS,
    SPFM_NUM_MODES
} SPFILEMODE;

cpp_quote("#if defined(__GNUC__)")

cpp_quote("#define SPCAT_AUDIOOUT (const WCHAR []){ 'H','K','E','Y','_','L','O','C','A','L','_','M','A','C','H','I','N','E','\\\\','S','O','F','T','W','A','R','E','\\\\','M','i','c','r','o','s','o','f','t','\\\\','S','p','e','e','c','h','\\\\','A','u','d','i','o','O','u','t','p','u','t',0 }")
cpp_quote("#define SPCAT_AUDIOIN (const WCHAR []){ 'H','K','E','Y','_','L','O','C','A','L','_','M','A','C','H','I','N','E','\\\\','S','O','F','T','W','A','R','E','\\\\','M','i','c','r','o','s','o','f','t','\\\\','S','p','e','e','c','h','\\\\','A','u','d','i','o','I','n','p','u','t',0 }")
cpp_quote("#define SPCAT_VOICES (const WCHAR []){ 'H','K','E','Y','_','L','O','C','A','L','_','M','A','C','H','I','N','E','\\\\','S','O','F','T','W','A','R','E','\\\\','M','i','c','r','o','s','o','f','t','\\\\','S','p','e','e','c','h','\\\\','V','o','i','c','e','s',0 }")

cpp_quote("#elif defined(_MSC_VER)")

cpp_quote("#define SPCAT_AUDIOOUT L\"HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Speech\\\\AudioOutput\"")
cpp_quote("#define SPCAT_AUDIOIN L\"HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Speech\\\\AudioInput\"")
cpp_quote("#define SPCAT_VOICES L\"HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Speech\\\\Voices\"")

cpp_quote("#else")

cpp_quote("static const WCHAR SPCAT_AUDIOOUT[] = {'H','K','E','Y','_','L','O','C','A','L','_','M','A','C','H','I','N','E','\\\\','S','O','F','T','W','A','R','E','\\\\','M','i','c','r','o','s','o','f','t','\\\\','S','p','e','e','c','h','\\\\','A','u','d','i','o','O','u','t','p','u','t',0};")
cpp_quote("static const WCHAR SPCAT_AUDIOIN[] = {'H','K','E','Y','_','L','O','C','A','L','_','M','A','C','H','I','N','E','\\\\','S','O','F','T','W','A','R','E','\\\\','M','i','c','r','o','s','o','f','t','\\\\','S','p','e','e','c','h','\\\\','A','u','d','i','o','I','n','p','u','t',0};")
cpp_quote("static const WCHAR SPCAT_VOICES[] = {'H','K','E','Y','_','L','O','C','A','L','_','M','A','C','H','I','N','E','\\\\','S','O','F','T','W','A','R','E','\\\\','M','i','c','r','o','s','o','f','t','\\\\','S','p','e','e','c','h','\\\\','V','o','i','c','e','s',0};")

cpp_quote("#endif")

interface IEnumSpObjectTokens;
interface ISpEventSource;
interface ISpRecoContext;
interface ISpRecognizer;
interface ISpStreamFormat;

[
    object,
    uuid(14056581-e16c-11d2-bb90-00c04f8ee6c0),
    helpstring("ISpDataKey"),
    pointer_default(unique),
    local,
    restricted
]
interface ISpDataKey : IUnknown
{
    HRESULT SetData([in] LPCWSTR pszValueName,
                    [in] ULONG cbData,
                    [in] const BYTE *pData);
    HRESULT GetData([in] LPCWSTR pszValueName,
                    [in] ULONG *pcbData,
                    [out] BYTE *pData);
    HRESULT SetStringValue([in] LPCWSTR pszValueName,
                           [in] LPCWSTR pszValue);
    HRESULT GetStringValue([in] LPCWSTR pszValueName,
                           [out] LPWSTR *ppszValue);
    HRESULT SetDWORD([in] LPCWSTR pszValueName,
                     [in] DWORD dwValue);
    HRESULT GetDWORD([in] LPCWSTR pszValueName,
                     [out] DWORD *pdwValue);
    HRESULT OpenKey([in] LPCWSTR pszSubKeyName,
                    [out] ISpDataKey **ppSubKey);
    HRESULT CreateKey([in] LPCWSTR pszSubKey,
                      [out] ISpDataKey **ppSubKey);
    HRESULT DeleteKey([in] LPCWSTR pszSubKey);
    HRESULT DeleteValue([in] LPCWSTR pszValueName);
    HRESULT EnumKeys([in] ULONG Index,
                     [out] LPWSTR *ppszSubKeyName);
    HRESULT EnumValues([in] ULONG Index,
                       [out] LPWSTR *ppszValueName);
}
[
    object,
    uuid(92a66e2b-c830-4149-83df-6fc2ba1e7a5b),
    helpstring("ISpRegDataKey"),
    pointer_default(unique),
    restricted
]
interface ISpRegDataKey : ISpDataKey
{
    [local] HRESULT SetKey([in] HKEY hkey, [in] BOOL fReadOnly);
}

[
    object,
    uuid(2d3d3845-39af-4850-bbf9-40b49780011d),
    helpstring("ISpObjectTokenCategory"),
    pointer_default(unique),
    local,
    restricted
]
interface ISpObjectTokenCategory : ISpDataKey
{
    HRESULT SetId([in] LPCWSTR pszCategoryId,
                  [in] BOOL fCreateIfNotExist);
    HRESULT GetId([out] LPWSTR *ppszCoMemCategoryId);
    HRESULT GetDataKey([in] SPDATAKEYLOCATION spdkl,
                       [out] ISpDataKey **ppDataKey);
    HRESULT EnumTokens([in, string] LPCWSTR pszReqAttribs,
                       [in, string] LPCWSTR pszOptAttribs,
                       [out] IEnumSpObjectTokens **ppEnum);
    HRESULT SetDefaultTokenId([in] LPCWSTR pszTokenId);
    HRESULT GetDefaultTokenId([out] LPWSTR *ppszCoMemTokenId);
}

[
    object,
    uuid(14056589-e16c-11d2-bb90-00c04f8ee6c0),
    helpstring("ISpObjectToken"),
    pointer_default(unique),
    local,
    restricted
]
interface ISpObjectToken : ISpDataKey
{
    HRESULT SetId(/*[in]*/ LPCWSTR pszCategoryId,
                  [in] LPCWSTR pszTokenId,
                  [in] BOOL fCreateIfNotExist);
    HRESULT GetId([out] LPWSTR *ppszCoMemTokenId);
    HRESULT GetCategory([out] ISpObjectTokenCategory **ppTokenCategory);
    HRESULT CreateInstance([in] IUnknown *pUnkOuter,
                           [in] DWORD dwClsContext,
                           [in] REFIID riid,
                           [out, iid_is(riid)] void **ppvObject);
    HRESULT GetStorageFileName([in] REFCLSID clsidCaller,
                               [in] LPCWSTR pszValueName,
                               [in, string] LPCWSTR pszFileNameSpecifier,
                               [in] ULONG nFolder,
                               [out] LPWSTR *ppszFilePath);
    HRESULT RemoveStorageFileName([in] REFCLSID clsidCaller,
                                  [in] LPCWSTR pszKeyName,
                                  [in] BOOL fDeleteFile);
    HRESULT Remove(/*[in]*/ const CLSID *pclsidCaller);
    [local] HRESULT IsUISupported([in] LPCWSTR pszTypeOfUI,
                                  [in] void *pvExtraData,
                                  [in] ULONG cbExtraData,
                                  [in] IUnknown *punkObject,
                                  [out] BOOL *pfSupported);
    [local] HRESULT DisplayUI([in] HWND hwndParent,
                              [in] LPCWSTR pszTitle,
                              [in] LPCWSTR pszTypeOfUI,
                              [in] void *pvExtraData,
                              [in] ULONG cbExtraData,
                              [in] IUnknown *punkObject);
    HRESULT MatchesAttributes([in] LPCWSTR pszAttributes,
                              [out] BOOL *pfMatches);
}

[
    object,
    uuid(06b64f9e-7fda-11d2-b4f2-00c04f797396),
    helpstring("IEnumSpObjectTokens"),
    pointer_default(unique),
    local,
    restricted
]
interface IEnumSpObjectTokens : IUnknown
{
    HRESULT Next([in] ULONG celt,
                 [out, size_is(celt), length_is(*pceltFetched)] ISpObjectToken **pelt,
                 [out] ULONG *pceltFetched);
    HRESULT Skip([in] ULONG celt);
    HRESULT Reset(void);
    HRESULT Clone([out] IEnumSpObjectTokens **ppEnum);
    HRESULT Item([in] ULONG Index,
                 [out] ISpObjectToken **ppToken);
    HRESULT GetCount([out] ULONG *pCount);
}

[
    object,
    uuid(1a5c0354-b621-4b5a-8791-d306ed379e53),
    local,
    pointer_default(unique),
    restricted
]
interface ISpPhrase : IUnknown
{
    HRESULT GetPhrase([out] SPPHRASE **phrase);
    HRESULT GetSerializedPhrase([out] SPSERIALIZEDPHRASE **phrase);
    HRESULT GetText([in] ULONG start, [in] ULONG count, [in] BOOL replacements,
					[out] WCHAR **text, [out] BYTE *attributes);
    HRESULT Discard([in] DWORD types);
};

[
    object,
    uuid(8fcebc98-4e49-4067-9c6c-d86a0e092e3d),
    local,
    pointer_default(unique),
    restricted
]
interface ISpPhraseAlt : ISpPhrase
{
    HRESULT GetAltInfo(ISpPhrase **parent, ULONG *start, ULONG *count,
                        ULONG *elements);
    HRESULT Commit();
};

[
    object,
    uuid(20b053be-e235-43cd-9a2a-8d17a48b7842),
    pointer_default(unique),
    local,
    restricted
]
interface ISpRecoResult : ISpPhrase
{
    HRESULT GetResultTimes([out] SPRECORESULTTIMES *times);

    HRESULT GetAlternates(
                [in] ULONG start,
                [in] ULONG elements,
                [in] ULONG count,
                [out] ISpPhraseAlt **phrases,
                [out] ULONG *returned);

    HRESULT GetAudio(
                [in] ULONG start,
                [in] ULONG elements,
                [out] ISpStreamFormat **stream);
    HRESULT SpeakAudio(
                [in] ULONG start,
                [in] ULONG elements,
                [in] DWORD flags,
                [out] ULONG *number);

    HRESULT Serialize([out] SPSERIALIZEDRESULT **result);

    HRESULT ScaleAudio([in] const GUID *format, [in] const WAVEFORMATEX *wave);

    HRESULT GetRecoContext([out] ISpRecoContext *context);
};

[
    object,
    uuid(8137828f-591a-4a42-be58-49ea7ebaac68),
    helpstring("ISpGrammarBuilder Interface"),
    pointer_default(unique),
    restricted,
    local
]
interface ISpGrammarBuilder : IUnknown
{
    HRESULT ResetGrammar([in] LANGID language);

    HRESULT GetRule([in] const WCHAR *rule,
                    [in] DWORD id,
                    [in] DWORD attributes,
                    [in] BOOL should_create,
                    [out] SPSTATEHANDLE *state);
    HRESULT ClearRule(SPSTATEHANDLE state);

    HRESULT CreateNewState(
                [in] SPSTATEHANDLE instate,
                [out] SPSTATEHANDLE *outstate);

    HRESULT AddWordTransition(
                    [in] SPSTATEHANDLE from_state,
                    [in] SPSTATEHANDLE to_state,
                    [in] const WCHAR *value,
                    [in] const WCHAR *separators,
                    [in] SPGRAMMARWORDTYPE type,
                    [in] float weight,
                    [in] const SPPROPERTYINFO *info);

    HRESULT AddRuleTransition(
                [in] SPSTATEHANDLE from_state,
                [in] SPSTATEHANDLE to_state,
                [in] SPSTATEHANDLE rule,
                [in] float weight,
                [in] const SPPROPERTYINFO *info);

    HRESULT AddResource([in] SPSTATEHANDLE state,
                        [in] const WCHAR *name,
                        [in] const WCHAR *value);

    HRESULT Commit([in] DWORD reserved);
};

[
    object,
    uuid(2177db29-7f45-47d0-8554-067e91c80502),
    pointer_default(unique),
    restricted,
    local
]
interface ISpRecoGrammar : ISpGrammarBuilder
{
    HRESULT GetGrammarId([out] ULONGLONG *grammar);
    HRESULT GetRecoContext([out] ISpRecoContext **context);

    HRESULT LoadCmdFromFile([in, string] const WCHAR * pszFileName, [in] SPLOADOPTIONS options);
    HRESULT LoadCmdFromObject([in] REFCLSID rcid, [in, string] const WCHAR * pszGrammarName, [in] SPLOADOPTIONS options);
    HRESULT LoadCmdFromResource([in] HMODULE hmod,
                                [in, string] const WCHAR *name,
                                [in, string] const WCHAR *type,
                                [in] WORD language,
                                [in] SPLOADOPTIONS options);
    HRESULT LoadCmdFromMemory([in] const SPBINARYGRAMMAR *grammar, [in] SPLOADOPTIONS options);
    HRESULT LoadCmdFromProprietaryGrammar(
                                [in] REFGUID guid,
                                [in, string] const WCHAR *param,
                                [in] const void *data,
                                [in] ULONG size,
                                [in] SPLOADOPTIONS options);
    HRESULT SetRuleState([in, string] const WCHAR *name, [in] void *reserved,
                         [in] SPRULESTATE state);
    HRESULT SetRuleIdState([in] ULONG rule, [in] SPRULESTATE state);

    HRESULT LoadDictation([in, string] const WCHAR *name, [in] SPLOADOPTIONS options);
    HRESULT UnloadDictation();
    HRESULT SetDictationState([in] SPRULESTATE state);

    HRESULT SetWordSequenceData([in] const WCHAR *text, [in] ULONG count, [in] const SPTEXTSELECTIONINFO *info);
    HRESULT SetTextSelection([in] const SPTEXTSELECTIONINFO *info);

    HRESULT IsPronounceable([in, string] const WCHAR *word, [out] SPWORDPRONOUNCEABLE *pronounceable);

    HRESULT SetGrammarState([in] SPGRAMMARSTATE state);

    HRESULT SaveCmd([in] IStream *stream, [out, optional] WCHAR **error);

    HRESULT GetGrammarState([out] SPGRAMMARSTATE *state);
};

[
    object,
    uuid(259684dc-37c3-11d2-9603-00c04f8ee628),
    pointer_default(unique),
    restricted
]
interface ISpNotifySink : IUnknown
{
    HRESULT Notify(void);
}

[
    object,
    uuid(6c44df74-72b9-4992-a1ec-ef996e0422d4),
    pointer_default(unique),
    restricted
]
interface ISpVoice : ISpEventSource
{
    HRESULT SetOutput([in] IUnknown *unk, [in] BOOL changes);
    HRESULT GetOutputObjectToken([out] ISpObjectToken **token);
    HRESULT GetOutputStream([out] ISpStreamFormat **stream);

    HRESULT Pause(void);
    HRESULT Resume(void);

    HRESULT SetVoice([in] ISpObjectToken *token);
    HRESULT GetVoice([out] ISpObjectToken **token);

    HRESULT Speak([in, string] const WCHAR *pwcs,
                [in] DWORD flags,
                [out] ULONG *number);
    HRESULT SpeakStream([in] IStream *stream,
                [in] DWORD flags,
                [out] ULONG *number);

    HRESULT GetStatus(
                [out] SPVOICESTATUS *status,
                [out, string] WCHAR **bookmark);

    HRESULT Skip([in,string] const WCHAR *type, [in] long items, [out] ULONG *skipped);

    HRESULT SetPriority([in] SPVPRIORITY priority);
    HRESULT GetPriority([out] SPVPRIORITY* priority);

    HRESULT SetAlertBoundary([in] SPEVENTENUM boundary);
    HRESULT GetAlertBoundary([out] SPEVENTENUM* boundary);

    HRESULT SetRate([in] long adjust);
    HRESULT GetRate([out] long *adjust);

    HRESULT SetVolume([in] USHORT volume);
    HRESULT GetVolume([out] USHORT *volume);

    HRESULT WaitUntilDone([in] ULONG timeout);

    HRESULT SetSyncSpeakTimeout([in] ULONG timeout);
    HRESULT GetSyncSpeakTimeout([out] ULONG *timeout);

    [local] HANDLE SpeakCompleteEvent();

    [local] HRESULT IsUISupported(
                [in] const WCHAR *type,
                [in] void * extra,
                [in] ULONG count,
                [out] BOOL *supported);
    [local] HRESULT DisplayUI(
                [in] HWND parent,
                [in] const WCHAR *title,
                [in] const WCHAR *type,
                [in] void *extra,
                [in] ULONG count);
};

[
    object,
    uuid(5eff4aef-8487-11d2-961c-00c04f8ee628),
    pointer_default(unique),
    restricted
]
interface ISpNotifySource : IUnknown
{
    HRESULT SetNotifySink([in] ISpNotifySink *sink);
    [local] HRESULT SetNotifyWindowMessage(
                [in] HWND hwnd,
                [in] UINT msg,
                [in] WPARAM wparam,
                [in] LPARAM lparam);
    [local] HRESULT SetNotifyCallbackFunction(
                [in] SPNOTIFYCALLBACK *callback,
                [in] WPARAM wparam,
                [in] LPARAM lparam);
    [local] HRESULT SetNotifyCallbackInterface(
                [in] ISpNotifyCallback *callback,
                [in] WPARAM wparam,
                [in] LPARAM lparam);
    [local] HRESULT SetNotifyWin32Event(void);
    [local] HRESULT WaitForNotifyEvent([in] DWORD milliseconds);
    [local] HANDLE  GetNotifyEventHandle();
}

[
    object,
    uuid(be7a9cce-5f9e-11d2-960f-00c04f8ee628),
    pointer_default(unique),
    local,
    restricted
]
interface ISpEventSource : ISpNotifySource
{
    HRESULT SetInterest([in] ULONGLONG event, [in] ULONGLONG queued);
    HRESULT GetEvents([in] ULONG count,
                    [out, size_is(count)] SPEVENT *array,
                    [out] ULONG *fetched);
    HRESULT GetInfo([out] SPEVENTSOURCEINFO *info);
};

[
    object,
    uuid(f740a62f-7c15-489e-8234-940a33d9272d),
    pointer_default(unique),
    local,
    restricted
]
interface ISpRecoContext : ISpEventSource
{
    HRESULT GetRecognizer([out] ISpRecognizer **recognizer);

    HRESULT CreateGrammar([in] ULONGLONG grammar, [out] ISpRecoGrammar **spgrammar);

    HRESULT GetStatus([out] SPRECOCONTEXTSTATUS *status);

    HRESULT GetMaxAlternates([in] ULONG *alternates);
    HRESULT SetMaxAlternates([in] ULONG alternates);

    HRESULT SetAudioOptions([in] SPAUDIOOPTIONS options, [in] const GUID *format, [in] const WAVEFORMATEX *wave);
    HRESULT GetAudioOptions([in] SPAUDIOOPTIONS *options, [out] GUID *format, [out] WAVEFORMATEX **wave);

    HRESULT DeserializeResult([in] const SPSERIALIZEDRESULT *serialized, [out] ISpRecoResult **result);

    HRESULT Bookmark([in] SPBOOKMARKOPTIONS options, [in] ULONGLONG position, [in] LPARAM event);

    HRESULT SetAdaptationData([in, string] const WCHAR *data, [in] const ULONG count);

    HRESULT Pause(DWORD reserved);
    HRESULT Resume(DWORD reserved);

    HRESULT SetVoice([in] ISpVoice *voice, [in] BOOL changes);
    HRESULT GetVoice([out] ISpVoice **voice);
    HRESULT SetVoicePurgeEvent([in] ULONGLONG interest);
    HRESULT GetVoicePurgeEvent([out] ULONGLONG *interest);

    HRESULT SetContextState([in] SPCONTEXTSTATE state);
    HRESULT GetContextState([in] SPCONTEXTSTATE *state);
};

[
    object,
    uuid(bed530be-2606-4f4d-a1c0-54c5cda5566f),
    pointer_default(unique),
    restricted
]
interface ISpStreamFormat : IStream
{
    HRESULT GetFormat(GUID *format, WAVEFORMATEX **wave);
}

[
    object,
    uuid(5b4fb971-b115-4de1-ad97-e482e3bf6ee4),
    pointer_default(unique),
    local,
    restricted
]
interface ISpProperties : IUnknown
{
    HRESULT SetPropertyNum([in] const WCHAR *name, [in] long value);
    HRESULT GetPropertyNum([in] const WCHAR *name, [out] long *value);
    HRESULT SetPropertyString([in] const WCHAR *name, [in] const WCHAR *value);
    HRESULT GetPropertyString([in] const WCHAR *name, [out] WCHAR **value);
};

[
    object,
    uuid(c2b5f241-daa0-4507-9e16-5a1eaa2b7a5c),
    pointer_default(unique),
    restricted
]
interface ISpRecognizer : ISpProperties
{
    HRESULT SetRecognizer([in] ISpObjectToken *recognizer);
    HRESULT GetRecognizer([out] ISpObjectToken **recognizer);

    HRESULT SetInput([in] IUnknown *input, [in] BOOL changes);
    HRESULT GetInputObjectToken([out] ISpObjectToken **token);

    HRESULT GetInputStream( [out] ISpStreamFormat **stream);
    HRESULT CreateRecoContext([out] ISpRecoContext **cxt);

    HRESULT GetRecoProfile([out] ISpObjectToken **token);
    HRESULT SetRecoProfile([in] ISpObjectToken *token);

    HRESULT IsSharedInstance(void);

    HRESULT GetRecoState([out] SPRECOSTATE *state);
    HRESULT SetRecoState([in] SPRECOSTATE state);

    HRESULT GetStatus([out] SPRECOGNIZERSTATUS *status);
    HRESULT GetFormat([in] SPSTREAMFORMATTYPE type, [out] GUID *format, [out] WAVEFORMATEX **wave);

    [local] HRESULT IsUISupported([in] const WCHAR *type, [in] void *extra, [in] ULONG count,
                [out] BOOL *supported);
    [local] HRESULT DisplayUI([in] HWND hwnd,[in] const WCHAR *title, [in] const WCHAR *type,
                [in] void *extra, [in] ULONG cnt);
    HRESULT EmulateRecognition([in] ISpPhrase *phrase);
};

[
    object,
    uuid(12e3cca9-7518-44c5-a5e7-ba5a79cb929e),
    pointer_default(unique),
    local,
    restricted
]
interface ISpStream : ISpStreamFormat
{
    HRESULT SetBaseStream([in] IStream *stream, [in] REFGUID format, [in] const WAVEFORMATEX *wave);
    HRESULT GetBaseStream([out] IStream **stream);
    HRESULT BindToFile([in] LPCWSTR filename, [in] SPFILEMODE mode, [in] const GUID *format,
                       const WAVEFORMATEX *wave, [in] ULONGLONG interest);
    HRESULT Close();
}

[
    helpstring("Speech Object Library"),
    uuid(c866ca3a-32f7-11d2-9602-00c04f8ee628),
    version(5.4)
]
library SpeechLib
{
    importlib("stdole2.tlb");

#include "sapiaut.idl"

    [
        uuid(a910187f-0c7a-45ac-92cc-59edafb77b53),
        helpstring("SpObjectTokenCategory Class"),
        progid("SAPI.SpObjectTokenCategory.1"),
        vi_progid("SAPI.SpObjectTokenCategory"),
        threading(both)
    ]
    coclass SpObjectTokenCategory
    {
        interface ISpObjectTokenCategory;
    }

    [
        uuid(3bee4890-4fe9-4a37-8c1e-5e7e12791c1f)
    ]
    coclass SpSharedRecognizer
    {
        /*[default] interface ISpeechRecognizer;*/
        interface ISpRecognizer;
    };

    [
        uuid(96749377-3391-11d2-9ee3-00c04f797396)
    ]
    coclass SpVoice
    {
        interface ISpVoice;
        [default] interface ISpeechVoice;
    };

    [
        uuid(947812b3-2ae1-4644-ba86-9e90ded7ec91),
    ]
    coclass SpFileStream
    {
        interface ISpStream;
        [default] interface ISpeechFileStream;
    };
}
