/*
 * 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
 */

#ifndef XAUDIO2_VER
#define XAUDIO2_VER 9
#endif

import "unknwn.idl";
import "mmdeviceapi.idl";

import "audiosessiontypes.h";

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

#if XAUDIO2_VER <= 7

[
    threading(both),
#if XAUDIO2_VER == 0
    uuid(fac23f48-31f5-45a8-b49b-5225d61401aa)
#elif XAUDIO2_VER == 1
    uuid(e21a7345-eb21-468e-be50-804db97cf708)
#elif XAUDIO2_VER == 2
    uuid(b802058a-464a-42db-bc10-b650d6f2586a)
#elif XAUDIO2_VER == 3
    uuid(4c5e637a-16c7-4de3-9c46-5ed22181962d)
#elif XAUDIO2_VER == 4
    uuid(03219e78-5bc3-44d1-b92e-f63d89cc6526)
#elif XAUDIO2_VER == 5
    uuid(4c9b6dde-6809-46e6-a278-9b6a97588670)
#elif XAUDIO2_VER == 6
    uuid(3eda9b49-2085-498b-9bb2-39a6778493de)
#else
    uuid(5a508685-a254-4fba-9b82-9a24b00306af)
#endif
]
coclass XAudio2 {
    interface IUnknown;
}

[
#if XAUDIO2_VER == 0
    uuid(fac23f48-31f5-45a8-b49b-5225d61401db)
#elif XAUDIO2_VER == 1
    uuid(f7a76c21-53d4-46bb-ac53-8b459cae46bd)
#elif XAUDIO2_VER == 2
    uuid(97dfb7e7-5161-4015-87a9-c79e6a1952cc)
#elif XAUDIO2_VER == 3
    uuid(ef0aa05d-8075-4e5d-bead-45be0c3ccbb3)
#elif XAUDIO2_VER == 4
    uuid(4256535c-1ea4-4d4b-8ad5-f9db762eca9e)
#elif XAUDIO2_VER == 5
    uuid(715bdd1a-aa82-436b-b0fa-6acea39bd0a1)
#elif XAUDIO2_VER == 6
    uuid(47199894-7cc2-444d-9873-ced2562cc60e)
#else
    uuid(db05ea35-0329-4d4b-a53a-6dead03d3852)
#endif
]
coclass XAudio2Debug {
    interface IUnknown;
}

#endif

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;
#if XAUDIO2_VER == 0
    UINT32 GlitchesSinceLastQuery;
#else
    UINT32 GlitchesSinceEngineStarted;
#endif
    UINT32 ActiveSourceVoiceCount;
    UINT32 TotalSourceVoiceCount;
    UINT32 ActiveSubmixVoiceCount;
#if XAUDIO2_VER <= 2
    UINT32 TotalSubmixVoiceCount;
#else
    UINT32 ActiveResamplerCount;
    UINT32 ActiveMatrixMixCount;
#endif
    UINT32 ActiveXmaSourceVoices;
    UINT32 ActiveXmaStreams;
} XAUDIO2_PERFORMANCE_DATA;

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

#if XAUDIO2_VER <= 7
typedef struct XAUDIO2_DEVICE_DETAILS
{
    WCHAR DeviceID[256];
    WCHAR DisplayName[256];
    XAUDIO2_DEVICE_ROLE Role;
    WAVEFORMATEXTENSIBLE OutputFormat;
} XAUDIO2_DEVICE_DETAILS;
#endif

typedef struct XAUDIO2_VOICE_DETAILS
{
    UINT32 CreationFlags;
#if XAUDIO2_VER >= 8
    UINT32 ActiveFlags;
#endif
    UINT32 InputChannels;
    UINT32 InputSampleRate;
} XAUDIO2_VOICE_DETAILS;

#if XAUDIO2_VER <= 3
typedef struct XAUDIO2_VOICE_SENDS
{
    UINT32 OutputCount;
    IXAudio2Voice **pOutputVoices;
} XAUDIO2_VOICE_SENDS;
#else
typedef struct XAUDIO2_SEND_DESCRIPTOR
{
    UINT32 Flags;
    IXAudio2Voice* pOutputVoice;
} XAUDIO2_SEND_DESCRIPTOR;

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

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;
#if XAUDIO2_VER > 0
const UINT32 XAUDIO2_MAX_LOOP_COUNT = 254;
#else
const UINT32 XAUDIO2_MAX_LOOP_COUNT = 0x100000;
#endif

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;
#if XAUDIO2_VER > 0
const UINT32 XAUDIO2_LOOP_INFINITE = 255;
#else
const UINT32 XAUDIO2_LOOP_INFINITE = ((UINT)-1);
#endif
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;

[
    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);

#if XAUDIO2_VER >= 4
    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);
#endif

    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);

#if XAUDIO2_VER == 0
    HRESULT
#else
    void
#endif
    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
]
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);

#if XAUDIO2_VER >= 8
    void GetState([out] XAUDIO2_VOICE_STATE* pVoiceState, [in, defaultvalue(0)] UINT32 Flags);
#else
    void GetState([out] XAUDIO2_VOICE_STATE* pVoiceState);
#endif

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

    void GetFrequencyRatio([out] float* pRatio);

#if XAUDIO2_VER >= 4
    HRESULT SetSourceSampleRate([in] UINT32 NewSourceSampleRate);
#endif
}

[
    local
]
interface IXAudio2SubmixVoice : IXAudio2Voice
{
}

[
    local
]
interface IXAudio2MasteringVoice : IXAudio2Voice
{
#if XAUDIO2_VER >= 8
    void GetChannelMask([out] DWORD *pChannelMask);
#endif
}

[
    object,
    local
]
interface IXAudio2VoiceCallback
{
#if XAUDIO2_VER > 0
    void OnVoiceProcessingPassStart([in] UINT32 BytesRequired);
#else
    void OnVoiceProcessingPassStart();
#endif

    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,
#if XAUDIO2_VER <= 7
    uuid(8bcf1f58-9fe7-4583-8ac6-e2adc465c8bb)
#elif XAUDIO2_VER == 8
    uuid(60d8dac8-5aa1-4e8e-b597-2f5e2883d484)
#else
    uuid(2b02e3cf-2e0b-4ec3-be45-1b2a3fe7210d)
#endif
]
/* XAudio2 2.9's IXAudio2 interface. */
interface IXAudio2 : IUnknown
{
#if XAUDIO2_VER <= 7
    HRESULT GetDeviceCount(UINT32 *count);

    HRESULT GetDeviceDetails(UINT32 index, XAUDIO2_DEVICE_DETAILS *details);

    HRESULT Initialize(UINT32 flags, XAUDIO2_PROCESSOR processor);
#endif

    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,
#if XAUDIO2_VER >= 8
        [in, defaultvalue(NULL)] LPCWSTR DeviceId,
#else
        [in, defaultvalue(0)] UINT32 index,
#endif
        [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain
#if XAUDIO2_VER >= 8
        , [in, defaultvalue(AudioCategory_GameEffects)] AUDIO_STREAM_CATEGORY category
#endif
        );

    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,
    local,
    uuid(84ac29bb-d619-44d2-b197-e4acf7df3ed6)
]
interface IXAudio2Extension : IUnknown
{
    void GetProcessingQuantum(UINT32 *quantum_numerator, UINT32 *quantum_denominator);

    void GetProcessor(XAUDIO2_PROCESSOR *processor);
}

const UINT32 XAUDIO2_DEBUG_ENGINE           = 0x00000001;
const UINT32 XAUDIO2_VOICE_NOPITCH          = 0x00000002;
const UINT32 XAUDIO2_VOICE_NOSRC            = 0x00000004;
const UINT32 XAUDIO2_VOICE_USEFILTER        = 0x00000008;
const UINT32 XAUDIO2_VOICE_MUSIC            = 0x00000010;
const UINT32 XAUDIO2_PLAY_TAILS             = 0x00000020;
const UINT32 XAUDIO2_END_OF_STREAM          = 0x00000040;
const UINT32 XAUDIO2_SEND_USEFILTER         = 0x00000080;
const UINT32 XAUDIO2_VOICE_NOSAMPLESPLAYED  = 0x00000100;

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 */
#if XAUDIO2_VER > 0
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)")
#else
cpp_quote("#define XAUDIO2_E_XMA_DECODER_ERROR ((HRESULT)0x88960001)")
cpp_quote("#define XAUDIO2_E_XAPO_CREATION_FAILED ((HRESULT)0x88960002)")
cpp_quote("#define XAUDIO2_E_DEVICE_INVALIDATED ((HRESULT)0x88960003)")
#endif

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("#include <poppack.h>")

#if XAUDIO2_VER >= 8
cpp_quote("HRESULT WINAPI XAudio2Create(IXAudio2** pxaudio2, UINT32 flags, XAUDIO2_PROCESSOR processor);")
#endif
