From: Vijay Kiran Kamuju Subject: [PATCH V2 2/2] xactengine3_7: Implement IXACT3Engine interface. Message-Id: Date: Fri, 3 Jul 2020 01:26:16 +0200 Based on patch from Ethan Lee. Signed-off-by: Vijay Kiran Kamuju From 7e0e70c1bc7bc945e8048b3750ad12e6bf57b349 Mon Sep 17 00:00:00 2001 From: Vijay Kiran Kamuju Date: Thu, 2 Jul 2020 09:27:39 +0200 Subject: [PATCH V2 2/2] xactengine3_7: Implement IXACT3Engine interface. Based on patch from Ethan Lee. Signed-off-by: Vijay Kiran Kamuju --- configure | 1 + configure.ac | 1 + dlls/xactengine3_7/Makefile.in | 7 +- dlls/xactengine3_7/xact_dll.c | 449 ++++++++++++++++++++++++++++++++- 4 files changed, 456 insertions(+), 2 deletions(-) diff --git a/configure b/configure index db89c70a15..dac8656384 100755 --- a/configure +++ b/configure @@ -16615,6 +16615,7 @@ then enable_x3daudio1_5=${enable_x3daudio1_5:-no} enable_x3daudio1_6=${enable_x3daudio1_6:-no} enable_x3daudio1_7=${enable_x3daudio1_7:-no} + enable_xactengine3_7=${enable_xactengine3_7:-no} enable_xapofx1_1=${enable_xapofx1_1:-no} enable_xapofx1_2=${enable_xapofx1_2:-no} enable_xapofx1_3=${enable_xapofx1_3:-no} diff --git a/configure.ac b/configure.ac index 34efb99780..006292d988 100644 --- a/configure.ac +++ b/configure.ac @@ -1961,6 +1961,7 @@ then enable_x3daudio1_5=${enable_x3daudio1_5:-no} enable_x3daudio1_6=${enable_x3daudio1_6:-no} enable_x3daudio1_7=${enable_x3daudio1_7:-no} + enable_xactengine3_7=${enable_xactengine3_7:-no} enable_xapofx1_1=${enable_xapofx1_1:-no} enable_xapofx1_2=${enable_xapofx1_2:-no} enable_xapofx1_3=${enable_xapofx1_3:-no} diff --git a/dlls/xactengine3_7/Makefile.in b/dlls/xactengine3_7/Makefile.in index f92aad6680..5259ed1cbd 100644 --- a/dlls/xactengine3_7/Makefile.in +++ b/dlls/xactengine3_7/Makefile.in @@ -1,6 +1,11 @@ MODULE = xactengine3_7.dll +IMPORTS = ole32 uuid +PARENTSRC = ../xaudio2_7 +EXTRALIBS = $(FAUDIO_LIBS) +EXTRAINCL = $(FAUDIO_CFLAGS) C_SRCS = \ - xact_dll.c + xact_dll.c \ + xaudio_allocator.c IDL_SRCS = xact_classes.idl diff --git a/dlls/xactengine3_7/xact_dll.c b/dlls/xactengine3_7/xact_dll.c index f4cd84f044..7e2401f7c9 100644 --- a/dlls/xactengine3_7/xact_dll.c +++ b/dlls/xactengine3_7/xact_dll.c @@ -20,16 +20,460 @@ #include +#define NONAMELESSUNION +#define COBJMACROS + +#include "xaudio_private.h" + +#include "initguid.h" #include "xact3.h" #include #include "rpcproxy.h" #include "wine/debug.h" +#include + WINE_DEFAULT_DEBUG_CHANNEL(xact3); static HINSTANCE instance; +typedef struct _XACT3EngineImpl { + IXACT3Engine IXACT3Engine_iface; + + FACTAudioEngine *fact_engine; + + XACT_READFILE_CALLBACK pReadFile; + XACT_GETOVERLAPPEDRESULT_CALLBACK pGetOverlappedResult; +} XACT3EngineImpl; + +typedef struct wrap_readfile_struct { + XACT3EngineImpl *engine; + HANDLE file; +} wrap_readfile_struct; + +static int32_t FACTCALL wrap_readfile( + void* hFile, + void* lpBuffer, + uint32_t nNumberOfBytesRead, + uint32_t *lpNumberOfBytesRead, + FACTOverlapped *lpOverlapped) +{ + wrap_readfile_struct *wrap = (wrap_readfile_struct*) hFile; + return wrap->engine->pReadFile(wrap->file, lpBuffer, nNumberOfBytesRead, + lpNumberOfBytesRead, lpOverlapped); +} + +static int32_t FACTCALL wrap_getoverlappedresult( + void* hFile, + FACTOverlapped *lpOverlapped, + uint32_t *lpNumberOfBytesTransferred, + int32_t bWait) +{ + wrap_readfile_struct *wrap = (wrap_readfile_struct*) hFile; + return wrap->engine->pGetOverlappedResult(wrap->file, lpOverlapped, + lpNumberOfBytesTransferred, bWait); +} + +static inline XACT3EngineImpl *impl_from_IXACT3Engine(IXACT3Engine *iface) +{ + return CONTAINING_RECORD(iface, XACT3EngineImpl, IXACT3Engine_iface); +} + +static HRESULT WINAPI IXACT3EngineImpl_QueryInterface(IXACT3Engine *iface, + REFIID riid, void **ppvObject) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject); + + if(IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IXACT3Engine)){ + *ppvObject = &This->IXACT3Engine_iface; + } + else + *ppvObject = NULL; + + if (*ppvObject){ + IUnknown_AddRef((IUnknown*)*ppvObject); + return S_OK; + } + + FIXME("(%p)->(%s,%p), not found\n", This, debugstr_guid(riid), ppvObject); + + return E_NOINTERFACE; +} + +static ULONG WINAPI IXACT3EngineImpl_AddRef(IXACT3Engine *iface) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + ULONG ref = FACTAudioEngine_AddRef(This->fact_engine); + TRACE("(%p)->(): Refcount now %u\n", This, ref); + return ref; +} + +static ULONG WINAPI IXACT3EngineImpl_Release(IXACT3Engine *iface) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + ULONG ref = FACTAudioEngine_Release(This->fact_engine); + + TRACE("(%p)->(): Refcount now %u\n", This, ref); + + if (!ref) + HeapFree(GetProcessHeap(), 0, This); + return ref; +} + +static HRESULT WINAPI IXACT3EngineImpl_GetRendererCount(IXACT3Engine *iface, + XACTINDEX *pnRendererCount) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + + TRACE("(%p)->(%p)\n", This, pnRendererCount); + + return FACTAudioEngine_GetRendererCount(This->fact_engine, pnRendererCount); +} + +static HRESULT WINAPI IXACT3EngineImpl_GetRendererDetails(IXACT3Engine *iface, + XACTINDEX nRendererIndex, XACT_RENDERER_DETAILS *pRendererDetails) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + + TRACE("(%p)->(%d, %p)\n", This, nRendererIndex, pRendererDetails); + + return FACTAudioEngine_GetRendererDetails(This->fact_engine, + nRendererIndex, (FACTRendererDetails*) pRendererDetails); +} + +static HRESULT WINAPI IXACT3EngineImpl_GetFinalMixFormat(IXACT3Engine *iface, + WAVEFORMATEXTENSIBLE *pFinalMixFormat) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + + TRACE("(%p)->(%p)\n", This, pFinalMixFormat); + + return FACTAudioEngine_GetFinalMixFormat(This->fact_engine, + (FAudioWaveFormatExtensible*) pFinalMixFormat); +} + +static HRESULT WINAPI IXACT3EngineImpl_Initialize(IXACT3Engine *iface, + const XACT_RUNTIME_PARAMETERS *pParams) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + FACTRuntimeParameters params; + + TRACE("(%p)->(%p)\n", This, pParams); + + memcpy(¶ms, pParams, sizeof(FACTRuntimeParameters)); + + /* FIXME: pXAudio2 and pMasteringVoice are pointers to + * IXAudio2/IXAudio2MasteringVoice objects. FACT wants pointers to + * FAudio/FAudioMasteringVoice objects. In Wine's XAudio2 implementation, we + * actually have them available, but only if you access their internal data. + * For now we can just force these pointers to NULL, as XACT simply + * generates its own engine and endpoint in that situation. These parameters + * are mostly an optimization for games with multiple XACT3Engines that want + * a single engine running everything. + * -flibit + */ + if (pParams->pXAudio2 != NULL){ + FIXME("pXAudio2 parameter not supported! Falling back to NULL\n"); + params.pXAudio2 = NULL; + + if (pParams->pMasteringVoice != NULL){ + FIXME("pXAudio2 parameter not supported! Falling back to NULL\n"); + params.pMasteringVoice = NULL; + } + } + + /* Force Windows I/O, do NOT use the FACT default! */ + This->pReadFile = (XACT_READFILE_CALLBACK) + pParams->fileIOCallbacks.readFileCallback; + This->pGetOverlappedResult = (XACT_GETOVERLAPPEDRESULT_CALLBACK) + pParams->fileIOCallbacks.getOverlappedResultCallback; + if (This->pReadFile == NULL) + This->pReadFile = (XACT_READFILE_CALLBACK) ReadFile; + if (This->pGetOverlappedResult == NULL) + This->pGetOverlappedResult = (XACT_GETOVERLAPPEDRESULT_CALLBACK) + GetOverlappedResult; + params.fileIOCallbacks.readFileCallback = wrap_readfile; + params.fileIOCallbacks.getOverlappedResultCallback = wrap_getoverlappedresult; + + return FACTAudioEngine_Initialize(This->fact_engine, ¶ms); +} + +static HRESULT WINAPI IXACT3EngineImpl_ShutDown(IXACT3Engine *iface) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + + TRACE("(%p)\n", This); + + return FACTAudioEngine_ShutDown(This->fact_engine); +} + +static HRESULT WINAPI IXACT3EngineImpl_DoWork(IXACT3Engine *iface) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + + TRACE("(%p)\n", This); + + return FACTAudioEngine_DoWork(This->fact_engine); +} + +static HRESULT WINAPI IXACT3EngineImpl_CreateSoundBank(IXACT3Engine *iface, + const void* pvBuffer, DWORD dwSize, DWORD dwFlags, + DWORD dwAllocAttributes, IXACT3SoundBank **ppSoundBank) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + FIXME("(%p)->(%p, %u, 0x%x, 0x%x, %p): stub!\n", This, pvBuffer, dwSize, dwFlags, + dwAllocAttributes, ppSoundBank); + return S_OK; +} + +static HRESULT WINAPI IXACT3EngineImpl_CreateInMemoryWaveBank(IXACT3Engine *iface, + const void* pvBuffer, DWORD dwSize, DWORD dwFlags, + DWORD dwAllocAttributes, IXACT3WaveBank **ppWaveBank) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + FIXME("(%p)->(%p, %u, 0x%x, 0x%x, %p): stub!\n", This, pvBuffer, dwSize, dwFlags, + dwAllocAttributes, ppWaveBank); + return S_OK; +} + +static HRESULT WINAPI IXACT3EngineImpl_CreateStreamingWaveBank(IXACT3Engine *iface, + const XACT_STREAMING_PARAMETERS *pParms, + IXACT3WaveBank **ppWaveBank) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + FIXME("(%p)->(%p, %p): stub!\n", This, pParms, ppWaveBank); + return S_OK; +} + +static HRESULT WINAPI IXACT3EngineImpl_PrepareInMemoryWave(IXACT3Engine *iface, + DWORD dwFlags, WAVEBANKENTRY entry, DWORD *pdwSeekTable, + BYTE *pbWaveData, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, + IXACT3Wave **ppWave) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + FIXME("(%p): stub!\n", This); + return S_OK; +} + +static HRESULT WINAPI IXACT3EngineImpl_PrepareStreamingWave(IXACT3Engine *iface, + DWORD dwFlags, WAVEBANKENTRY entry, + XACT_STREAMING_PARAMETERS streamingParams, DWORD dwAlignment, + DWORD *pdwSeekTable, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, + IXACT3Wave **ppWave) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + FIXME("(%p): stub!\n", This); + return S_OK; +} + +static HRESULT WINAPI IXACT3EngineImpl_PrepareWave(IXACT3Engine *iface, + DWORD dwFlags, PCSTR szWavePath, WORD wStreamingPacketSize, + DWORD dwAlignment, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount, + IXACT3Wave **ppWave) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + FIXME("(%p): stub!\n", This); + return S_OK; +} + +static HRESULT WINAPI IXACT3EngineImpl_RegisterNotification(IXACT3Engine *iface, + const XACT_NOTIFICATION_DESCRIPTION *pNotificationDesc) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + + FIXME("(%p)->(%p): stub!\n", This, pNotificationDesc); + return S_OK; +} + +static HRESULT WINAPI IXACT3EngineImpl_UnRegisterNotification(IXACT3Engine *iface, + const XACT_NOTIFICATION_DESCRIPTION *pNotificationDesc) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + + FIXME("(%p)->(%p): stub!\n", This, pNotificationDesc); + return S_OK; +} + +static XACTCATEGORY WINAPI IXACT3EngineImpl_GetCategory(IXACT3Engine *iface, + PCSTR szFriendlyName) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + + TRACE("(%p)->(%s)\n", This, szFriendlyName); + + return FACTAudioEngine_GetCategory(This->fact_engine, szFriendlyName); +} + +static HRESULT WINAPI IXACT3EngineImpl_Stop(IXACT3Engine *iface, + XACTCATEGORY nCategory, DWORD dwFlags) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + + TRACE("(%p)->(%u, 0x%x)\n", This, nCategory, dwFlags); + + return FACTAudioEngine_Stop(This->fact_engine, nCategory, dwFlags); +} + +static HRESULT WINAPI IXACT3EngineImpl_SetVolume(IXACT3Engine *iface, + XACTCATEGORY nCategory, XACTVOLUME nVolume) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + + TRACE("(%p)->(%u, %f)\n", This, nCategory, nVolume); + + return FACTAudioEngine_SetVolume(This->fact_engine, nCategory, nVolume); +} + +static HRESULT WINAPI IXACT3EngineImpl_Pause(IXACT3Engine *iface, + XACTCATEGORY nCategory, BOOL fPause) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + + TRACE("(%p)->(%u, %u)\n", This, nCategory, fPause); + + return FACTAudioEngine_Pause(This->fact_engine, nCategory, fPause); +} + +static XACTVARIABLEINDEX WINAPI IXACT3EngineImpl_GetGlobalVariableIndex( + IXACT3Engine *iface, PCSTR szFriendlyName) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + + TRACE("(%p)->(%s)\n", This, szFriendlyName); + + return FACTAudioEngine_GetGlobalVariableIndex(This->fact_engine, + szFriendlyName); +} + +static HRESULT WINAPI IXACT3EngineImpl_SetGlobalVariable(IXACT3Engine *iface, + XACTVARIABLEINDEX nIndex, XACTVARIABLEVALUE nValue) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + + TRACE("(%p)->(%u, %f)\n", This, nIndex, nValue); + + return FACTAudioEngine_SetGlobalVariable(This->fact_engine, nIndex, nValue); +} + +static HRESULT WINAPI IXACT3EngineImpl_GetGlobalVariable(IXACT3Engine *iface, + XACTVARIABLEINDEX nIndex, XACTVARIABLEVALUE *nValue) +{ + XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + + TRACE("(%p)->(%u, %p)\n", This, nIndex, nValue); + + return FACTAudioEngine_GetGlobalVariable(This->fact_engine, nIndex, nValue); +} + +static const IXACT3EngineVtbl XACT3Engine_Vtbl = +{ + IXACT3EngineImpl_QueryInterface, + IXACT3EngineImpl_AddRef, + IXACT3EngineImpl_Release, + IXACT3EngineImpl_GetRendererCount, + IXACT3EngineImpl_GetRendererDetails, + IXACT3EngineImpl_GetFinalMixFormat, + IXACT3EngineImpl_Initialize, + IXACT3EngineImpl_ShutDown, + IXACT3EngineImpl_DoWork, + IXACT3EngineImpl_CreateSoundBank, + IXACT3EngineImpl_CreateInMemoryWaveBank, + IXACT3EngineImpl_CreateStreamingWaveBank, + IXACT3EngineImpl_PrepareWave, + IXACT3EngineImpl_PrepareInMemoryWave, + IXACT3EngineImpl_PrepareStreamingWave, + IXACT3EngineImpl_RegisterNotification, + IXACT3EngineImpl_UnRegisterNotification, + IXACT3EngineImpl_GetCategory, + IXACT3EngineImpl_Stop, + IXACT3EngineImpl_SetVolume, + IXACT3EngineImpl_Pause, + IXACT3EngineImpl_GetGlobalVariableIndex, + IXACT3EngineImpl_SetGlobalVariable, + IXACT3EngineImpl_GetGlobalVariable +}; + +static HRESULT WINAPI XACT3CF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj) +{ + if(IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IClassFactory)) + { + *ppobj = iface; + return S_OK; + } + + *ppobj = NULL; + WARN("(%p)->(%s, %p): interface not found\n", iface, debugstr_guid(riid), ppobj); + return E_NOINTERFACE; +} + +static ULONG WINAPI XACT3CF_AddRef(IClassFactory *iface) +{ + return 2; +} + +static ULONG WINAPI XACT3CF_Release(IClassFactory *iface) +{ + return 1; +} + +static HRESULT WINAPI XACT3CF_CreateInstance(IClassFactory *iface, IUnknown *pOuter, + REFIID riid, void **ppobj) +{ + HRESULT hr; + XACT3EngineImpl *object; + + TRACE("(%p)->(%p,%s,%p)\n", iface, 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->IXACT3Engine_iface.lpVtbl = &XACT3Engine_Vtbl; + + FACTCreateEngineWithCustomAllocatorEXT( + 0, + &object->fact_engine, + XAudio_Internal_Malloc, + XAudio_Internal_Free, + XAudio_Internal_Realloc + ); + + hr = IXACT3Engine_QueryInterface(&object->IXACT3Engine_iface, riid, ppobj); + if(FAILED(hr)){ + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + + return hr; +} + +static HRESULT WINAPI XACT3CF_LockServer(IClassFactory *iface, BOOL dolock) +{ + TRACE("(%p)->(%d): stub!\n", iface, dolock); + return S_OK; +} + +static const IClassFactoryVtbl XACT3CF_Vtbl = +{ + XACT3CF_QueryInterface, + XACT3CF_AddRef, + XACT3CF_Release, + XACT3CF_CreateInstance, + XACT3CF_LockServer +}; + +static IClassFactory XACTFactory = { &XACT3CF_Vtbl }; + BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, void *pReserved) { TRACE("(%p, %d, %p)\n", hinstDLL, reason, pReserved); @@ -51,7 +495,10 @@ HRESULT WINAPI DllCanUnloadNow(void) HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv) { - FIXME("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); + TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); + + if (IsEqualGUID(rclsid, &CLSID_XACTEngine37)) + return IClassFactory_QueryInterface(&XACTFactory, riid, ppv); return CLASS_E_CLASSNOTAVAILABLE; } -- 2.27.0