[PATCH 2/2] xaudio2: Don't build interfaces for other versions

Andrew Eikum aeikum at codeweavers.com
Mon Jan 18 13:15:57 CST 2016


Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
---
 dlls/xaudio2_7/compat.c         | 2707 ++++++++++++++++++++-------------------
 dlls/xaudio2_7/tests/xaudio2.c  |    3 +
 dlls/xaudio2_7/xaudio_dll.c     |   32 +-
 dlls/xaudio2_7/xaudio_private.h |   48 +-
 4 files changed, 1434 insertions(+), 1356 deletions(-)

diff --git a/dlls/xaudio2_7/compat.c b/dlls/xaudio2_7/compat.c
index 88dd850..9488529 100644
--- a/dlls/xaudio2_7/compat.c
+++ b/dlls/xaudio2_7/compat.c
@@ -94,6 +94,511 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(xaudio2);
 
+/* BEGIN IXAudio2SourceVoice */
+#if XAUDIO2_VER == 0
+static XA2SourceImpl *impl_from_IXAudio20SourceVoice(IXAudio20SourceVoice *iface)
+{
+    return CONTAINING_RECORD(iface, XA2SourceImpl, IXAudio20SourceVoice_iface);
+}
+
+static void WINAPI XA20SRC_GetVoiceDetails(IXAudio20SourceVoice *iface,
+        XAUDIO2_VOICE_DETAILS *pVoiceDetails)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_GetVoiceDetails(&This->IXAudio2SourceVoice_iface, pVoiceDetails);
+}
+
+static HRESULT WINAPI XA20SRC_SetOutputVoices(IXAudio20SourceVoice *iface,
+        const XAUDIO23_VOICE_SENDS *pSendList)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    XAUDIO2_VOICE_SENDS sends;
+    HRESULT hr;
+    DWORD i;
+
+    TRACE("%p, %p\n", This, pSendList);
+
+    sends.SendCount = pSendList->OutputCount;
+    sends.pSends = HeapAlloc(GetProcessHeap(), 0, sends.SendCount * sizeof(*sends.pSends));
+    for(i = 0; i < sends.SendCount; ++i){
+        sends.pSends[i].Flags = 0;
+        sends.pSends[i].pOutputVoice = pSendList->pOutputVoices[i];
+    }
+
+    hr = IXAudio2SourceVoice_SetOutputVoices(&This->IXAudio2SourceVoice_iface, &sends);
+
+    HeapFree(GetProcessHeap(), 0, sends.pSends);
+
+    return hr;
+}
+
+static HRESULT WINAPI XA20SRC_SetEffectChain(IXAudio20SourceVoice *iface,
+        const XAUDIO2_EFFECT_CHAIN *pEffectChain)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_SetEffectChain(&This->IXAudio2SourceVoice_iface, pEffectChain);
+}
+
+static HRESULT WINAPI XA20SRC_EnableEffect(IXAudio20SourceVoice *iface,
+        UINT32 EffectIndex, UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_EnableEffect(&This->IXAudio2SourceVoice_iface,
+            EffectIndex, OperationSet);
+}
+
+static HRESULT WINAPI XA20SRC_DisableEffect(IXAudio20SourceVoice *iface,
+        UINT32 EffectIndex, UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_DisableEffect(&This->IXAudio2SourceVoice_iface,
+            EffectIndex, OperationSet);
+}
+
+static void WINAPI XA20SRC_GetEffectState(IXAudio20SourceVoice *iface,
+        UINT32 EffectIndex, BOOL *pEnabled)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_GetEffectState(&This->IXAudio2SourceVoice_iface,
+            EffectIndex, pEnabled);
+}
+
+static HRESULT WINAPI XA20SRC_SetEffectParameters(IXAudio20SourceVoice *iface,
+        UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize,
+        UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_SetEffectParameters(&This->IXAudio2SourceVoice_iface,
+            EffectIndex, pParameters, ParametersByteSize, OperationSet);
+}
+
+static HRESULT WINAPI XA20SRC_GetEffectParameters(IXAudio20SourceVoice *iface,
+        UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_GetEffectParameters(&This->IXAudio2SourceVoice_iface,
+            EffectIndex, pParameters, ParametersByteSize);
+}
+
+static HRESULT WINAPI XA20SRC_SetFilterParameters(IXAudio20SourceVoice *iface,
+        const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_SetFilterParameters(&This->IXAudio2SourceVoice_iface,
+            pParameters, OperationSet);
+}
+
+static void WINAPI XA20SRC_GetFilterParameters(IXAudio20SourceVoice *iface,
+        XAUDIO2_FILTER_PARAMETERS *pParameters)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_GetFilterParameters(&This->IXAudio2SourceVoice_iface, pParameters);
+}
+
+static HRESULT WINAPI XA20SRC_SetVolume(IXAudio20SourceVoice *iface,
+        float Volume, UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_SetVolume(&This->IXAudio2SourceVoice_iface,
+            Volume, OperationSet);
+}
+
+static void WINAPI XA20SRC_GetVolume(IXAudio20SourceVoice *iface,
+        float *pVolume)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_GetVolume(&This->IXAudio2SourceVoice_iface, pVolume);
+}
+
+static HRESULT WINAPI XA20SRC_SetChannelVolumes(IXAudio20SourceVoice *iface,
+        UINT32 Channels, const float *pVolumes, UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_SetChannelVolumes(&This->IXAudio2SourceVoice_iface,
+            Channels, pVolumes, OperationSet);
+}
+
+static void WINAPI XA20SRC_GetChannelVolumes(IXAudio20SourceVoice *iface,
+        UINT32 Channels, float *pVolumes)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_GetChannelVolumes(&This->IXAudio2SourceVoice_iface,
+            Channels, pVolumes);
+}
+
+static HRESULT WINAPI XA20SRC_SetOutputMatrix(IXAudio20SourceVoice *iface,
+        IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels,
+        UINT32 DestinationChannels, const float *pLevelMatrix,
+        UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_SetOutputMatrix(&This->IXAudio2SourceVoice_iface,
+            pDestinationVoice, SourceChannels, DestinationChannels,
+            pLevelMatrix, OperationSet);
+}
+
+static HRESULT WINAPI XA20SRC_GetOutputMatrix(IXAudio20SourceVoice *iface,
+        IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels,
+        UINT32 DestinationChannels, float *pLevelMatrix)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    IXAudio2SourceVoice_GetOutputMatrix(&This->IXAudio2SourceVoice_iface,
+            pDestinationVoice, SourceChannels, DestinationChannels,
+            pLevelMatrix);
+    return S_OK;
+}
+
+static void WINAPI XA20SRC_DestroyVoice(IXAudio20SourceVoice *iface)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_DestroyVoice(&This->IXAudio2SourceVoice_iface);
+}
+
+static HRESULT WINAPI XA20SRC_Start(IXAudio20SourceVoice *iface, UINT32 Flags,
+        UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_Start(&This->IXAudio2SourceVoice_iface, Flags, OperationSet);
+}
+
+static HRESULT WINAPI XA20SRC_Stop(IXAudio20SourceVoice *iface, UINT32 Flags,
+        UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_Stop(&This->IXAudio2SourceVoice_iface, Flags, OperationSet);
+}
+
+static HRESULT WINAPI XA20SRC_SubmitSourceBuffer(IXAudio20SourceVoice *iface,
+        const XAUDIO2_BUFFER *pBuffer, const XAUDIO2_BUFFER_WMA *pBufferWMA)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_SubmitSourceBuffer(&This->IXAudio2SourceVoice_iface,
+            pBuffer, pBufferWMA);
+}
+
+static HRESULT WINAPI XA20SRC_FlushSourceBuffers(IXAudio20SourceVoice *iface)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_FlushSourceBuffers(&This->IXAudio2SourceVoice_iface);
+}
+
+static HRESULT WINAPI XA20SRC_Discontinuity(IXAudio20SourceVoice *iface)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_Discontinuity(&This->IXAudio2SourceVoice_iface);
+}
+
+static HRESULT WINAPI XA20SRC_ExitLoop(IXAudio20SourceVoice *iface,
+        UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_ExitLoop(&This->IXAudio2SourceVoice_iface, OperationSet);
+}
+
+static void WINAPI XA20SRC_GetState(IXAudio20SourceVoice *iface,
+        XAUDIO2_VOICE_STATE *pVoiceState)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_GetState(&This->IXAudio2SourceVoice_iface, pVoiceState, 0);
+}
+
+static HRESULT WINAPI XA20SRC_SetFrequencyRatio(IXAudio20SourceVoice *iface,
+        float Ratio, UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_SetFrequencyRatio(&This->IXAudio2SourceVoice_iface,
+            Ratio, OperationSet);
+}
+
+static void WINAPI XA20SRC_GetFrequencyRatio(IXAudio20SourceVoice *iface,
+        float *pRatio)
+{
+    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
+    return IXAudio2SourceVoice_GetFrequencyRatio(&This->IXAudio2SourceVoice_iface, pRatio);
+}
+
+const IXAudio20SourceVoiceVtbl XAudio20SourceVoice_Vtbl = {
+    XA20SRC_GetVoiceDetails,
+    XA20SRC_SetOutputVoices,
+    XA20SRC_SetEffectChain,
+    XA20SRC_EnableEffect,
+    XA20SRC_DisableEffect,
+    XA20SRC_GetEffectState,
+    XA20SRC_SetEffectParameters,
+    XA20SRC_GetEffectParameters,
+    XA20SRC_SetFilterParameters,
+    XA20SRC_GetFilterParameters,
+    XA20SRC_SetVolume,
+    XA20SRC_GetVolume,
+    XA20SRC_SetChannelVolumes,
+    XA20SRC_GetChannelVolumes,
+    XA20SRC_SetOutputMatrix,
+    XA20SRC_GetOutputMatrix,
+    XA20SRC_DestroyVoice,
+    XA20SRC_Start,
+    XA20SRC_Stop,
+    XA20SRC_SubmitSourceBuffer,
+    XA20SRC_FlushSourceBuffers,
+    XA20SRC_Discontinuity,
+    XA20SRC_ExitLoop,
+    XA20SRC_GetState,
+    XA20SRC_SetFrequencyRatio,
+    XA20SRC_GetFrequencyRatio,
+};
+
+#elif XAUDIO2_VER <= 3
+
+static XA2SourceImpl *impl_from_IXAudio23SourceVoice(IXAudio23SourceVoice *iface)
+{
+    return CONTAINING_RECORD(iface, XA2SourceImpl, IXAudio23SourceVoice_iface);
+}
+
+static void WINAPI XA23SRC_GetVoiceDetails(IXAudio23SourceVoice *iface,
+        XAUDIO2_VOICE_DETAILS *pVoiceDetails)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_GetVoiceDetails(&This->IXAudio2SourceVoice_iface, pVoiceDetails);
+}
+
+static HRESULT WINAPI XA23SRC_SetOutputVoices(IXAudio23SourceVoice *iface,
+        const XAUDIO23_VOICE_SENDS *pSendList)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    XAUDIO2_VOICE_SENDS sends;
+    HRESULT hr;
+    DWORD i;
+
+    TRACE("%p, %p\n", This, pSendList);
+
+    sends.SendCount = pSendList->OutputCount;
+    sends.pSends = HeapAlloc(GetProcessHeap(), 0, sends.SendCount * sizeof(*sends.pSends));
+    for(i = 0; i < sends.SendCount; ++i){
+        sends.pSends[i].Flags = 0;
+        sends.pSends[i].pOutputVoice = pSendList->pOutputVoices[i];
+    }
+
+    hr = IXAudio2SourceVoice_SetOutputVoices(&This->IXAudio2SourceVoice_iface, &sends);
+
+    HeapFree(GetProcessHeap(), 0, sends.pSends);
+
+    return hr;
+}
+
+static HRESULT WINAPI XA23SRC_SetEffectChain(IXAudio23SourceVoice *iface,
+        const XAUDIO2_EFFECT_CHAIN *pEffectChain)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_SetEffectChain(&This->IXAudio2SourceVoice_iface, pEffectChain);
+}
+
+static HRESULT WINAPI XA23SRC_EnableEffect(IXAudio23SourceVoice *iface,
+        UINT32 EffectIndex, UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_EnableEffect(&This->IXAudio2SourceVoice_iface,
+            EffectIndex, OperationSet);
+}
+
+static HRESULT WINAPI XA23SRC_DisableEffect(IXAudio23SourceVoice *iface,
+        UINT32 EffectIndex, UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_DisableEffect(&This->IXAudio2SourceVoice_iface,
+            EffectIndex, OperationSet);
+}
+
+static void WINAPI XA23SRC_GetEffectState(IXAudio23SourceVoice *iface,
+        UINT32 EffectIndex, BOOL *pEnabled)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_GetEffectState(&This->IXAudio2SourceVoice_iface,
+            EffectIndex, pEnabled);
+}
+
+static HRESULT WINAPI XA23SRC_SetEffectParameters(IXAudio23SourceVoice *iface,
+        UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize,
+        UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_SetEffectParameters(&This->IXAudio2SourceVoice_iface,
+            EffectIndex, pParameters, ParametersByteSize, OperationSet);
+}
+
+static HRESULT WINAPI XA23SRC_GetEffectParameters(IXAudio23SourceVoice *iface,
+        UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_GetEffectParameters(&This->IXAudio2SourceVoice_iface,
+            EffectIndex, pParameters, ParametersByteSize);
+}
+
+static HRESULT WINAPI XA23SRC_SetFilterParameters(IXAudio23SourceVoice *iface,
+        const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_SetFilterParameters(&This->IXAudio2SourceVoice_iface,
+            pParameters, OperationSet);
+}
+
+static void WINAPI XA23SRC_GetFilterParameters(IXAudio23SourceVoice *iface,
+        XAUDIO2_FILTER_PARAMETERS *pParameters)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_GetFilterParameters(&This->IXAudio2SourceVoice_iface, pParameters);
+}
+
+static HRESULT WINAPI XA23SRC_SetVolume(IXAudio23SourceVoice *iface,
+        float Volume, UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_SetVolume(&This->IXAudio2SourceVoice_iface,
+            Volume, OperationSet);
+}
+
+static void WINAPI XA23SRC_GetVolume(IXAudio23SourceVoice *iface,
+        float *pVolume)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_GetVolume(&This->IXAudio2SourceVoice_iface, pVolume);
+}
+
+static HRESULT WINAPI XA23SRC_SetChannelVolumes(IXAudio23SourceVoice *iface,
+        UINT32 Channels, const float *pVolumes, UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_SetChannelVolumes(&This->IXAudio2SourceVoice_iface,
+            Channels, pVolumes, OperationSet);
+}
+
+static void WINAPI XA23SRC_GetChannelVolumes(IXAudio23SourceVoice *iface,
+        UINT32 Channels, float *pVolumes)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_GetChannelVolumes(&This->IXAudio2SourceVoice_iface,
+            Channels, pVolumes);
+}
+
+static HRESULT WINAPI XA23SRC_SetOutputMatrix(IXAudio23SourceVoice *iface,
+        IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels,
+        UINT32 DestinationChannels, const float *pLevelMatrix,
+        UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_SetOutputMatrix(&This->IXAudio2SourceVoice_iface,
+            pDestinationVoice, SourceChannels, DestinationChannels,
+            pLevelMatrix, OperationSet);
+}
+
+static void WINAPI XA23SRC_GetOutputMatrix(IXAudio23SourceVoice *iface,
+        IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels,
+        UINT32 DestinationChannels, float *pLevelMatrix)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_GetOutputMatrix(&This->IXAudio2SourceVoice_iface,
+            pDestinationVoice, SourceChannels, DestinationChannels,
+            pLevelMatrix);
+}
+
+static void WINAPI XA23SRC_DestroyVoice(IXAudio23SourceVoice *iface)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_DestroyVoice(&This->IXAudio2SourceVoice_iface);
+}
+
+static HRESULT WINAPI XA23SRC_Start(IXAudio23SourceVoice *iface, UINT32 Flags,
+        UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_Start(&This->IXAudio2SourceVoice_iface, Flags, OperationSet);
+}
+
+static HRESULT WINAPI XA23SRC_Stop(IXAudio23SourceVoice *iface, UINT32 Flags,
+        UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_Stop(&This->IXAudio2SourceVoice_iface, Flags, OperationSet);
+}
+
+static HRESULT WINAPI XA23SRC_SubmitSourceBuffer(IXAudio23SourceVoice *iface,
+        const XAUDIO2_BUFFER *pBuffer, const XAUDIO2_BUFFER_WMA *pBufferWMA)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_SubmitSourceBuffer(&This->IXAudio2SourceVoice_iface,
+            pBuffer, pBufferWMA);
+}
+
+static HRESULT WINAPI XA23SRC_FlushSourceBuffers(IXAudio23SourceVoice *iface)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_FlushSourceBuffers(&This->IXAudio2SourceVoice_iface);
+}
+
+static HRESULT WINAPI XA23SRC_Discontinuity(IXAudio23SourceVoice *iface)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_Discontinuity(&This->IXAudio2SourceVoice_iface);
+}
+
+static HRESULT WINAPI XA23SRC_ExitLoop(IXAudio23SourceVoice *iface,
+        UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_ExitLoop(&This->IXAudio2SourceVoice_iface, OperationSet);
+}
+
+static void WINAPI XA23SRC_GetState(IXAudio23SourceVoice *iface,
+        XAUDIO2_VOICE_STATE *pVoiceState)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_GetState(&This->IXAudio2SourceVoice_iface, pVoiceState, 0);
+}
+
+static HRESULT WINAPI XA23SRC_SetFrequencyRatio(IXAudio23SourceVoice *iface,
+        float Ratio, UINT32 OperationSet)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_SetFrequencyRatio(&This->IXAudio2SourceVoice_iface,
+            Ratio, OperationSet);
+}
+
+static void WINAPI XA23SRC_GetFrequencyRatio(IXAudio23SourceVoice *iface,
+        float *pRatio)
+{
+    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
+    return IXAudio2SourceVoice_GetFrequencyRatio(&This->IXAudio2SourceVoice_iface, pRatio);
+}
+
+const IXAudio23SourceVoiceVtbl XAudio23SourceVoice_Vtbl = {
+    XA23SRC_GetVoiceDetails,
+    XA23SRC_SetOutputVoices,
+    XA23SRC_SetEffectChain,
+    XA23SRC_EnableEffect,
+    XA23SRC_DisableEffect,
+    XA23SRC_GetEffectState,
+    XA23SRC_SetEffectParameters,
+    XA23SRC_GetEffectParameters,
+    XA23SRC_SetFilterParameters,
+    XA23SRC_GetFilterParameters,
+    XA23SRC_SetVolume,
+    XA23SRC_GetVolume,
+    XA23SRC_SetChannelVolumes,
+    XA23SRC_GetChannelVolumes,
+    XA23SRC_SetOutputMatrix,
+    XA23SRC_GetOutputMatrix,
+    XA23SRC_DestroyVoice,
+    XA23SRC_Start,
+    XA23SRC_Stop,
+    XA23SRC_SubmitSourceBuffer,
+    XA23SRC_FlushSourceBuffers,
+    XA23SRC_Discontinuity,
+    XA23SRC_ExitLoop,
+    XA23SRC_GetState,
+    XA23SRC_SetFrequencyRatio,
+    XA23SRC_GetFrequencyRatio,
+};
+
+#elif XAUDIO2_VER <= 7
+
 static XA2SourceImpl *impl_from_IXAudio27SourceVoice(IXAudio27SourceVoice *iface)
 {
     return CONTAINING_RECORD(iface, XA2SourceImpl, IXAudio27SourceVoice_iface);
@@ -346,1346 +851,12 @@ const IXAudio27SourceVoiceVtbl XAudio27SourceVoice_Vtbl = {
     XA27SRC_GetFrequencyRatio,
     XA27SRC_SetSourceSampleRate
 };
+#endif
+/* END IXAudio2SourceVoice */
 
-static inline IXAudio2Impl *impl_from_IXAudio27(IXAudio27 *iface)
-{
-    return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio27_iface);
-}
-
-static HRESULT WINAPI XA27_QueryInterface(IXAudio27 *iface, REFIID riid,
-        void **ppvObject)
-{
-    IXAudio2Impl *This = impl_from_IXAudio27(iface);
-    return IXAudio2_QueryInterface(&This->IXAudio2_iface, riid, ppvObject);
-}
-
-static ULONG WINAPI XA27_AddRef(IXAudio27 *iface)
-{
-    IXAudio2Impl *This = impl_from_IXAudio27(iface);
-    return IXAudio2_AddRef(&This->IXAudio2_iface);
-}
-
-static ULONG WINAPI XA27_Release(IXAudio27 *iface)
-{
-    IXAudio2Impl *This = impl_from_IXAudio27(iface);
-    return IXAudio2_Release(&This->IXAudio2_iface);
-}
-
-static HRESULT WINAPI XA27_GetDeviceCount(IXAudio27 *iface, UINT32 *pCount)
-{
-    IXAudio2Impl *This = impl_from_IXAudio27(iface);
-
-    TRACE("%p, %p\n", This, pCount);
-
-    *pCount = This->ndevs;
-
-    return S_OK;
-}
-
-static HRESULT WINAPI XA27_GetDeviceDetails(IXAudio27 *iface, UINT32 index,
-        XAUDIO2_DEVICE_DETAILS *pDeviceDetails)
-{
-    IXAudio2Impl *This = impl_from_IXAudio27(iface);
-    HRESULT hr;
-    IMMDevice *dev;
-    IAudioClient *client;
-    IPropertyStore *ps;
-    WAVEFORMATEX *wfx;
-    PROPVARIANT var;
-
-    TRACE("%p, %u, %p\n", This, index, pDeviceDetails);
-
-    if(index >= This->ndevs)
-        return E_INVALIDARG;
-
-    hr = IMMDeviceEnumerator_GetDevice(This->devenum, This->devids[index], &dev);
-    if(FAILED(hr)){
-        WARN("GetDevice failed: %08x\n", hr);
-        return hr;
-    }
-
-    hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
-            NULL, (void**)&client);
-    if(FAILED(hr)){
-        WARN("Activate failed: %08x\n", hr);
-        IMMDevice_Release(dev);
-        return hr;
-    }
-
-    hr = IMMDevice_OpenPropertyStore(dev, STGM_READ, &ps);
-    if(FAILED(hr)){
-        WARN("OpenPropertyStore failed: %08x\n", hr);
-        IAudioClient_Release(client);
-        IMMDevice_Release(dev);
-        return hr;
-    }
-
-    PropVariantInit(&var);
-
-    hr = IPropertyStore_GetValue(ps, (PROPERTYKEY*)&DEVPKEY_Device_FriendlyName, &var);
-    if(FAILED(hr)){
-        WARN("GetValue failed: %08x\n", hr);
-        goto done;
-    }
-
-    lstrcpynW(pDeviceDetails->DisplayName, var.u.pwszVal, sizeof(pDeviceDetails->DisplayName)/sizeof(WCHAR));
-
-    PropVariantClear(&var);
-
-    hr = IAudioClient_GetMixFormat(client, &wfx);
-    if(FAILED(hr)){
-        WARN("GetMixFormat failed: %08x\n", hr);
-        goto done;
-    }
-
-    lstrcpyW(pDeviceDetails->DeviceID, This->devids[index]);
-
-    if(index == 0)
-        pDeviceDetails->Role = GlobalDefaultDevice;
-    else
-        pDeviceDetails->Role = NotDefaultDevice;
-
-    if(sizeof(WAVEFORMATEX) + wfx->cbSize > sizeof(pDeviceDetails->OutputFormat)){
-        FIXME("AudioClient format is too large to fit into WAVEFORMATEXTENSIBLE!\n");
-        CoTaskMemFree(wfx);
-        hr = E_FAIL;
-        goto done;
-    }
-    memcpy(&pDeviceDetails->OutputFormat, wfx, sizeof(WAVEFORMATEX) + wfx->cbSize);
-
-    CoTaskMemFree(wfx);
-
-done:
-    IPropertyStore_Release(ps);
-    IAudioClient_Release(client);
-    IMMDevice_Release(dev);
-
-    return hr;
-}
-
-static HRESULT WINAPI XA27_Initialize(IXAudio27 *iface, UINT32 flags,
-        XAUDIO2_PROCESSOR processor)
-{
-    IXAudio2Impl *This = impl_from_IXAudio27(iface);
-    TRACE("(%p)->(0x%x, 0x%x)\n", This, flags, processor);
-    return xaudio2_initialize(This, flags, processor);
-}
-
-static HRESULT WINAPI XA27_RegisterForCallbacks(IXAudio27 *iface,
-        IXAudio2EngineCallback *pCallback)
-{
-    IXAudio2Impl *This = impl_from_IXAudio27(iface);
-    return IXAudio2_RegisterForCallbacks(&This->IXAudio2_iface, pCallback);
-}
-
-static void WINAPI XA27_UnregisterForCallbacks(IXAudio27 *iface,
-        IXAudio2EngineCallback *pCallback)
-{
-    IXAudio2Impl *This = impl_from_IXAudio27(iface);
-    IXAudio2_UnregisterForCallbacks(&This->IXAudio2_iface, pCallback);
-}
-
-static HRESULT WINAPI XA27_CreateSourceVoice(IXAudio27 *iface,
-        IXAudio2SourceVoice **ppSourceVoice, const WAVEFORMATEX *pSourceFormat,
-        UINT32 flags, float maxFrequencyRatio,
-        IXAudio2VoiceCallback *pCallback, const XAUDIO2_VOICE_SENDS *pSendList,
-        const XAUDIO2_EFFECT_CHAIN *pEffectChain)
-{
-    IXAudio2Impl *This = impl_from_IXAudio27(iface);
-    return IXAudio2_CreateSourceVoice(&This->IXAudio2_iface, ppSourceVoice,
-            pSourceFormat, flags, maxFrequencyRatio, pCallback, pSendList,
-            pEffectChain);
-}
-
-static HRESULT WINAPI XA27_CreateSubmixVoice(IXAudio27 *iface,
-        IXAudio2SubmixVoice **ppSubmixVoice, UINT32 inputChannels,
-        UINT32 inputSampleRate, UINT32 flags, UINT32 processingStage,
-        const XAUDIO2_VOICE_SENDS *pSendList,
-        const XAUDIO2_EFFECT_CHAIN *pEffectChain)
-{
-    IXAudio2Impl *This = impl_from_IXAudio27(iface);
-    return IXAudio2_CreateSubmixVoice(&This->IXAudio2_iface, ppSubmixVoice,
-            inputChannels, inputSampleRate, flags, processingStage, pSendList,
-            pEffectChain);
-}
-
-static HRESULT WINAPI XA27_CreateMasteringVoice(IXAudio27 *iface,
-        IXAudio2MasteringVoice **ppMasteringVoice, UINT32 inputChannels,
-        UINT32 inputSampleRate, UINT32 flags, UINT32 deviceIndex,
-        const XAUDIO2_EFFECT_CHAIN *pEffectChain)
-{
-    IXAudio2Impl *This = impl_from_IXAudio27(iface);
-
-    TRACE("(%p)->(%p, %u, %u, 0x%x, %u, %p)\n", This, ppMasteringVoice,
-            inputChannels, inputSampleRate, flags, deviceIndex,
-            pEffectChain);
-
-    if(deviceIndex >= This->ndevs)
-        return E_INVALIDARG;
-
-    return IXAudio2_CreateMasteringVoice(&This->IXAudio2_iface, ppMasteringVoice,
-            inputChannels, inputSampleRate, flags, This->devids[deviceIndex],
-            pEffectChain, AudioCategory_GameEffects);
-}
-
-static HRESULT WINAPI XA27_StartEngine(IXAudio27 *iface)
-{
-    IXAudio2Impl *This = impl_from_IXAudio27(iface);
-    return IXAudio2_StartEngine(&This->IXAudio2_iface);
-}
-
-static void WINAPI XA27_StopEngine(IXAudio27 *iface)
-{
-    IXAudio2Impl *This = impl_from_IXAudio27(iface);
-    return IXAudio2_StopEngine(&This->IXAudio2_iface);
-}
-
-static HRESULT WINAPI XA27_CommitChanges(IXAudio27 *iface, UINT32 operationSet)
-{
-    IXAudio2Impl *This = impl_from_IXAudio27(iface);
-    return IXAudio2_CommitChanges(&This->IXAudio2_iface, operationSet);
-}
-
-static void WINAPI XA27_GetPerformanceData(IXAudio27 *iface,
-        XAUDIO2_PERFORMANCE_DATA *pPerfData)
-{
-    IXAudio2Impl *This = impl_from_IXAudio27(iface);
-    return IXAudio2_GetPerformanceData(&This->IXAudio2_iface, pPerfData);
-}
-
-static void WINAPI XA27_SetDebugConfiguration(IXAudio27 *iface,
-        const XAUDIO2_DEBUG_CONFIGURATION *pDebugConfiguration,
-        void *pReserved)
-{
-    IXAudio2Impl *This = impl_from_IXAudio27(iface);
-    return IXAudio2_SetDebugConfiguration(&This->IXAudio2_iface,
-            pDebugConfiguration, pReserved);
-}
-
-const IXAudio27Vtbl XAudio27_Vtbl = {
-    XA27_QueryInterface,
-    XA27_AddRef,
-    XA27_Release,
-    XA27_GetDeviceCount,
-    XA27_GetDeviceDetails,
-    XA27_Initialize,
-    XA27_RegisterForCallbacks,
-    XA27_UnregisterForCallbacks,
-    XA27_CreateSourceVoice,
-    XA27_CreateSubmixVoice,
-    XA27_CreateMasteringVoice,
-    XA27_StartEngine,
-    XA27_StopEngine,
-    XA27_CommitChanges,
-    XA27_GetPerformanceData,
-    XA27_SetDebugConfiguration
-};
-
-static XA2SourceImpl *impl_from_IXAudio23SourceVoice(IXAudio23SourceVoice *iface)
-{
-    return CONTAINING_RECORD(iface, XA2SourceImpl, IXAudio23SourceVoice_iface);
-}
-
-static void WINAPI XA23SRC_GetVoiceDetails(IXAudio23SourceVoice *iface,
-        XAUDIO2_VOICE_DETAILS *pVoiceDetails)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_GetVoiceDetails(&This->IXAudio2SourceVoice_iface, pVoiceDetails);
-}
-
-static HRESULT WINAPI XA23SRC_SetOutputVoices(IXAudio23SourceVoice *iface,
-        const XAUDIO23_VOICE_SENDS *pSendList)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    XAUDIO2_VOICE_SENDS sends;
-    HRESULT hr;
-    DWORD i;
-
-    TRACE("%p, %p\n", This, pSendList);
-
-    sends.SendCount = pSendList->OutputCount;
-    sends.pSends = HeapAlloc(GetProcessHeap(), 0, sends.SendCount * sizeof(*sends.pSends));
-    for(i = 0; i < sends.SendCount; ++i){
-        sends.pSends[i].Flags = 0;
-        sends.pSends[i].pOutputVoice = pSendList->pOutputVoices[i];
-    }
-
-    hr = IXAudio2SourceVoice_SetOutputVoices(&This->IXAudio2SourceVoice_iface, &sends);
-
-    HeapFree(GetProcessHeap(), 0, sends.pSends);
-
-    return hr;
-}
-
-static HRESULT WINAPI XA23SRC_SetEffectChain(IXAudio23SourceVoice *iface,
-        const XAUDIO2_EFFECT_CHAIN *pEffectChain)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_SetEffectChain(&This->IXAudio2SourceVoice_iface, pEffectChain);
-}
-
-static HRESULT WINAPI XA23SRC_EnableEffect(IXAudio23SourceVoice *iface,
-        UINT32 EffectIndex, UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_EnableEffect(&This->IXAudio2SourceVoice_iface,
-            EffectIndex, OperationSet);
-}
-
-static HRESULT WINAPI XA23SRC_DisableEffect(IXAudio23SourceVoice *iface,
-        UINT32 EffectIndex, UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_DisableEffect(&This->IXAudio2SourceVoice_iface,
-            EffectIndex, OperationSet);
-}
-
-static void WINAPI XA23SRC_GetEffectState(IXAudio23SourceVoice *iface,
-        UINT32 EffectIndex, BOOL *pEnabled)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_GetEffectState(&This->IXAudio2SourceVoice_iface,
-            EffectIndex, pEnabled);
-}
-
-static HRESULT WINAPI XA23SRC_SetEffectParameters(IXAudio23SourceVoice *iface,
-        UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize,
-        UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_SetEffectParameters(&This->IXAudio2SourceVoice_iface,
-            EffectIndex, pParameters, ParametersByteSize, OperationSet);
-}
-
-static HRESULT WINAPI XA23SRC_GetEffectParameters(IXAudio23SourceVoice *iface,
-        UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_GetEffectParameters(&This->IXAudio2SourceVoice_iface,
-            EffectIndex, pParameters, ParametersByteSize);
-}
-
-static HRESULT WINAPI XA23SRC_SetFilterParameters(IXAudio23SourceVoice *iface,
-        const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_SetFilterParameters(&This->IXAudio2SourceVoice_iface,
-            pParameters, OperationSet);
-}
-
-static void WINAPI XA23SRC_GetFilterParameters(IXAudio23SourceVoice *iface,
-        XAUDIO2_FILTER_PARAMETERS *pParameters)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_GetFilterParameters(&This->IXAudio2SourceVoice_iface, pParameters);
-}
-
-static HRESULT WINAPI XA23SRC_SetVolume(IXAudio23SourceVoice *iface,
-        float Volume, UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_SetVolume(&This->IXAudio2SourceVoice_iface,
-            Volume, OperationSet);
-}
-
-static void WINAPI XA23SRC_GetVolume(IXAudio23SourceVoice *iface,
-        float *pVolume)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_GetVolume(&This->IXAudio2SourceVoice_iface, pVolume);
-}
-
-static HRESULT WINAPI XA23SRC_SetChannelVolumes(IXAudio23SourceVoice *iface,
-        UINT32 Channels, const float *pVolumes, UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_SetChannelVolumes(&This->IXAudio2SourceVoice_iface,
-            Channels, pVolumes, OperationSet);
-}
-
-static void WINAPI XA23SRC_GetChannelVolumes(IXAudio23SourceVoice *iface,
-        UINT32 Channels, float *pVolumes)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_GetChannelVolumes(&This->IXAudio2SourceVoice_iface,
-            Channels, pVolumes);
-}
-
-static HRESULT WINAPI XA23SRC_SetOutputMatrix(IXAudio23SourceVoice *iface,
-        IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels,
-        UINT32 DestinationChannels, const float *pLevelMatrix,
-        UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_SetOutputMatrix(&This->IXAudio2SourceVoice_iface,
-            pDestinationVoice, SourceChannels, DestinationChannels,
-            pLevelMatrix, OperationSet);
-}
-
-static void WINAPI XA23SRC_GetOutputMatrix(IXAudio23SourceVoice *iface,
-        IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels,
-        UINT32 DestinationChannels, float *pLevelMatrix)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_GetOutputMatrix(&This->IXAudio2SourceVoice_iface,
-            pDestinationVoice, SourceChannels, DestinationChannels,
-            pLevelMatrix);
-}
-
-static void WINAPI XA23SRC_DestroyVoice(IXAudio23SourceVoice *iface)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_DestroyVoice(&This->IXAudio2SourceVoice_iface);
-}
-
-static HRESULT WINAPI XA23SRC_Start(IXAudio23SourceVoice *iface, UINT32 Flags,
-        UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_Start(&This->IXAudio2SourceVoice_iface, Flags, OperationSet);
-}
-
-static HRESULT WINAPI XA23SRC_Stop(IXAudio23SourceVoice *iface, UINT32 Flags,
-        UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_Stop(&This->IXAudio2SourceVoice_iface, Flags, OperationSet);
-}
-
-static HRESULT WINAPI XA23SRC_SubmitSourceBuffer(IXAudio23SourceVoice *iface,
-        const XAUDIO2_BUFFER *pBuffer, const XAUDIO2_BUFFER_WMA *pBufferWMA)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_SubmitSourceBuffer(&This->IXAudio2SourceVoice_iface,
-            pBuffer, pBufferWMA);
-}
-
-static HRESULT WINAPI XA23SRC_FlushSourceBuffers(IXAudio23SourceVoice *iface)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_FlushSourceBuffers(&This->IXAudio2SourceVoice_iface);
-}
-
-static HRESULT WINAPI XA23SRC_Discontinuity(IXAudio23SourceVoice *iface)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_Discontinuity(&This->IXAudio2SourceVoice_iface);
-}
-
-static HRESULT WINAPI XA23SRC_ExitLoop(IXAudio23SourceVoice *iface,
-        UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_ExitLoop(&This->IXAudio2SourceVoice_iface, OperationSet);
-}
-
-static void WINAPI XA23SRC_GetState(IXAudio23SourceVoice *iface,
-        XAUDIO2_VOICE_STATE *pVoiceState)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_GetState(&This->IXAudio2SourceVoice_iface, pVoiceState, 0);
-}
-
-static HRESULT WINAPI XA23SRC_SetFrequencyRatio(IXAudio23SourceVoice *iface,
-        float Ratio, UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_SetFrequencyRatio(&This->IXAudio2SourceVoice_iface,
-            Ratio, OperationSet);
-}
-
-static void WINAPI XA23SRC_GetFrequencyRatio(IXAudio23SourceVoice *iface,
-        float *pRatio)
-{
-    XA2SourceImpl *This = impl_from_IXAudio23SourceVoice(iface);
-    return IXAudio2SourceVoice_GetFrequencyRatio(&This->IXAudio2SourceVoice_iface, pRatio);
-}
-
-const IXAudio23SourceVoiceVtbl XAudio23SourceVoice_Vtbl = {
-    XA23SRC_GetVoiceDetails,
-    XA23SRC_SetOutputVoices,
-    XA23SRC_SetEffectChain,
-    XA23SRC_EnableEffect,
-    XA23SRC_DisableEffect,
-    XA23SRC_GetEffectState,
-    XA23SRC_SetEffectParameters,
-    XA23SRC_GetEffectParameters,
-    XA23SRC_SetFilterParameters,
-    XA23SRC_GetFilterParameters,
-    XA23SRC_SetVolume,
-    XA23SRC_GetVolume,
-    XA23SRC_SetChannelVolumes,
-    XA23SRC_GetChannelVolumes,
-    XA23SRC_SetOutputMatrix,
-    XA23SRC_GetOutputMatrix,
-    XA23SRC_DestroyVoice,
-    XA23SRC_Start,
-    XA23SRC_Stop,
-    XA23SRC_SubmitSourceBuffer,
-    XA23SRC_FlushSourceBuffers,
-    XA23SRC_Discontinuity,
-    XA23SRC_ExitLoop,
-    XA23SRC_GetState,
-    XA23SRC_SetFrequencyRatio,
-    XA23SRC_GetFrequencyRatio,
-};
-
-static XA2SubmixImpl *impl_from_IXAudio23SubmixVoice(IXAudio23SubmixVoice *iface)
-{
-    return CONTAINING_RECORD(iface, XA2SubmixImpl, IXAudio23SubmixVoice_iface);
-}
-
-static void WINAPI XA23SUB_GetVoiceDetails(IXAudio23SubmixVoice *iface,
-        XAUDIO2_VOICE_DETAILS *pVoiceDetails)
-{
-    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
-    return IXAudio2SubmixVoice_GetVoiceDetails(&This->IXAudio2SubmixVoice_iface, pVoiceDetails);
-}
-
-static HRESULT WINAPI XA23SUB_SetOutputVoices(IXAudio23SubmixVoice *iface,
-        const XAUDIO23_VOICE_SENDS *pSendList)
-{
-    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
-    XAUDIO2_VOICE_SENDS sends;
-    HRESULT hr;
-    DWORD i;
-
-    TRACE("%p, %p\n", This, pSendList);
-
-    sends.SendCount = pSendList->OutputCount;
-    sends.pSends = HeapAlloc(GetProcessHeap(), 0, sends.SendCount * sizeof(*sends.pSends));
-    for(i = 0; i < sends.SendCount; ++i){
-        sends.pSends[i].Flags = 0;
-        sends.pSends[i].pOutputVoice = pSendList->pOutputVoices[i];
-    }
-
-    hr = IXAudio2SubmixVoice_SetOutputVoices(&This->IXAudio2SubmixVoice_iface, &sends);
-
-    HeapFree(GetProcessHeap(), 0, sends.pSends);
-
-    return hr;
-}
-
-static HRESULT WINAPI XA23SUB_SetEffectChain(IXAudio23SubmixVoice *iface,
-        const XAUDIO2_EFFECT_CHAIN *pEffectChain)
-{
-    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
-    return IXAudio2SubmixVoice_SetEffectChain(&This->IXAudio2SubmixVoice_iface, pEffectChain);
-}
-
-static HRESULT WINAPI XA23SUB_EnableEffect(IXAudio23SubmixVoice *iface,
-        UINT32 EffectIndex, UINT32 OperationSet)
-{
-    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
-    return IXAudio2SubmixVoice_EnableEffect(&This->IXAudio2SubmixVoice_iface,
-            EffectIndex, OperationSet);
-}
-
-static HRESULT WINAPI XA23SUB_DisableEffect(IXAudio23SubmixVoice *iface,
-        UINT32 EffectIndex, UINT32 OperationSet)
-{
-    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
-    return IXAudio2SubmixVoice_DisableEffect(&This->IXAudio2SubmixVoice_iface,
-            EffectIndex, OperationSet);
-}
-
-static void WINAPI XA23SUB_GetEffectState(IXAudio23SubmixVoice *iface,
-        UINT32 EffectIndex, BOOL *pEnabled)
-{
-    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
-    return IXAudio2SubmixVoice_GetEffectState(&This->IXAudio2SubmixVoice_iface,
-            EffectIndex, pEnabled);
-}
-
-static HRESULT WINAPI XA23SUB_SetEffectParameters(IXAudio23SubmixVoice *iface,
-        UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize,
-        UINT32 OperationSet)
-{
-    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
-    return IXAudio2SubmixVoice_SetEffectParameters(&This->IXAudio2SubmixVoice_iface,
-            EffectIndex, pParameters, ParametersByteSize, OperationSet);
-}
-
-static HRESULT WINAPI XA23SUB_GetEffectParameters(IXAudio23SubmixVoice *iface,
-        UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize)
-{
-    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
-    return IXAudio2SubmixVoice_GetEffectParameters(&This->IXAudio2SubmixVoice_iface,
-            EffectIndex, pParameters, ParametersByteSize);
-}
-
-static HRESULT WINAPI XA23SUB_SetFilterParameters(IXAudio23SubmixVoice *iface,
-        const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet)
-{
-    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
-    return IXAudio2SubmixVoice_SetFilterParameters(&This->IXAudio2SubmixVoice_iface,
-            pParameters, OperationSet);
-}
-
-static void WINAPI XA23SUB_GetFilterParameters(IXAudio23SubmixVoice *iface,
-        XAUDIO2_FILTER_PARAMETERS *pParameters)
-{
-    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
-    return IXAudio2SubmixVoice_GetFilterParameters(&This->IXAudio2SubmixVoice_iface, pParameters);
-}
-
-static HRESULT WINAPI XA23SUB_SetVolume(IXAudio23SubmixVoice *iface,
-        float Volume, UINT32 OperationSet)
-{
-    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
-    return IXAudio2SubmixVoice_SetVolume(&This->IXAudio2SubmixVoice_iface,
-            Volume, OperationSet);
-}
-
-static void WINAPI XA23SUB_GetVolume(IXAudio23SubmixVoice *iface,
-        float *pVolume)
-{
-    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
-    return IXAudio2SubmixVoice_GetVolume(&This->IXAudio2SubmixVoice_iface, pVolume);
-}
-
-static HRESULT WINAPI XA23SUB_SetChannelVolumes(IXAudio23SubmixVoice *iface,
-        UINT32 Channels, const float *pVolumes, UINT32 OperationSet)
-{
-    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
-    return IXAudio2SubmixVoice_SetChannelVolumes(&This->IXAudio2SubmixVoice_iface,
-            Channels, pVolumes, OperationSet);
-}
-
-static void WINAPI XA23SUB_GetChannelVolumes(IXAudio23SubmixVoice *iface,
-        UINT32 Channels, float *pVolumes)
-{
-    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
-    return IXAudio2SubmixVoice_GetChannelVolumes(&This->IXAudio2SubmixVoice_iface,
-            Channels, pVolumes);
-}
-
-static HRESULT WINAPI XA23SUB_SetOutputMatrix(IXAudio23SubmixVoice *iface,
-        IXAudio2Voice *pDestinationVoice, UINT32 SubmixChannels,
-        UINT32 DestinationChannels, const float *pLevelMatrix,
-        UINT32 OperationSet)
-{
-    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
-    return IXAudio2SubmixVoice_SetOutputMatrix(&This->IXAudio2SubmixVoice_iface,
-            pDestinationVoice, SubmixChannels, DestinationChannels,
-            pLevelMatrix, OperationSet);
-}
-
-static void WINAPI XA23SUB_GetOutputMatrix(IXAudio23SubmixVoice *iface,
-        IXAudio2Voice *pDestinationVoice, UINT32 SubmixChannels,
-        UINT32 DestinationChannels, float *pLevelMatrix)
-{
-    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
-    return IXAudio2SubmixVoice_GetOutputMatrix(&This->IXAudio2SubmixVoice_iface,
-            pDestinationVoice, SubmixChannels, DestinationChannels,
-            pLevelMatrix);
-}
-
-static void WINAPI XA23SUB_DestroyVoice(IXAudio23SubmixVoice *iface)
-{
-    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
-    return IXAudio2SubmixVoice_DestroyVoice(&This->IXAudio2SubmixVoice_iface);
-}
-
-const IXAudio23SubmixVoiceVtbl XAudio23SubmixVoice_Vtbl = {
-    XA23SUB_GetVoiceDetails,
-    XA23SUB_SetOutputVoices,
-    XA23SUB_SetEffectChain,
-    XA23SUB_EnableEffect,
-    XA23SUB_DisableEffect,
-    XA23SUB_GetEffectState,
-    XA23SUB_SetEffectParameters,
-    XA23SUB_GetEffectParameters,
-    XA23SUB_SetFilterParameters,
-    XA23SUB_GetFilterParameters,
-    XA23SUB_SetVolume,
-    XA23SUB_GetVolume,
-    XA23SUB_SetChannelVolumes,
-    XA23SUB_GetChannelVolumes,
-    XA23SUB_SetOutputMatrix,
-    XA23SUB_GetOutputMatrix,
-    XA23SUB_DestroyVoice
-};
-
-static IXAudio2Impl *impl_from_IXAudio23MasteringVoice(IXAudio23MasteringVoice *iface)
-{
-    return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio23MasteringVoice_iface);
-}
-
-static void WINAPI XA23M_GetVoiceDetails(IXAudio23MasteringVoice *iface,
-        XAUDIO2_VOICE_DETAILS *pVoiceDetails)
-{
-    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
-    return IXAudio2MasteringVoice_GetVoiceDetails(&This->IXAudio2MasteringVoice_iface, pVoiceDetails);
-}
-
-static HRESULT WINAPI XA23M_SetOutputVoices(IXAudio23MasteringVoice *iface,
-        const XAUDIO23_VOICE_SENDS *pSendList)
-{
-    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
-    XAUDIO2_VOICE_SENDS sends;
-    HRESULT hr;
-    DWORD i;
-
-    TRACE("%p, %p\n", This, pSendList);
-
-    sends.SendCount = pSendList->OutputCount;
-    sends.pSends = HeapAlloc(GetProcessHeap(), 0, sends.SendCount * sizeof(*sends.pSends));
-    for(i = 0; i < sends.SendCount; ++i){
-        sends.pSends[i].Flags = 0;
-        sends.pSends[i].pOutputVoice = pSendList->pOutputVoices[i];
-    }
-
-    hr = IXAudio2MasteringVoice_SetOutputVoices(&This->IXAudio2MasteringVoice_iface, &sends);
-
-    HeapFree(GetProcessHeap(), 0, sends.pSends);
-
-    return hr;
-}
-
-static HRESULT WINAPI XA23M_SetEffectChain(IXAudio23MasteringVoice *iface,
-        const XAUDIO2_EFFECT_CHAIN *pEffectChain)
-{
-    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
-    return IXAudio2MasteringVoice_SetEffectChain(&This->IXAudio2MasteringVoice_iface, pEffectChain);
-}
-
-static HRESULT WINAPI XA23M_EnableEffect(IXAudio23MasteringVoice *iface,
-        UINT32 EffectIndex, UINT32 OperationSet)
-{
-    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
-    return IXAudio2MasteringVoice_EnableEffect(&This->IXAudio2MasteringVoice_iface,
-            EffectIndex, OperationSet);
-}
-
-static HRESULT WINAPI XA23M_DisableEffect(IXAudio23MasteringVoice *iface,
-        UINT32 EffectIndex, UINT32 OperationSet)
-{
-    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
-    return IXAudio2MasteringVoice_DisableEffect(&This->IXAudio2MasteringVoice_iface,
-            EffectIndex, OperationSet);
-}
-
-static void WINAPI XA23M_GetEffectState(IXAudio23MasteringVoice *iface,
-        UINT32 EffectIndex, BOOL *pEnabled)
-{
-    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
-    return IXAudio2MasteringVoice_GetEffectState(&This->IXAudio2MasteringVoice_iface,
-            EffectIndex, pEnabled);
-}
-
-static HRESULT WINAPI XA23M_SetEffectParameters(IXAudio23MasteringVoice *iface,
-        UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize,
-        UINT32 OperationSet)
-{
-    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
-    return IXAudio2MasteringVoice_SetEffectParameters(&This->IXAudio2MasteringVoice_iface,
-            EffectIndex, pParameters, ParametersByteSize, OperationSet);
-}
-
-static HRESULT WINAPI XA23M_GetEffectParameters(IXAudio23MasteringVoice *iface,
-        UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize)
-{
-    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
-    return IXAudio2MasteringVoice_GetEffectParameters(&This->IXAudio2MasteringVoice_iface,
-            EffectIndex, pParameters, ParametersByteSize);
-}
-
-static HRESULT WINAPI XA23M_SetFilterParameters(IXAudio23MasteringVoice *iface,
-        const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet)
-{
-    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
-    return IXAudio2MasteringVoice_SetFilterParameters(&This->IXAudio2MasteringVoice_iface,
-            pParameters, OperationSet);
-}
-
-static void WINAPI XA23M_GetFilterParameters(IXAudio23MasteringVoice *iface,
-        XAUDIO2_FILTER_PARAMETERS *pParameters)
-{
-    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
-    return IXAudio2MasteringVoice_GetFilterParameters(&This->IXAudio2MasteringVoice_iface, pParameters);
-}
-
-static HRESULT WINAPI XA23M_SetVolume(IXAudio23MasteringVoice *iface,
-        float Volume, UINT32 OperationSet)
-{
-    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
-    return IXAudio2MasteringVoice_SetVolume(&This->IXAudio2MasteringVoice_iface,
-            Volume, OperationSet);
-}
-
-static void WINAPI XA23M_GetVolume(IXAudio23MasteringVoice *iface,
-        float *pVolume)
-{
-    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
-    return IXAudio2MasteringVoice_GetVolume(&This->IXAudio2MasteringVoice_iface, pVolume);
-}
-
-static HRESULT WINAPI XA23M_SetChannelVolumes(IXAudio23MasteringVoice *iface,
-        UINT32 Channels, const float *pVolumes, UINT32 OperationSet)
-{
-    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
-    return IXAudio2MasteringVoice_SetChannelVolumes(&This->IXAudio2MasteringVoice_iface,
-            Channels, pVolumes, OperationSet);
-}
-
-static void WINAPI XA23M_GetChannelVolumes(IXAudio23MasteringVoice *iface,
-        UINT32 Channels, float *pVolumes)
-{
-    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
-    return IXAudio2MasteringVoice_GetChannelVolumes(&This->IXAudio2MasteringVoice_iface,
-            Channels, pVolumes);
-}
-
-static HRESULT WINAPI XA23M_SetOutputMatrix(IXAudio23MasteringVoice *iface,
-        IXAudio2Voice *pDestinationVoice, UINT32 MasteringChannels,
-        UINT32 DestinationChannels, const float *pLevelMatrix,
-        UINT32 OperationSet)
-{
-    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
-    return IXAudio2MasteringVoice_SetOutputMatrix(&This->IXAudio2MasteringVoice_iface,
-            pDestinationVoice, MasteringChannels, DestinationChannels,
-            pLevelMatrix, OperationSet);
-}
-
-static void WINAPI XA23M_GetOutputMatrix(IXAudio23MasteringVoice *iface,
-        IXAudio2Voice *pDestinationVoice, UINT32 MasteringChannels,
-        UINT32 DestinationChannels, float *pLevelMatrix)
-{
-    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
-    return IXAudio2MasteringVoice_GetOutputMatrix(&This->IXAudio2MasteringVoice_iface,
-            pDestinationVoice, MasteringChannels, DestinationChannels,
-            pLevelMatrix);
-}
-
-static void WINAPI XA23M_DestroyVoice(IXAudio23MasteringVoice *iface)
-{
-    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
-    return IXAudio2MasteringVoice_DestroyVoice(&This->IXAudio2MasteringVoice_iface);
-}
-
-const IXAudio23MasteringVoiceVtbl XAudio23MasteringVoice_Vtbl = {
-    XA23M_GetVoiceDetails,
-    XA23M_SetOutputVoices,
-    XA23M_SetEffectChain,
-    XA23M_EnableEffect,
-    XA23M_DisableEffect,
-    XA23M_GetEffectState,
-    XA23M_SetEffectParameters,
-    XA23M_GetEffectParameters,
-    XA23M_SetFilterParameters,
-    XA23M_GetFilterParameters,
-    XA23M_SetVolume,
-    XA23M_GetVolume,
-    XA23M_SetChannelVolumes,
-    XA23M_GetChannelVolumes,
-    XA23M_SetOutputMatrix,
-    XA23M_GetOutputMatrix,
-    XA23M_DestroyVoice
-};
-
-static inline IXAudio2Impl *impl_from_IXAudio22(IXAudio22 *iface)
-{
-    return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio22_iface);
-}
-
-static HRESULT WINAPI XA22_QueryInterface(IXAudio22 *iface, REFIID riid,
-        void **ppvObject)
-{
-    IXAudio2Impl *This = impl_from_IXAudio22(iface);
-    return IXAudio2_QueryInterface(&This->IXAudio2_iface, riid, ppvObject);
-}
-
-static ULONG WINAPI XA22_AddRef(IXAudio22 *iface)
-{
-    IXAudio2Impl *This = impl_from_IXAudio22(iface);
-    return IXAudio2_AddRef(&This->IXAudio2_iface);
-}
-
-static ULONG WINAPI XA22_Release(IXAudio22 *iface)
-{
-    IXAudio2Impl *This = impl_from_IXAudio22(iface);
-    return IXAudio2_Release(&This->IXAudio2_iface);
-}
-
-static HRESULT WINAPI XA22_GetDeviceCount(IXAudio22 *iface, UINT32 *pCount)
-{
-    IXAudio2Impl *This = impl_from_IXAudio22(iface);
-
-    TRACE("%p, %p\n", This, pCount);
-
-    *pCount = This->ndevs;
-
-    return S_OK;
-}
-
-static HRESULT WINAPI XA22_GetDeviceDetails(IXAudio22 *iface, UINT32 index,
-        XAUDIO2_DEVICE_DETAILS *pDeviceDetails)
-{
-    IXAudio2Impl *This = impl_from_IXAudio22(iface);
-    HRESULT hr;
-    IMMDevice *dev;
-    IAudioClient *client;
-    IPropertyStore *ps;
-    WAVEFORMATEX *wfx;
-    PROPVARIANT var;
-
-    TRACE("%p, %u, %p\n", This, index, pDeviceDetails);
-
-    if(index >= This->ndevs)
-        return E_INVALIDARG;
-
-    hr = IMMDeviceEnumerator_GetDevice(This->devenum, This->devids[index], &dev);
-    if(FAILED(hr)){
-        WARN("GetDevice failed: %08x\n", hr);
-        return hr;
-    }
-
-    hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
-            NULL, (void**)&client);
-    if(FAILED(hr)){
-        WARN("Activate failed: %08x\n", hr);
-        IMMDevice_Release(dev);
-        return hr;
-    }
-
-    hr = IMMDevice_OpenPropertyStore(dev, STGM_READ, &ps);
-    if(FAILED(hr)){
-        WARN("OpenPropertyStore failed: %08x\n", hr);
-        IAudioClient_Release(client);
-        IMMDevice_Release(dev);
-        return hr;
-    }
-
-    PropVariantInit(&var);
-
-    hr = IPropertyStore_GetValue(ps, (PROPERTYKEY*)&DEVPKEY_Device_FriendlyName, &var);
-    if(FAILED(hr)){
-        WARN("GetValue failed: %08x\n", hr);
-        goto done;
-    }
-
-    lstrcpynW(pDeviceDetails->DisplayName, var.u.pwszVal, sizeof(pDeviceDetails->DisplayName)/sizeof(WCHAR));
-
-    PropVariantClear(&var);
-
-    hr = IAudioClient_GetMixFormat(client, &wfx);
-    if(FAILED(hr)){
-        WARN("GetMixFormat failed: %08x\n", hr);
-        goto done;
-    }
-
-    lstrcpyW(pDeviceDetails->DeviceID, This->devids[index]);
-
-    if(index == 0)
-        pDeviceDetails->Role = GlobalDefaultDevice;
-    else
-        pDeviceDetails->Role = NotDefaultDevice;
-
-    if(sizeof(WAVEFORMATEX) + wfx->cbSize > sizeof(pDeviceDetails->OutputFormat)){
-        FIXME("AudioClient format is too large to fit into WAVEFORMATEXTENSIBLE!\n");
-        CoTaskMemFree(wfx);
-        hr = E_FAIL;
-        goto done;
-    }
-    memcpy(&pDeviceDetails->OutputFormat, wfx, sizeof(WAVEFORMATEX) + wfx->cbSize);
-
-    CoTaskMemFree(wfx);
-
-done:
-    IPropertyStore_Release(ps);
-    IAudioClient_Release(client);
-    IMMDevice_Release(dev);
-
-    return hr;
-}
-
-static HRESULT WINAPI XA22_Initialize(IXAudio22 *iface, UINT32 flags,
-        XAUDIO2_PROCESSOR processor)
-{
-    IXAudio2Impl *This = impl_from_IXAudio22(iface);
-    TRACE("(%p)->(0x%x, 0x%x)\n", This, flags, processor);
-    return xaudio2_initialize(This, flags, processor);
-}
-
-static HRESULT WINAPI XA22_RegisterForCallbacks(IXAudio22 *iface,
-        IXAudio2EngineCallback *pCallback)
-{
-    IXAudio2Impl *This = impl_from_IXAudio22(iface);
-    return IXAudio2_RegisterForCallbacks(&This->IXAudio2_iface, pCallback);
-}
-
-static void WINAPI XA22_UnregisterForCallbacks(IXAudio22 *iface,
-        IXAudio2EngineCallback *pCallback)
-{
-    IXAudio2Impl *This = impl_from_IXAudio22(iface);
-    IXAudio2_UnregisterForCallbacks(&This->IXAudio2_iface, pCallback);
-}
-
-static HRESULT WINAPI XA22_CreateSourceVoice(IXAudio22 *iface,
-        IXAudio2SourceVoice **ppSourceVoice, const WAVEFORMATEX *pSourceFormat,
-        UINT32 flags, float maxFrequencyRatio,
-        IXAudio2VoiceCallback *pCallback, const XAUDIO2_VOICE_SENDS *pSendList,
-        const XAUDIO2_EFFECT_CHAIN *pEffectChain)
-{
-    IXAudio2Impl *This = impl_from_IXAudio22(iface);
-    return IXAudio2_CreateSourceVoice(&This->IXAudio2_iface, ppSourceVoice,
-            pSourceFormat, flags, maxFrequencyRatio, pCallback, pSendList,
-            pEffectChain);
-}
-
-static HRESULT WINAPI XA22_CreateSubmixVoice(IXAudio22 *iface,
-        IXAudio2SubmixVoice **ppSubmixVoice, UINT32 inputChannels,
-        UINT32 inputSampleRate, UINT32 flags, UINT32 processingStage,
-        const XAUDIO2_VOICE_SENDS *pSendList,
-        const XAUDIO2_EFFECT_CHAIN *pEffectChain)
-{
-    IXAudio2Impl *This = impl_from_IXAudio22(iface);
-    return IXAudio2_CreateSubmixVoice(&This->IXAudio2_iface, ppSubmixVoice,
-            inputChannels, inputSampleRate, flags, processingStage, pSendList,
-            pEffectChain);
-}
-
-static HRESULT WINAPI XA22_CreateMasteringVoice(IXAudio22 *iface,
-        IXAudio2MasteringVoice **ppMasteringVoice, UINT32 inputChannels,
-        UINT32 inputSampleRate, UINT32 flags, UINT32 deviceIndex,
-        const XAUDIO2_EFFECT_CHAIN *pEffectChain)
-{
-    IXAudio2Impl *This = impl_from_IXAudio22(iface);
-
-    TRACE("(%p)->(%p, %u, %u, 0x%x, %u, %p)\n", This, ppMasteringVoice,
-            inputChannels, inputSampleRate, flags, deviceIndex,
-            pEffectChain);
-
-    if(deviceIndex >= This->ndevs)
-        return E_INVALIDARG;
-
-    return IXAudio2_CreateMasteringVoice(&This->IXAudio2_iface, ppMasteringVoice,
-            inputChannels, inputSampleRate, flags, This->devids[deviceIndex],
-            pEffectChain, AudioCategory_GameEffects);
-}
-
-static HRESULT WINAPI XA22_StartEngine(IXAudio22 *iface)
-{
-    IXAudio2Impl *This = impl_from_IXAudio22(iface);
-    return IXAudio2_StartEngine(&This->IXAudio2_iface);
-}
-
-static void WINAPI XA22_StopEngine(IXAudio22 *iface)
-{
-    IXAudio2Impl *This = impl_from_IXAudio22(iface);
-    return IXAudio2_StopEngine(&This->IXAudio2_iface);
-}
-
-static HRESULT WINAPI XA22_CommitChanges(IXAudio22 *iface, UINT32 operationSet)
-{
-    IXAudio2Impl *This = impl_from_IXAudio22(iface);
-    return IXAudio2_CommitChanges(&This->IXAudio2_iface, operationSet);
-}
-
-static void WINAPI XA22_GetPerformanceData(IXAudio22 *iface,
-        XAUDIO22_PERFORMANCE_DATA *pPerfData)
-{
-    IXAudio2Impl *This = impl_from_IXAudio22(iface);
-    XAUDIO2_PERFORMANCE_DATA data;
-
-    IXAudio2_GetPerformanceData(&This->IXAudio2_iface, &data);
-
-    pPerfData->AudioCyclesSinceLastQuery = data.AudioCyclesSinceLastQuery;
-    pPerfData->TotalCyclesSinceLastQuery = data.TotalCyclesSinceLastQuery;
-    pPerfData->MinimumCyclesPerQuantum = data.MinimumCyclesPerQuantum;
-    pPerfData->MaximumCyclesPerQuantum = data.MaximumCyclesPerQuantum;
-    pPerfData->MemoryUsageInBytes = data.MemoryUsageInBytes;
-    pPerfData->CurrentLatencyInSamples = data.CurrentLatencyInSamples;
-    pPerfData->GlitchesSinceEngineStarted = data.GlitchesSinceEngineStarted;
-    pPerfData->ActiveSourceVoiceCount = data.ActiveSourceVoiceCount;
-    pPerfData->TotalSourceVoiceCount = data.TotalSourceVoiceCount;
-
-    pPerfData->ActiveSubmixVoiceCount = data.ActiveSubmixVoiceCount;
-    pPerfData->TotalSubmixVoiceCount = data.ActiveSubmixVoiceCount;
-
-    pPerfData->ActiveXmaSourceVoices = data.ActiveXmaSourceVoices;
-    pPerfData->ActiveXmaStreams = data.ActiveXmaStreams;
-}
-
-static void WINAPI XA22_SetDebugConfiguration(IXAudio22 *iface,
-        const XAUDIO2_DEBUG_CONFIGURATION *pDebugConfiguration,
-        void *pReserved)
-{
-    IXAudio2Impl *This = impl_from_IXAudio22(iface);
-    return IXAudio2_SetDebugConfiguration(&This->IXAudio2_iface,
-            pDebugConfiguration, pReserved);
-}
-
-const IXAudio22Vtbl XAudio22_Vtbl = {
-    XA22_QueryInterface,
-    XA22_AddRef,
-    XA22_Release,
-    XA22_GetDeviceCount,
-    XA22_GetDeviceDetails,
-    XA22_Initialize,
-    XA22_RegisterForCallbacks,
-    XA22_UnregisterForCallbacks,
-    XA22_CreateSourceVoice,
-    XA22_CreateSubmixVoice,
-    XA22_CreateMasteringVoice,
-    XA22_StartEngine,
-    XA22_StopEngine,
-    XA22_CommitChanges,
-    XA22_GetPerformanceData,
-    XA22_SetDebugConfiguration
-};
-
-static XA2SourceImpl *impl_from_IXAudio20SourceVoice(IXAudio20SourceVoice *iface)
-{
-    return CONTAINING_RECORD(iface, XA2SourceImpl, IXAudio20SourceVoice_iface);
-}
-
-static void WINAPI XA20SRC_GetVoiceDetails(IXAudio20SourceVoice *iface,
-        XAUDIO2_VOICE_DETAILS *pVoiceDetails)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_GetVoiceDetails(&This->IXAudio2SourceVoice_iface, pVoiceDetails);
-}
-
-static HRESULT WINAPI XA20SRC_SetOutputVoices(IXAudio20SourceVoice *iface,
-        const XAUDIO23_VOICE_SENDS *pSendList)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    XAUDIO2_VOICE_SENDS sends;
-    HRESULT hr;
-    DWORD i;
-
-    TRACE("%p, %p\n", This, pSendList);
-
-    sends.SendCount = pSendList->OutputCount;
-    sends.pSends = HeapAlloc(GetProcessHeap(), 0, sends.SendCount * sizeof(*sends.pSends));
-    for(i = 0; i < sends.SendCount; ++i){
-        sends.pSends[i].Flags = 0;
-        sends.pSends[i].pOutputVoice = pSendList->pOutputVoices[i];
-    }
-
-    hr = IXAudio2SourceVoice_SetOutputVoices(&This->IXAudio2SourceVoice_iface, &sends);
-
-    HeapFree(GetProcessHeap(), 0, sends.pSends);
-
-    return hr;
-}
-
-static HRESULT WINAPI XA20SRC_SetEffectChain(IXAudio20SourceVoice *iface,
-        const XAUDIO2_EFFECT_CHAIN *pEffectChain)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_SetEffectChain(&This->IXAudio2SourceVoice_iface, pEffectChain);
-}
-
-static HRESULT WINAPI XA20SRC_EnableEffect(IXAudio20SourceVoice *iface,
-        UINT32 EffectIndex, UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_EnableEffect(&This->IXAudio2SourceVoice_iface,
-            EffectIndex, OperationSet);
-}
-
-static HRESULT WINAPI XA20SRC_DisableEffect(IXAudio20SourceVoice *iface,
-        UINT32 EffectIndex, UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_DisableEffect(&This->IXAudio2SourceVoice_iface,
-            EffectIndex, OperationSet);
-}
-
-static void WINAPI XA20SRC_GetEffectState(IXAudio20SourceVoice *iface,
-        UINT32 EffectIndex, BOOL *pEnabled)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_GetEffectState(&This->IXAudio2SourceVoice_iface,
-            EffectIndex, pEnabled);
-}
-
-static HRESULT WINAPI XA20SRC_SetEffectParameters(IXAudio20SourceVoice *iface,
-        UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize,
-        UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_SetEffectParameters(&This->IXAudio2SourceVoice_iface,
-            EffectIndex, pParameters, ParametersByteSize, OperationSet);
-}
-
-static HRESULT WINAPI XA20SRC_GetEffectParameters(IXAudio20SourceVoice *iface,
-        UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_GetEffectParameters(&This->IXAudio2SourceVoice_iface,
-            EffectIndex, pParameters, ParametersByteSize);
-}
-
-static HRESULT WINAPI XA20SRC_SetFilterParameters(IXAudio20SourceVoice *iface,
-        const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_SetFilterParameters(&This->IXAudio2SourceVoice_iface,
-            pParameters, OperationSet);
-}
-
-static void WINAPI XA20SRC_GetFilterParameters(IXAudio20SourceVoice *iface,
-        XAUDIO2_FILTER_PARAMETERS *pParameters)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_GetFilterParameters(&This->IXAudio2SourceVoice_iface, pParameters);
-}
-
-static HRESULT WINAPI XA20SRC_SetVolume(IXAudio20SourceVoice *iface,
-        float Volume, UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_SetVolume(&This->IXAudio2SourceVoice_iface,
-            Volume, OperationSet);
-}
-
-static void WINAPI XA20SRC_GetVolume(IXAudio20SourceVoice *iface,
-        float *pVolume)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_GetVolume(&This->IXAudio2SourceVoice_iface, pVolume);
-}
-
-static HRESULT WINAPI XA20SRC_SetChannelVolumes(IXAudio20SourceVoice *iface,
-        UINT32 Channels, const float *pVolumes, UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_SetChannelVolumes(&This->IXAudio2SourceVoice_iface,
-            Channels, pVolumes, OperationSet);
-}
-
-static void WINAPI XA20SRC_GetChannelVolumes(IXAudio20SourceVoice *iface,
-        UINT32 Channels, float *pVolumes)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_GetChannelVolumes(&This->IXAudio2SourceVoice_iface,
-            Channels, pVolumes);
-}
-
-static HRESULT WINAPI XA20SRC_SetOutputMatrix(IXAudio20SourceVoice *iface,
-        IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels,
-        UINT32 DestinationChannels, const float *pLevelMatrix,
-        UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_SetOutputMatrix(&This->IXAudio2SourceVoice_iface,
-            pDestinationVoice, SourceChannels, DestinationChannels,
-            pLevelMatrix, OperationSet);
-}
-
-static HRESULT WINAPI XA20SRC_GetOutputMatrix(IXAudio20SourceVoice *iface,
-        IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels,
-        UINT32 DestinationChannels, float *pLevelMatrix)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    IXAudio2SourceVoice_GetOutputMatrix(&This->IXAudio2SourceVoice_iface,
-            pDestinationVoice, SourceChannels, DestinationChannels,
-            pLevelMatrix);
-    return S_OK;
-}
-
-static void WINAPI XA20SRC_DestroyVoice(IXAudio20SourceVoice *iface)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_DestroyVoice(&This->IXAudio2SourceVoice_iface);
-}
-
-static HRESULT WINAPI XA20SRC_Start(IXAudio20SourceVoice *iface, UINT32 Flags,
-        UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_Start(&This->IXAudio2SourceVoice_iface, Flags, OperationSet);
-}
-
-static HRESULT WINAPI XA20SRC_Stop(IXAudio20SourceVoice *iface, UINT32 Flags,
-        UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_Stop(&This->IXAudio2SourceVoice_iface, Flags, OperationSet);
-}
-
-static HRESULT WINAPI XA20SRC_SubmitSourceBuffer(IXAudio20SourceVoice *iface,
-        const XAUDIO2_BUFFER *pBuffer, const XAUDIO2_BUFFER_WMA *pBufferWMA)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_SubmitSourceBuffer(&This->IXAudio2SourceVoice_iface,
-            pBuffer, pBufferWMA);
-}
-
-static HRESULT WINAPI XA20SRC_FlushSourceBuffers(IXAudio20SourceVoice *iface)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_FlushSourceBuffers(&This->IXAudio2SourceVoice_iface);
-}
-
-static HRESULT WINAPI XA20SRC_Discontinuity(IXAudio20SourceVoice *iface)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_Discontinuity(&This->IXAudio2SourceVoice_iface);
-}
-
-static HRESULT WINAPI XA20SRC_ExitLoop(IXAudio20SourceVoice *iface,
-        UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_ExitLoop(&This->IXAudio2SourceVoice_iface, OperationSet);
-}
-
-static void WINAPI XA20SRC_GetState(IXAudio20SourceVoice *iface,
-        XAUDIO2_VOICE_STATE *pVoiceState)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_GetState(&This->IXAudio2SourceVoice_iface, pVoiceState, 0);
-}
-
-static HRESULT WINAPI XA20SRC_SetFrequencyRatio(IXAudio20SourceVoice *iface,
-        float Ratio, UINT32 OperationSet)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_SetFrequencyRatio(&This->IXAudio2SourceVoice_iface,
-            Ratio, OperationSet);
-}
-
-static void WINAPI XA20SRC_GetFrequencyRatio(IXAudio20SourceVoice *iface,
-        float *pRatio)
-{
-    XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface);
-    return IXAudio2SourceVoice_GetFrequencyRatio(&This->IXAudio2SourceVoice_iface, pRatio);
-}
-
-const IXAudio20SourceVoiceVtbl XAudio20SourceVoice_Vtbl = {
-    XA20SRC_GetVoiceDetails,
-    XA20SRC_SetOutputVoices,
-    XA20SRC_SetEffectChain,
-    XA20SRC_EnableEffect,
-    XA20SRC_DisableEffect,
-    XA20SRC_GetEffectState,
-    XA20SRC_SetEffectParameters,
-    XA20SRC_GetEffectParameters,
-    XA20SRC_SetFilterParameters,
-    XA20SRC_GetFilterParameters,
-    XA20SRC_SetVolume,
-    XA20SRC_GetVolume,
-    XA20SRC_SetChannelVolumes,
-    XA20SRC_GetChannelVolumes,
-    XA20SRC_SetOutputMatrix,
-    XA20SRC_GetOutputMatrix,
-    XA20SRC_DestroyVoice,
-    XA20SRC_Start,
-    XA20SRC_Stop,
-    XA20SRC_SubmitSourceBuffer,
-    XA20SRC_FlushSourceBuffers,
-    XA20SRC_Discontinuity,
-    XA20SRC_ExitLoop,
-    XA20SRC_GetState,
-    XA20SRC_SetFrequencyRatio,
-    XA20SRC_GetFrequencyRatio,
-};
 
+/* BEGIN IXAudio2SubmixVoice */
+#if XAUDIO2_VER == 0
 static XA2SubmixImpl *impl_from_IXAudio20SubmixVoice(IXAudio20SubmixVoice *iface)
 {
     return CONTAINING_RECORD(iface, XA2SubmixImpl, IXAudio20SubmixVoice_iface);
@@ -1864,6 +1035,190 @@ const IXAudio20SubmixVoiceVtbl XAudio20SubmixVoice_Vtbl = {
     XA20SUB_DestroyVoice
 };
 
+#elif XAUDIO2_VER <= 3
+
+static XA2SubmixImpl *impl_from_IXAudio23SubmixVoice(IXAudio23SubmixVoice *iface)
+{
+    return CONTAINING_RECORD(iface, XA2SubmixImpl, IXAudio23SubmixVoice_iface);
+}
+
+static void WINAPI XA23SUB_GetVoiceDetails(IXAudio23SubmixVoice *iface,
+        XAUDIO2_VOICE_DETAILS *pVoiceDetails)
+{
+    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
+    return IXAudio2SubmixVoice_GetVoiceDetails(&This->IXAudio2SubmixVoice_iface, pVoiceDetails);
+}
+
+static HRESULT WINAPI XA23SUB_SetOutputVoices(IXAudio23SubmixVoice *iface,
+        const XAUDIO23_VOICE_SENDS *pSendList)
+{
+    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
+    XAUDIO2_VOICE_SENDS sends;
+    HRESULT hr;
+    DWORD i;
+
+    TRACE("%p, %p\n", This, pSendList);
+
+    sends.SendCount = pSendList->OutputCount;
+    sends.pSends = HeapAlloc(GetProcessHeap(), 0, sends.SendCount * sizeof(*sends.pSends));
+    for(i = 0; i < sends.SendCount; ++i){
+        sends.pSends[i].Flags = 0;
+        sends.pSends[i].pOutputVoice = pSendList->pOutputVoices[i];
+    }
+
+    hr = IXAudio2SubmixVoice_SetOutputVoices(&This->IXAudio2SubmixVoice_iface, &sends);
+
+    HeapFree(GetProcessHeap(), 0, sends.pSends);
+
+    return hr;
+}
+
+static HRESULT WINAPI XA23SUB_SetEffectChain(IXAudio23SubmixVoice *iface,
+        const XAUDIO2_EFFECT_CHAIN *pEffectChain)
+{
+    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
+    return IXAudio2SubmixVoice_SetEffectChain(&This->IXAudio2SubmixVoice_iface, pEffectChain);
+}
+
+static HRESULT WINAPI XA23SUB_EnableEffect(IXAudio23SubmixVoice *iface,
+        UINT32 EffectIndex, UINT32 OperationSet)
+{
+    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
+    return IXAudio2SubmixVoice_EnableEffect(&This->IXAudio2SubmixVoice_iface,
+            EffectIndex, OperationSet);
+}
+
+static HRESULT WINAPI XA23SUB_DisableEffect(IXAudio23SubmixVoice *iface,
+        UINT32 EffectIndex, UINT32 OperationSet)
+{
+    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
+    return IXAudio2SubmixVoice_DisableEffect(&This->IXAudio2SubmixVoice_iface,
+            EffectIndex, OperationSet);
+}
+
+static void WINAPI XA23SUB_GetEffectState(IXAudio23SubmixVoice *iface,
+        UINT32 EffectIndex, BOOL *pEnabled)
+{
+    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
+    return IXAudio2SubmixVoice_GetEffectState(&This->IXAudio2SubmixVoice_iface,
+            EffectIndex, pEnabled);
+}
+
+static HRESULT WINAPI XA23SUB_SetEffectParameters(IXAudio23SubmixVoice *iface,
+        UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize,
+        UINT32 OperationSet)
+{
+    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
+    return IXAudio2SubmixVoice_SetEffectParameters(&This->IXAudio2SubmixVoice_iface,
+            EffectIndex, pParameters, ParametersByteSize, OperationSet);
+}
+
+static HRESULT WINAPI XA23SUB_GetEffectParameters(IXAudio23SubmixVoice *iface,
+        UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize)
+{
+    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
+    return IXAudio2SubmixVoice_GetEffectParameters(&This->IXAudio2SubmixVoice_iface,
+            EffectIndex, pParameters, ParametersByteSize);
+}
+
+static HRESULT WINAPI XA23SUB_SetFilterParameters(IXAudio23SubmixVoice *iface,
+        const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet)
+{
+    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
+    return IXAudio2SubmixVoice_SetFilterParameters(&This->IXAudio2SubmixVoice_iface,
+            pParameters, OperationSet);
+}
+
+static void WINAPI XA23SUB_GetFilterParameters(IXAudio23SubmixVoice *iface,
+        XAUDIO2_FILTER_PARAMETERS *pParameters)
+{
+    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
+    return IXAudio2SubmixVoice_GetFilterParameters(&This->IXAudio2SubmixVoice_iface, pParameters);
+}
+
+static HRESULT WINAPI XA23SUB_SetVolume(IXAudio23SubmixVoice *iface,
+        float Volume, UINT32 OperationSet)
+{
+    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
+    return IXAudio2SubmixVoice_SetVolume(&This->IXAudio2SubmixVoice_iface,
+            Volume, OperationSet);
+}
+
+static void WINAPI XA23SUB_GetVolume(IXAudio23SubmixVoice *iface,
+        float *pVolume)
+{
+    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
+    return IXAudio2SubmixVoice_GetVolume(&This->IXAudio2SubmixVoice_iface, pVolume);
+}
+
+static HRESULT WINAPI XA23SUB_SetChannelVolumes(IXAudio23SubmixVoice *iface,
+        UINT32 Channels, const float *pVolumes, UINT32 OperationSet)
+{
+    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
+    return IXAudio2SubmixVoice_SetChannelVolumes(&This->IXAudio2SubmixVoice_iface,
+            Channels, pVolumes, OperationSet);
+}
+
+static void WINAPI XA23SUB_GetChannelVolumes(IXAudio23SubmixVoice *iface,
+        UINT32 Channels, float *pVolumes)
+{
+    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
+    return IXAudio2SubmixVoice_GetChannelVolumes(&This->IXAudio2SubmixVoice_iface,
+            Channels, pVolumes);
+}
+
+static HRESULT WINAPI XA23SUB_SetOutputMatrix(IXAudio23SubmixVoice *iface,
+        IXAudio2Voice *pDestinationVoice, UINT32 SubmixChannels,
+        UINT32 DestinationChannels, const float *pLevelMatrix,
+        UINT32 OperationSet)
+{
+    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
+    return IXAudio2SubmixVoice_SetOutputMatrix(&This->IXAudio2SubmixVoice_iface,
+            pDestinationVoice, SubmixChannels, DestinationChannels,
+            pLevelMatrix, OperationSet);
+}
+
+static void WINAPI XA23SUB_GetOutputMatrix(IXAudio23SubmixVoice *iface,
+        IXAudio2Voice *pDestinationVoice, UINT32 SubmixChannels,
+        UINT32 DestinationChannels, float *pLevelMatrix)
+{
+    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
+    return IXAudio2SubmixVoice_GetOutputMatrix(&This->IXAudio2SubmixVoice_iface,
+            pDestinationVoice, SubmixChannels, DestinationChannels,
+            pLevelMatrix);
+}
+
+static void WINAPI XA23SUB_DestroyVoice(IXAudio23SubmixVoice *iface)
+{
+    XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface);
+    return IXAudio2SubmixVoice_DestroyVoice(&This->IXAudio2SubmixVoice_iface);
+}
+
+const IXAudio23SubmixVoiceVtbl XAudio23SubmixVoice_Vtbl = {
+    XA23SUB_GetVoiceDetails,
+    XA23SUB_SetOutputVoices,
+    XA23SUB_SetEffectChain,
+    XA23SUB_EnableEffect,
+    XA23SUB_DisableEffect,
+    XA23SUB_GetEffectState,
+    XA23SUB_SetEffectParameters,
+    XA23SUB_GetEffectParameters,
+    XA23SUB_SetFilterParameters,
+    XA23SUB_GetFilterParameters,
+    XA23SUB_SetVolume,
+    XA23SUB_GetVolume,
+    XA23SUB_SetChannelVolumes,
+    XA23SUB_GetChannelVolumes,
+    XA23SUB_SetOutputMatrix,
+    XA23SUB_GetOutputMatrix,
+    XA23SUB_DestroyVoice
+};
+#endif
+/* END IXAudio2SubmixVoice */
+
+
+/* BEGIN IXAudio2MasteringVoice */
+#if XAUDIO2_VER == 0
 static IXAudio2Impl *impl_from_IXAudio20MasteringVoice(IXAudio20MasteringVoice *iface)
 {
     return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio20MasteringVoice_iface);
@@ -2042,6 +1397,190 @@ const IXAudio20MasteringVoiceVtbl XAudio20MasteringVoice_Vtbl = {
     XA20M_DestroyVoice
 };
 
+#elif XAUDIO2_VER <= 3
+
+static IXAudio2Impl *impl_from_IXAudio23MasteringVoice(IXAudio23MasteringVoice *iface)
+{
+    return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio23MasteringVoice_iface);
+}
+
+static void WINAPI XA23M_GetVoiceDetails(IXAudio23MasteringVoice *iface,
+        XAUDIO2_VOICE_DETAILS *pVoiceDetails)
+{
+    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
+    return IXAudio2MasteringVoice_GetVoiceDetails(&This->IXAudio2MasteringVoice_iface, pVoiceDetails);
+}
+
+static HRESULT WINAPI XA23M_SetOutputVoices(IXAudio23MasteringVoice *iface,
+        const XAUDIO23_VOICE_SENDS *pSendList)
+{
+    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
+    XAUDIO2_VOICE_SENDS sends;
+    HRESULT hr;
+    DWORD i;
+
+    TRACE("%p, %p\n", This, pSendList);
+
+    sends.SendCount = pSendList->OutputCount;
+    sends.pSends = HeapAlloc(GetProcessHeap(), 0, sends.SendCount * sizeof(*sends.pSends));
+    for(i = 0; i < sends.SendCount; ++i){
+        sends.pSends[i].Flags = 0;
+        sends.pSends[i].pOutputVoice = pSendList->pOutputVoices[i];
+    }
+
+    hr = IXAudio2MasteringVoice_SetOutputVoices(&This->IXAudio2MasteringVoice_iface, &sends);
+
+    HeapFree(GetProcessHeap(), 0, sends.pSends);
+
+    return hr;
+}
+
+static HRESULT WINAPI XA23M_SetEffectChain(IXAudio23MasteringVoice *iface,
+        const XAUDIO2_EFFECT_CHAIN *pEffectChain)
+{
+    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
+    return IXAudio2MasteringVoice_SetEffectChain(&This->IXAudio2MasteringVoice_iface, pEffectChain);
+}
+
+static HRESULT WINAPI XA23M_EnableEffect(IXAudio23MasteringVoice *iface,
+        UINT32 EffectIndex, UINT32 OperationSet)
+{
+    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
+    return IXAudio2MasteringVoice_EnableEffect(&This->IXAudio2MasteringVoice_iface,
+            EffectIndex, OperationSet);
+}
+
+static HRESULT WINAPI XA23M_DisableEffect(IXAudio23MasteringVoice *iface,
+        UINT32 EffectIndex, UINT32 OperationSet)
+{
+    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
+    return IXAudio2MasteringVoice_DisableEffect(&This->IXAudio2MasteringVoice_iface,
+            EffectIndex, OperationSet);
+}
+
+static void WINAPI XA23M_GetEffectState(IXAudio23MasteringVoice *iface,
+        UINT32 EffectIndex, BOOL *pEnabled)
+{
+    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
+    return IXAudio2MasteringVoice_GetEffectState(&This->IXAudio2MasteringVoice_iface,
+            EffectIndex, pEnabled);
+}
+
+static HRESULT WINAPI XA23M_SetEffectParameters(IXAudio23MasteringVoice *iface,
+        UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize,
+        UINT32 OperationSet)
+{
+    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
+    return IXAudio2MasteringVoice_SetEffectParameters(&This->IXAudio2MasteringVoice_iface,
+            EffectIndex, pParameters, ParametersByteSize, OperationSet);
+}
+
+static HRESULT WINAPI XA23M_GetEffectParameters(IXAudio23MasteringVoice *iface,
+        UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize)
+{
+    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
+    return IXAudio2MasteringVoice_GetEffectParameters(&This->IXAudio2MasteringVoice_iface,
+            EffectIndex, pParameters, ParametersByteSize);
+}
+
+static HRESULT WINAPI XA23M_SetFilterParameters(IXAudio23MasteringVoice *iface,
+        const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet)
+{
+    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
+    return IXAudio2MasteringVoice_SetFilterParameters(&This->IXAudio2MasteringVoice_iface,
+            pParameters, OperationSet);
+}
+
+static void WINAPI XA23M_GetFilterParameters(IXAudio23MasteringVoice *iface,
+        XAUDIO2_FILTER_PARAMETERS *pParameters)
+{
+    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
+    return IXAudio2MasteringVoice_GetFilterParameters(&This->IXAudio2MasteringVoice_iface, pParameters);
+}
+
+static HRESULT WINAPI XA23M_SetVolume(IXAudio23MasteringVoice *iface,
+        float Volume, UINT32 OperationSet)
+{
+    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
+    return IXAudio2MasteringVoice_SetVolume(&This->IXAudio2MasteringVoice_iface,
+            Volume, OperationSet);
+}
+
+static void WINAPI XA23M_GetVolume(IXAudio23MasteringVoice *iface,
+        float *pVolume)
+{
+    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
+    return IXAudio2MasteringVoice_GetVolume(&This->IXAudio2MasteringVoice_iface, pVolume);
+}
+
+static HRESULT WINAPI XA23M_SetChannelVolumes(IXAudio23MasteringVoice *iface,
+        UINT32 Channels, const float *pVolumes, UINT32 OperationSet)
+{
+    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
+    return IXAudio2MasteringVoice_SetChannelVolumes(&This->IXAudio2MasteringVoice_iface,
+            Channels, pVolumes, OperationSet);
+}
+
+static void WINAPI XA23M_GetChannelVolumes(IXAudio23MasteringVoice *iface,
+        UINT32 Channels, float *pVolumes)
+{
+    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
+    return IXAudio2MasteringVoice_GetChannelVolumes(&This->IXAudio2MasteringVoice_iface,
+            Channels, pVolumes);
+}
+
+static HRESULT WINAPI XA23M_SetOutputMatrix(IXAudio23MasteringVoice *iface,
+        IXAudio2Voice *pDestinationVoice, UINT32 MasteringChannels,
+        UINT32 DestinationChannels, const float *pLevelMatrix,
+        UINT32 OperationSet)
+{
+    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
+    return IXAudio2MasteringVoice_SetOutputMatrix(&This->IXAudio2MasteringVoice_iface,
+            pDestinationVoice, MasteringChannels, DestinationChannels,
+            pLevelMatrix, OperationSet);
+}
+
+static void WINAPI XA23M_GetOutputMatrix(IXAudio23MasteringVoice *iface,
+        IXAudio2Voice *pDestinationVoice, UINT32 MasteringChannels,
+        UINT32 DestinationChannels, float *pLevelMatrix)
+{
+    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
+    return IXAudio2MasteringVoice_GetOutputMatrix(&This->IXAudio2MasteringVoice_iface,
+            pDestinationVoice, MasteringChannels, DestinationChannels,
+            pLevelMatrix);
+}
+
+static void WINAPI XA23M_DestroyVoice(IXAudio23MasteringVoice *iface)
+{
+    IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface);
+    return IXAudio2MasteringVoice_DestroyVoice(&This->IXAudio2MasteringVoice_iface);
+}
+
+const IXAudio23MasteringVoiceVtbl XAudio23MasteringVoice_Vtbl = {
+    XA23M_GetVoiceDetails,
+    XA23M_SetOutputVoices,
+    XA23M_SetEffectChain,
+    XA23M_EnableEffect,
+    XA23M_DisableEffect,
+    XA23M_GetEffectState,
+    XA23M_SetEffectParameters,
+    XA23M_GetEffectParameters,
+    XA23M_SetFilterParameters,
+    XA23M_GetFilterParameters,
+    XA23M_SetVolume,
+    XA23M_GetVolume,
+    XA23M_SetChannelVolumes,
+    XA23M_GetChannelVolumes,
+    XA23M_SetOutputMatrix,
+    XA23M_GetOutputMatrix,
+    XA23M_DestroyVoice
+};
+#endif
+/* END IXAudio2MasteringVoice */
+
+
+/* BEGIN IXAudio2 */
+#if XAUDIO2_VER == 0
 static inline IXAudio2Impl *impl_from_IXAudio20(IXAudio20 *iface)
 {
     return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio20_iface);
@@ -2294,3 +1833,495 @@ const IXAudio20Vtbl XAudio20_Vtbl = {
     XA20_GetPerformanceData,
     XA20_SetDebugConfiguration
 };
+
+#elif XAUDIO2_VER <= 2
+
+static inline IXAudio2Impl *impl_from_IXAudio22(IXAudio22 *iface)
+{
+    return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio22_iface);
+}
+
+static HRESULT WINAPI XA22_QueryInterface(IXAudio22 *iface, REFIID riid,
+        void **ppvObject)
+{
+    IXAudio2Impl *This = impl_from_IXAudio22(iface);
+    return IXAudio2_QueryInterface(&This->IXAudio2_iface, riid, ppvObject);
+}
+
+static ULONG WINAPI XA22_AddRef(IXAudio22 *iface)
+{
+    IXAudio2Impl *This = impl_from_IXAudio22(iface);
+    return IXAudio2_AddRef(&This->IXAudio2_iface);
+}
+
+static ULONG WINAPI XA22_Release(IXAudio22 *iface)
+{
+    IXAudio2Impl *This = impl_from_IXAudio22(iface);
+    return IXAudio2_Release(&This->IXAudio2_iface);
+}
+
+static HRESULT WINAPI XA22_GetDeviceCount(IXAudio22 *iface, UINT32 *pCount)
+{
+    IXAudio2Impl *This = impl_from_IXAudio22(iface);
+
+    TRACE("%p, %p\n", This, pCount);
+
+    *pCount = This->ndevs;
+
+    return S_OK;
+}
+
+static HRESULT WINAPI XA22_GetDeviceDetails(IXAudio22 *iface, UINT32 index,
+        XAUDIO2_DEVICE_DETAILS *pDeviceDetails)
+{
+    IXAudio2Impl *This = impl_from_IXAudio22(iface);
+    HRESULT hr;
+    IMMDevice *dev;
+    IAudioClient *client;
+    IPropertyStore *ps;
+    WAVEFORMATEX *wfx;
+    PROPVARIANT var;
+
+    TRACE("%p, %u, %p\n", This, index, pDeviceDetails);
+
+    if(index >= This->ndevs)
+        return E_INVALIDARG;
+
+    hr = IMMDeviceEnumerator_GetDevice(This->devenum, This->devids[index], &dev);
+    if(FAILED(hr)){
+        WARN("GetDevice failed: %08x\n", hr);
+        return hr;
+    }
+
+    hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
+            NULL, (void**)&client);
+    if(FAILED(hr)){
+        WARN("Activate failed: %08x\n", hr);
+        IMMDevice_Release(dev);
+        return hr;
+    }
+
+    hr = IMMDevice_OpenPropertyStore(dev, STGM_READ, &ps);
+    if(FAILED(hr)){
+        WARN("OpenPropertyStore failed: %08x\n", hr);
+        IAudioClient_Release(client);
+        IMMDevice_Release(dev);
+        return hr;
+    }
+
+    PropVariantInit(&var);
+
+    hr = IPropertyStore_GetValue(ps, (PROPERTYKEY*)&DEVPKEY_Device_FriendlyName, &var);
+    if(FAILED(hr)){
+        WARN("GetValue failed: %08x\n", hr);
+        goto done;
+    }
+
+    lstrcpynW(pDeviceDetails->DisplayName, var.u.pwszVal, sizeof(pDeviceDetails->DisplayName)/sizeof(WCHAR));
+
+    PropVariantClear(&var);
+
+    hr = IAudioClient_GetMixFormat(client, &wfx);
+    if(FAILED(hr)){
+        WARN("GetMixFormat failed: %08x\n", hr);
+        goto done;
+    }
+
+    lstrcpyW(pDeviceDetails->DeviceID, This->devids[index]);
+
+    if(index == 0)
+        pDeviceDetails->Role = GlobalDefaultDevice;
+    else
+        pDeviceDetails->Role = NotDefaultDevice;
+
+    if(sizeof(WAVEFORMATEX) + wfx->cbSize > sizeof(pDeviceDetails->OutputFormat)){
+        FIXME("AudioClient format is too large to fit into WAVEFORMATEXTENSIBLE!\n");
+        CoTaskMemFree(wfx);
+        hr = E_FAIL;
+        goto done;
+    }
+    memcpy(&pDeviceDetails->OutputFormat, wfx, sizeof(WAVEFORMATEX) + wfx->cbSize);
+
+    CoTaskMemFree(wfx);
+
+done:
+    IPropertyStore_Release(ps);
+    IAudioClient_Release(client);
+    IMMDevice_Release(dev);
+
+    return hr;
+}
+
+static HRESULT WINAPI XA22_Initialize(IXAudio22 *iface, UINT32 flags,
+        XAUDIO2_PROCESSOR processor)
+{
+    IXAudio2Impl *This = impl_from_IXAudio22(iface);
+    TRACE("(%p)->(0x%x, 0x%x)\n", This, flags, processor);
+    return xaudio2_initialize(This, flags, processor);
+}
+
+static HRESULT WINAPI XA22_RegisterForCallbacks(IXAudio22 *iface,
+        IXAudio2EngineCallback *pCallback)
+{
+    IXAudio2Impl *This = impl_from_IXAudio22(iface);
+    return IXAudio2_RegisterForCallbacks(&This->IXAudio2_iface, pCallback);
+}
+
+static void WINAPI XA22_UnregisterForCallbacks(IXAudio22 *iface,
+        IXAudio2EngineCallback *pCallback)
+{
+    IXAudio2Impl *This = impl_from_IXAudio22(iface);
+    IXAudio2_UnregisterForCallbacks(&This->IXAudio2_iface, pCallback);
+}
+
+static HRESULT WINAPI XA22_CreateSourceVoice(IXAudio22 *iface,
+        IXAudio2SourceVoice **ppSourceVoice, const WAVEFORMATEX *pSourceFormat,
+        UINT32 flags, float maxFrequencyRatio,
+        IXAudio2VoiceCallback *pCallback, const XAUDIO2_VOICE_SENDS *pSendList,
+        const XAUDIO2_EFFECT_CHAIN *pEffectChain)
+{
+    IXAudio2Impl *This = impl_from_IXAudio22(iface);
+    return IXAudio2_CreateSourceVoice(&This->IXAudio2_iface, ppSourceVoice,
+            pSourceFormat, flags, maxFrequencyRatio, pCallback, pSendList,
+            pEffectChain);
+}
+
+static HRESULT WINAPI XA22_CreateSubmixVoice(IXAudio22 *iface,
+        IXAudio2SubmixVoice **ppSubmixVoice, UINT32 inputChannels,
+        UINT32 inputSampleRate, UINT32 flags, UINT32 processingStage,
+        const XAUDIO2_VOICE_SENDS *pSendList,
+        const XAUDIO2_EFFECT_CHAIN *pEffectChain)
+{
+    IXAudio2Impl *This = impl_from_IXAudio22(iface);
+    return IXAudio2_CreateSubmixVoice(&This->IXAudio2_iface, ppSubmixVoice,
+            inputChannels, inputSampleRate, flags, processingStage, pSendList,
+            pEffectChain);
+}
+
+static HRESULT WINAPI XA22_CreateMasteringVoice(IXAudio22 *iface,
+        IXAudio2MasteringVoice **ppMasteringVoice, UINT32 inputChannels,
+        UINT32 inputSampleRate, UINT32 flags, UINT32 deviceIndex,
+        const XAUDIO2_EFFECT_CHAIN *pEffectChain)
+{
+    IXAudio2Impl *This = impl_from_IXAudio22(iface);
+
+    TRACE("(%p)->(%p, %u, %u, 0x%x, %u, %p)\n", This, ppMasteringVoice,
+            inputChannels, inputSampleRate, flags, deviceIndex,
+            pEffectChain);
+
+    if(deviceIndex >= This->ndevs)
+        return E_INVALIDARG;
+
+    return IXAudio2_CreateMasteringVoice(&This->IXAudio2_iface, ppMasteringVoice,
+            inputChannels, inputSampleRate, flags, This->devids[deviceIndex],
+            pEffectChain, AudioCategory_GameEffects);
+}
+
+static HRESULT WINAPI XA22_StartEngine(IXAudio22 *iface)
+{
+    IXAudio2Impl *This = impl_from_IXAudio22(iface);
+    return IXAudio2_StartEngine(&This->IXAudio2_iface);
+}
+
+static void WINAPI XA22_StopEngine(IXAudio22 *iface)
+{
+    IXAudio2Impl *This = impl_from_IXAudio22(iface);
+    return IXAudio2_StopEngine(&This->IXAudio2_iface);
+}
+
+static HRESULT WINAPI XA22_CommitChanges(IXAudio22 *iface, UINT32 operationSet)
+{
+    IXAudio2Impl *This = impl_from_IXAudio22(iface);
+    return IXAudio2_CommitChanges(&This->IXAudio2_iface, operationSet);
+}
+
+static void WINAPI XA22_GetPerformanceData(IXAudio22 *iface,
+        XAUDIO22_PERFORMANCE_DATA *pPerfData)
+{
+    IXAudio2Impl *This = impl_from_IXAudio22(iface);
+    XAUDIO2_PERFORMANCE_DATA data;
+
+    IXAudio2_GetPerformanceData(&This->IXAudio2_iface, &data);
+
+    pPerfData->AudioCyclesSinceLastQuery = data.AudioCyclesSinceLastQuery;
+    pPerfData->TotalCyclesSinceLastQuery = data.TotalCyclesSinceLastQuery;
+    pPerfData->MinimumCyclesPerQuantum = data.MinimumCyclesPerQuantum;
+    pPerfData->MaximumCyclesPerQuantum = data.MaximumCyclesPerQuantum;
+    pPerfData->MemoryUsageInBytes = data.MemoryUsageInBytes;
+    pPerfData->CurrentLatencyInSamples = data.CurrentLatencyInSamples;
+    pPerfData->GlitchesSinceEngineStarted = data.GlitchesSinceEngineStarted;
+    pPerfData->ActiveSourceVoiceCount = data.ActiveSourceVoiceCount;
+    pPerfData->TotalSourceVoiceCount = data.TotalSourceVoiceCount;
+
+    pPerfData->ActiveSubmixVoiceCount = data.ActiveSubmixVoiceCount;
+    pPerfData->TotalSubmixVoiceCount = data.ActiveSubmixVoiceCount;
+
+    pPerfData->ActiveXmaSourceVoices = data.ActiveXmaSourceVoices;
+    pPerfData->ActiveXmaStreams = data.ActiveXmaStreams;
+}
+
+static void WINAPI XA22_SetDebugConfiguration(IXAudio22 *iface,
+        const XAUDIO2_DEBUG_CONFIGURATION *pDebugConfiguration,
+        void *pReserved)
+{
+    IXAudio2Impl *This = impl_from_IXAudio22(iface);
+    return IXAudio2_SetDebugConfiguration(&This->IXAudio2_iface,
+            pDebugConfiguration, pReserved);
+}
+
+const IXAudio22Vtbl XAudio22_Vtbl = {
+    XA22_QueryInterface,
+    XA22_AddRef,
+    XA22_Release,
+    XA22_GetDeviceCount,
+    XA22_GetDeviceDetails,
+    XA22_Initialize,
+    XA22_RegisterForCallbacks,
+    XA22_UnregisterForCallbacks,
+    XA22_CreateSourceVoice,
+    XA22_CreateSubmixVoice,
+    XA22_CreateMasteringVoice,
+    XA22_StartEngine,
+    XA22_StopEngine,
+    XA22_CommitChanges,
+    XA22_GetPerformanceData,
+    XA22_SetDebugConfiguration
+};
+
+#elif XAUDIO2_VER <= 7
+
+static inline IXAudio2Impl *impl_from_IXAudio27(IXAudio27 *iface)
+{
+    return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio27_iface);
+}
+
+static HRESULT WINAPI XA27_QueryInterface(IXAudio27 *iface, REFIID riid,
+        void **ppvObject)
+{
+    IXAudio2Impl *This = impl_from_IXAudio27(iface);
+    return IXAudio2_QueryInterface(&This->IXAudio2_iface, riid, ppvObject);
+}
+
+static ULONG WINAPI XA27_AddRef(IXAudio27 *iface)
+{
+    IXAudio2Impl *This = impl_from_IXAudio27(iface);
+    return IXAudio2_AddRef(&This->IXAudio2_iface);
+}
+
+static ULONG WINAPI XA27_Release(IXAudio27 *iface)
+{
+    IXAudio2Impl *This = impl_from_IXAudio27(iface);
+    return IXAudio2_Release(&This->IXAudio2_iface);
+}
+
+static HRESULT WINAPI XA27_GetDeviceCount(IXAudio27 *iface, UINT32 *pCount)
+{
+    IXAudio2Impl *This = impl_from_IXAudio27(iface);
+
+    TRACE("%p, %p\n", This, pCount);
+
+    *pCount = This->ndevs;
+
+    return S_OK;
+}
+
+static HRESULT WINAPI XA27_GetDeviceDetails(IXAudio27 *iface, UINT32 index,
+        XAUDIO2_DEVICE_DETAILS *pDeviceDetails)
+{
+    IXAudio2Impl *This = impl_from_IXAudio27(iface);
+    HRESULT hr;
+    IMMDevice *dev;
+    IAudioClient *client;
+    IPropertyStore *ps;
+    WAVEFORMATEX *wfx;
+    PROPVARIANT var;
+
+    TRACE("%p, %u, %p\n", This, index, pDeviceDetails);
+
+    if(index >= This->ndevs)
+        return E_INVALIDARG;
+
+    hr = IMMDeviceEnumerator_GetDevice(This->devenum, This->devids[index], &dev);
+    if(FAILED(hr)){
+        WARN("GetDevice failed: %08x\n", hr);
+        return hr;
+    }
+
+    hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
+            NULL, (void**)&client);
+    if(FAILED(hr)){
+        WARN("Activate failed: %08x\n", hr);
+        IMMDevice_Release(dev);
+        return hr;
+    }
+
+    hr = IMMDevice_OpenPropertyStore(dev, STGM_READ, &ps);
+    if(FAILED(hr)){
+        WARN("OpenPropertyStore failed: %08x\n", hr);
+        IAudioClient_Release(client);
+        IMMDevice_Release(dev);
+        return hr;
+    }
+
+    PropVariantInit(&var);
+
+    hr = IPropertyStore_GetValue(ps, (PROPERTYKEY*)&DEVPKEY_Device_FriendlyName, &var);
+    if(FAILED(hr)){
+        WARN("GetValue failed: %08x\n", hr);
+        goto done;
+    }
+
+    lstrcpynW(pDeviceDetails->DisplayName, var.u.pwszVal, sizeof(pDeviceDetails->DisplayName)/sizeof(WCHAR));
+
+    PropVariantClear(&var);
+
+    hr = IAudioClient_GetMixFormat(client, &wfx);
+    if(FAILED(hr)){
+        WARN("GetMixFormat failed: %08x\n", hr);
+        goto done;
+    }
+
+    lstrcpyW(pDeviceDetails->DeviceID, This->devids[index]);
+
+    if(index == 0)
+        pDeviceDetails->Role = GlobalDefaultDevice;
+    else
+        pDeviceDetails->Role = NotDefaultDevice;
+
+    if(sizeof(WAVEFORMATEX) + wfx->cbSize > sizeof(pDeviceDetails->OutputFormat)){
+        FIXME("AudioClient format is too large to fit into WAVEFORMATEXTENSIBLE!\n");
+        CoTaskMemFree(wfx);
+        hr = E_FAIL;
+        goto done;
+    }
+    memcpy(&pDeviceDetails->OutputFormat, wfx, sizeof(WAVEFORMATEX) + wfx->cbSize);
+
+    CoTaskMemFree(wfx);
+
+done:
+    IPropertyStore_Release(ps);
+    IAudioClient_Release(client);
+    IMMDevice_Release(dev);
+
+    return hr;
+}
+
+static HRESULT WINAPI XA27_Initialize(IXAudio27 *iface, UINT32 flags,
+        XAUDIO2_PROCESSOR processor)
+{
+    IXAudio2Impl *This = impl_from_IXAudio27(iface);
+    TRACE("(%p)->(0x%x, 0x%x)\n", This, flags, processor);
+    return xaudio2_initialize(This, flags, processor);
+}
+
+static HRESULT WINAPI XA27_RegisterForCallbacks(IXAudio27 *iface,
+        IXAudio2EngineCallback *pCallback)
+{
+    IXAudio2Impl *This = impl_from_IXAudio27(iface);
+    return IXAudio2_RegisterForCallbacks(&This->IXAudio2_iface, pCallback);
+}
+
+static void WINAPI XA27_UnregisterForCallbacks(IXAudio27 *iface,
+        IXAudio2EngineCallback *pCallback)
+{
+    IXAudio2Impl *This = impl_from_IXAudio27(iface);
+    IXAudio2_UnregisterForCallbacks(&This->IXAudio2_iface, pCallback);
+}
+
+static HRESULT WINAPI XA27_CreateSourceVoice(IXAudio27 *iface,
+        IXAudio2SourceVoice **ppSourceVoice, const WAVEFORMATEX *pSourceFormat,
+        UINT32 flags, float maxFrequencyRatio,
+        IXAudio2VoiceCallback *pCallback, const XAUDIO2_VOICE_SENDS *pSendList,
+        const XAUDIO2_EFFECT_CHAIN *pEffectChain)
+{
+    IXAudio2Impl *This = impl_from_IXAudio27(iface);
+    return IXAudio2_CreateSourceVoice(&This->IXAudio2_iface, ppSourceVoice,
+            pSourceFormat, flags, maxFrequencyRatio, pCallback, pSendList,
+            pEffectChain);
+}
+
+static HRESULT WINAPI XA27_CreateSubmixVoice(IXAudio27 *iface,
+        IXAudio2SubmixVoice **ppSubmixVoice, UINT32 inputChannels,
+        UINT32 inputSampleRate, UINT32 flags, UINT32 processingStage,
+        const XAUDIO2_VOICE_SENDS *pSendList,
+        const XAUDIO2_EFFECT_CHAIN *pEffectChain)
+{
+    IXAudio2Impl *This = impl_from_IXAudio27(iface);
+    return IXAudio2_CreateSubmixVoice(&This->IXAudio2_iface, ppSubmixVoice,
+            inputChannels, inputSampleRate, flags, processingStage, pSendList,
+            pEffectChain);
+}
+
+static HRESULT WINAPI XA27_CreateMasteringVoice(IXAudio27 *iface,
+        IXAudio2MasteringVoice **ppMasteringVoice, UINT32 inputChannels,
+        UINT32 inputSampleRate, UINT32 flags, UINT32 deviceIndex,
+        const XAUDIO2_EFFECT_CHAIN *pEffectChain)
+{
+    IXAudio2Impl *This = impl_from_IXAudio27(iface);
+
+    TRACE("(%p)->(%p, %u, %u, 0x%x, %u, %p)\n", This, ppMasteringVoice,
+            inputChannels, inputSampleRate, flags, deviceIndex,
+            pEffectChain);
+
+    if(deviceIndex >= This->ndevs)
+        return E_INVALIDARG;
+
+    return IXAudio2_CreateMasteringVoice(&This->IXAudio2_iface, ppMasteringVoice,
+            inputChannels, inputSampleRate, flags, This->devids[deviceIndex],
+            pEffectChain, AudioCategory_GameEffects);
+}
+
+static HRESULT WINAPI XA27_StartEngine(IXAudio27 *iface)
+{
+    IXAudio2Impl *This = impl_from_IXAudio27(iface);
+    return IXAudio2_StartEngine(&This->IXAudio2_iface);
+}
+
+static void WINAPI XA27_StopEngine(IXAudio27 *iface)
+{
+    IXAudio2Impl *This = impl_from_IXAudio27(iface);
+    return IXAudio2_StopEngine(&This->IXAudio2_iface);
+}
+
+static HRESULT WINAPI XA27_CommitChanges(IXAudio27 *iface, UINT32 operationSet)
+{
+    IXAudio2Impl *This = impl_from_IXAudio27(iface);
+    return IXAudio2_CommitChanges(&This->IXAudio2_iface, operationSet);
+}
+
+static void WINAPI XA27_GetPerformanceData(IXAudio27 *iface,
+        XAUDIO2_PERFORMANCE_DATA *pPerfData)
+{
+    IXAudio2Impl *This = impl_from_IXAudio27(iface);
+    return IXAudio2_GetPerformanceData(&This->IXAudio2_iface, pPerfData);
+}
+
+static void WINAPI XA27_SetDebugConfiguration(IXAudio27 *iface,
+        const XAUDIO2_DEBUG_CONFIGURATION *pDebugConfiguration,
+        void *pReserved)
+{
+    IXAudio2Impl *This = impl_from_IXAudio27(iface);
+    return IXAudio2_SetDebugConfiguration(&This->IXAudio2_iface,
+            pDebugConfiguration, pReserved);
+}
+
+const IXAudio27Vtbl XAudio27_Vtbl = {
+    XA27_QueryInterface,
+    XA27_AddRef,
+    XA27_Release,
+    XA27_GetDeviceCount,
+    XA27_GetDeviceDetails,
+    XA27_Initialize,
+    XA27_RegisterForCallbacks,
+    XA27_UnregisterForCallbacks,
+    XA27_CreateSourceVoice,
+    XA27_CreateSubmixVoice,
+    XA27_CreateMasteringVoice,
+    XA27_StartEngine,
+    XA27_StopEngine,
+    XA27_CommitChanges,
+    XA27_GetPerformanceData,
+    XA27_SetDebugConfiguration
+};
+#endif
+/* END IXAudio2 */
diff --git a/dlls/xaudio2_7/tests/xaudio2.c b/dlls/xaudio2_7/tests/xaudio2.c
index 9a7b011..0f045b8 100644
--- a/dlls/xaudio2_7/tests/xaudio2.c
+++ b/dlls/xaudio2_7/tests/xaudio2.c
@@ -1087,6 +1087,9 @@ START_TEST(xaudio2)
         hr = pXAudio2Create(&xa, 0, XAUDIO2_DEFAULT_PROCESSOR);
         ok(hr == S_OK, "XAudio2Create failed: %08x\n", hr);
 
+        hr = IXAudio2_QueryInterface(xa, &IID_IXAudio27, (void**)&xa27);
+        ok(hr == E_NOINTERFACE, "XA28 object should support IXAudio27, gave: %08x\n", hr);
+
         has_devices = check_has_devices(xa);
         if(has_devices){
             test_simple_streaming(xa);
diff --git a/dlls/xaudio2_7/xaudio_dll.c b/dlls/xaudio2_7/xaudio_dll.c
index 86c8cbf..ac1b2fe 100644
--- a/dlls/xaudio2_7/xaudio_dll.c
+++ b/dlls/xaudio2_7/xaudio_dll.c
@@ -1198,10 +1198,12 @@ static HRESULT WINAPI IXAudio2Impl_QueryInterface(IXAudio2 *iface, REFIID riid,
         /* all xaudio versions before 28 share an IID */
 #if XAUDIO2_VER == 0
         *ppvObject = &This->IXAudio20_iface;
-#elif XAUDIO2_VER == 1 || XAUDIO2_VER == 2
+#elif XAUDIO2_VER <= 2
         *ppvObject = &This->IXAudio22_iface;
-#else
+#elif XAUDIO2_VER <= 7
         *ppvObject = &This->IXAudio27_iface;
+#else
+        *ppvObject = NULL;
 #endif
     }else
         *ppvObject = NULL;
@@ -1374,10 +1376,15 @@ static HRESULT WINAPI IXAudio2Impl_CreateSourceVoice(IXAudio2 *iface,
 
         list_add_head(&This->source_voices, &src->entry);
 
+        src->IXAudio2SourceVoice_iface.lpVtbl = &XAudio2SourceVoice_Vtbl;
+
+#if XAUDIO2_VER == 0
         src->IXAudio20SourceVoice_iface.lpVtbl = &XAudio20SourceVoice_Vtbl;
+#elif XAUDIO2_VER <= 3
         src->IXAudio23SourceVoice_iface.lpVtbl = &XAudio23SourceVoice_Vtbl;
+#elif XAUDIO2_VER <= 7
         src->IXAudio27SourceVoice_iface.lpVtbl = &XAudio27SourceVoice_Vtbl;
-        src->IXAudio2SourceVoice_iface.lpVtbl = &XAudio2SourceVoice_Vtbl;
+#endif
 
         InitializeCriticalSection(&src->lock);
         src->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": XA2SourceImpl.lock");
@@ -1458,9 +1465,13 @@ static HRESULT WINAPI IXAudio2Impl_CreateSubmixVoice(IXAudio2 *iface,
 
         list_add_head(&This->submix_voices, &sub->entry);
 
+        sub->IXAudio2SubmixVoice_iface.lpVtbl = &XAudio2SubmixVoice_Vtbl;
+
+#if XAUDIO2_VER == 0
         sub->IXAudio20SubmixVoice_iface.lpVtbl = &XAudio20SubmixVoice_Vtbl;
+#elif XAUDIO2_VER <= 3
         sub->IXAudio23SubmixVoice_iface.lpVtbl = &XAudio23SubmixVoice_Vtbl;
-        sub->IXAudio2SubmixVoice_iface.lpVtbl = &XAudio2SubmixVoice_Vtbl;
+#endif
 
         InitializeCriticalSection(&sub->lock);
         sub->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": XA2SubmixImpl.lock");
@@ -1944,13 +1955,22 @@ static HRESULT WINAPI XAudio2CF_CreateInstance(IClassFactory *iface, IUnknown *p
     if(!object)
         return E_OUTOFMEMORY;
 
+    object->IXAudio2_iface.lpVtbl = &XAudio2_Vtbl;
+    object->IXAudio2MasteringVoice_iface.lpVtbl = &XAudio2MasteringVoice_Vtbl;
+
+#if XAUDIO2_VER == 0
     object->IXAudio20_iface.lpVtbl = &XAudio20_Vtbl;
+#elif XAUDIO2_VER <= 2
     object->IXAudio22_iface.lpVtbl = &XAudio22_Vtbl;
+#elif XAUDIO2_VER <= 7
     object->IXAudio27_iface.lpVtbl = &XAudio27_Vtbl;
-    object->IXAudio2_iface.lpVtbl = &XAudio2_Vtbl;
+#endif
+
+#if XAUDIO2_VER == 0
     object->IXAudio20MasteringVoice_iface.lpVtbl = &XAudio20MasteringVoice_Vtbl;
+#elif XAUDIO2_VER <= 3
     object->IXAudio23MasteringVoice_iface.lpVtbl = &XAudio23MasteringVoice_Vtbl;
-    object->IXAudio2MasteringVoice_iface.lpVtbl = &XAudio2MasteringVoice_Vtbl;
+#endif
 
     list_init(&object->source_voices);
     list_init(&object->submix_voices);
diff --git a/dlls/xaudio2_7/xaudio_private.h b/dlls/xaudio2_7/xaudio_private.h
index 39ed2c8..e6179fb 100644
--- a/dlls/xaudio2_7/xaudio_private.h
+++ b/dlls/xaudio2_7/xaudio_private.h
@@ -42,10 +42,15 @@ typedef struct _XA2Buffer {
 typedef struct _IXAudio2Impl IXAudio2Impl;
 
 typedef struct _XA2SourceImpl {
+    IXAudio2SourceVoice IXAudio2SourceVoice_iface;
+
+#if XAUDIO2_VER == 0
     IXAudio20SourceVoice IXAudio20SourceVoice_iface;
+#elif XAUDIO2_VER <= 3
     IXAudio23SourceVoice IXAudio23SourceVoice_iface;
+#elif XAUDIO2_VER <= 7
     IXAudio27SourceVoice IXAudio27SourceVoice_iface;
-    IXAudio2SourceVoice IXAudio2SourceVoice_iface;
+#endif
 
     IXAudio2Impl *xa2;
 
@@ -82,9 +87,13 @@ typedef struct _XA2SourceImpl {
 } XA2SourceImpl;
 
 typedef struct _XA2SubmixImpl {
+    IXAudio2SubmixVoice IXAudio2SubmixVoice_iface;
+
+#if XAUDIO2_VER == 0
     IXAudio20SubmixVoice IXAudio20SubmixVoice_iface;
+#elif XAUDIO2_VER <= 3
     IXAudio23SubmixVoice IXAudio23SubmixVoice_iface;
-    IXAudio2SubmixVoice IXAudio2SubmixVoice_iface;
+#endif
 
     BOOL in_use;
 
@@ -94,13 +103,22 @@ typedef struct _XA2SubmixImpl {
 } XA2SubmixImpl;
 
 struct _IXAudio2Impl {
+    IXAudio2 IXAudio2_iface;
+    IXAudio2MasteringVoice IXAudio2MasteringVoice_iface;
+
+#if XAUDIO2_VER == 0
     IXAudio20 IXAudio20_iface;
+#elif XAUDIO2_VER <= 2
     IXAudio22 IXAudio22_iface;
+#elif XAUDIO2_VER <= 7
     IXAudio27 IXAudio27_iface;
-    IXAudio2 IXAudio2_iface;
+#endif
+
+#if XAUDIO2_VER == 0
     IXAudio20MasteringVoice IXAudio20MasteringVoice_iface;
+#elif XAUDIO2_VER <= 3
     IXAudio23MasteringVoice IXAudio23MasteringVoice_iface;
-    IXAudio2MasteringVoice IXAudio2MasteringVoice_iface;
+#endif
 
     LONG ref;
 
@@ -135,19 +153,25 @@ struct _IXAudio2Impl {
     BOOL running;
 };
 
-extern const IXAudio27SourceVoiceVtbl XAudio27SourceVoice_Vtbl DECLSPEC_HIDDEN;
-extern const IXAudio27Vtbl XAudio27_Vtbl DECLSPEC_HIDDEN;
-
+#if XAUDIO2_VER == 0
+extern const IXAudio20SourceVoiceVtbl XAudio20SourceVoice_Vtbl DECLSPEC_HIDDEN;
+extern const IXAudio20SubmixVoiceVtbl XAudio20SubmixVoice_Vtbl DECLSPEC_HIDDEN;
+extern const IXAudio20MasteringVoiceVtbl XAudio20MasteringVoice_Vtbl DECLSPEC_HIDDEN;
+#elif XAUDIO2_VER <= 3
 extern const IXAudio23SourceVoiceVtbl XAudio23SourceVoice_Vtbl DECLSPEC_HIDDEN;
 extern const IXAudio23SubmixVoiceVtbl XAudio23SubmixVoice_Vtbl DECLSPEC_HIDDEN;
 extern const IXAudio23MasteringVoiceVtbl XAudio23MasteringVoice_Vtbl DECLSPEC_HIDDEN;
+#elif XAUDIO2_VER <= 7
+extern const IXAudio27SourceVoiceVtbl XAudio27SourceVoice_Vtbl DECLSPEC_HIDDEN;
+#endif
 
-extern const IXAudio22Vtbl XAudio22_Vtbl DECLSPEC_HIDDEN;
-
+#if XAUDIO2_VER == 0
 extern const IXAudio20Vtbl XAudio20_Vtbl DECLSPEC_HIDDEN;
-extern const IXAudio20SourceVoiceVtbl XAudio20SourceVoice_Vtbl DECLSPEC_HIDDEN;
-extern const IXAudio20SubmixVoiceVtbl XAudio20SubmixVoice_Vtbl DECLSPEC_HIDDEN;
-extern const IXAudio20MasteringVoiceVtbl XAudio20MasteringVoice_Vtbl DECLSPEC_HIDDEN;
+#elif XAUDIO2_VER <= 2
+extern const IXAudio22Vtbl XAudio22_Vtbl DECLSPEC_HIDDEN;
+#elif XAUDIO2_VER <= 7
+extern const IXAudio27Vtbl XAudio27_Vtbl DECLSPEC_HIDDEN;
+#endif
 
 extern IClassFactory *make_xapo_factory(REFCLSID clsid) DECLSPEC_HIDDEN;
 extern HRESULT xaudio2_initialize(IXAudio2Impl *This, UINT32 flags, XAUDIO2_PROCESSOR proc) DECLSPEC_HIDDEN;
-- 
2.7.0




More information about the wine-patches mailing list