[PATCH] xaudio2_0: Add compatibility implementation and forward to xaudio2_7
Andrew Eikum
aeikum at codeweavers.com
Wed Oct 7 11:19:35 CDT 2015
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
---
configure.ac | 1 +
dlls/xaudio2_0/Makefile.in | 7 +
dlls/xaudio2_0/xaudio2_0.spec | 4 +
dlls/xaudio2_0/xaudio_classes.idl | 42 ++
dlls/xaudio2_0/xaudio_dll.c | 52 +++
dlls/xaudio2_7/compat.c | 859 ++++++++++++++++++++++++++++++++++++++
dlls/xaudio2_7/xaudio_dll.c | 271 +++++++-----
dlls/xaudio2_7/xaudio_private.h | 11 +
include/xapo.idl | 16 +
include/xaudio2.idl | 243 +++++++++++
include/xaudio2fx.idl | 14 +
11 files changed, 1415 insertions(+), 105 deletions(-)
create mode 100644 dlls/xaudio2_0/Makefile.in
create mode 100644 dlls/xaudio2_0/xaudio2_0.spec
create mode 100644 dlls/xaudio2_0/xaudio_classes.idl
create mode 100644 dlls/xaudio2_0/xaudio_dll.c
diff --git a/configure.ac b/configure.ac
index ce631e4..5e83d39 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3463,6 +3463,7 @@ WINE_CONFIG_DLL(xapofx1_2)
WINE_CONFIG_DLL(xapofx1_3)
WINE_CONFIG_DLL(xapofx1_4)
WINE_CONFIG_DLL(xapofx1_5)
+WINE_CONFIG_DLL(xaudio2_0,,[clean])
WINE_CONFIG_DLL(xaudio2_1,,[clean])
WINE_CONFIG_DLL(xaudio2_2,,[clean])
WINE_CONFIG_DLL(xaudio2_3,,[clean])
diff --git a/dlls/xaudio2_0/Makefile.in b/dlls/xaudio2_0/Makefile.in
new file mode 100644
index 0000000..cc9d161
--- /dev/null
+++ b/dlls/xaudio2_0/Makefile.in
@@ -0,0 +1,7 @@
+MODULE = xaudio2_0.dll
+IMPORTS = ole32
+
+C_SRCS = \
+ xaudio_dll.c
+
+IDL_SRCS = xaudio_classes.idl
diff --git a/dlls/xaudio2_0/xaudio2_0.spec b/dlls/xaudio2_0/xaudio2_0.spec
new file mode 100644
index 0000000..cb263d4
--- /dev/null
+++ b/dlls/xaudio2_0/xaudio2_0.spec
@@ -0,0 +1,4 @@
+@ stdcall -private DllCanUnloadNow()
+@ stdcall -private DllGetClassObject(ptr ptr ptr) xaudio2_7.DllGetClassObject
+@ stdcall -private DllRegisterServer()
+@ stdcall -private DllUnregisterServer()
diff --git a/dlls/xaudio2_0/xaudio_classes.idl b/dlls/xaudio2_0/xaudio_classes.idl
new file mode 100644
index 0000000..4a81eb1
--- /dev/null
+++ b/dlls/xaudio2_0/xaudio_classes.idl
@@ -0,0 +1,42 @@
+/*
+ * COM Classes for xaudio
+ *
+ * Copyright 2015 Andrew Eikum for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#pragma makedep register
+
+[
+ helpstring("XAudio2.0 Class"),
+ threading(both),
+ uuid(e21a7345-eb21-468e-be50-804db97cf708)
+]
+coclass XAudio20 { interface IXAudio20; }
+
+[
+ helpstring("XAudio2.0 AudioReverb Class"),
+ threading(both),
+ uuid(6f6ea3a9-2cf5-41cf-91c1-2170b1540063)
+]
+coclass AudioReverb20 { interface IXAPO; }
+
+[
+ helpstring("XAudio2.0 AudioVolumeMeter Class"),
+ threading(both),
+ uuid(c0c56f46-29b1-44e9-9939-a32ce86867e2)
+]
+coclass AudioVolumeMeter20 { interface IXAPO; }
diff --git a/dlls/xaudio2_0/xaudio_dll.c b/dlls/xaudio2_0/xaudio_dll.c
new file mode 100644
index 0000000..7c95c28
--- /dev/null
+++ b/dlls/xaudio2_0/xaudio_dll.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015 Andrew Eikum for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+#include "windef.h"
+#include "winbase.h"
+#include "objbase.h"
+#include "rpcproxy.h"
+
+static HINSTANCE instance;
+
+BOOL WINAPI DllMain(HINSTANCE hinstance, DWORD reason, LPVOID reserved)
+{
+ switch (reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ instance = hinstance;
+ DisableThreadLibraryCalls(hinstance);
+ break;
+ }
+ return TRUE;
+}
+
+HRESULT WINAPI DllCanUnloadNow(void)
+{
+ return S_FALSE;
+}
+
+HRESULT WINAPI DllRegisterServer(void)
+{
+ return __wine_register_resources(instance);
+}
+
+HRESULT WINAPI DllUnregisterServer(void)
+{
+ return __wine_unregister_resources(instance);
+}
diff --git a/dlls/xaudio2_7/compat.c b/dlls/xaudio2_7/compat.c
index bee57c6..8eb0efc 100644
--- a/dlls/xaudio2_7/compat.c
+++ b/dlls/xaudio2_7/compat.c
@@ -1435,3 +1435,862 @@ const IXAudio22Vtbl XAudio22_Vtbl = {
XA22_GetPerformanceData,
XA22_SetDebugConfiguration
};
+
+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,
+};
+
+XA2SubmixImpl *impl_from_IXAudio20SubmixVoice(IXAudio20SubmixVoice *iface)
+{
+ return CONTAINING_RECORD(iface, XA2SubmixImpl, IXAudio20SubmixVoice_iface);
+}
+
+static void WINAPI XA20SUB_GetVoiceDetails(IXAudio20SubmixVoice *iface,
+ XAUDIO2_VOICE_DETAILS *pVoiceDetails)
+{
+ XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface);
+ return IXAudio2SubmixVoice_GetVoiceDetails(&This->IXAudio2SubmixVoice_iface, pVoiceDetails);
+}
+
+static HRESULT WINAPI XA20SUB_SetOutputVoices(IXAudio20SubmixVoice *iface,
+ const XAUDIO23_VOICE_SENDS *pSendList)
+{
+ XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(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 XA20SUB_SetEffectChain(IXAudio20SubmixVoice *iface,
+ const XAUDIO2_EFFECT_CHAIN *pEffectChain)
+{
+ XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface);
+ return IXAudio2SubmixVoice_SetEffectChain(&This->IXAudio2SubmixVoice_iface, pEffectChain);
+}
+
+static HRESULT WINAPI XA20SUB_EnableEffect(IXAudio20SubmixVoice *iface,
+ UINT32 EffectIndex, UINT32 OperationSet)
+{
+ XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface);
+ return IXAudio2SubmixVoice_EnableEffect(&This->IXAudio2SubmixVoice_iface,
+ EffectIndex, OperationSet);
+}
+
+static HRESULT WINAPI XA20SUB_DisableEffect(IXAudio20SubmixVoice *iface,
+ UINT32 EffectIndex, UINT32 OperationSet)
+{
+ XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface);
+ return IXAudio2SubmixVoice_DisableEffect(&This->IXAudio2SubmixVoice_iface,
+ EffectIndex, OperationSet);
+}
+
+static void WINAPI XA20SUB_GetEffectState(IXAudio20SubmixVoice *iface,
+ UINT32 EffectIndex, BOOL *pEnabled)
+{
+ XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface);
+ return IXAudio2SubmixVoice_GetEffectState(&This->IXAudio2SubmixVoice_iface,
+ EffectIndex, pEnabled);
+}
+
+static HRESULT WINAPI XA20SUB_SetEffectParameters(IXAudio20SubmixVoice *iface,
+ UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize,
+ UINT32 OperationSet)
+{
+ XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface);
+ return IXAudio2SubmixVoice_SetEffectParameters(&This->IXAudio2SubmixVoice_iface,
+ EffectIndex, pParameters, ParametersByteSize, OperationSet);
+}
+
+static HRESULT WINAPI XA20SUB_GetEffectParameters(IXAudio20SubmixVoice *iface,
+ UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize)
+{
+ XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface);
+ return IXAudio2SubmixVoice_GetEffectParameters(&This->IXAudio2SubmixVoice_iface,
+ EffectIndex, pParameters, ParametersByteSize);
+}
+
+static HRESULT WINAPI XA20SUB_SetFilterParameters(IXAudio20SubmixVoice *iface,
+ const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet)
+{
+ XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface);
+ return IXAudio2SubmixVoice_SetFilterParameters(&This->IXAudio2SubmixVoice_iface,
+ pParameters, OperationSet);
+}
+
+static void WINAPI XA20SUB_GetFilterParameters(IXAudio20SubmixVoice *iface,
+ XAUDIO2_FILTER_PARAMETERS *pParameters)
+{
+ XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface);
+ return IXAudio2SubmixVoice_GetFilterParameters(&This->IXAudio2SubmixVoice_iface, pParameters);
+}
+
+static HRESULT WINAPI XA20SUB_SetVolume(IXAudio20SubmixVoice *iface,
+ float Volume, UINT32 OperationSet)
+{
+ XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface);
+ return IXAudio2SubmixVoice_SetVolume(&This->IXAudio2SubmixVoice_iface,
+ Volume, OperationSet);
+}
+
+static void WINAPI XA20SUB_GetVolume(IXAudio20SubmixVoice *iface,
+ float *pVolume)
+{
+ XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface);
+ return IXAudio2SubmixVoice_GetVolume(&This->IXAudio2SubmixVoice_iface, pVolume);
+}
+
+static HRESULT WINAPI XA20SUB_SetChannelVolumes(IXAudio20SubmixVoice *iface,
+ UINT32 Channels, const float *pVolumes, UINT32 OperationSet)
+{
+ XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface);
+ return IXAudio2SubmixVoice_SetChannelVolumes(&This->IXAudio2SubmixVoice_iface,
+ Channels, pVolumes, OperationSet);
+}
+
+static void WINAPI XA20SUB_GetChannelVolumes(IXAudio20SubmixVoice *iface,
+ UINT32 Channels, float *pVolumes)
+{
+ XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface);
+ return IXAudio2SubmixVoice_GetChannelVolumes(&This->IXAudio2SubmixVoice_iface,
+ Channels, pVolumes);
+}
+
+static HRESULT WINAPI XA20SUB_SetOutputMatrix(IXAudio20SubmixVoice *iface,
+ IXAudio2Voice *pDestinationVoice, UINT32 SubmixChannels,
+ UINT32 DestinationChannels, const float *pLevelMatrix,
+ UINT32 OperationSet)
+{
+ XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface);
+ return IXAudio2SubmixVoice_SetOutputMatrix(&This->IXAudio2SubmixVoice_iface,
+ pDestinationVoice, SubmixChannels, DestinationChannels,
+ pLevelMatrix, OperationSet);
+}
+
+static HRESULT WINAPI XA20SUB_GetOutputMatrix(IXAudio20SubmixVoice *iface,
+ IXAudio2Voice *pDestinationVoice, UINT32 SubmixChannels,
+ UINT32 DestinationChannels, float *pLevelMatrix)
+{
+ XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface);
+ IXAudio2SubmixVoice_GetOutputMatrix(&This->IXAudio2SubmixVoice_iface,
+ pDestinationVoice, SubmixChannels, DestinationChannels,
+ pLevelMatrix);
+ return S_OK;
+}
+
+static void WINAPI XA20SUB_DestroyVoice(IXAudio20SubmixVoice *iface)
+{
+ XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface);
+ return IXAudio2SubmixVoice_DestroyVoice(&This->IXAudio2SubmixVoice_iface);
+}
+
+const IXAudio20SubmixVoiceVtbl XAudio20SubmixVoice_Vtbl = {
+ XA20SUB_GetVoiceDetails,
+ XA20SUB_SetOutputVoices,
+ XA20SUB_SetEffectChain,
+ XA20SUB_EnableEffect,
+ XA20SUB_DisableEffect,
+ XA20SUB_GetEffectState,
+ XA20SUB_SetEffectParameters,
+ XA20SUB_GetEffectParameters,
+ XA20SUB_SetFilterParameters,
+ XA20SUB_GetFilterParameters,
+ XA20SUB_SetVolume,
+ XA20SUB_GetVolume,
+ XA20SUB_SetChannelVolumes,
+ XA20SUB_GetChannelVolumes,
+ XA20SUB_SetOutputMatrix,
+ XA20SUB_GetOutputMatrix,
+ XA20SUB_DestroyVoice
+};
+
+IXAudio2Impl *impl_from_IXAudio20MasteringVoice(IXAudio20MasteringVoice *iface)
+{
+ return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio20MasteringVoice_iface);
+}
+
+static void WINAPI XA20M_GetVoiceDetails(IXAudio20MasteringVoice *iface,
+ XAUDIO2_VOICE_DETAILS *pVoiceDetails)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface);
+ return IXAudio2MasteringVoice_GetVoiceDetails(&This->IXAudio2MasteringVoice_iface, pVoiceDetails);
+}
+
+static HRESULT WINAPI XA20M_SetOutputVoices(IXAudio20MasteringVoice *iface,
+ const XAUDIO23_VOICE_SENDS *pSendList)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(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 XA20M_SetEffectChain(IXAudio20MasteringVoice *iface,
+ const XAUDIO2_EFFECT_CHAIN *pEffectChain)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface);
+ return IXAudio2MasteringVoice_SetEffectChain(&This->IXAudio2MasteringVoice_iface, pEffectChain);
+}
+
+static HRESULT WINAPI XA20M_EnableEffect(IXAudio20MasteringVoice *iface,
+ UINT32 EffectIndex, UINT32 OperationSet)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface);
+ return IXAudio2MasteringVoice_EnableEffect(&This->IXAudio2MasteringVoice_iface,
+ EffectIndex, OperationSet);
+}
+
+static HRESULT WINAPI XA20M_DisableEffect(IXAudio20MasteringVoice *iface,
+ UINT32 EffectIndex, UINT32 OperationSet)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface);
+ return IXAudio2MasteringVoice_DisableEffect(&This->IXAudio2MasteringVoice_iface,
+ EffectIndex, OperationSet);
+}
+
+static void WINAPI XA20M_GetEffectState(IXAudio20MasteringVoice *iface,
+ UINT32 EffectIndex, BOOL *pEnabled)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface);
+ return IXAudio2MasteringVoice_GetEffectState(&This->IXAudio2MasteringVoice_iface,
+ EffectIndex, pEnabled);
+}
+
+static HRESULT WINAPI XA20M_SetEffectParameters(IXAudio20MasteringVoice *iface,
+ UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize,
+ UINT32 OperationSet)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface);
+ return IXAudio2MasteringVoice_SetEffectParameters(&This->IXAudio2MasteringVoice_iface,
+ EffectIndex, pParameters, ParametersByteSize, OperationSet);
+}
+
+static HRESULT WINAPI XA20M_GetEffectParameters(IXAudio20MasteringVoice *iface,
+ UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface);
+ return IXAudio2MasteringVoice_GetEffectParameters(&This->IXAudio2MasteringVoice_iface,
+ EffectIndex, pParameters, ParametersByteSize);
+}
+
+static HRESULT WINAPI XA20M_SetFilterParameters(IXAudio20MasteringVoice *iface,
+ const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface);
+ return IXAudio2MasteringVoice_SetFilterParameters(&This->IXAudio2MasteringVoice_iface,
+ pParameters, OperationSet);
+}
+
+static void WINAPI XA20M_GetFilterParameters(IXAudio20MasteringVoice *iface,
+ XAUDIO2_FILTER_PARAMETERS *pParameters)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface);
+ return IXAudio2MasteringVoice_GetFilterParameters(&This->IXAudio2MasteringVoice_iface, pParameters);
+}
+
+static HRESULT WINAPI XA20M_SetVolume(IXAudio20MasteringVoice *iface,
+ float Volume, UINT32 OperationSet)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface);
+ return IXAudio2MasteringVoice_SetVolume(&This->IXAudio2MasteringVoice_iface,
+ Volume, OperationSet);
+}
+
+static void WINAPI XA20M_GetVolume(IXAudio20MasteringVoice *iface,
+ float *pVolume)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface);
+ return IXAudio2MasteringVoice_GetVolume(&This->IXAudio2MasteringVoice_iface, pVolume);
+}
+
+static HRESULT WINAPI XA20M_SetChannelVolumes(IXAudio20MasteringVoice *iface,
+ UINT32 Channels, const float *pVolumes, UINT32 OperationSet)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface);
+ return IXAudio2MasteringVoice_SetChannelVolumes(&This->IXAudio2MasteringVoice_iface,
+ Channels, pVolumes, OperationSet);
+}
+
+static void WINAPI XA20M_GetChannelVolumes(IXAudio20MasteringVoice *iface,
+ UINT32 Channels, float *pVolumes)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface);
+ return IXAudio2MasteringVoice_GetChannelVolumes(&This->IXAudio2MasteringVoice_iface,
+ Channels, pVolumes);
+}
+
+static HRESULT WINAPI XA20M_SetOutputMatrix(IXAudio20MasteringVoice *iface,
+ IXAudio2Voice *pDestinationVoice, UINT32 MasteringChannels,
+ UINT32 DestinationChannels, const float *pLevelMatrix,
+ UINT32 OperationSet)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface);
+ return IXAudio2MasteringVoice_SetOutputMatrix(&This->IXAudio2MasteringVoice_iface,
+ pDestinationVoice, MasteringChannels, DestinationChannels,
+ pLevelMatrix, OperationSet);
+}
+
+static HRESULT WINAPI XA20M_GetOutputMatrix(IXAudio20MasteringVoice *iface,
+ IXAudio2Voice *pDestinationVoice, UINT32 MasteringChannels,
+ UINT32 DestinationChannels, float *pLevelMatrix)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface);
+ IXAudio2MasteringVoice_GetOutputMatrix(&This->IXAudio2MasteringVoice_iface,
+ pDestinationVoice, MasteringChannels, DestinationChannels,
+ pLevelMatrix);
+ return S_OK;
+}
+
+static void WINAPI XA20M_DestroyVoice(IXAudio20MasteringVoice *iface)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface);
+ return IXAudio2MasteringVoice_DestroyVoice(&This->IXAudio2MasteringVoice_iface);
+}
+
+const IXAudio20MasteringVoiceVtbl XAudio20MasteringVoice_Vtbl = {
+ XA20M_GetVoiceDetails,
+ XA20M_SetOutputVoices,
+ XA20M_SetEffectChain,
+ XA20M_EnableEffect,
+ XA20M_DisableEffect,
+ XA20M_GetEffectState,
+ XA20M_SetEffectParameters,
+ XA20M_GetEffectParameters,
+ XA20M_SetFilterParameters,
+ XA20M_GetFilterParameters,
+ XA20M_SetVolume,
+ XA20M_GetVolume,
+ XA20M_SetChannelVolumes,
+ XA20M_GetChannelVolumes,
+ XA20M_SetOutputMatrix,
+ XA20M_GetOutputMatrix,
+ XA20M_DestroyVoice
+};
+
+static inline IXAudio2Impl *impl_from_IXAudio20(IXAudio20 *iface)
+{
+ return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio20_iface);
+}
+
+static HRESULT WINAPI XA20_QueryInterface(IXAudio20 *iface, REFIID riid,
+ void **ppvObject)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20(iface);
+ return IXAudio2_QueryInterface(&This->IXAudio2_iface, riid, ppvObject);
+}
+
+static ULONG WINAPI XA20_AddRef(IXAudio20 *iface)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20(iface);
+ return IXAudio2_AddRef(&This->IXAudio2_iface);
+}
+
+static ULONG WINAPI XA20_Release(IXAudio20 *iface)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20(iface);
+ return IXAudio2_Release(&This->IXAudio2_iface);
+}
+
+static HRESULT WINAPI XA20_GetDeviceCount(IXAudio20 *iface, UINT32 *pCount)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20(iface);
+
+ TRACE("%p, %p\n", This, pCount);
+
+ *pCount = This->ndevs;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI XA20_GetDeviceDetails(IXAudio20 *iface, UINT32 index,
+ XAUDIO2_DEVICE_DETAILS *pDeviceDetails)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20(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 XA20_Initialize(IXAudio20 *iface, UINT32 flags,
+ XAUDIO2_PROCESSOR processor)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20(iface);
+ TRACE("(%p)->(0x%x, 0x%x)\n", This, flags, processor);
+ return S_OK;
+}
+
+static HRESULT WINAPI XA20_RegisterForCallbacks(IXAudio20 *iface,
+ IXAudio2EngineCallback *pCallback)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20(iface);
+ return IXAudio2_RegisterForCallbacks(&This->IXAudio2_iface, pCallback);
+}
+
+static void WINAPI XA20_UnregisterForCallbacks(IXAudio20 *iface,
+ IXAudio2EngineCallback *pCallback)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20(iface);
+ return IXAudio2_UnregisterForCallbacks(&This->IXAudio2_iface, pCallback);
+}
+
+static HRESULT WINAPI XA20_CreateSourceVoice(IXAudio20 *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_IXAudio20(iface);
+ return IXAudio2_CreateSourceVoice(&This->IXAudio2_iface, ppSourceVoice,
+ pSourceFormat, flags, maxFrequencyRatio, pCallback, pSendList,
+ pEffectChain);
+}
+
+static HRESULT WINAPI XA20_CreateSubmixVoice(IXAudio20 *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_IXAudio20(iface);
+ return IXAudio2_CreateSubmixVoice(&This->IXAudio2_iface, ppSubmixVoice,
+ inputChannels, inputSampleRate, flags, processingStage, pSendList,
+ pEffectChain);
+}
+
+static HRESULT WINAPI XA20_CreateMasteringVoice(IXAudio20 *iface,
+ IXAudio2MasteringVoice **ppMasteringVoice, UINT32 inputChannels,
+ UINT32 inputSampleRate, UINT32 flags, UINT32 deviceIndex,
+ const XAUDIO2_EFFECT_CHAIN *pEffectChain)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20(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 XA20_StartEngine(IXAudio20 *iface)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20(iface);
+ return IXAudio2_StartEngine(&This->IXAudio2_iface);
+}
+
+static void WINAPI XA20_StopEngine(IXAudio20 *iface)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20(iface);
+ return IXAudio2_StopEngine(&This->IXAudio2_iface);
+}
+
+static HRESULT WINAPI XA20_CommitChanges(IXAudio20 *iface, UINT32 operationSet)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20(iface);
+ return IXAudio2_CommitChanges(&This->IXAudio2_iface, operationSet);
+}
+
+static void WINAPI XA20_GetPerformanceData(IXAudio20 *iface,
+ XAUDIO20_PERFORMANCE_DATA *pPerfData)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20(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->GlitchesSinceLastQuery = data.GlitchesSinceEngineStarted - This->last_query_glitches;
+ This->last_query_glitches = 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 XA20_SetDebugConfiguration(IXAudio20 *iface,
+ const XAUDIO2_DEBUG_CONFIGURATION *pDebugConfiguration,
+ void *pReserved)
+{
+ IXAudio2Impl *This = impl_from_IXAudio20(iface);
+ return IXAudio2_SetDebugConfiguration(&This->IXAudio2_iface,
+ pDebugConfiguration, pReserved);
+}
+
+const IXAudio20Vtbl XAudio20_Vtbl = {
+ XA20_QueryInterface,
+ XA20_AddRef,
+ XA20_Release,
+ XA20_GetDeviceCount,
+ XA20_GetDeviceDetails,
+ XA20_Initialize,
+ XA20_RegisterForCallbacks,
+ XA20_UnregisterForCallbacks,
+ XA20_CreateSourceVoice,
+ XA20_CreateSubmixVoice,
+ XA20_CreateMasteringVoice,
+ XA20_StartEngine,
+ XA20_StopEngine,
+ XA20_CommitChanges,
+ XA20_GetPerformanceData,
+ XA20_SetDebugConfiguration
+};
diff --git a/dlls/xaudio2_7/xaudio_dll.c b/dlls/xaudio2_7/xaudio_dll.c
index 868cca3..feab321 100644
--- a/dlls/xaudio2_7/xaudio_dll.c
+++ b/dlls/xaudio2_7/xaudio_dll.c
@@ -38,6 +38,9 @@ static void (ALC_APIENTRY *palcRenderSamplesSOFT)(ALCdevice*, ALCvoid*, ALCsizei
static HINSTANCE instance;
+#define COMPAT_E_INVALID_CALL(v) (v == 20) ? E_INVALIDARG : XAUDIO2_E_INVALID_CALL
+#define COMPAT_E_DEVICE_INVALIDATED(v) (v == 20) ? XAUDIO20_E_DEVICE_INVALIDATED : XAUDIO2_E_DEVICE_INVALIDATED
+
static void dump_fmt(const WAVEFORMATEX *fmt)
{
TRACE("wFormatTag: 0x%x (", fmt->wFormatTag);
@@ -501,7 +504,7 @@ static HRESULT WINAPI XA2SRC_SubmitSourceBuffer(IXAudio2SourceVoice *iface,
if(This->nbufs >= XAUDIO2_MAX_QUEUED_BUFFERS){
TRACE("Too many buffers queued!\n");
LeaveCriticalSection(&This->lock);
- return XAUDIO2_E_INVALID_CALL;
+ return COMPAT_E_INVALID_CALL(This->xa2->version);
}
buf_idx = (This->first_buf + This->nbufs) % XAUDIO2_MAX_QUEUED_BUFFERS;
@@ -512,6 +515,11 @@ static HRESULT WINAPI XA2SRC_SubmitSourceBuffer(IXAudio2SourceVoice *iface,
* but pBuffer itself may be reused immediately */
memcpy(&buf->xa2buffer, pBuffer, sizeof(*pBuffer));
+ if(This->xa2->version == 20){
+ if(buf->xa2buffer.LoopCount == XAUDIO20_LOOP_INFINITE)
+ buf->xa2buffer.LoopCount = XAUDIO2_LOOP_INFINITE;
+ }
+
/* convert samples offsets to bytes */
if(This->fmt->wFormatTag == WAVE_FORMAT_ADPCM){
/* ADPCM gives us a number of samples per block, so round down to
@@ -541,7 +549,7 @@ static HRESULT WINAPI XA2SRC_SubmitSourceBuffer(IXAudio2SourceVoice *iface,
if(buf->xa2buffer.LoopBegin >= buf->play_end_bytes){
/* this actually crashes on native xaudio 2.7 */
LeaveCriticalSection(&This->lock);
- return XAUDIO2_E_INVALID_CALL;
+ return COMPAT_E_INVALID_CALL(This->xa2->version);
}
buf->loop_end_bytes = buf->xa2buffer.LoopBegin + buf->xa2buffer.LoopLength;
@@ -551,12 +559,12 @@ static HRESULT WINAPI XA2SRC_SubmitSourceBuffer(IXAudio2SourceVoice *iface,
if(This->xa2->version > 27){
if(buf->loop_end_bytes > buf->play_end_bytes){
LeaveCriticalSection(&This->lock);
- return XAUDIO2_E_INVALID_CALL;
+ return COMPAT_E_INVALID_CALL(This->xa2->version);
}
if(buf->loop_end_bytes <= buf->xa2buffer.PlayBegin){
LeaveCriticalSection(&This->lock);
- return XAUDIO2_E_INVALID_CALL;
+ return COMPAT_E_INVALID_CALL(This->xa2->version);
}
}else{
if(buf->loop_end_bytes <= buf->xa2buffer.PlayBegin){
@@ -732,7 +740,7 @@ static HRESULT WINAPI XA2SRC_SetSourceSampleRate(
if(This->nbufs){
LeaveCriticalSection(&This->lock);
- return XAUDIO2_E_INVALID_CALL;
+ return COMPAT_E_INVALID_CALL(This->xa2->version);
}
This->fmt->nSamplesPerSec = NewSourceSampleRate;
@@ -1177,7 +1185,9 @@ static HRESULT WINAPI IXAudio2Impl_QueryInterface(IXAudio2 *iface, REFIID riid,
*ppvObject = &This->IXAudio2_iface;
else if(IsEqualGUID(riid, &IID_IXAudio27)){
/* all xaudio versions before 28 share an IID */
- if(This->version == 21 || This->version == 22)
+ if(This->version == 20)
+ *ppvObject = &This->IXAudio20_iface;
+ else if(This->version == 21 || This->version == 22)
*ppvObject = &This->IXAudio22_iface;
else
*ppvObject = &This->IXAudio27_iface;
@@ -1352,6 +1362,7 @@ static HRESULT WINAPI IXAudio2Impl_CreateSourceVoice(IXAudio2 *iface,
list_add_head(&This->source_voices, &src->entry);
+ src->IXAudio20SourceVoice_iface.lpVtbl = &XAudio20SourceVoice_Vtbl;
src->IXAudio23SourceVoice_iface.lpVtbl = &XAudio23SourceVoice_Vtbl;
src->IXAudio27SourceVoice_iface.lpVtbl = &XAudio27SourceVoice_Vtbl;
src->IXAudio2SourceVoice_iface.lpVtbl = &XAudio2SourceVoice_Vtbl;
@@ -1391,7 +1402,9 @@ static HRESULT WINAPI IXAudio2Impl_CreateSourceVoice(IXAudio2 *iface,
alSourcePlay(src->al_src);
- if(This->version <= 23)
+ if(This->version == 20)
+ *ppSourceVoice = (IXAudio2SourceVoice*)&src->IXAudio20SourceVoice_iface;
+ else if(This->version <= 23)
*ppSourceVoice = (IXAudio2SourceVoice*)&src->IXAudio23SourceVoice_iface;
else if(This->version <= 27)
*ppSourceVoice = (IXAudio2SourceVoice*)&src->IXAudio27SourceVoice_iface;
@@ -1432,6 +1445,7 @@ static HRESULT WINAPI IXAudio2Impl_CreateSubmixVoice(IXAudio2 *iface,
list_add_head(&This->submix_voices, &sub->entry);
+ sub->IXAudio20SubmixVoice_iface.lpVtbl = &XAudio20SubmixVoice_Vtbl;
sub->IXAudio23SubmixVoice_iface.lpVtbl = &XAudio23SubmixVoice_Vtbl;
sub->IXAudio2SubmixVoice_iface.lpVtbl = &XAudio2SubmixVoice_Vtbl;
@@ -1443,7 +1457,9 @@ static HRESULT WINAPI IXAudio2Impl_CreateSubmixVoice(IXAudio2 *iface,
LeaveCriticalSection(&This->lock);
- if(This->version <= 23)
+ if(This->version == 20)
+ *ppSubmixVoice = (IXAudio2SubmixVoice*)&sub->IXAudio20SubmixVoice_iface;
+ else if(This->version <= 23)
*ppSubmixVoice = (IXAudio2SubmixVoice*)&sub->IXAudio23SubmixVoice_iface;
else
*ppSubmixVoice = &sub->IXAudio2SubmixVoice_iface;
@@ -1503,7 +1519,7 @@ static HRESULT WINAPI IXAudio2Impl_CreateMasteringVoice(IXAudio2 *iface,
/* there can only be one Mastering Voice, so just build it into XA2 */
if(This->aclient){
LeaveCriticalSection(&This->lock);
- return XAUDIO2_E_INVALID_CALL;
+ return COMPAT_E_INVALID_CALL(This->version);
}
if(!deviceId){
@@ -1517,7 +1533,7 @@ static HRESULT WINAPI IXAudio2Impl_CreateMasteringVoice(IXAudio2 *iface,
hr = IMMDeviceEnumerator_GetDevice(This->devenum, deviceId, &dev);
if(FAILED(hr)){
WARN("GetDevice failed: %08x\n", hr);
- hr = XAUDIO2_E_DEVICE_INVALIDATED;
+ hr = COMPAT_E_DEVICE_INVALIDATED(This->version);
goto exit;
}
@@ -1526,7 +1542,7 @@ static HRESULT WINAPI IXAudio2Impl_CreateMasteringVoice(IXAudio2 *iface,
if(FAILED(hr)){
WARN("Activate(IAudioClient) failed: %08x\n", hr);
IMMDevice_Release(dev);
- hr = XAUDIO2_E_DEVICE_INVALIDATED;
+ hr = COMPAT_E_DEVICE_INVALIDATED(This->version);
goto exit;
}
@@ -1535,13 +1551,13 @@ static HRESULT WINAPI IXAudio2Impl_CreateMasteringVoice(IXAudio2 *iface,
hr = IAudioClient_GetMixFormat(This->aclient, &fmt);
if(FAILED(hr)){
WARN("GetMixFormat failed: %08x\n", hr);
- hr = XAUDIO2_E_DEVICE_INVALIDATED;
+ hr = COMPAT_E_DEVICE_INVALIDATED(This->version);
goto exit;
}
if(sizeof(WAVEFORMATEX) + fmt->cbSize > sizeof(WAVEFORMATEXTENSIBLE)){
FIXME("Mix format doesn't fit into WAVEFORMATEXTENSIBLE!\n");
- hr = XAUDIO2_E_DEVICE_INVALIDATED;
+ hr = COMPAT_E_DEVICE_INVALIDATED(This->version);
goto exit;
}
@@ -1565,7 +1581,7 @@ static HRESULT WINAPI IXAudio2Impl_CreateMasteringVoice(IXAudio2 *iface,
if(hr == S_FALSE){
if(sizeof(WAVEFORMATEX) + fmt->cbSize > sizeof(WAVEFORMATEXTENSIBLE)){
FIXME("Mix format doesn't fit into WAVEFORMATEXTENSIBLE!\n");
- hr = XAUDIO2_E_DEVICE_INVALIDATED;
+ hr = COMPAT_E_DEVICE_INVALIDATED(This->version);
goto exit;
}
memcpy(&This->fmt, fmt, sizeof(WAVEFORMATEX) + fmt->cbSize);
@@ -1576,7 +1592,7 @@ static HRESULT WINAPI IXAudio2Impl_CreateMasteringVoice(IXAudio2 *iface,
hr = IAudioClient_GetDevicePeriod(This->aclient, &period, NULL);
if(FAILED(hr)){
WARN("GetDevicePeriod failed: %08x\n", hr);
- hr = XAUDIO2_E_DEVICE_INVALIDATED;
+ hr = COMPAT_E_DEVICE_INVALIDATED(This->version);
goto exit;
}
@@ -1588,7 +1604,7 @@ static HRESULT WINAPI IXAudio2Impl_CreateMasteringVoice(IXAudio2 *iface,
0, &This->fmt.Format, NULL);
if(FAILED(hr)){
WARN("Initialize failed: %08x\n", hr);
- hr = XAUDIO2_E_DEVICE_INVALIDATED;
+ hr = COMPAT_E_DEVICE_INVALIDATED(This->version);
goto exit;
}
@@ -1597,7 +1613,7 @@ static HRESULT WINAPI IXAudio2Impl_CreateMasteringVoice(IXAudio2 *iface,
hr = IAudioClient_SetEventHandle(This->aclient, This->mmevt);
if(FAILED(hr)){
WARN("Initialize failed: %08x\n", hr);
- hr = XAUDIO2_E_DEVICE_INVALIDATED;
+ hr = COMPAT_E_DEVICE_INVALIDATED(This->version);
goto exit;
}
@@ -1605,7 +1621,7 @@ static HRESULT WINAPI IXAudio2Impl_CreateMasteringVoice(IXAudio2 *iface,
(void**)&This->render);
if(FAILED(hr)){
WARN("GetService(IAudioRenderClient) failed: %08x\n", hr);
- hr = XAUDIO2_E_DEVICE_INVALIDATED;
+ hr = COMPAT_E_DEVICE_INVALIDATED(This->version);
goto exit;
}
@@ -1643,33 +1659,35 @@ static HRESULT WINAPI IXAudio2Impl_CreateMasteringVoice(IXAudio2 *iface,
if(!attrs[5]){
WARN("OpenAL can't output samples in this format\n");
- hr = XAUDIO2_E_DEVICE_INVALIDATED;
+ hr = COMPAT_E_DEVICE_INVALIDATED(This->version);
goto exit;
}
This->al_device = palcLoopbackOpenDeviceSOFT(NULL);
if(!This->al_device){
WARN("alcLoopbackOpenDeviceSOFT failed\n");
- hr = XAUDIO2_E_DEVICE_INVALIDATED;
+ hr = COMPAT_E_DEVICE_INVALIDATED(This->version);
goto exit;
}
This->al_ctx = alcCreateContext(This->al_device, attrs);
if(!This->al_ctx){
WARN("alcCreateContext failed\n");
- hr = XAUDIO2_E_DEVICE_INVALIDATED;
+ hr = COMPAT_E_DEVICE_INVALIDATED(This->version);
goto exit;
}
if(alcMakeContextCurrent(This->al_ctx) == ALC_FALSE){
WARN("alcMakeContextCurrent failed\n");
- hr = XAUDIO2_E_DEVICE_INVALIDATED;
+ hr = COMPAT_E_DEVICE_INVALIDATED(This->version);
goto exit;
}
IAudioClient_Start(This->aclient);
- if(This->version <= 23)
+ if(This->version <= 20)
+ *ppMasteringVoice = (IXAudio2MasteringVoice*)&This->IXAudio20MasteringVoice_iface;
+ else if(This->version <= 23)
*ppMasteringVoice = (IXAudio2MasteringVoice*)&This->IXAudio23MasteringVoice_iface;
else
*ppMasteringVoice = &This->IXAudio2MasteringVoice_iface;
@@ -1776,6 +1794,8 @@ typedef struct _VUMeterImpl {
IXAPOParameters IXAPOParameters_iface;
LONG ref;
+
+ DWORD version;
} VUMeterImpl;
static VUMeterImpl *VUMeterImpl_from_IXAPO(IXAPO *iface)
@@ -1838,6 +1858,7 @@ static HRESULT WINAPI VUMXAPO_GetRegistrationProperties(IXAPO *iface,
{
VUMeterImpl *This = VUMeterImpl_from_IXAPO(iface);
TRACE("%p, %p\n", This, props);
+ /* TODO: check for version == 20 and use XAPO20_REGISTRATION_PROPERTIES */
return E_NOTIMPL;
}
@@ -1978,6 +1999,8 @@ typedef struct _ReverbImpl {
IXAPOParameters IXAPOParameters_iface;
LONG ref;
+
+ DWORD version;
} ReverbImpl;
static ReverbImpl *ReverbImpl_from_IXAPO(IXAPO *iface)
@@ -2039,6 +2062,7 @@ static HRESULT WINAPI RVBXAPO_GetRegistrationProperties(IXAPO *iface,
{
ReverbImpl *This = ReverbImpl_from_IXAPO(iface);
TRACE("%p, %p\n", This, props);
+ /* TODO: check for version == 20 and use XAPO20_REGISTRATION_PROPERTIES */
return E_NOTIMPL;
}
@@ -2308,9 +2332,11 @@ static HRESULT WINAPI XAudio2CF_CreateInstance(IClassFactory *iface, IUnknown *p
if(!object)
return E_OUTOFMEMORY;
+ object->IXAudio20_iface.lpVtbl = &XAudio20_Vtbl;
object->IXAudio22_iface.lpVtbl = &XAudio22_Vtbl;
object->IXAudio27_iface.lpVtbl = &XAudio27_Vtbl;
object->IXAudio2_iface.lpVtbl = &XAudio2_Vtbl;
+ object->IXAudio20MasteringVoice_iface.lpVtbl = &XAudio20MasteringVoice_Vtbl;
object->IXAudio23MasteringVoice_iface.lpVtbl = &XAudio23MasteringVoice_Vtbl;
object->IXAudio2MasteringVoice_iface.lpVtbl = &XAudio2MasteringVoice_Vtbl;
@@ -2346,70 +2372,83 @@ static HRESULT WINAPI XAudio2CF_CreateInstance(IClassFactory *iface, IUnknown *p
return hr;
}
-static ULONG WINAPI static_AddRef(IClassFactory *iface)
+struct xapo_cf {
+ IClassFactory IClassFactory_iface;
+ LONG ref;
+ DWORD version;
+ const CLSID *class;
+};
+
+struct xapo_cf *xapo_impl_from_IClassFactory(IClassFactory *iface)
{
- return 2;
+ return CONTAINING_RECORD(iface, struct xapo_cf, IClassFactory_iface);
}
-static ULONG WINAPI static_Release(IClassFactory *iface)
+static ULONG WINAPI xapo_AddRef(IClassFactory *iface)
{
- return 1;
+ struct xapo_cf *This = xapo_impl_from_IClassFactory(iface);
+ ULONG ref = InterlockedIncrement(&This->ref);
+ TRACE("(%p)->(): Refcount now %u\n", This, ref);
+ return ref;
}
-static HRESULT WINAPI VUMeterCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
- REFIID riid, void **ppobj)
+static ULONG WINAPI xapo_Release(IClassFactory *iface)
{
- HRESULT hr;
- VUMeterImpl *object;
-
- TRACE("(static)->(%p,%s,%p)\n", pOuter, debugstr_guid(riid), ppobj);
-
- *ppobj = NULL;
-
- if(pOuter)
- return CLASS_E_NOAGGREGATION;
-
- object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
- if(!object)
- return E_OUTOFMEMORY;
-
- object->IXAPO_iface.lpVtbl = &VUMXAPO_Vtbl;
- object->IXAPOParameters_iface.lpVtbl = &VUMXAPOParameters_Vtbl;
-
- hr = IXAPO_QueryInterface(&object->IXAPO_iface, riid, ppobj);
- if(FAILED(hr)){
- HeapFree(GetProcessHeap(), 0, object);
- return hr;
- }
-
- return S_OK;
+ struct xapo_cf *This = xapo_impl_from_IClassFactory(iface);
+ ULONG ref = InterlockedDecrement(&This->ref);
+ TRACE("(%p)->(): Refcount now %u\n", This, ref);
+ if (!ref)
+ HeapFree(GetProcessHeap(), 0, This);
+ return ref;
}
-static HRESULT WINAPI ReverbCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
+static HRESULT WINAPI xapo_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
REFIID riid, void **ppobj)
{
+ struct xapo_cf *This = xapo_impl_from_IClassFactory(iface);
HRESULT hr;
- ReverbImpl *object;
- TRACE("(static)->(%p,%s,%p)\n", pOuter, debugstr_guid(riid), ppobj);
+ TRACE("(%p)->(%p,%s,%p)\n", This, pOuter, debugstr_guid(riid), ppobj);
*ppobj = NULL;
if(pOuter)
return CLASS_E_NOAGGREGATION;
- object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
- if(!object)
- return E_OUTOFMEMORY;
-
- object->IXAPO_iface.lpVtbl = &RVBXAPO_Vtbl;
- object->IXAPOParameters_iface.lpVtbl = &RVBXAPOParameters_Vtbl;
-
- hr = IXAPO_QueryInterface(&object->IXAPO_iface, riid, ppobj);
- if(FAILED(hr)){
- HeapFree(GetProcessHeap(), 0, object);
- return hr;
- }
+ if(IsEqualGUID(This->class, &CLSID_AudioVolumeMeter)){
+ VUMeterImpl *object;
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if(!object)
+ return E_OUTOFMEMORY;
+
+ object->IXAPO_iface.lpVtbl = &VUMXAPO_Vtbl;
+ object->IXAPOParameters_iface.lpVtbl = &VUMXAPOParameters_Vtbl;
+ object->version = This->version;
+
+ hr = IXAPO_QueryInterface(&object->IXAPO_iface, riid, ppobj);
+ if(FAILED(hr)){
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+ }else if(IsEqualGUID(This->class, &CLSID_AudioReverb)){
+ ReverbImpl *object;
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if(!object)
+ return E_OUTOFMEMORY;
+
+ object->IXAPO_iface.lpVtbl = &RVBXAPO_Vtbl;
+ object->IXAPOParameters_iface.lpVtbl = &RVBXAPOParameters_Vtbl;
+ object->version = This->version;
+
+ hr = IXAPO_QueryInterface(&object->IXAPO_iface, riid, ppobj);
+ if(FAILED(hr)){
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+ }else
+ return E_INVALIDARG;
return S_OK;
}
@@ -2429,43 +2468,43 @@ static const IClassFactoryVtbl XAudio2CF_Vtbl =
XAudio2CF_LockServer
};
-static const IClassFactoryVtbl VUMeterCF_Vtbl =
+static const IClassFactoryVtbl xapo_Vtbl =
{
XAudio2CF_QueryInterface,
- static_AddRef,
- static_Release,
- VUMeterCF_CreateInstance,
+ xapo_AddRef,
+ xapo_Release,
+ xapo_CreateInstance,
XAudio2CF_LockServer
};
-static const IClassFactoryVtbl ReverbCF_Vtbl =
-{
- XAudio2CF_QueryInterface,
- static_AddRef,
- static_Release,
- ReverbCF_CreateInstance,
- XAudio2CF_LockServer
-};
-
-static IClassFactory vumeter_cf = { &VUMeterCF_Vtbl };
-static IClassFactory reverb_cf = { &ReverbCF_Vtbl };
-
static IClassFactory *make_xaudio2_factory(DWORD version)
{
- struct xaudio2_cf *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(struct xaudio2_cf));
+ struct xapo_cf *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(struct xaudio2_cf));
ret->IClassFactory_iface.lpVtbl = &XAudio2CF_Vtbl;
ret->version = version;
ret->ref = 0;
return &ret->IClassFactory_iface;
}
+static IClassFactory *make_xapo_factory(REFCLSID clsid, DWORD version)
+{
+ struct xapo_cf *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(struct xaudio2_cf));
+ ret->IClassFactory_iface.lpVtbl = &XAudio2CF_Vtbl;
+ ret->version = version;
+ ret->class = clsid;
+ ret->ref = 0;
+ return &ret->IClassFactory_iface;
+}
+
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
{
IClassFactory *factory = NULL;
TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
- if IsEqualGUID(rclsid, &CLSID_XAudio21){
+ if IsEqualGUID(rclsid, &CLSID_XAudio20){
+ factory = make_xaudio2_factory(20);
+ }else if IsEqualGUID(rclsid, &CLSID_XAudio21){
factory = make_xaudio2_factory(21);
}else if IsEqualGUID(rclsid, &CLSID_XAudio22){
factory = make_xaudio2_factory(22);
@@ -2479,22 +2518,40 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
factory = make_xaudio2_factory(26);
}else if(IsEqualGUID(rclsid, &CLSID_XAudio2)){
factory = make_xaudio2_factory(27);
- }else if(IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter) ||
- IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter21) ||
- IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter22) ||
- IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter23) ||
- IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter24) ||
- IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter25) ||
- IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter26)){
- factory = &vumeter_cf;
- }else if(IsEqualGUID(rclsid, &CLSID_AudioReverb) ||
- IsEqualGUID(rclsid, &CLSID_AudioReverb21) ||
- IsEqualGUID(rclsid, &CLSID_AudioReverb22) ||
- IsEqualGUID(rclsid, &CLSID_AudioReverb23) ||
- IsEqualGUID(rclsid, &CLSID_AudioReverb24) ||
- IsEqualGUID(rclsid, &CLSID_AudioReverb25) ||
- IsEqualGUID(rclsid, &CLSID_AudioReverb26)){
- factory = &reverb_cf;
+
+ }else if IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter20){
+ factory = make_xapo_factory(&CLSID_AudioVolumeMeter, 20);
+ }else if IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter21){
+ factory = make_xapo_factory(&CLSID_AudioVolumeMeter, 21);
+ }else if IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter22){
+ factory = make_xapo_factory(&CLSID_AudioVolumeMeter, 22);
+ }else if IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter23){
+ factory = make_xapo_factory(&CLSID_AudioVolumeMeter, 23);
+ }else if(IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter24)){
+ factory = make_xapo_factory(&CLSID_AudioVolumeMeter, 24);
+ }else if(IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter25)){
+ factory = make_xapo_factory(&CLSID_AudioVolumeMeter, 25);
+ }else if(IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter26)){
+ factory = make_xapo_factory(&CLSID_AudioVolumeMeter, 26);
+ }else if(IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter)){
+ factory = make_xapo_factory(&CLSID_AudioVolumeMeter, 27);
+
+ }else if IsEqualGUID(rclsid, &CLSID_AudioReverb20){
+ factory = make_xapo_factory(&CLSID_AudioReverb, 20);
+ }else if IsEqualGUID(rclsid, &CLSID_AudioReverb21){
+ factory = make_xapo_factory(&CLSID_AudioReverb, 21);
+ }else if IsEqualGUID(rclsid, &CLSID_AudioReverb22){
+ factory = make_xapo_factory(&CLSID_AudioReverb, 22);
+ }else if IsEqualGUID(rclsid, &CLSID_AudioReverb23){
+ factory = make_xapo_factory(&CLSID_AudioReverb, 23);
+ }else if(IsEqualGUID(rclsid, &CLSID_AudioReverb24)){
+ factory = make_xapo_factory(&CLSID_AudioReverb, 24);
+ }else if(IsEqualGUID(rclsid, &CLSID_AudioReverb25)){
+ factory = make_xapo_factory(&CLSID_AudioReverb, 25);
+ }else if(IsEqualGUID(rclsid, &CLSID_AudioReverb26)){
+ factory = make_xapo_factory(&CLSID_AudioReverb, 26);
+ }else if(IsEqualGUID(rclsid, &CLSID_AudioReverb)){
+ factory = make_xapo_factory(&CLSID_AudioReverb, 27);
}
if(!factory) return CLASS_E_CLASSNOTAVAILABLE;
@@ -2679,9 +2736,13 @@ static void do_engine_tick(IXAudio2Impl *This)
continue;
}
- if(src->cb)
- /* TODO: detect incoming underrun and inform callback */
- IXAudio2VoiceCallback_OnVoiceProcessingPassStart(src->cb, 0);
+ if(src->cb){
+ if(This->version == 20)
+ IXAudio20VoiceCallback_OnVoiceProcessingPassStart((IXAudio20VoiceCallback*)src->cb);
+ else
+ /* TODO: detect incoming underrun and inform callback */
+ IXAudio2VoiceCallback_OnVoiceProcessingPassStart(src->cb, 0);
+ }
update_source_state(src);
diff --git a/dlls/xaudio2_7/xaudio_private.h b/dlls/xaudio2_7/xaudio_private.h
index 91966ca..7772a5b 100644
--- a/dlls/xaudio2_7/xaudio_private.h
+++ b/dlls/xaudio2_7/xaudio_private.h
@@ -42,6 +42,7 @@ typedef struct _XA2Buffer {
typedef struct _IXAudio2Impl IXAudio2Impl;
typedef struct _XA2SourceImpl {
+ IXAudio20SourceVoice IXAudio20SourceVoice_iface;
IXAudio23SourceVoice IXAudio23SourceVoice_iface;
IXAudio27SourceVoice IXAudio27SourceVoice_iface;
IXAudio2SourceVoice IXAudio2SourceVoice_iface;
@@ -81,6 +82,7 @@ typedef struct _XA2SourceImpl {
} XA2SourceImpl;
typedef struct _XA2SubmixImpl {
+ IXAudio20SubmixVoice IXAudio20SubmixVoice_iface;
IXAudio23SubmixVoice IXAudio23SubmixVoice_iface;
IXAudio2SubmixVoice IXAudio2SubmixVoice_iface;
@@ -92,9 +94,11 @@ typedef struct _XA2SubmixImpl {
} XA2SubmixImpl;
struct _IXAudio2Impl {
+ IXAudio20 IXAudio20_iface;
IXAudio22 IXAudio22_iface;
IXAudio27 IXAudio27_iface;
IXAudio2 IXAudio2_iface;
+ IXAudio20MasteringVoice IXAudio20MasteringVoice_iface;
IXAudio23MasteringVoice IXAudio23MasteringVoice_iface;
IXAudio2MasteringVoice IXAudio2MasteringVoice_iface;
@@ -115,6 +119,8 @@ struct _IXAudio2Impl {
WCHAR **devids;
UINT32 ndevs;
+ UINT32 last_query_glitches;
+
IAudioClient *aclient;
IAudioRenderClient *render;
@@ -139,3 +145,8 @@ extern const IXAudio23SubmixVoiceVtbl XAudio23SubmixVoice_Vtbl DECLSPEC_HIDDEN;
extern const IXAudio23MasteringVoiceVtbl XAudio23MasteringVoice_Vtbl DECLSPEC_HIDDEN;
extern const IXAudio22Vtbl XAudio22_Vtbl DECLSPEC_HIDDEN;
+
+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;
diff --git a/include/xapo.idl b/include/xapo.idl
index 9055775..de09ba0 100644
--- a/include/xapo.idl
+++ b/include/xapo.idl
@@ -60,6 +60,22 @@ typedef struct XAPO_REGISTRATION_PROPERTIES
UINT32 MaxOutputBufferCount;
} XAPO_REGISTRATION_PROPERTIES;
+typedef struct XAPO20_REGISTRATION_PROPERTIES
+{
+ CLSID clsid;
+ WCHAR FriendlyName[XAPO_REGISTRATION_STRING_LENGTH];
+ WCHAR CopyrightInfo[XAPO_REGISTRATION_STRING_LENGTH];
+ UINT32 MajorVersion;
+ UINT32 MinorVersion;
+ UINT32 Flags;
+ UINT32 MinInputBufferCount;
+ UINT32 MaxInputBufferCount;
+ UINT32 MinOutputBufferCount;
+ UINT32 MaxOutputBufferCount;
+ UINT32 InterfaceCount;
+ IID InterfaceArray[1];
+} XAPO20_REGISTRATION_PROPERTIES;
+
typedef struct XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS {
const WAVEFORMATEX *pFormat;
UINT32 MaxFrameCount;
diff --git a/include/xaudio2.idl b/include/xaudio2.idl
index 5d4726a..84bd456 100644
--- a/include/xaudio2.idl
+++ b/include/xaudio2.idl
@@ -31,6 +31,13 @@ coclass XAudio2 {
}
[
+ uuid(fac23f48-31f5-45a8-b49b-5225d61401aa)
+]
+coclass XAudio20 {
+ interface IUnknown;
+}
+
+[
uuid(e21a7345-eb21-468e-be50-804db97cf708)
]
coclass XAudio21 {
@@ -180,6 +187,23 @@ typedef struct XAUDIO22_PERFORMANCE_DATA
UINT32 ActiveXmaStreams;
} XAUDIO22_PERFORMANCE_DATA;
+typedef struct XAUDIO20_PERFORMANCE_DATA
+{
+ UINT64 AudioCyclesSinceLastQuery;
+ UINT64 TotalCyclesSinceLastQuery;
+ UINT32 MinimumCyclesPerQuantum;
+ UINT32 MaximumCyclesPerQuantum;
+ UINT32 MemoryUsageInBytes;
+ UINT32 CurrentLatencyInSamples;
+ UINT32 GlitchesSinceLastQuery;
+ UINT32 ActiveSourceVoiceCount;
+ UINT32 TotalSourceVoiceCount;
+ UINT32 ActiveSubmixVoiceCount;
+ UINT32 TotalSubmixVoiceCount;
+ UINT32 ActiveXmaSourceVoices;
+ UINT32 ActiveXmaStreams;
+} XAUDIO20_PERFORMANCE_DATA;
+
typedef enum XAUDIO2_DEVICE_ROLE
{
NotDefaultDevice = 0x0,
@@ -251,12 +275,14 @@ const float XAUDIO2_DEFAULT_FREQ_RATIO = 2.0;
const float XAUDIO2_MAX_FILTER_ONEOVERQ = 1.5;
const float XAUDIO2_MAX_FILTER_FREQUENCY = 1.0;
const UINT32 XAUDIO2_MAX_LOOP_COUNT = 254;
+const UINT32 XAUDIO20_MAX_LOOP_COUNT = 0x100000; /* xaudio 2.0 */
const UINT32 XAUDIO2_COMMIT_NOW = 0;
const UINT32 XAUDIO2_COMMIT_ALL = 0;
const UINT32 XAUDIO2_INVALID_OPSET = 0xffffffff;
const UINT32 XAUDIO2_NO_LOOP_REGION = 0;
const UINT32 XAUDIO2_LOOP_INFINITE = 255;
+const UINT32 XAUDIO20_LOOP_INFINITE = ((UINT)-1); /* xaudio 2.0 */
const UINT32 XAUDIO2_DEFAULT_CHANNELS = 0;
const UINT32 XAUDIO2_DEFAULT_SAMPLERATE = 0;
@@ -288,6 +314,81 @@ typedef struct XAUDIO2_FILTER_PARAMETERS
float OneOverQ;
} XAUDIO2_FILTER_PARAMETERS;
+/* XAudio 2.0's IXAudio2Voice */
+/* XAudio2 2.0's IXAudio2Voice interface. Actually called
+ * IXAudio2Voice in the Mar 2008 DX SDK */
+[
+ object,
+ local
+]
+interface IXAudio20Voice
+{
+ void GetVoiceDetails([out] XAUDIO2_VOICE_DETAILS* pVoiceDetails);
+
+ HRESULT SetOutputVoices([in] const XAUDIO23_VOICE_SENDS* pSendList);
+
+ HRESULT SetEffectChain([in] const XAUDIO2_EFFECT_CHAIN* pEffectChain);
+
+ HRESULT EnableEffect(
+ [in] UINT32 EffectIndex,
+ [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);
+
+ HRESULT DisableEffect(
+ [in] UINT32 EffectIndex,
+ [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);
+
+ void GetEffectState(
+ [in] UINT32 EffectIndex,
+ [out] BOOL* pEnabled);
+
+ HRESULT SetEffectParameters(
+ [in] UINT32 EffectIndex,
+ [in] const void* pParameters,
+ [in] UINT32 ParametersByteSize,
+ [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);
+
+ HRESULT GetEffectParameters(
+ [in] UINT32 EffectIndex,
+ [out] void* pParameters,
+ [in] UINT32 ParametersByteSize);
+
+ HRESULT SetFilterParameters(
+ [in] const XAUDIO2_FILTER_PARAMETERS* pParameters,
+ [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);
+
+ void GetFilterParameters([out] XAUDIO2_FILTER_PARAMETERS* pParameters);
+
+ HRESULT SetVolume(
+ [in] float Volume,
+ [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);
+
+ void GetVolume([out] float* pVolume);
+
+ HRESULT SetChannelVolumes(
+ [in] UINT32 Channels,
+ [in, size_is(Channels)] const float* pVolumes,
+ [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);
+
+ void GetChannelVolumes(
+ [in] UINT32 Channels,
+ [out, size_is(Channels)] float* pVolumes);
+
+ HRESULT SetOutputMatrix(
+ [in] IXAudio2Voice* pDestinationVoice,
+ [in] UINT32 SourceChannels,
+ [in] UINT32 DestinationChannels,
+ [in, size_is(SourceChannels * DestinationChannels)] const float* pLevelMatrix,
+ [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);
+
+ HRESULT GetOutputMatrix(
+ [in] IXAudio2Voice* pDestinationVoice,
+ [in] UINT32 SourceChannels,
+ [in] UINT32 DestinationChannels,
+ [out, size_is(SourceChannels * DestinationChannels)] float* pLevelMatrix);
+
+ void DestroyVoice();
+}
+
/* XAudio 2.3's IXAudio2Voice */
/* XAudio2 2.3's IXAudio2Voice interface. Actually called
* IXAudio2Voice in the Nov 2008 DX SDK */
@@ -362,6 +463,7 @@ interface IXAudio23Voice
void DestroyVoice();
}
+
[
object,
local
@@ -472,6 +574,40 @@ typedef struct XAUDIO2_VOICE_STATE
[
local
]
+/* XAudio2 2.0's IXAudio2SourceVoice interface. Actually called
+ * IXAudio2SourceVoice in the Mar 2008 DX SDK */
+interface IXAudio20SourceVoice : IXAudio20Voice
+{
+ HRESULT Start(
+ [in, defaultvalue(0)] UINT32 Flags,
+ [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);
+
+ HRESULT Stop(
+ [in, defaultvalue(0)] UINT32 Flags,
+ [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);
+
+ HRESULT SubmitSourceBuffer(
+ [in] const XAUDIO2_BUFFER* pBuffer,
+ [in, defaultvalue(NULL)] const XAUDIO2_BUFFER_WMA* pBufferWMA);
+
+ HRESULT FlushSourceBuffers();
+
+ HRESULT Discontinuity();
+
+ HRESULT ExitLoop([in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);
+
+ void GetState([out] XAUDIO2_VOICE_STATE* pVoiceState);
+
+ HRESULT SetFrequencyRatio(
+ [in] float Ratio,
+ [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet);
+
+ void GetFrequencyRatio([out] float* pRatio);
+}
+
+[
+ local
+]
/* XAudio2 2.3's IXAudio2SourceVoice interface. Actually called
* IXAudio2SourceVoice in the Nov 2008 DX SDK */
interface IXAudio23SourceVoice : IXAudio23Voice
@@ -577,6 +713,15 @@ interface IXAudio2SourceVoice : IXAudio2Voice
[
local
]
+/* XAudio2 2.0's IXAudio2SubmixVoice interface. Actually called
+ * IXAudio2SubmixVoice in the Mar 2008 DX SDK */
+interface IXAudio20SubmixVoice : IXAudio20Voice
+{
+}
+
+[
+ local
+]
/* XAudio2 2.3's IXAudio2SubmixVoice interface. Actually called
* IXAudio2SubmixVoice in the Nov 2008 DX SDK */
interface IXAudio23SubmixVoice : IXAudio23Voice
@@ -593,6 +738,15 @@ interface IXAudio2SubmixVoice : IXAudio2Voice
[
local
]
+/* XAudio2 2.0's IXAudio2MasteringVoice interface. Actually called
+ * IXAudio2MasteringVoice in the Mar 2008 DX SDK */
+interface IXAudio20MasteringVoice : IXAudio20Voice
+{
+}
+
+[
+ local
+]
/* XAudio2 2.3's IXAudio2MasteringVoice interface. Actually called
* IXAudio2MasteringVoice in the Nov 2008 DX SDK */
interface IXAudio23MasteringVoice : IXAudio23Voice
@@ -612,6 +766,29 @@ interface IXAudio2MasteringVoice : IXAudio2Voice
object,
local
]
+interface IXAudio20VoiceCallback
+{
+ void OnVoiceProcessingPassStart();
+
+ void OnVoiceProcessingPassEnd();
+
+ void OnStreamEnd();
+
+ void OnBufferStart([in] void* pBufferContext);
+
+ void OnBufferEnd([in] void* pBufferContext);
+
+ void OnLoopEnd([in] void* pBufferContext);
+
+ void OnVoiceError(
+ [in] void* pBuffercontext,
+ [in] HRESULT Error);
+}
+
+[
+ object,
+ local
+]
interface IXAudio2VoiceCallback
{
void OnVoiceProcessingPassStart([in] UINT32 BytesRequired);
@@ -645,6 +822,67 @@ typedef struct XAUDIO2_DEBUG_CONFIGURATION
object,
uuid(8bcf1f58-9fe7-4583-8ac6-e2adc465c8bb), /* all versions before 28 share IID_IXAudio */
]
+/* XAudio2 2.0's IXAudio2 interface. Actually called IXAudio2 in the Mar 2008
+ * DX SDK */
+interface IXAudio20 : IUnknown
+{
+ HRESULT GetDeviceCount([out] UINT32* pCount);
+
+ HRESULT GetDeviceDetails(
+ [in] UINT32 Index,
+ [out] XAUDIO2_DEVICE_DETAILS* pDeviceDetails);
+
+ HRESULT Initialize(
+ [in, defaultvalue(0)] UINT32 Flags,
+ [in, defaultvalue(XAUDIO2_DEFAULT_PROCESSOR)] XAUDIO2_PROCESSOR XAudio2Processor);
+
+ HRESULT RegisterForCallbacks([in] IXAudio2EngineCallback* pCallback);
+
+ void UnregisterForCallbacks([in] IXAudio2EngineCallback* pCallback);
+
+ HRESULT CreateSourceVoice(
+ [out] IXAudio2SourceVoice** ppSourceVoice,
+ [in] const WAVEFORMATEX* pSourceFormat,
+ [in, defaultvalue(0)] UINT32 Flags,
+ [in, defaultvalue(XAUDIO2_DEFAULT_FREQ_RATIO)] float MaxFrequencyRatio,
+ [in, defaultvalue(NULL)] IXAudio2VoiceCallback* pCallback,
+ [in, defaultvalue(NULL)] const XAUDIO2_VOICE_SENDS* pSendList,
+ [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain);
+
+ HRESULT CreateSubmixVoice(
+ [out] IXAudio2SubmixVoice** ppSubmixVoice,
+ [in] UINT32 InputChannels,
+ [in] UINT32 InputSampleRate,
+ [in, defaultvalue(0)] UINT32 Flags,
+ [in, defaultvalue(0)] UINT32 ProcessingStage,
+ [in, defaultvalue(NULL)] const XAUDIO2_VOICE_SENDS* pSendList,
+ [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain);
+
+ HRESULT CreateMasteringVoice(
+ [out] IXAudio2MasteringVoice** ppMasteringVoice,
+ [in, defaultvalue(XAUDIO2_DEFAULT_CHANNELS)] UINT32 InputChannels,
+ [in, defaultvalue(XAUDIO2_DEFAULT_SAMPLERATE)] UINT32 InputSampleRate,
+ [in, defaultvalue(0)] UINT32 Flags,
+ [in, defaultvalue(0)] UINT32 DeviceIndex,
+ [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain);
+
+ HRESULT StartEngine();
+
+ void StopEngine();
+
+ HRESULT CommitChanges([in] UINT32 OperationSet);
+
+ void GetPerformanceData([out] XAUDIO20_PERFORMANCE_DATA* pPerfData);
+
+ [local] void SetDebugConfiguration(
+ [in] const XAUDIO2_DEBUG_CONFIGURATION* pDebugConfiguration,
+ [in, defaultvalue(NULL)] void* pReserved);
+}
+
+[
+ object,
+ uuid(8bcf1f58-9fe7-4583-8ac6-e2adc465c8bb), /* all versions before 28 share IID_IXAudio */
+]
/* XAudio2 2.2's IXAudio2 interface. Actually called IXAudio2 in the Jun 2010
* DX SDK */
interface IXAudio22 : IUnknown
@@ -836,6 +1074,11 @@ const HRESULT XAUDIO2_E_XMA_DECODER_ERROR = 0x88960002;
const HRESULT XAUDIO2_E_XAPO_CREATION_FAILED = 0x88960003;
const HRESULT XAUDIO2_E_DEVICE_INVALIDATED = 0x88960004;
+/* xaudio 2.0 error codes */
+const HRESULT XAUDIO20_E_XMA_DECODER_ERROR = 0x88960001;
+const HRESULT XAUDIO20_E_XAPO_CREATION_FAILED = 0x88960002;
+const HRESULT XAUDIO20_E_DEVICE_INVALIDATED = 0x88960003;
+
cpp_quote("#ifdef XAUDIO2_HELPER_FUNCTIONS")
cpp_quote("#define _USE_MATH_DEFINES")
cpp_quote("#include <math.h>")
diff --git a/include/xaudio2fx.idl b/include/xaudio2fx.idl
index c152b98..ad58232 100644
--- a/include/xaudio2fx.idl
+++ b/include/xaudio2fx.idl
@@ -26,6 +26,13 @@ coclass AudioVolumeMeter {
}
[
+ uuid(c0c56f46-29b1-44e9-9939-a32ce86867e2)
+]
+coclass AudioVolumeMeter20 {
+ interface IUnknown;
+}
+
+[
uuid(c1e3f122-a2ea-442c-854f-20d98f8357a1)
]
coclass AudioVolumeMeter21 {
@@ -75,6 +82,13 @@ coclass AudioReverb {
}
[
+ uuid(6f6ea3a9-2cf5-41cf-91c1-2170b1540063)
+]
+coclass AudioReverb20 {
+ interface IUnknown;
+}
+
+[
uuid(f4769300-b949-4df9-b333-00d33932e9a6)
]
coclass AudioReverb21 {
--
2.6.1
More information about the wine-patches
mailing list