xaudio2_2: Add compatibility implementation and forward to xaudio2_7.

Signed-off-by: Andrew Eikum <aeikum@codeweavers.com>
This commit is contained in:
Andrew Eikum 2015-10-05 11:33:03 -05:00 committed by Alexandre Julliard
parent d25737b381
commit 831095ed93
11 changed files with 454 additions and 4 deletions

2
configure vendored
View File

@ -1374,6 +1374,7 @@ enable_xapofx1_1
enable_xapofx1_3
enable_xapofx1_4
enable_xapofx1_5
enable_xaudio2_2
enable_xaudio2_3
enable_xaudio2_4
enable_xaudio2_5
@ -17915,6 +17916,7 @@ wine_fn_config_dll xapofx1_1 enable_xapofx1_1
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_2 enable_xaudio2_2 clean
wine_fn_config_dll xaudio2_3 enable_xaudio2_3 clean
wine_fn_config_dll xaudio2_4 enable_xaudio2_4 clean
wine_fn_config_dll xaudio2_5 enable_xaudio2_5 clean

View File

@ -3460,6 +3460,7 @@ WINE_CONFIG_DLL(xapofx1_1)
WINE_CONFIG_DLL(xapofx1_3)
WINE_CONFIG_DLL(xapofx1_4)
WINE_CONFIG_DLL(xapofx1_5)
WINE_CONFIG_DLL(xaudio2_2,,[clean])
WINE_CONFIG_DLL(xaudio2_3,,[clean])
WINE_CONFIG_DLL(xaudio2_4,,[clean])
WINE_CONFIG_DLL(xaudio2_5,,[clean])

View File

@ -0,0 +1,7 @@
MODULE = xaudio2_2.dll
IMPORTS = ole32
C_SRCS = \
xaudio_dll.c
IDL_SRCS = xaudio_classes.idl

View File

@ -0,0 +1,4 @@
@ stdcall -private DllCanUnloadNow()
@ stdcall -private DllGetClassObject(ptr ptr ptr) xaudio2_7.DllGetClassObject
@ stdcall -private DllRegisterServer()
@ stdcall -private DllUnregisterServer()

View File

@ -0,0 +1,28 @@
/*
* 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.2 Class"),
threading(both),
uuid(b802058a-464a-42db-bc10-b650d6f2586a)
]
coclass XAudio22 { interface IXAudio22; }

View File

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

View File

@ -1183,3 +1183,255 @@ const IXAudio23MasteringVoiceVtbl XAudio23MasteringVoice_Vtbl = {
XA23M_GetOutputMatrix,
XA23M_DestroyVoice
};
static inline IXAudio2Impl *impl_from_IXAudio22(IXAudio22 *iface)
{
return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio22_iface);
}
static HRESULT WINAPI XA22_QueryInterface(IXAudio22 *iface, REFIID riid,
void **ppvObject)
{
IXAudio2Impl *This = impl_from_IXAudio22(iface);
return IXAudio2_QueryInterface(&This->IXAudio2_iface, riid, ppvObject);
}
static ULONG WINAPI XA22_AddRef(IXAudio22 *iface)
{
IXAudio2Impl *This = impl_from_IXAudio22(iface);
return IXAudio2_AddRef(&This->IXAudio2_iface);
}
static ULONG WINAPI XA22_Release(IXAudio22 *iface)
{
IXAudio2Impl *This = impl_from_IXAudio22(iface);
return IXAudio2_Release(&This->IXAudio2_iface);
}
static HRESULT WINAPI XA22_GetDeviceCount(IXAudio22 *iface, UINT32 *pCount)
{
IXAudio2Impl *This = impl_from_IXAudio22(iface);
TRACE("%p, %p\n", This, pCount);
*pCount = This->ndevs;
return S_OK;
}
static HRESULT WINAPI XA22_GetDeviceDetails(IXAudio22 *iface, UINT32 index,
XAUDIO2_DEVICE_DETAILS *pDeviceDetails)
{
IXAudio2Impl *This = impl_from_IXAudio22(iface);
HRESULT hr;
IMMDevice *dev;
IAudioClient *client;
IPropertyStore *ps;
WAVEFORMATEX *wfx;
PROPVARIANT var;
TRACE("%p, %u, %p\n", This, index, pDeviceDetails);
if(index >= This->ndevs)
return E_INVALIDARG;
hr = IMMDeviceEnumerator_GetDevice(This->devenum, This->devids[index], &dev);
if(FAILED(hr)){
WARN("GetDevice failed: %08x\n", hr);
return hr;
}
hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
NULL, (void**)&client);
if(FAILED(hr)){
WARN("Activate failed: %08x\n", hr);
IMMDevice_Release(dev);
return hr;
}
hr = IMMDevice_OpenPropertyStore(dev, STGM_READ, &ps);
if(FAILED(hr)){
WARN("OpenPropertyStore failed: %08x\n", hr);
IAudioClient_Release(client);
IMMDevice_Release(dev);
return hr;
}
PropVariantInit(&var);
hr = IPropertyStore_GetValue(ps, (PROPERTYKEY*)&DEVPKEY_Device_FriendlyName, &var);
if(FAILED(hr)){
WARN("GetValue failed: %08x\n", hr);
goto done;
}
lstrcpynW(pDeviceDetails->DisplayName, var.u.pwszVal, sizeof(pDeviceDetails->DisplayName)/sizeof(WCHAR));
PropVariantClear(&var);
hr = IAudioClient_GetMixFormat(client, &wfx);
if(FAILED(hr)){
WARN("GetMixFormat failed: %08x\n", hr);
goto done;
}
lstrcpyW(pDeviceDetails->DeviceID, This->devids[index]);
if(index == 0)
pDeviceDetails->Role = GlobalDefaultDevice;
else
pDeviceDetails->Role = NotDefaultDevice;
if(sizeof(WAVEFORMATEX) + wfx->cbSize > sizeof(pDeviceDetails->OutputFormat)){
FIXME("AudioClient format is too large to fit into WAVEFORMATEXTENSIBLE!\n");
CoTaskMemFree(wfx);
hr = E_FAIL;
goto done;
}
memcpy(&pDeviceDetails->OutputFormat, wfx, sizeof(WAVEFORMATEX) + wfx->cbSize);
CoTaskMemFree(wfx);
done:
IPropertyStore_Release(ps);
IAudioClient_Release(client);
IMMDevice_Release(dev);
return hr;
}
static HRESULT WINAPI XA22_Initialize(IXAudio22 *iface, UINT32 flags,
XAUDIO2_PROCESSOR processor)
{
IXAudio2Impl *This = impl_from_IXAudio22(iface);
TRACE("(%p)->(0x%x, 0x%x)\n", This, flags, processor);
return S_OK;
}
static HRESULT WINAPI XA22_RegisterForCallbacks(IXAudio22 *iface,
IXAudio2EngineCallback *pCallback)
{
IXAudio2Impl *This = impl_from_IXAudio22(iface);
return IXAudio2_RegisterForCallbacks(&This->IXAudio2_iface, pCallback);
}
static void WINAPI XA22_UnregisterForCallbacks(IXAudio22 *iface,
IXAudio2EngineCallback *pCallback)
{
IXAudio2Impl *This = impl_from_IXAudio22(iface);
IXAudio2_UnregisterForCallbacks(&This->IXAudio2_iface, pCallback);
}
static HRESULT WINAPI XA22_CreateSourceVoice(IXAudio22 *iface,
IXAudio2SourceVoice **ppSourceVoice, const WAVEFORMATEX *pSourceFormat,
UINT32 flags, float maxFrequencyRatio,
IXAudio2VoiceCallback *pCallback, const XAUDIO2_VOICE_SENDS *pSendList,
const XAUDIO2_EFFECT_CHAIN *pEffectChain)
{
IXAudio2Impl *This = impl_from_IXAudio22(iface);
return IXAudio2_CreateSourceVoice(&This->IXAudio2_iface, ppSourceVoice,
pSourceFormat, flags, maxFrequencyRatio, pCallback, pSendList,
pEffectChain);
}
static HRESULT WINAPI XA22_CreateSubmixVoice(IXAudio22 *iface,
IXAudio2SubmixVoice **ppSubmixVoice, UINT32 inputChannels,
UINT32 inputSampleRate, UINT32 flags, UINT32 processingStage,
const XAUDIO2_VOICE_SENDS *pSendList,
const XAUDIO2_EFFECT_CHAIN *pEffectChain)
{
IXAudio2Impl *This = impl_from_IXAudio22(iface);
return IXAudio2_CreateSubmixVoice(&This->IXAudio2_iface, ppSubmixVoice,
inputChannels, inputSampleRate, flags, processingStage, pSendList,
pEffectChain);
}
static HRESULT WINAPI XA22_CreateMasteringVoice(IXAudio22 *iface,
IXAudio2MasteringVoice **ppMasteringVoice, UINT32 inputChannels,
UINT32 inputSampleRate, UINT32 flags, UINT32 deviceIndex,
const XAUDIO2_EFFECT_CHAIN *pEffectChain)
{
IXAudio2Impl *This = impl_from_IXAudio22(iface);
TRACE("(%p)->(%p, %u, %u, 0x%x, %u, %p)\n", This, ppMasteringVoice,
inputChannels, inputSampleRate, flags, deviceIndex,
pEffectChain);
if(deviceIndex >= This->ndevs)
return E_INVALIDARG;
return IXAudio2_CreateMasteringVoice(&This->IXAudio2_iface, ppMasteringVoice,
inputChannels, inputSampleRate, flags, This->devids[deviceIndex],
pEffectChain, AudioCategory_GameEffects);
}
static HRESULT WINAPI XA22_StartEngine(IXAudio22 *iface)
{
IXAudio2Impl *This = impl_from_IXAudio22(iface);
return IXAudio2_StartEngine(&This->IXAudio2_iface);
}
static void WINAPI XA22_StopEngine(IXAudio22 *iface)
{
IXAudio2Impl *This = impl_from_IXAudio22(iface);
return IXAudio2_StopEngine(&This->IXAudio2_iface);
}
static HRESULT WINAPI XA22_CommitChanges(IXAudio22 *iface, UINT32 operationSet)
{
IXAudio2Impl *This = impl_from_IXAudio22(iface);
return IXAudio2_CommitChanges(&This->IXAudio2_iface, operationSet);
}
static void WINAPI XA22_GetPerformanceData(IXAudio22 *iface,
XAUDIO22_PERFORMANCE_DATA *pPerfData)
{
IXAudio2Impl *This = impl_from_IXAudio22(iface);
XAUDIO2_PERFORMANCE_DATA data;
IXAudio2_GetPerformanceData(&This->IXAudio2_iface, &data);
pPerfData->AudioCyclesSinceLastQuery = data.AudioCyclesSinceLastQuery;
pPerfData->TotalCyclesSinceLastQuery = data.TotalCyclesSinceLastQuery;
pPerfData->MinimumCyclesPerQuantum = data.MinimumCyclesPerQuantum;
pPerfData->MaximumCyclesPerQuantum = data.MaximumCyclesPerQuantum;
pPerfData->MemoryUsageInBytes = data.MemoryUsageInBytes;
pPerfData->CurrentLatencyInSamples = data.CurrentLatencyInSamples;
pPerfData->GlitchesSinceEngineStarted = data.GlitchesSinceEngineStarted;
pPerfData->ActiveSourceVoiceCount = data.ActiveSourceVoiceCount;
pPerfData->TotalSourceVoiceCount = data.TotalSourceVoiceCount;
pPerfData->ActiveSubmixVoiceCount = data.ActiveSubmixVoiceCount;
pPerfData->TotalSubmixVoiceCount = data.ActiveSubmixVoiceCount;
pPerfData->ActiveXmaSourceVoices = data.ActiveXmaSourceVoices;
pPerfData->ActiveXmaStreams = data.ActiveXmaStreams;
}
static void WINAPI XA22_SetDebugConfiguration(IXAudio22 *iface,
const XAUDIO2_DEBUG_CONFIGURATION *pDebugConfiguration,
void *pReserved)
{
IXAudio2Impl *This = impl_from_IXAudio22(iface);
return IXAudio2_SetDebugConfiguration(&This->IXAudio2_iface,
pDebugConfiguration, pReserved);
}
const IXAudio22Vtbl XAudio22_Vtbl = {
XA22_QueryInterface,
XA22_AddRef,
XA22_Release,
XA22_GetDeviceCount,
XA22_GetDeviceDetails,
XA22_Initialize,
XA22_RegisterForCallbacks,
XA22_UnregisterForCallbacks,
XA22_CreateSourceVoice,
XA22_CreateSubmixVoice,
XA22_CreateMasteringVoice,
XA22_StartEngine,
XA22_StopEngine,
XA22_CommitChanges,
XA22_GetPerformanceData,
XA22_SetDebugConfiguration
};

View File

@ -40,3 +40,10 @@ coclass AudioVolumeMeter { interface IUnknown; }
uuid(6a93130e-1d53-41d1-a9cf-e758800bb179)
]
coclass AudioReverb { interface IUnknown; }
[
helpstring("XACT 31 Class"),
threading(both),
uuid(962f5027-99be-4692-a468-85802cf8de61)
]
coclass XACT31 { interface IUnknown; }

View File

@ -1175,9 +1175,13 @@ static HRESULT WINAPI IXAudio2Impl_QueryInterface(IXAudio2 *iface, REFIID riid,
if(IsEqualGUID(riid, &IID_IUnknown) ||
IsEqualGUID(riid, &IID_IXAudio2))
*ppvObject = &This->IXAudio2_iface;
else if(IsEqualGUID(riid, &IID_IXAudio27))
*ppvObject = &This->IXAudio27_iface;
else
else if(IsEqualGUID(riid, &IID_IXAudio27)){
/* all xaudio versions before 28 share an IID */
if(This->version == 21 || This->version == 22)
*ppvObject = &This->IXAudio22_iface;
else
*ppvObject = &This->IXAudio27_iface;
}else
*ppvObject = NULL;
if(*ppvObject){
@ -2304,6 +2308,7 @@ static HRESULT WINAPI XAudio2CF_CreateInstance(IClassFactory *iface, IUnknown *p
if(!object)
return E_OUTOFMEMORY;
object->IXAudio22_iface.lpVtbl = &XAudio22_Vtbl;
object->IXAudio27_iface.lpVtbl = &XAudio27_Vtbl;
object->IXAudio2_iface.lpVtbl = &XAudio2_Vtbl;
object->IXAudio23MasteringVoice_iface.lpVtbl = &XAudio23MasteringVoice_Vtbl;
@ -2460,7 +2465,11 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
if IsEqualGUID(rclsid, &CLSID_XAudio23){
if IsEqualGUID(rclsid, &CLSID_XAudio21){
factory = make_xaudio2_factory(21);
}else if IsEqualGUID(rclsid, &CLSID_XAudio22){
factory = make_xaudio2_factory(22);
}else if IsEqualGUID(rclsid, &CLSID_XAudio23){
factory = make_xaudio2_factory(23);
}else if(IsEqualGUID(rclsid, &CLSID_XAudio24)){
factory = make_xaudio2_factory(24);

View File

@ -92,6 +92,7 @@ typedef struct _XA2SubmixImpl {
} XA2SubmixImpl;
struct _IXAudio2Impl {
IXAudio22 IXAudio22_iface;
IXAudio27 IXAudio27_iface;
IXAudio2 IXAudio2_iface;
IXAudio23MasteringVoice IXAudio23MasteringVoice_iface;
@ -136,3 +137,5 @@ extern const IXAudio27Vtbl XAudio27_Vtbl DECLSPEC_HIDDEN;
extern const IXAudio23SourceVoiceVtbl XAudio23SourceVoice_Vtbl DECLSPEC_HIDDEN;
extern const IXAudio23SubmixVoiceVtbl XAudio23SubmixVoice_Vtbl DECLSPEC_HIDDEN;
extern const IXAudio23MasteringVoiceVtbl XAudio23MasteringVoice_Vtbl DECLSPEC_HIDDEN;
extern const IXAudio22Vtbl XAudio22_Vtbl DECLSPEC_HIDDEN;

View File

@ -30,6 +30,13 @@ coclass XAudio2 {
interface IUnknown;
}
[
uuid(b802058a-464a-42db-bc10-b650d6f2586a)
]
coclass XAudio22 {
interface IUnknown;
}
[
uuid(4c5e637a-16c7-4de3-9c46-5ed22181962d)
]
@ -149,6 +156,23 @@ typedef struct XAUDIO2_PERFORMANCE_DATA
UINT32 ActiveXmaStreams;
} XAUDIO2_PERFORMANCE_DATA;
typedef struct XAUDIO22_PERFORMANCE_DATA
{
UINT64 AudioCyclesSinceLastQuery;
UINT64 TotalCyclesSinceLastQuery;
UINT32 MinimumCyclesPerQuantum;
UINT32 MaximumCyclesPerQuantum;
UINT32 MemoryUsageInBytes;
UINT32 CurrentLatencyInSamples;
UINT32 GlitchesSinceEngineStarted;
UINT32 ActiveSourceVoiceCount;
UINT32 TotalSourceVoiceCount;
UINT32 ActiveSubmixVoiceCount;
UINT32 TotalSubmixVoiceCount;
UINT32 ActiveXmaSourceVoices;
UINT32 ActiveXmaStreams;
} XAUDIO22_PERFORMANCE_DATA;
typedef enum XAUDIO2_DEVICE_ROLE
{
NotDefaultDevice = 0x0,
@ -610,6 +634,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.2's IXAudio2 interface. Actually called IXAudio2 in the Jun 2010
* DX SDK */
interface IXAudio22 : 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] XAUDIO22_PERFORMANCE_DATA* pPerfData);
[local] void SetDebugConfiguration(
[in] const XAUDIO2_DEBUG_CONFIGURATION* pDebugConfiguration,
[in, defaultvalue(NULL)] void* pReserved);
}
[
object,
uuid(8bcf1f58-9fe7-4583-8ac6-e2adc465c8bb),