From 4185cc7a94cd74ce2b76ea57601dc32305c944b1 Mon Sep 17 00:00:00 2001 From: Andrew Eikum Date: Wed, 7 Oct 2015 11:19:35 -0500 Subject: [PATCH] xaudio2_0: Add compatibility implementation and forward to xaudio2_7. Signed-off-by: Andrew Eikum Signed-off-by: Alexandre Julliard --- configure | 2 + 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 | 265 +++++---- dlls/xaudio2_7/xaudio_private.h | 11 + include/xapo.idl | 16 + include/xaudio2.idl | 243 +++++++++ include/xaudio2fx.idl | 14 + 12 files changed, 1414 insertions(+), 102 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 b/configure index b4bbb2f22fe..8b1fb86c0ea 100755 --- a/configure +++ b/configure @@ -1377,6 +1377,7 @@ enable_xapofx1_2 enable_xapofx1_3 enable_xapofx1_4 enable_xapofx1_5 +enable_xaudio2_0 enable_xaudio2_1 enable_xaudio2_2 enable_xaudio2_3 @@ -17949,6 +17950,7 @@ wine_fn_config_dll xapofx1_2 enable_xapofx1_2 wine_fn_config_dll xapofx1_3 enable_xapofx1_3 wine_fn_config_dll xapofx1_4 enable_xapofx1_4 wine_fn_config_dll xapofx1_5 enable_xapofx1_5 +wine_fn_config_dll xaudio2_0 enable_xaudio2_0 clean wine_fn_config_dll xaudio2_1 enable_xaudio2_1 clean wine_fn_config_dll xaudio2_2 enable_xaudio2_2 clean wine_fn_config_dll xaudio2_3 enable_xaudio2_3 clean diff --git a/configure.ac b/configure.ac index ce631e4dbb1..5e83d397659 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 00000000000..cc9d1610878 --- /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 00000000000..cb263d4836b --- /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 00000000000..4a81eb1f4bd --- /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 00000000000..7c95c288ca0 --- /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 +#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 bee57c6e2a7..8eb0efc8d87 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 868cca3074b..feab32117a7 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, +static ULONG WINAPI xapo_Release(IClassFactory *iface) +{ + 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 xapo_CreateInstance(IClassFactory *iface, IUnknown *pOuter, REFIID riid, void **ppobj) { + struct xapo_cf *This = xapo_impl_from_IClassFactory(iface); HRESULT hr; - VUMeterImpl *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; + if(IsEqualGUID(This->class, &CLSID_AudioVolumeMeter)){ + VUMeterImpl *object; - object->IXAPO_iface.lpVtbl = &VUMXAPO_Vtbl; - object->IXAPOParameters_iface.lpVtbl = &VUMXAPOParameters_Vtbl; + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + if(!object) + return E_OUTOFMEMORY; - hr = IXAPO_QueryInterface(&object->IXAPO_iface, riid, ppobj); - if(FAILED(hr)){ - HeapFree(GetProcessHeap(), 0, object); - return hr; - } + object->IXAPO_iface.lpVtbl = &VUMXAPO_Vtbl; + object->IXAPOParameters_iface.lpVtbl = &VUMXAPOParameters_Vtbl; + object->version = This->version; - return S_OK; -} + 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; -static HRESULT WINAPI ReverbCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter, - REFIID riid, void **ppobj) -{ - HRESULT hr; - ReverbImpl *object; + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + if(!object) + return E_OUTOFMEMORY; - TRACE("(static)->(%p,%s,%p)\n", pOuter, debugstr_guid(riid), ppobj); + object->IXAPO_iface.lpVtbl = &RVBXAPO_Vtbl; + object->IXAPOParameters_iface.lpVtbl = &RVBXAPOParameters_Vtbl; + object->version = This->version; - *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; - } + 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 91966ca6eb2..7772a5b59e9 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 9055775ff1e..de09ba0c91d 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 5d4726a8545..84bd4564aa4 100644 --- a/include/xaudio2.idl +++ b/include/xaudio2.idl @@ -30,6 +30,13 @@ coclass XAudio2 { interface IUnknown; } +[ + uuid(fac23f48-31f5-45a8-b49b-5225d61401aa) +] +coclass XAudio20 { + interface IUnknown; +} + [ uuid(e21a7345-eb21-468e-be50-804db97cf708) ] @@ -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 @@ -469,6 +571,40 @@ typedef struct XAUDIO2_VOICE_STATE UINT64 SamplesPlayed; } XAUDIO2_VOICE_STATE; +[ + local +] +/* XAudio2 2.0's IXAudio2SourceVoice interface. Actually called + * IXAudio2SourceVoice in the Mar 2008 DX SDK */ +interface IXAudio20SourceVoice : IXAudio20Voice +{ + HRESULT Start( + [in, defaultvalue(0)] UINT32 Flags, + [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet); + + HRESULT Stop( + [in, defaultvalue(0)] UINT32 Flags, + [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet); + + HRESULT SubmitSourceBuffer( + [in] const XAUDIO2_BUFFER* pBuffer, + [in, defaultvalue(NULL)] const XAUDIO2_BUFFER_WMA* pBufferWMA); + + HRESULT FlushSourceBuffers(); + + HRESULT Discontinuity(); + + HRESULT ExitLoop([in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet); + + void GetState([out] XAUDIO2_VOICE_STATE* pVoiceState); + + HRESULT SetFrequencyRatio( + [in] float Ratio, + [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet); + + void GetFrequencyRatio([out] float* pRatio); +} + [ local ] @@ -574,6 +710,15 @@ interface IXAudio2SourceVoice : IXAudio2Voice HRESULT SetSourceSampleRate([in] UINT32 NewSourceSampleRate); } +[ + local +] +/* XAudio2 2.0's IXAudio2SubmixVoice interface. Actually called + * IXAudio2SubmixVoice in the Mar 2008 DX SDK */ +interface IXAudio20SubmixVoice : IXAudio20Voice +{ +} + [ local ] @@ -590,6 +735,15 @@ interface IXAudio2SubmixVoice : IXAudio2Voice { } +[ + local +] +/* XAudio2 2.0's IXAudio2MasteringVoice interface. Actually called + * IXAudio2MasteringVoice in the Mar 2008 DX SDK */ +interface IXAudio20MasteringVoice : IXAudio20Voice +{ +} + [ local ] @@ -608,6 +762,29 @@ interface IXAudio2MasteringVoice : IXAudio2Voice void GetChannelMask([out] DWORD *pChannelMask); } +[ + object, + local +] +interface IXAudio20VoiceCallback +{ + void OnVoiceProcessingPassStart(); + + void OnVoiceProcessingPassEnd(); + + void OnStreamEnd(); + + void OnBufferStart([in] void* pBufferContext); + + void OnBufferEnd([in] void* pBufferContext); + + void OnLoopEnd([in] void* pBufferContext); + + void OnVoiceError( + [in] void* pBuffercontext, + [in] HRESULT Error); +} + [ object, local @@ -641,6 +818,67 @@ typedef struct XAUDIO2_DEBUG_CONFIGURATION BOOL LogTiming; } XAUDIO2_DEBUG_CONFIGURATION; +[ + object, + uuid(8bcf1f58-9fe7-4583-8ac6-e2adc465c8bb), /* all versions before 28 share IID_IXAudio */ +] +/* XAudio2 2.0's IXAudio2 interface. Actually called IXAudio2 in the Mar 2008 + * DX SDK */ +interface IXAudio20 : IUnknown +{ + HRESULT GetDeviceCount([out] UINT32* pCount); + + HRESULT GetDeviceDetails( + [in] UINT32 Index, + [out] XAUDIO2_DEVICE_DETAILS* pDeviceDetails); + + HRESULT Initialize( + [in, defaultvalue(0)] UINT32 Flags, + [in, defaultvalue(XAUDIO2_DEFAULT_PROCESSOR)] XAUDIO2_PROCESSOR XAudio2Processor); + + HRESULT RegisterForCallbacks([in] IXAudio2EngineCallback* pCallback); + + void UnregisterForCallbacks([in] IXAudio2EngineCallback* pCallback); + + HRESULT CreateSourceVoice( + [out] IXAudio2SourceVoice** ppSourceVoice, + [in] const WAVEFORMATEX* pSourceFormat, + [in, defaultvalue(0)] UINT32 Flags, + [in, defaultvalue(XAUDIO2_DEFAULT_FREQ_RATIO)] float MaxFrequencyRatio, + [in, defaultvalue(NULL)] IXAudio2VoiceCallback* pCallback, + [in, defaultvalue(NULL)] const 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 */ @@ -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 ") diff --git a/include/xaudio2fx.idl b/include/xaudio2fx.idl index c152b98d3ba..ad582321b92 100644 --- a/include/xaudio2fx.idl +++ b/include/xaudio2fx.idl @@ -25,6 +25,13 @@ coclass AudioVolumeMeter { interface IUnknown; } +[ + uuid(c0c56f46-29b1-44e9-9939-a32ce86867e2) +] +coclass AudioVolumeMeter20 { + interface IUnknown; +} + [ uuid(c1e3f122-a2ea-442c-854f-20d98f8357a1) ] @@ -74,6 +81,13 @@ coclass AudioReverb { interface IUnknown; } +[ + uuid(6f6ea3a9-2cf5-41cf-91c1-2170b1540063) +] +coclass AudioReverb20 { + interface IUnknown; +} + [ uuid(f4769300-b949-4df9-b333-00d33932e9a6) ]