/*
 * Structure and enum definitions are from audioclient.h in the Windows 10 SDK
 *
 * These should be defined by MinGW, but they aren't yet since they're very new
 * so we keep a copy in our tree. All definitions are guarded, so it should be
 * fine to always include this even when building with MSVC.
 */
#pragma once

#ifndef __IAudioClient3_FWD_DEFINED__
#define __IAudioClient3_FWD_DEFINED__
typedef interface IAudioClient3 IAudioClient3;

#endif 	/* __IAudioClient3_FWD_DEFINED__ */

#ifndef __IAudioClient3_INTERFACE_DEFINED__
#define __IAudioClient3_INTERFACE_DEFINED__

#ifndef AUDIO_STREAM_CATEGORY
typedef enum _AUDIO_STREAM_CATEGORY {
  AudioCategory_Other                   = 0,
  AudioCategory_ForegroundOnlyMedia,
  AudioCategory_BackgroundCapableMedia,
  AudioCategory_Communications,
  AudioCategory_Alerts,
  AudioCategory_SoundEffects,
  AudioCategory_GameEffects,
  AudioCategory_GameMedia,
  AudioCategory_GameChat,
  AudioCategory_Speech,
  AudioCategory_Movie,
  AudioCategory_Media
} AUDIO_STREAM_CATEGORY;
#endif

#ifndef AUDCLNT_STREAMOPTIONS
typedef enum AUDCLNT_STREAMOPTIONS
{
    AUDCLNT_STREAMOPTIONS_NONE	        = 0,
    AUDCLNT_STREAMOPTIONS_RAW	        = 0x1,
    AUDCLNT_STREAMOPTIONS_MATCH_FORMAT	= 0x2
} AUDCLNT_STREAMOPTIONS;
#endif

#ifndef AudioClientProperties
typedef struct AudioClientProperties
{
    UINT32 cbSize;
    BOOL bIsOffload;
    AUDIO_STREAM_CATEGORY eCategory;
    AUDCLNT_STREAMOPTIONS Options;
} AudioClientProperties;
#endif

EXTERN_C const IID IID_IAudioClient3;

typedef struct IAudioClient3Vtbl
{
    BEGIN_INTERFACE

    HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
        IAudioClient3 * This,
        REFIID riid,
        void **ppvObject);

    ULONG ( STDMETHODCALLTYPE *AddRef )(
        IAudioClient3 * This);

    ULONG ( STDMETHODCALLTYPE *Release )(
        IAudioClient3 * This);

    HRESULT ( STDMETHODCALLTYPE *Initialize )(
        IAudioClient3 * This,
        AUDCLNT_SHAREMODE ShareMode,
        DWORD StreamFlags,
        REFERENCE_TIME hnsBufferDuration,
        REFERENCE_TIME hnsPeriodicity,
        const WAVEFORMATEX *pFormat,
        LPCGUID AudioSessionGuid);

    HRESULT ( STDMETHODCALLTYPE *GetBufferSize )(
        IAudioClient3 * This,
        UINT32 *pNumBufferFrames);

    HRESULT ( STDMETHODCALLTYPE *GetStreamLatency )(
        IAudioClient3 * This,
        REFERENCE_TIME *phnsLatency);

    HRESULT ( STDMETHODCALLTYPE *GetCurrentPadding )(
        IAudioClient3 * This,
        UINT32 *pNumPaddingFrames);

    HRESULT ( STDMETHODCALLTYPE *IsFormatSupported )(
        IAudioClient3 * This,
        AUDCLNT_SHAREMODE ShareMode,
        const WAVEFORMATEX *pFormat,
        WAVEFORMATEX **ppClosestMatch);

    HRESULT ( STDMETHODCALLTYPE *GetMixFormat )(
        IAudioClient3 * This,
        WAVEFORMATEX **ppDeviceFormat);

    HRESULT ( STDMETHODCALLTYPE *GetDevicePeriod )(
        IAudioClient3 * This,
        REFERENCE_TIME *phnsDefaultDevicePeriod,
        REFERENCE_TIME *phnsMinimumDevicePeriod);

    HRESULT ( STDMETHODCALLTYPE *Start )(
        IAudioClient3 * This);

    HRESULT ( STDMETHODCALLTYPE *Stop )(
        IAudioClient3 * This);

    HRESULT ( STDMETHODCALLTYPE *Reset )(
        IAudioClient3 * This);

    HRESULT ( STDMETHODCALLTYPE *SetEventHandle )(
        IAudioClient3 * This,
        HANDLE eventHandle);

    HRESULT ( STDMETHODCALLTYPE *GetService )(
        IAudioClient3 * This,
        REFIID riid,
        void **ppv);

    HRESULT ( STDMETHODCALLTYPE *IsOffloadCapable )(
        IAudioClient3 * This,
        AUDIO_STREAM_CATEGORY Category,
        BOOL *pbOffloadCapable);

    HRESULT ( STDMETHODCALLTYPE *SetClientProperties )(
        IAudioClient3 * This,
        const AudioClientProperties *pProperties);

    HRESULT ( STDMETHODCALLTYPE *GetBufferSizeLimits )(
        IAudioClient3 * This,
        const WAVEFORMATEX *pFormat,
        BOOL bEventDriven,
        REFERENCE_TIME *phnsMinBufferDuration,
        REFERENCE_TIME *phnsMaxBufferDuration);

    HRESULT ( STDMETHODCALLTYPE *GetSharedModeEnginePeriod )(
        IAudioClient3 * This,
        const WAVEFORMATEX *pFormat,
        UINT32 *pDefaultPeriodInFrames,
        UINT32 *pFundamentalPeriodInFrames,
        UINT32 *pMinPeriodInFrames,
        UINT32 *pMaxPeriodInFrames);

    HRESULT ( STDMETHODCALLTYPE *GetCurrentSharedModeEnginePeriod )(
        IAudioClient3 * This,
        WAVEFORMATEX **ppFormat,
        UINT32 *pCurrentPeriodInFrames);

    HRESULT ( STDMETHODCALLTYPE *InitializeSharedAudioStream )(
        IAudioClient3 * This,
        DWORD StreamFlags,
        UINT32 PeriodInFrames,
        const WAVEFORMATEX *pFormat,
        LPCGUID AudioSessionGuid);

    END_INTERFACE
} IAudioClient3Vtbl;

interface IAudioClient3
{
    CONST_VTBL struct IAudioClient3Vtbl *lpVtbl;
};

#define IAudioClient3_QueryInterface(This,riid,ppvObject)	\
    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )

#define IAudioClient3_AddRef(This)	\
    ( (This)->lpVtbl -> AddRef(This) )

#define IAudioClient3_Release(This)	\
    ( (This)->lpVtbl -> Release(This) )


#define IAudioClient3_Initialize(This,ShareMode,StreamFlags,hnsBufferDuration,hnsPeriodicity,pFormat,AudioSessionGuid)	\
    ( (This)->lpVtbl -> Initialize(This,ShareMode,StreamFlags,hnsBufferDuration,hnsPeriodicity,pFormat,AudioSessionGuid) )

#define IAudioClient3_GetBufferSize(This,pNumBufferFrames)	\
    ( (This)->lpVtbl -> GetBufferSize(This,pNumBufferFrames) )

#define IAudioClient3_GetStreamLatency(This,phnsLatency)	\
    ( (This)->lpVtbl -> GetStreamLatency(This,phnsLatency) )

#define IAudioClient3_GetCurrentPadding(This,pNumPaddingFrames)	\
    ( (This)->lpVtbl -> GetCurrentPadding(This,pNumPaddingFrames) )

#define IAudioClient3_IsFormatSupported(This,ShareMode,pFormat,ppClosestMatch)	\
    ( (This)->lpVtbl -> IsFormatSupported(This,ShareMode,pFormat,ppClosestMatch) )

#define IAudioClient3_GetMixFormat(This,ppDeviceFormat)	\
    ( (This)->lpVtbl -> GetMixFormat(This,ppDeviceFormat) )

#define IAudioClient3_GetDevicePeriod(This,phnsDefaultDevicePeriod,phnsMinimumDevicePeriod)	\
    ( (This)->lpVtbl -> GetDevicePeriod(This,phnsDefaultDevicePeriod,phnsMinimumDevicePeriod) )

#define IAudioClient3_Start(This)	\
    ( (This)->lpVtbl -> Start(This) )

#define IAudioClient3_Stop(This)	\
    ( (This)->lpVtbl -> Stop(This) )

#define IAudioClient3_Reset(This)	\
    ( (This)->lpVtbl -> Reset(This) )

#define IAudioClient3_SetEventHandle(This,eventHandle)	\
    ( (This)->lpVtbl -> SetEventHandle(This,eventHandle) )

#define IAudioClient3_GetService(This,riid,ppv)	\
    ( (This)->lpVtbl -> GetService(This,riid,ppv) )


#define IAudioClient3_IsOffloadCapable(This,Category,pbOffloadCapable)	\
    ( (This)->lpVtbl -> IsOffloadCapable(This,Category,pbOffloadCapable) )

#define IAudioClient3_SetClientProperties(This,pProperties)	\
    ( (This)->lpVtbl -> SetClientProperties(This,pProperties) )

#define IAudioClient3_GetBufferSizeLimits(This,pFormat,bEventDriven,phnsMinBufferDuration,phnsMaxBufferDuration)	\
    ( (This)->lpVtbl -> GetBufferSizeLimits(This,pFormat,bEventDriven,phnsMinBufferDuration,phnsMaxBufferDuration) )


#define IAudioClient3_GetSharedModeEnginePeriod(This,pFormat,pDefaultPeriodInFrames,pFundamentalPeriodInFrames,pMinPeriodInFrames,pMaxPeriodInFrames)	\
    ( (This)->lpVtbl -> GetSharedModeEnginePeriod(This,pFormat,pDefaultPeriodInFrames,pFundamentalPeriodInFrames,pMinPeriodInFrames,pMaxPeriodInFrames) )

#define IAudioClient3_GetCurrentSharedModeEnginePeriod(This,ppFormat,pCurrentPeriodInFrames)	\
    ( (This)->lpVtbl -> GetCurrentSharedModeEnginePeriod(This,ppFormat,pCurrentPeriodInFrames) )

#define IAudioClient3_InitializeSharedAudioStream(This,StreamFlags,PeriodInFrames,pFormat,AudioSessionGuid)	\
    ( (This)->lpVtbl -> InitializeSharedAudioStream(This,StreamFlags,PeriodInFrames,pFormat,AudioSessionGuid) )


#endif 	/* __IAudioClient3_INTERFACE_DEFINED__ */
