/*
 * Copyright (c) 2015 Mark Harmstone
 *
 * 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 "unknwn.idl";
import "mmdeviceapi.idl";

import "audiosessiontypes.h";

cpp_quote("#include <pshpack1.h>")

[
    uuid(fac23f48-31f5-45a8-b49b-5225d61401aa)
]
coclass XAudio20 {
    interface IUnknown;
}

[
    uuid(e21a7345-eb21-468e-be50-804db97cf708)
]
coclass XAudio21 {
    interface IUnknown;
}

[
    uuid(b802058a-464a-42db-bc10-b650d6f2586a)
]
coclass XAudio22 {
    interface IUnknown;
}

[
    uuid(4c5e637a-16c7-4de3-9c46-5ed22181962d)
]
coclass XAudio23 {
    interface IUnknown;
}

[
    uuid(03219e78-5bc3-44d1-b92e-f63d89cc6526)
]
coclass XAudio24 {
    interface IUnknown;
}

[
    uuid(4c9b6dde-6809-46e6-a278-9b6a97588670)
]
coclass XAudio25 {
    interface IUnknown;
}

[
    uuid(3eda9b49-2085-498b-9bb2-39a6778493de)
]
coclass XAudio26 {
    interface IUnknown;
}

[
    uuid(5a508685-a254-4fba-9b82-9a24b00306af)
]
coclass XAudio27 {
    interface IUnknown;
}

[
    uuid(db05ea35-0329-4d4b-a53a-6dead03d3852)
]
coclass XAudio2Debug {
    interface IUnknown;
}

cpp_quote("#if 0")
typedef struct WAVEFORMATEX
{
    WORD wFormatTag;
    WORD nChannels;
    DWORD nSamplesPerSec;
    DWORD nAvgBytesPerSec;
    WORD nBlockAlign;
    WORD wBitsPerSample;
    WORD cbSize;
} WAVEFORMATEX;

typedef struct {
    WAVEFORMATEX    Format;
    union {
        WORD        wValidBitsPerSample;
        WORD        wSamplesPerBlock;
        WORD        wReserved;
    } Samples;
    DWORD           dwChannelMask;
    GUID            SubFormat;
} WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE;
cpp_quote("#else")
cpp_quote("#include <mmreg.h>")
cpp_quote("#endif")

interface IXAudio2Voice;

typedef enum XAUDIO2_WINDOWS_PROCESSOR_SPECIFIER
{
    Processor1  = 0x00000001,
    Processor2  = 0x00000002,
    Processor3  = 0x00000004,
    Processor4  = 0x00000008,
    Processor5  = 0x00000010,
    Processor6  = 0x00000020,
    Processor7  = 0x00000040,
    Processor8  = 0x00000080,
    Processor9  = 0x00000100,
    Processor10 = 0x00000200,
    Processor11 = 0x00000400,
    Processor12 = 0x00000800,
    Processor13 = 0x00001000,
    Processor14 = 0x00002000,
    Processor15 = 0x00004000,
    Processor16 = 0x00008000,
    Processor17 = 0x00010000,
    Processor18 = 0x00020000,
    Processor19 = 0x00040000,
    Processor20 = 0x00080000,
    Processor21 = 0x00100000,
    Processor22 = 0x00200000,
    Processor23 = 0x00400000,
    Processor24 = 0x00800000,
    Processor25 = 0x01000000,
    Processor26 = 0x02000000,
    Processor27 = 0x04000000,
    Processor28 = 0x08000000,
    Processor29 = 0x10000000,
    Processor30 = 0x20000000,
    Processor31 = 0x40000000,
    Processor32 = 0x80000000,
    XAUDIO2_ANY_PROCESSOR = 0xffffffff,
    XAUDIO2_DEFAULT_PROCESSOR = XAUDIO2_ANY_PROCESSOR
} XAUDIO2_WINDOWS_PROCESSOR_SPECIFIER, XAUDIO2_PROCESSOR;

typedef struct XAUDIO2_PERFORMANCE_DATA
{
    UINT64 AudioCyclesSinceLastQuery;
    UINT64 TotalCyclesSinceLastQuery;
    UINT32 MinimumCyclesPerQuantum;
    UINT32 MaximumCyclesPerQuantum;
    UINT32 MemoryUsageInBytes;
    UINT32 CurrentLatencyInSamples;
    UINT32 GlitchesSinceEngineStarted;
    UINT32 ActiveSourceVoiceCount;
    UINT32 TotalSourceVoiceCount;
    UINT32 ActiveSubmixVoiceCount;
    UINT32 ActiveResamplerCount;
    UINT32 ActiveMatrixMixCount;
    UINT32 ActiveXmaSourceVoices;
    UINT32 ActiveXmaStreams;
} XAUDIO2_PERFORMANCE_DATA;

typedef struct XAUDIO22_PERFORMANCE_DATA
{
    UINT64 AudioCyclesSinceLastQuery;
    UINT64 TotalCyclesSinceLastQuery;
    UINT32 MinimumCyclesPerQuantum;
    UINT32 MaximumCyclesPerQuantum;
    UINT32 MemoryUsageInBytes;
    UINT32 CurrentLatencyInSamples;
    UINT32 GlitchesSinceEngineStarted;
    UINT32 ActiveSourceVoiceCount;
    UINT32 TotalSourceVoiceCount;
    UINT32 ActiveSubmixVoiceCount;
    UINT32 TotalSubmixVoiceCount;
    UINT32 ActiveXmaSourceVoices;
    UINT32 ActiveXmaStreams;
} XAUDIO22_PERFORMANCE_DATA;

typedef struct XAUDIO20_PERFORMANCE_DATA
{
    UINT64 AudioCyclesSinceLastQuery;
    UINT64 TotalCyclesSinceLastQuery;
    UINT32 MinimumCyclesPerQuantum;
    UINT32 MaximumCyclesPerQuantum;
    UINT32 MemoryUsageInBytes;
    UINT32 CurrentLatencyInSamples;
    UINT32 GlitchesSinceLastQuery;
    UINT32 ActiveSourceVoiceCount;
    UINT32 TotalSourceVoiceCount;
    UINT32 ActiveSubmixVoiceCount;
    UINT32 TotalSubmixVoiceCount;
    UINT32 ActiveXmaSourceVoices;
    UINT32 ActiveXmaStreams;
} XAUDIO20_PERFORMANCE_DATA;

typedef enum XAUDIO2_DEVICE_ROLE
{
    NotDefaultDevice            = 0x0,
    DefaultConsoleDevice        = 0x1,
    DefaultMultimediaDevice     = 0x2,
    DefaultCommunicationsDevice = 0x4,
    DefaultGameDevice           = 0x8,
    GlobalDefaultDevice         = 0xf,
    InvalidDeviceRole = ~GlobalDefaultDevice
} XAUDIO2_DEVICE_ROLE;

typedef struct XAUDIO2_DEVICE_DETAILS
{
    WCHAR DeviceID[256];
    WCHAR DisplayName[256];
    XAUDIO2_DEVICE_ROLE Role;
    WAVEFORMATEXTENSIBLE OutputFormat;
} XAUDIO2_DEVICE_DETAILS;

typedef struct XAUDIO27_VOICE_DETAILS
{
    UINT32 CreationFlags;
    UINT32 InputChannels;
    UINT32 InputSampleRate;
} XAUDIO27_VOICE_DETAILS;

typedef struct XAUDIO2_VOICE_DETAILS
{
    UINT32 CreationFlags;
    UINT32 ActiveFlags;
    UINT32 InputChannels;
    UINT32 InputSampleRate;
} XAUDIO2_VOICE_DETAILS;

typedef struct XAUDIO2_SEND_DESCRIPTOR
{
    UINT32 Flags;
    IXAudio2Voice* pOutputVoice;
} XAUDIO2_SEND_DESCRIPTOR;

/* XAudio2 2.3's XAUDIO2_VOICE_SENDS struct */
typedef struct XAUDIO23_VOICE_SENDS
{
    UINT32 OutputCount;
    IXAudio2Voice **pOutputVoices;
} XAUDIO23_VOICE_SENDS;

typedef struct XAUDIO2_VOICE_SENDS
{
    UINT32 SendCount;
    XAUDIO2_SEND_DESCRIPTOR* pSends;
} XAUDIO2_VOICE_SENDS;

typedef struct XAUDIO2_EFFECT_DESCRIPTOR
{
    IUnknown* pEffect;
    BOOL InitialState;
    UINT32 OutputChannels;
} XAUDIO2_EFFECT_DESCRIPTOR;

typedef struct XAUDIO2_EFFECT_CHAIN
{
    UINT32 EffectCount;
    XAUDIO2_EFFECT_DESCRIPTOR* pEffectDescriptors;
} XAUDIO2_EFFECT_CHAIN;

const UINT32 XAUDIO2_MAX_BUFFER_BYTES = 0x80000000;
const UINT32 XAUDIO2_MAX_QUEUED_BUFFERS = 64;
const UINT32 XAUDIO2_MAX_BUFFERS_SYSTEM = 2;
const UINT32 XAUDIO2_MAX_AUDIO_CHANNELS = 64;
const UINT32 XAUDIO2_MIN_SAMPLE_RATE = 1000;
const UINT32 XAUDIO2_MAX_SAMPLE_RATE = 200000;
const float XAUDIO2_MAX_VOLUME_LEVEL = 16777216.0;
const float XAUDIO2_MIN_FREQ_RATIO = (1/1024.0);
const float XAUDIO2_MAX_FREQ_RATIO = 1024.0;
const float XAUDIO2_DEFAULT_FREQ_RATIO = 2.0;
const float XAUDIO2_MAX_FILTER_ONEOVERQ = 1.5;
const float XAUDIO2_MAX_FILTER_FREQUENCY = 1.0;
const UINT32 XAUDIO2_MAX_LOOP_COUNT = 254;
const UINT32 XAUDIO20_MAX_LOOP_COUNT = 0x100000; /* xaudio 2.0 */

const UINT32 XAUDIO2_COMMIT_NOW = 0;
const UINT32 XAUDIO2_COMMIT_ALL = 0;
const UINT32 XAUDIO2_INVALID_OPSET = 0xffffffff;
const UINT32 XAUDIO2_NO_LOOP_REGION = 0;
const UINT32 XAUDIO2_LOOP_INFINITE = 255;
const UINT32 XAUDIO20_LOOP_INFINITE = ((UINT)-1); /* xaudio 2.0 */
const UINT32 XAUDIO2_DEFAULT_CHANNELS = 0;
const UINT32 XAUDIO2_DEFAULT_SAMPLERATE = 0;

[
    object,
    local
]
interface IXAudio2EngineCallback
{
    void OnProcessingPassStart();

    void OnProcessingPassEnd();

    void OnCriticalError([in] HRESULT Error);
}

typedef enum XAUDIO2_FILTER_TYPE
{
    LowPassFilter,
    BandPassFilter,
    HighPassFilter,
    NotchFilter
} XAUDIO2_FILTER_TYPE;

typedef struct XAUDIO2_FILTER_PARAMETERS
{
    XAUDIO2_FILTER_TYPE Type;
    float Frequency;
    float OneOverQ;
} XAUDIO2_FILTER_PARAMETERS;

/* XAudio 2.0's IXAudio2Voice */
/* XAudio2 2.0's IXAudio2Voice interface. Actually called
 * IXAudio2Voice in the Mar 2008 DX SDK */
[
    object,
    local
]
interface IXAudio20Voice
{
    void GetVoiceDetails([out] XAUDIO27_VOICE_DETAILS* pVoiceDetails);

    HRESULT SetOutputVoices([in] const XAUDIO23_VOICE_SENDS* pSendList);

    HRESULT SetEffectChain([in] const XAUDIO2_EFFECT_CHAIN* pEffectChain);

    HRESULT EnableEffect(
        [in] UINT32 EffectIndex,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    HRESULT DisableEffect(
        [in] UINT32 EffectIndex,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetEffectState(
        [in] UINT32 EffectIndex,
        [out] BOOL* pEnabled);

    HRESULT SetEffectParameters(
        [in] UINT32 EffectIndex,
        [in] const void* pParameters,
        [in] UINT32 ParametersByteSize,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    HRESULT GetEffectParameters(
        [in] UINT32 EffectIndex,
        [out] void* pParameters,
        [in] UINT32 ParametersByteSize);

    HRESULT SetFilterParameters(
        [in] const XAUDIO2_FILTER_PARAMETERS* pParameters,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetFilterParameters([out] XAUDIO2_FILTER_PARAMETERS* pParameters);

    HRESULT SetVolume(
        [in] float Volume,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetVolume([out] float* pVolume);

    HRESULT SetChannelVolumes(
        [in] UINT32 Channels,
        [in, size_is(Channels)] const float* pVolumes,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetChannelVolumes(
        [in] UINT32 Channels,
        [out, size_is(Channels)] float* pVolumes);

    HRESULT SetOutputMatrix(
        [in] IXAudio2Voice* pDestinationVoice,
        [in] UINT32 SourceChannels,
        [in] UINT32 DestinationChannels,
        [in, size_is(SourceChannels * DestinationChannels)] const float* pLevelMatrix,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    HRESULT GetOutputMatrix(
        [in] IXAudio2Voice* pDestinationVoice,
        [in] UINT32 SourceChannels,
        [in] UINT32 DestinationChannels,
        [out, size_is(SourceChannels * DestinationChannels)] float* pLevelMatrix);

    void DestroyVoice();
}

/* XAudio 2.3's IXAudio2Voice */
/* XAudio2 2.3's IXAudio2Voice interface. Actually called
 * IXAudio2Voice in the Nov 2008 DX SDK */
[
    object,
    local
]
interface IXAudio23Voice
{
    void GetVoiceDetails([out] XAUDIO27_VOICE_DETAILS* pVoiceDetails);

    HRESULT SetOutputVoices([in] const XAUDIO23_VOICE_SENDS* pSendList);

    HRESULT SetEffectChain([in] const XAUDIO2_EFFECT_CHAIN* pEffectChain);

    HRESULT EnableEffect(
        [in] UINT32 EffectIndex,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    HRESULT DisableEffect(
        [in] UINT32 EffectIndex,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetEffectState(
        [in] UINT32 EffectIndex,
        [out] BOOL* pEnabled);

    HRESULT SetEffectParameters(
        [in] UINT32 EffectIndex,
        [in] const void* pParameters,
        [in] UINT32 ParametersByteSize,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    HRESULT GetEffectParameters(
        [in] UINT32 EffectIndex,
        [out] void* pParameters,
        [in] UINT32 ParametersByteSize);

    HRESULT SetFilterParameters(
        [in] const XAUDIO2_FILTER_PARAMETERS* pParameters,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetFilterParameters([out] XAUDIO2_FILTER_PARAMETERS* pParameters);

    HRESULT SetVolume(
        [in] float Volume,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetVolume([out] float* pVolume);

    HRESULT SetChannelVolumes(
        [in] UINT32 Channels,
        [in, size_is(Channels)] const float* pVolumes,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetChannelVolumes(
        [in] UINT32 Channels,
        [out, size_is(Channels)] float* pVolumes);

    HRESULT SetOutputMatrix(
        [in] IXAudio2Voice* pDestinationVoice,
        [in] UINT32 SourceChannels,
        [in] UINT32 DestinationChannels,
        [in, size_is(SourceChannels * DestinationChannels)] const float* pLevelMatrix,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetOutputMatrix(
        [in] IXAudio2Voice* pDestinationVoice,
        [in] UINT32 SourceChannels,
        [in] UINT32 DestinationChannels,
        [out, size_is(SourceChannels * DestinationChannels)] float* pLevelMatrix);

    void DestroyVoice();
}

/* XAudio 2.7's IXAudio2Voice */
/* XAudio2 2.7's IXAudio2Voice interface. Actually called
 * IXAudio2Voice in the Jun 2010 DX SDK */
[
    object,
    local
]
interface IXAudio27Voice
{
    void GetVoiceDetails([out] XAUDIO27_VOICE_DETAILS* pVoiceDetails);

    HRESULT SetOutputVoices([in] const XAUDIO2_VOICE_SENDS* pSendList);

    HRESULT SetEffectChain([in] const XAUDIO2_EFFECT_CHAIN* pEffectChain);

    HRESULT EnableEffect(
        [in] UINT32 EffectIndex,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    HRESULT DisableEffect(
        [in] UINT32 EffectIndex,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetEffectState(
        [in] UINT32 EffectIndex,
        [out] BOOL* pEnabled);

    HRESULT SetEffectParameters(
        [in] UINT32 EffectIndex,
        [in] const void* pParameters,
        [in] UINT32 ParametersByteSize,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    HRESULT GetEffectParameters(
        [in] UINT32 EffectIndex,
        [out] void* pParameters,
        [in] UINT32 ParametersByteSize);

    HRESULT SetFilterParameters(
        [in] const XAUDIO2_FILTER_PARAMETERS* pParameters,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetFilterParameters([out] XAUDIO2_FILTER_PARAMETERS* pParameters);

    HRESULT SetOutputFilterParameters(
        [in] IXAudio2Voice* pDestinationVoice,
        [in] const XAUDIO2_FILTER_PARAMETERS* pParameters,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetOutputFilterParameters(
        [in] IXAudio2Voice* pDestinationVoice,
        [out] XAUDIO2_FILTER_PARAMETERS* pParameters);

    HRESULT SetVolume(
        [in] float Volume,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetVolume([out] float* pVolume);

    HRESULT SetChannelVolumes(
        [in] UINT32 Channels,
        [in, size_is(Channels)] const float* pVolumes,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetChannelVolumes(
        [in] UINT32 Channels,
        [out, size_is(Channels)] float* pVolumes);

    HRESULT SetOutputMatrix(
        [in] IXAudio2Voice* pDestinationVoice,
        [in] UINT32 SourceChannels,
        [in] UINT32 DestinationChannels,
        [in, size_is(SourceChannels * DestinationChannels)] const float* pLevelMatrix,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetOutputMatrix(
        [in] IXAudio2Voice* pDestinationVoice,
        [in] UINT32 SourceChannels,
        [in] UINT32 DestinationChannels,
        [out, size_is(SourceChannels * DestinationChannels)] float* pLevelMatrix);

    void DestroyVoice();
}

[
    object,
    local
]
interface IXAudio2Voice
{
    void GetVoiceDetails([out] XAUDIO2_VOICE_DETAILS* pVoiceDetails);

    HRESULT SetOutputVoices([in] const XAUDIO2_VOICE_SENDS* pSendList);

    HRESULT SetEffectChain([in] const XAUDIO2_EFFECT_CHAIN* pEffectChain);

    HRESULT EnableEffect(
        [in] UINT32 EffectIndex,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    HRESULT DisableEffect(
        [in] UINT32 EffectIndex,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetEffectState(
        [in] UINT32 EffectIndex,
        [out] BOOL* pEnabled);

    HRESULT SetEffectParameters(
        [in] UINT32 EffectIndex,
        [in] const void* pParameters,
        [in] UINT32 ParametersByteSize,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    HRESULT GetEffectParameters(
        [in] UINT32 EffectIndex,
        [out] void* pParameters,
        [in] UINT32 ParametersByteSize);

    HRESULT SetFilterParameters(
        [in] const XAUDIO2_FILTER_PARAMETERS* pParameters,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetFilterParameters([out] XAUDIO2_FILTER_PARAMETERS* pParameters);

    HRESULT SetOutputFilterParameters(
        [in] IXAudio2Voice* pDestinationVoice,
        [in] const XAUDIO2_FILTER_PARAMETERS* pParameters,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetOutputFilterParameters(
        [in] IXAudio2Voice* pDestinationVoice,
        [out] XAUDIO2_FILTER_PARAMETERS* pParameters);

    HRESULT SetVolume(
        [in] float Volume,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetVolume([out] float* pVolume);

    HRESULT SetChannelVolumes(
        [in] UINT32 Channels,
        [in, size_is(Channels)] const float* pVolumes,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetChannelVolumes(
        [in] UINT32 Channels,
        [out, size_is(Channels)] float* pVolumes);

    HRESULT SetOutputMatrix(
        [in] IXAudio2Voice* pDestinationVoice,
        [in] UINT32 SourceChannels,
        [in] UINT32 DestinationChannels,
        [in, size_is(SourceChannels * DestinationChannels)] const float* pLevelMatrix,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetOutputMatrix(
        [in] IXAudio2Voice* pDestinationVoice,
        [in] UINT32 SourceChannels,
        [in] UINT32 DestinationChannels,
        [out, size_is(SourceChannels * DestinationChannels)] float* pLevelMatrix);

    void DestroyVoice();
}

typedef struct XAUDIO2_BUFFER
{
    UINT32 Flags;
    UINT32 AudioBytes;
    const BYTE* pAudioData;
    UINT32 PlayBegin;
    UINT32 PlayLength;
    UINT32 LoopBegin;
    UINT32 LoopLength;
    UINT32 LoopCount;
    void* pContext;
} XAUDIO2_BUFFER;

typedef struct XAUDIO2_BUFFER_WMA
{
    const UINT32* pDecodedPacketCumulativeBytes;
    UINT32 PacketCount;
} XAUDIO2_BUFFER_WMA;

typedef struct XAUDIO2_VOICE_STATE
{
    void* pCurrentBufferContext;
    UINT32 BuffersQueued;
    UINT64 SamplesPlayed;
} XAUDIO2_VOICE_STATE;

[
    local
]
/* XAudio2 2.0's IXAudio2SourceVoice interface. Actually called
 * IXAudio2SourceVoice in the Mar 2008 DX SDK */
interface IXAudio20SourceVoice : IXAudio20Voice
{
    HRESULT Start(
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    HRESULT Stop(
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    HRESULT SubmitSourceBuffer(
        [in] const XAUDIO2_BUFFER* pBuffer,
        [in, defaultvalue(NULL)] const XAUDIO2_BUFFER_WMA* pBufferWMA);

    HRESULT FlushSourceBuffers();

    HRESULT Discontinuity();

    HRESULT ExitLoop([in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetState([out] XAUDIO2_VOICE_STATE* pVoiceState);

    HRESULT SetFrequencyRatio(
        [in] float Ratio,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetFrequencyRatio([out] float* pRatio);
}

[
    local
]
/* XAudio2 2.3's IXAudio2SourceVoice interface. Actually called
 * IXAudio2SourceVoice in the Nov 2008 DX SDK */
interface IXAudio23SourceVoice : IXAudio23Voice
{
    HRESULT Start(
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    HRESULT Stop(
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    HRESULT SubmitSourceBuffer(
        [in] const XAUDIO2_BUFFER* pBuffer,
        [in, defaultvalue(NULL)] const XAUDIO2_BUFFER_WMA* pBufferWMA);

    HRESULT FlushSourceBuffers();

    HRESULT Discontinuity();

    HRESULT ExitLoop([in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetState([out] XAUDIO2_VOICE_STATE* pVoiceState);

    HRESULT SetFrequencyRatio(
        [in] float Ratio,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetFrequencyRatio([out] float* pRatio);
}

[
    local
]
/* XAudio2 2.7's IXAudio2SourceVoice interface. Actually called
 * IXAudio2SourceVoice in the Jun 2010 DX SDK */
interface IXAudio27SourceVoice : IXAudio27Voice
{
    HRESULT Start(
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    HRESULT Stop(
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    HRESULT SubmitSourceBuffer(
        [in] const XAUDIO2_BUFFER* pBuffer,
        [in, defaultvalue(NULL)] const XAUDIO2_BUFFER_WMA* pBufferWMA);

    HRESULT FlushSourceBuffers();

    HRESULT Discontinuity();

    HRESULT ExitLoop([in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetState([out] XAUDIO2_VOICE_STATE* pVoiceState);

    HRESULT SetFrequencyRatio(
        [in] float Ratio,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetFrequencyRatio([out] float* pRatio);

    HRESULT SetSourceSampleRate([in] UINT32 NewSourceSampleRate);
}

[
    local
]
/* XAudio2 2.8's IXAudio2SourceVoice interface. */
interface IXAudio2SourceVoice : IXAudio2Voice
{
    HRESULT Start(
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    HRESULT Stop(
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    HRESULT SubmitSourceBuffer(
        [in] const XAUDIO2_BUFFER* pBuffer,
        [in, defaultvalue(NULL)] const XAUDIO2_BUFFER_WMA* pBufferWMA);

    HRESULT FlushSourceBuffers();

    HRESULT Discontinuity();

    HRESULT ExitLoop([in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetState([out] XAUDIO2_VOICE_STATE* pVoiceState, [in, defaultvalue(0)] UINT32 Flags);

    HRESULT SetFrequencyRatio(
        [in] float Ratio,
        [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);

    void GetFrequencyRatio([out] float* pRatio);

    HRESULT SetSourceSampleRate([in] UINT32 NewSourceSampleRate);
}

[
    local
]
/* XAudio2 2.0's IXAudio2SubmixVoice interface. Actually called
 * IXAudio2SubmixVoice in the Mar 2008 DX SDK */
interface IXAudio20SubmixVoice : IXAudio20Voice
{
}

[
    local
]
/* XAudio2 2.3's IXAudio2SubmixVoice interface. Actually called
 * IXAudio2SubmixVoice in the Nov 2008 DX SDK */
interface IXAudio23SubmixVoice : IXAudio23Voice
{
}

[
    local
]
/* XAudio2 2.7's IXAudio2SubmixVoice interface. Actually called
 * IXAudio2SubmixVoice in the Jun 2010 DX SDK */
interface IXAudio27SubmixVoice : IXAudio27Voice
{
}

[
    local
]
interface IXAudio2SubmixVoice : IXAudio2Voice
{
}

[
    local
]
/* XAudio2 2.0's IXAudio2MasteringVoice interface. Actually called
 * IXAudio2MasteringVoice in the Mar 2008 DX SDK */
interface IXAudio20MasteringVoice : IXAudio20Voice
{
}

[
    local
]
/* XAudio2 2.3's IXAudio2MasteringVoice interface. Actually called
 * IXAudio2MasteringVoice in the Nov 2008 DX SDK */
interface IXAudio23MasteringVoice : IXAudio23Voice
{
}

[
    local
]
/* XAudio2 2.7's IXAudio2MasteringVoice interface. Actually called
 * IXAudio2MasteringVoice in the Jun 2010 DX SDK */
interface IXAudio27MasteringVoice : IXAudio27Voice
{
}

[
    local
]
interface IXAudio2MasteringVoice : IXAudio2Voice
{
    /* not present in XAudio2 2.7 */
    void GetChannelMask([out] DWORD *pChannelMask);
}

[
    object,
    local
]
interface IXAudio20VoiceCallback
{
    void OnVoiceProcessingPassStart();

    void OnVoiceProcessingPassEnd();

    void OnStreamEnd();

    void OnBufferStart([in] void* pBufferContext);

    void OnBufferEnd([in] void* pBufferContext);

    void OnLoopEnd([in] void* pBufferContext);

    void OnVoiceError(
        [in] void* pBuffercontext,
        [in] HRESULT Error);
}

[
    object,
    local
]
interface IXAudio2VoiceCallback
{
    void OnVoiceProcessingPassStart([in] UINT32 BytesRequired);

    void OnVoiceProcessingPassEnd();

    void OnStreamEnd();

    void OnBufferStart([in] void* pBufferContext);

    void OnBufferEnd([in] void* pBufferContext);

    void OnLoopEnd([in] void* pBufferContext);

    void OnVoiceError(
        [in] void* pBuffercontext,
        [in] HRESULT Error);
}

typedef struct XAUDIO2_DEBUG_CONFIGURATION
{
    UINT32 TraceMask;
    UINT32 BreakMask;
    BOOL LogThreadID;
    BOOL LogFileline;
    BOOL LogFunctionName;
    BOOL LogTiming;
} XAUDIO2_DEBUG_CONFIGURATION;

[
    object,
    uuid(8bcf1f58-9fe7-4583-8ac6-e2adc465c8bb), /* all versions before 28 share IID_IXAudio */
]
/* XAudio2 2.0's IXAudio2 interface. Actually called IXAudio2 in the Mar 2008
 * DX SDK */
interface IXAudio20 : IUnknown
{
    HRESULT GetDeviceCount([out] UINT32* pCount);

    HRESULT GetDeviceDetails(
        [in] UINT32 Index,
        [out] XAUDIO2_DEVICE_DETAILS* pDeviceDetails);

    HRESULT Initialize(
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(XAUDIO2_DEFAULT_PROCESSOR)] XAUDIO2_PROCESSOR XAudio2Processor);

    HRESULT RegisterForCallbacks([in] IXAudio2EngineCallback* pCallback);

    void UnregisterForCallbacks([in] IXAudio2EngineCallback* pCallback);

    HRESULT CreateSourceVoice(
        [out] IXAudio2SourceVoice** ppSourceVoice,
        [in] const WAVEFORMATEX* pSourceFormat,
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(XAUDIO2_DEFAULT_FREQ_RATIO)] float MaxFrequencyRatio,
        [in, defaultvalue(NULL)] IXAudio2VoiceCallback* pCallback,
        [in, defaultvalue(NULL)] const XAUDIO23_VOICE_SENDS* pSendList,
        [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain);

    HRESULT CreateSubmixVoice(
        [out] IXAudio2SubmixVoice** ppSubmixVoice,
        [in] UINT32 InputChannels,
        [in] UINT32 InputSampleRate,
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(0)] UINT32 ProcessingStage,
        [in, defaultvalue(NULL)] const XAUDIO23_VOICE_SENDS* pSendList,
        [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain);

    HRESULT CreateMasteringVoice(
        [out] IXAudio2MasteringVoice** ppMasteringVoice,
        [in, defaultvalue(XAUDIO2_DEFAULT_CHANNELS)] UINT32 InputChannels,
        [in, defaultvalue(XAUDIO2_DEFAULT_SAMPLERATE)] UINT32 InputSampleRate,
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(0)] UINT32 DeviceIndex,
        [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain);

    HRESULT StartEngine();

    void StopEngine();

    HRESULT CommitChanges([in] UINT32 OperationSet);

    void GetPerformanceData([out] XAUDIO20_PERFORMANCE_DATA* pPerfData);

    [local] void SetDebugConfiguration(
        [in] const XAUDIO2_DEBUG_CONFIGURATION* pDebugConfiguration,
        [in, defaultvalue(NULL)] void* pReserved);
}

[
    object,
    uuid(8bcf1f58-9fe7-4583-8ac6-e2adc465c8bb), /* all versions before 28 share IID_IXAudio */
]
/* XAudio2 2.2's IXAudio2 interface. Actually called IXAudio2 in the Jun 2010
 * DX SDK */
interface IXAudio22 : IUnknown
{
    HRESULT GetDeviceCount([out] UINT32* pCount);

    HRESULT GetDeviceDetails(
        [in] UINT32 Index,
        [out] XAUDIO2_DEVICE_DETAILS* pDeviceDetails);

    HRESULT Initialize(
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(XAUDIO2_DEFAULT_PROCESSOR)] XAUDIO2_PROCESSOR XAudio2Processor);

    HRESULT RegisterForCallbacks([in] IXAudio2EngineCallback* pCallback);

    void UnregisterForCallbacks([in] IXAudio2EngineCallback* pCallback);

    HRESULT CreateSourceVoice(
        [out] IXAudio2SourceVoice** ppSourceVoice,
        [in] const WAVEFORMATEX* pSourceFormat,
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(XAUDIO2_DEFAULT_FREQ_RATIO)] float MaxFrequencyRatio,
        [in, defaultvalue(NULL)] IXAudio2VoiceCallback* pCallback,
        [in, defaultvalue(NULL)] const XAUDIO23_VOICE_SENDS* pSendList,
        [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain);

    HRESULT CreateSubmixVoice(
        [out] IXAudio2SubmixVoice** ppSubmixVoice,
        [in] UINT32 InputChannels,
        [in] UINT32 InputSampleRate,
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(0)] UINT32 ProcessingStage,
        [in, defaultvalue(NULL)] const XAUDIO23_VOICE_SENDS* pSendList,
        [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain);

    HRESULT CreateMasteringVoice(
        [out] IXAudio2MasteringVoice** ppMasteringVoice,
        [in, defaultvalue(XAUDIO2_DEFAULT_CHANNELS)] UINT32 InputChannels,
        [in, defaultvalue(XAUDIO2_DEFAULT_SAMPLERATE)] UINT32 InputSampleRate,
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(0)] UINT32 DeviceIndex,
        [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain);

    HRESULT StartEngine();

    void StopEngine();

    HRESULT CommitChanges([in] UINT32 OperationSet);

    void GetPerformanceData([out] XAUDIO22_PERFORMANCE_DATA* pPerfData);

    [local] void SetDebugConfiguration(
        [in] const XAUDIO2_DEBUG_CONFIGURATION* pDebugConfiguration,
        [in, defaultvalue(NULL)] void* pReserved);
}

[
    object,
    uuid(8bcf1f58-9fe7-4583-8ac6-e2adc465c8bb), /* all versions before 28 share IID_IXAudio */
]
/* XAudio2 2.3's IXAudio2 interface. Actually called IXAudio2 in the Nov 2008
 * DX SDK */
interface IXAudio23 : IUnknown
{
    HRESULT GetDeviceCount([out] UINT32* pCount);

    HRESULT GetDeviceDetails(
        [in] UINT32 Index,
        [out] XAUDIO2_DEVICE_DETAILS* pDeviceDetails);

    HRESULT Initialize(
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(XAUDIO2_DEFAULT_PROCESSOR)] XAUDIO2_PROCESSOR XAudio2Processor);

    HRESULT RegisterForCallbacks([in] IXAudio2EngineCallback* pCallback);

    void UnregisterForCallbacks([in] IXAudio2EngineCallback* pCallback);

    HRESULT CreateSourceVoice(
        [out] IXAudio2SourceVoice** ppSourceVoice,
        [in] const WAVEFORMATEX* pSourceFormat,
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(XAUDIO2_DEFAULT_FREQ_RATIO)] float MaxFrequencyRatio,
        [in, defaultvalue(NULL)] IXAudio2VoiceCallback* pCallback,
        [in, defaultvalue(NULL)] const XAUDIO23_VOICE_SENDS* pSendList,
        [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain);

    HRESULT CreateSubmixVoice(
        [out] IXAudio2SubmixVoice** ppSubmixVoice,
        [in] UINT32 InputChannels,
        [in] UINT32 InputSampleRate,
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(0)] UINT32 ProcessingStage,
        [in, defaultvalue(NULL)] const XAUDIO23_VOICE_SENDS* pSendList,
        [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain);

    HRESULT CreateMasteringVoice(
        [out] IXAudio2MasteringVoice** ppMasteringVoice,
        [in, defaultvalue(XAUDIO2_DEFAULT_CHANNELS)] UINT32 InputChannels,
        [in, defaultvalue(XAUDIO2_DEFAULT_SAMPLERATE)] UINT32 InputSampleRate,
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(0)] UINT32 DeviceIndex,
        [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain);

    HRESULT StartEngine();

    void StopEngine();

    HRESULT CommitChanges([in] UINT32 OperationSet);

    void GetPerformanceData([out] XAUDIO2_PERFORMANCE_DATA* pPerfData);

    [local] void SetDebugConfiguration(
        [in] const XAUDIO2_DEBUG_CONFIGURATION* pDebugConfiguration,
        [in, defaultvalue(NULL)] void* pReserved);
}

[
    object,
    uuid(8bcf1f58-9fe7-4583-8ac6-e2adc465c8bb),
]
/* XAudio2 2.7's IXAudio2 interface. Actually called IXAudio2 in the Jun 2010
 * DX SDK */
interface IXAudio27 : IUnknown
{
    HRESULT GetDeviceCount([out] UINT32* pCount);

    HRESULT GetDeviceDetails(
        [in] UINT32 Index,
        [out] XAUDIO2_DEVICE_DETAILS* pDeviceDetails);

    HRESULT Initialize(
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(XAUDIO2_DEFAULT_PROCESSOR)] XAUDIO2_PROCESSOR XAudio2Processor);

    HRESULT RegisterForCallbacks([in] IXAudio2EngineCallback* pCallback);

    void UnregisterForCallbacks([in] IXAudio2EngineCallback* pCallback);

    HRESULT CreateSourceVoice(
        [out] IXAudio2SourceVoice** ppSourceVoice,
        [in] const WAVEFORMATEX* pSourceFormat,
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(XAUDIO2_DEFAULT_FREQ_RATIO)] float MaxFrequencyRatio,
        [in, defaultvalue(NULL)] IXAudio2VoiceCallback* pCallback,
        [in, defaultvalue(NULL)] const XAUDIO2_VOICE_SENDS* pSendList,
        [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain);

    HRESULT CreateSubmixVoice(
        [out] IXAudio2SubmixVoice** ppSubmixVoice,
        [in] UINT32 InputChannels,
        [in] UINT32 InputSampleRate,
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(0)] UINT32 ProcessingStage,
        [in, defaultvalue(NULL)] const XAUDIO2_VOICE_SENDS* pSendList,
        [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain);

    HRESULT CreateMasteringVoice(
        [out] IXAudio2MasteringVoice** ppMasteringVoice,
        [in, defaultvalue(XAUDIO2_DEFAULT_CHANNELS)] UINT32 InputChannels,
        [in, defaultvalue(XAUDIO2_DEFAULT_SAMPLERATE)] UINT32 InputSampleRate,
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(0)] UINT32 DeviceIndex,
        [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain);

    HRESULT StartEngine();

    void StopEngine();

    HRESULT CommitChanges([in] UINT32 OperationSet);

    void GetPerformanceData([out] XAUDIO2_PERFORMANCE_DATA* pPerfData);

    [local] void SetDebugConfiguration(
        [in] const XAUDIO2_DEBUG_CONFIGURATION* pDebugConfiguration,
        [in, defaultvalue(NULL)] void* pReserved);
}

/* XAudio2 2.8's IXAudio2 is identical to 2.9's */
cpp_quote("DEFINE_GUID(IID_IXAudio28, 0x60d8dac8, 0x5aa1, 0x4e8e, 0xb5, 0x97, 0x2f, 0x5e, 0x28, 0x83, 0xd4, 0x84);")

[
    object,
    uuid(2b02e3cf-2e0b-4ec3-be45-1b2a3fe7210d)
]
/* XAudio2 2.9's IXAudio2 interface. */
interface IXAudio2 : IUnknown
{
    HRESULT RegisterForCallbacks([in] IXAudio2EngineCallback* pCallback);

    void UnregisterForCallbacks([in] IXAudio2EngineCallback* pCallback);

    HRESULT CreateSourceVoice(
        [out] IXAudio2SourceVoice** ppSourceVoice,
        [in] const WAVEFORMATEX* pSourceFormat,
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(XAUDIO2_DEFAULT_FREQ_RATIO)] float MaxFrequencyRatio,
        [in, defaultvalue(NULL)] IXAudio2VoiceCallback* pCallback,
        [in, defaultvalue(NULL)] const XAUDIO2_VOICE_SENDS* pSendList,
        [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain);

    HRESULT CreateSubmixVoice(
        [out] IXAudio2SubmixVoice** ppSubmixVoice,
        [in] UINT32 InputChannels,
        [in] UINT32 InputSampleRate,
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(0)] UINT32 ProcessingStage,
        [in, defaultvalue(NULL)] const XAUDIO2_VOICE_SENDS* pSendList,
        [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain);

    HRESULT CreateMasteringVoice(
        [out] IXAudio2MasteringVoice** ppMasteringVoice,
        [in, defaultvalue(XAUDIO2_DEFAULT_CHANNELS)] UINT32 InputChannels,
        [in, defaultvalue(XAUDIO2_DEFAULT_SAMPLERATE)] UINT32 InputSampleRate,
        [in, defaultvalue(0)] UINT32 Flags,
        [in, defaultvalue(NULL)] LPCWSTR DeviceId,
        [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain,
        [in, defaultvalue(AudioCategory_GameEffects)] AUDIO_STREAM_CATEGORY StreamCategory);

    HRESULT StartEngine();

    void StopEngine();

    HRESULT CommitChanges([in] UINT32 OperationSet);

    void GetPerformanceData([out] XAUDIO2_PERFORMANCE_DATA* pPerfData);

    [local] void SetDebugConfiguration(
        [in] const XAUDIO2_DEBUG_CONFIGURATION* pDebugConfiguration,
        [in, defaultvalue(NULL)] void* pReserved);
}

const UINT32 XAUDIO2_DEBUG_ENGINE = 1;
const UINT32 XAUDIO2_VOICE_NOPITCH = 2;
const UINT32 XAUDIO2_VOICE_NOSRC = 4;
const UINT32 XAUDIO2_VOICE_USEFILTER = 8;
const UINT32 XAUDIO2_VOICE_MUSIC = 16;
const UINT32 XAUDIO2_PLAY_TAILS = 32;
const UINT32 XAUDIO2_END_OF_STREAM = 64;
const UINT32 XAUDIO2_SEND_USEFILTER = 128;
const UINT32 XAUDIO2_VOICE_NOSAMPLESPLAYED = 256;

const XAUDIO2_FILTER_TYPE XAUDIO2_DEFAULT_FILTER_TYPE = LowPassFilter;
const float XAUDIO2_DEFAULT_FILTER_FREQUENCY = XAUDIO2_MAX_FILTER_FREQUENCY;
const float XAUDIO2_DEFAULT_FILTER_ONEOVERQ = 1.0;
const UINT32 XAUDIO2_QUANTUM_NUMERATOR = 1;
const UINT32 XAUDIO2_QUANTUM_DENOMINATOR = 100;
const float XAUDIO2_QUANTUM_MS = (1000.0 * XAUDIO2_QUANTUM_NUMERATOR / XAUDIO2_QUANTUM_DENOMINATOR);

/* use cpp_quote to retain the HRESULT type in header file */
cpp_quote("#define XAUDIO2_E_INVALID_CALL ((HRESULT)0x88960001)")
cpp_quote("#define XAUDIO2_E_XMA_DECODER_ERROR ((HRESULT)0x88960002)")
cpp_quote("#define XAUDIO2_E_XAPO_CREATION_FAILED ((HRESULT)0x88960003)")
cpp_quote("#define XAUDIO2_E_DEVICE_INVALIDATED ((HRESULT)0x88960004)")

/* xaudio 2.0 error codes */
cpp_quote("#define XAUDIO20_E_XMA_DECODER_ERROR ((HRESULT)0x88960001)")
cpp_quote("#define XAUDIO20_E_XAPO_CREATION_FAILED ((HRESULT)0x88960002)")
cpp_quote("#define XAUDIO20_E_DEVICE_INVALIDATED ((HRESULT)0x88960003)")

cpp_quote("#ifdef XAUDIO2_HELPER_FUNCTIONS")
cpp_quote("#define _USE_MATH_DEFINES")
cpp_quote("#include <math.h>")
cpp_quote("inline static float XAudio2DecibelsToAmplitudeRatio(float decibels) { return powf(10.0f, decibels/20.0f); }")
cpp_quote("inline static float XAudio2AmplitudeRatioToDecibels(float volume) { if (volume == 0) { return -3.402823466e+38f; } return 20.0f * log10f(volume); }")
cpp_quote("inline static float XAudio2SemitonesToFrequencyRatio(float semitones) { return powf(2.0f, semitones/12.0f); }")
cpp_quote("inline static float XAudio2FrequencyRatioToSemitones(float freqratio) { return 39.86313713864835f * log10f(freqratio); }")
cpp_quote("inline static float XAudio2CutoffFrequencyToRadians(float cutofffreq, UINT32 samplerate) { if ((UINT32)(cutofffreq * 6.0f) >= samplerate) { return XAUDIO2_MAX_FILTER_FREQUENCY; } return 2.0f * sinf((float)M_PI * cutofffreq / samplerate); }")
cpp_quote("inline static float XAudio2RadiansToCutoffFrequency(float radians, float samplerate) { return samplerate * asinf(radians/2.0f) / (float)M_PI; }")
cpp_quote("#endif")

cpp_quote("HRESULT WINAPI XAudio2Create(IXAudio2** pxaudio2, UINT32 flags, XAUDIO2_PROCESSOR processor);")

cpp_quote("#include <poppack.h>")