From dab7a608c2a0421e4016aaf84685d0db6d6e4aa1 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Tue, 21 Apr 2020 22:10:53 -0500 Subject: [PATCH 01/19] oops --- src/core/hle/DSOUND/DirectSound/DirectSound.hpp | 2 +- src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp | 4 ++-- src/core/hle/DSOUND/DirectSound/DirectSoundStream.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/hle/DSOUND/DirectSound/DirectSound.hpp b/src/core/hle/DSOUND/DirectSound/DirectSound.hpp index e4d87f7ac..cce3bbcea 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSound.hpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSound.hpp @@ -1420,7 +1420,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetNotificationPositions) // ****************************************************************** HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetRolloffCurve) ( - X_CDirectSoundBuffer* pThis, + X_CDirectSoundStream* pThis, const FLOAT* pflPoints, DWORD dwPointCount, DWORD dwApply diff --git a/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp b/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp index 7435c0575..6c45375c6 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp @@ -1045,7 +1045,7 @@ static inline HRESULT HybridDirectSound3DListener_SetDopplerFactor( RETURN_RESULT_CHECK(hRet); } /* -//TODO: PC DirectSound does not have SetHeadroom method function. +//TODO: PC DirectSound does not have SetEG method function. //IDirectSoundStream //IDirectSoundBuffer static inline HRESULT HybridDirectSoundBuffer_SetEG( @@ -1056,7 +1056,7 @@ static inline HRESULT HybridDirectSoundBuffer_SetEG( return DS_OK; } -//TODO: PC DirectSound does not have SetHeadroom method function. +//TODO: PC DirectSound does not have SetFilter method function. //IDirectSoundStream //IDirectSoundBuffer static inline HRESULT HybridDirectSoundBuffer_SetFilter( diff --git a/src/core/hle/DSOUND/DirectSound/DirectSoundStream.cpp b/src/core/hle/DSOUND/DirectSound/DirectSoundStream.cpp index cf5c0e953..2291875f6 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSoundStream.cpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSoundStream.cpp @@ -1303,7 +1303,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetPosition) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetRolloffCurve) ( - X_CDirectSoundBuffer* pThis, + X_CDirectSoundStream* pThis, const FLOAT* pflPoints, DWORD dwPointCount, DWORD dwApply) From d7d1d781d8fbb540d9311dd2d034e05d61f35e8b Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Fri, 1 May 2020 06:25:54 -0500 Subject: [PATCH 02/19] implement hybrid buffer for partial internal exposure --- CMakeLists.txt | 3 + .../hle/DSOUND/DirectSound/DirectSound.cpp | 11 +- .../hle/DSOUND/DirectSound/DirectSound.hpp | 168 +++++----- .../DSOUND/DirectSound/DirectSoundBuffer.cpp | 303 ++++++++++-------- .../DSOUND/DirectSound/DirectSoundGlobal.hpp | 2 +- .../DSOUND/DirectSound/DirectSoundInline.hpp | 99 +++--- .../DSOUND/DirectSound/DirectSoundStream.cpp | 31 +- src/core/hle/DSOUND/XbDSoundTypes.h | 24 ++ .../hle/DSOUND/common/XbInternalDSVoice.cpp | 272 ++++++++++++++++ .../hle/DSOUND/common/XbInternalStruct.cpp | 34 ++ .../hle/DSOUND/common/XbInternalStruct.hpp | 227 +++++++++++++ 11 files changed, 896 insertions(+), 278 deletions(-) create mode 100644 src/core/hle/DSOUND/common/XbInternalDSVoice.cpp create mode 100644 src/core/hle/DSOUND/common/XbInternalStruct.cpp create mode 100644 src/core/hle/DSOUND/common/XbInternalStruct.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 61264e9a9..4297f44ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -154,6 +154,7 @@ file (GLOB CXBXR_HEADER_EMU "${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/DirectSound/DSStream_PacketManager.hpp" "${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/XbDSoundLogging.hpp" "${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/XbDSoundTypes.h" + "${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/common/XbInternalStruct.hpp" "${CXBXR_ROOT_DIR}/src/core/hle/Intercept.hpp" "${CXBXR_ROOT_DIR}/src/core/hle/Patches.hpp" "${CXBXR_ROOT_DIR}/src/core/hle/XACTENG/XactEng.h" @@ -296,6 +297,8 @@ file (GLOB CXBXR_SOURCE_EMU "${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/DirectSound/DSStream_PacketManager.cpp" "${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp" "${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/XbDSoundLogging.cpp" + "${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp" + "${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/common/XbInternalStruct.cpp" "${CXBXR_ROOT_DIR}/src/core/hle/Intercept.cpp" "${CXBXR_ROOT_DIR}/src/core/hle/Patches.cpp" "${CXBXR_ROOT_DIR}/src/core/hle/XACTENG/XactEng.cpp" diff --git a/src/core/hle/DSOUND/DirectSound/DirectSound.cpp b/src/core/hle/DSOUND/DirectSound/DirectSound.cpp index 6e48f193b..ff1df98ef 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSound.cpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSound.cpp @@ -887,14 +887,15 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSound_SynchPlayback) vector_ds_buffer::iterator ppDSBuffer = g_pDSoundBufferCache.begin(); for (; ppDSBuffer != g_pDSoundBufferCache.end(); ppDSBuffer++) { - if ((*ppDSBuffer)->X_BufferCache == nullptr) { + EmuDirectSoundBuffer* pDSBuffer = (*ppDSBuffer)->emuDSBuffer; + if (pDSBuffer->X_BufferCache == nullptr) { continue; } - if (((*ppDSBuffer)->EmuFlags & DSE_FLAG_SYNCHPLAYBACK_CONTROL) > 0) { - DSoundBufferSynchPlaybackFlagRemove((*ppDSBuffer)->EmuFlags); - EmuLog(LOG_LEVEL::DEBUG, "SynchPlayback - pDSBuffer: %08X; EmuPlayFlags: %08X", *ppDSBuffer, (*ppDSBuffer)->EmuPlayFlags); - (*ppDSBuffer)->EmuDirectSoundBuffer8->Play(0, 0, (*ppDSBuffer)->EmuPlayFlags); + if ((pDSBuffer->EmuFlags & DSE_FLAG_SYNCHPLAYBACK_CONTROL) > 0) { + DSoundBufferSynchPlaybackFlagRemove(pDSBuffer->EmuFlags); + EmuLog(LOG_LEVEL::DEBUG, "SynchPlayback - pDSBuffer: %08X; EmuPlayFlags: %08X", *ppDSBuffer, pDSBuffer->EmuPlayFlags); + pDSBuffer->EmuDirectSoundBuffer8->Play(0, 0, pDSBuffer->EmuPlayFlags); } } diff --git a/src/core/hle/DSOUND/DirectSound/DirectSound.hpp b/src/core/hle/DSOUND/DirectSound/DirectSound.hpp index cce3bbcea..68ecebf82 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSound.hpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSound.hpp @@ -28,6 +28,7 @@ #include "core\kernel\init\CxbxKrnl.h" #include "core\hle\DSOUND\XbDSoundTypes.h" +#include "core\hle\DSOUND\common\XbInternalStruct.hpp" typedef struct IDirectSound3DListener8* LPDIRECTSOUND3DLISTENER8; typedef struct IDirectSound3DBuffer8* LPDIRECTSOUND3DBUFFER8; @@ -73,25 +74,21 @@ typedef struct _DSoundBuffer_Lock { // ****************************************************************** // * X_CDirectSoundBuffer // ****************************************************************** -struct X_CDirectSoundBuffer +struct EmuDirectSoundBuffer { - BYTE UnknownA[0x20]; // Offset: 0x00 - - union // Offset: 0x20 + union { PVOID pMpcxBuffer; LPDIRECTSOUNDBUFFER8 EmuDirectSoundBuffer8; }; - - BYTE UnknownB[0x0C]; // Offset: 0x24 - LPVOID X_BufferCache; // Offset: 0x28 - DSBUFFERDESC EmuBufferDesc; // Offset: 0x2C - /*LPVOID EmuLockPtr1; // Offset: 0x30 - DWORD EmuLockBytes1; // Offset: 0x34 - LPVOID EmuLockPtr2; // Offset: 0x38 - DWORD EmuLockBytes2; // Offset: 0x3C*/ - DWORD EmuPlayFlags; // Offset: 0x40 - DWORD EmuFlags; // Offset: 0x44 + LPVOID X_BufferCache; + DSBUFFERDESC EmuBufferDesc; + /*LPVOID EmuLockPtr1; + DWORD EmuLockBytes1; + LPVOID EmuLockPtr2; + DWORD EmuLockBytes2;*/ + DWORD EmuPlayFlags; + DWORD EmuFlags; LPDIRECTSOUND3DBUFFER8 EmuDirectSound3DBuffer8; //DWORD EmuLockOffset; //DWORD EmuLockFlags; @@ -111,9 +108,19 @@ struct X_CDirectSoundBuffer DWORD Xb_dwHeadroom; X_DSENVOLOPEDESC Xb_EnvolopeDesc; X_DSVOICEPROPS Xb_VoiceProperties; - DWORD Xb_Frequency; DWORD Xb_Flags; }; + +struct XbHybridDSBuffer : DSBUFFER_S::DSBUFFER_I { + EmuDirectSoundBuffer* emuDSBuffer; +}; + +struct SharedDSBuffer : DSBUFFER_S { + SharedDSBuffer(bool is3D) : DSBUFFER_S(is3D) { + emuDSBuffer = new EmuDirectSoundBuffer(); + } + EmuDirectSoundBuffer* emuDSBuffer; +}; //Custom flags (4 bytes support up to 31 shifts,starting from 0) #define DSE_FLAG_PCM (1 << 0) @@ -188,7 +195,7 @@ class X_CDirectSoundStream { public: // construct vtable (or grab ptr to existing) - X_CDirectSoundStream() : pVtbl(&vtbl) { pMcpxStream = new X_CMcpxStream(this); }; + X_CDirectSoundStream(bool is3D) : pVtbl(&vtbl), Xb_Voice(is3D) { pMcpxStream = new X_CMcpxStream(this); }; private: // vtable (cached by each instance, via constructor) @@ -243,6 +250,8 @@ class X_CDirectSoundStream #endif public: + // Placeholder until have positive offset + CDirectSoundVoice Xb_Voice; // cached data LPDIRECTSOUNDBUFFER8 EmuDirectSoundBuffer8; LPDIRECTSOUND3DBUFFER8 EmuDirectSound3DBuffer8; @@ -268,7 +277,6 @@ class X_CDirectSoundStream DWORD Xb_dwHeadroom; X_DSENVOLOPEDESC Xb_EnvolopeDesc; X_DSVOICEPROPS Xb_VoiceProperties; - DWORD Xb_Frequency; DWORD Host_dwLastWritePos; DWORD Xb_Flags; DWORD Xb_Status; @@ -481,7 +489,7 @@ HRESULT WINAPI EMUPATCH(IDirectSound_SetMixBinHeadroom) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMixBins) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwMixBinMask ); @@ -490,7 +498,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMixBins) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMixBinVolumes_12) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwMixBinMask, const LONG* alVolumes ); @@ -500,7 +508,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMixBinVolumes_12) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMixBinVolumes_8) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, X_LPDSMIXBINS pMixBins ); @@ -551,10 +559,10 @@ HRESULT WINAPI EMUPATCH(CDirectSound_CommitDeferredSettings) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSound_CreateSoundBuffer) ( - LPDIRECTSOUND8 pThis, - X_DSBUFFERDESC* pdsbd, - X_CDirectSoundBuffer** ppBuffer, - LPUNKNOWN pUnkOuter + LPDIRECTSOUND8 pThis, + X_DSBUFFERDESC* pdsbd, + XbHybridDSBuffer** ppBuffer, + LPUNKNOWN pUnkOuter ); // ****************************************************************** @@ -562,8 +570,8 @@ HRESULT WINAPI EMUPATCH(IDirectSound_CreateSoundBuffer) // ****************************************************************** HRESULT WINAPI EMUPATCH(DirectSoundCreateBuffer) ( - X_DSBUFFERDESC* pdsbd, - X_CDirectSoundBuffer** ppBuffer + X_DSBUFFERDESC* pdsbd, + XbHybridDSBuffer** ppBuffer ); // ****************************************************************** @@ -571,9 +579,9 @@ HRESULT WINAPI EMUPATCH(DirectSoundCreateBuffer) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetBufferData) ( - X_CDirectSoundBuffer* pThis, - LPVOID pvBufferData, - DWORD dwBufferBytes + XbHybridDSBuffer* pHybridThis, + LPVOID pvBufferData, + DWORD dwBufferBytes ); // ****************************************************************** @@ -581,9 +589,9 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetBufferData) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPlayRegion) ( - X_CDirectSoundBuffer* pThis, - DWORD dwPlayStart, - DWORD dwPlayLength + XbHybridDSBuffer* pHybridThis, + DWORD dwPlayStart, + DWORD dwPlayLength ); // ****************************************************************** @@ -591,7 +599,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPlayRegion) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Lock) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwOffset, DWORD dwBytes, LPVOID* ppvAudioPtr1, @@ -605,7 +613,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Lock) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Unlock) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, LPVOID ppvAudioPtr1, DWORD pdwAudioBytes1, LPVOID ppvAudioPtr2, @@ -617,7 +625,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Unlock) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetHeadroom) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwHeadroom ); @@ -626,7 +634,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetHeadroom) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetLoopRegion) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwLoopStart, DWORD dwLoopLength ); @@ -636,7 +644,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetLoopRegion) // ****************************************************************** ULONG WINAPI EMUPATCH(IDirectSoundBuffer_Release) ( - X_CDirectSoundBuffer* pThis + XbHybridDSBuffer* pHybridThis ); // ****************************************************************** @@ -644,7 +652,7 @@ ULONG WINAPI EMUPATCH(IDirectSoundBuffer_Release) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPitch) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, LONG lPitch ); @@ -653,7 +661,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPitch) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_GetStatus) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, LPDWORD pdwStatus ); @@ -662,7 +670,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_GetStatus) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVolume) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, LONG lVolume ); @@ -671,7 +679,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVolume) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetCurrentPosition) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwNewPosition ); @@ -680,7 +688,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetCurrentPosition) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_GetCurrentPosition) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, PDWORD pdwCurrentPlayCursor, PDWORD pdwCurrentWriteCursor ); @@ -690,7 +698,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_GetCurrentPosition) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Stop) ( - X_CDirectSoundBuffer* pThis + XbHybridDSBuffer* pHybridThis ); // ****************************************************************** @@ -698,7 +706,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Stop) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_StopEx) ( - X_CDirectSoundBuffer *pBuffer, + XbHybridDSBuffer* pHybridThis, REFERENCE_TIME rtTimeStamp, DWORD dwFlags ); @@ -708,7 +716,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_StopEx) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Play) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwReserved1, DWORD dwReserved2, DWORD dwFlags @@ -719,7 +727,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Play) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_PlayEx) ( - X_CDirectSoundBuffer* pBuffer, + XbHybridDSBuffer* pHybridThis, REFERENCE_TIME rtTimeStamp, DWORD dwFlags ); @@ -729,7 +737,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_PlayEx) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVolume) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, LONG lVolume ); @@ -738,7 +746,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVolume) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetFrequency) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwFrequency ); @@ -972,7 +980,7 @@ HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetMixBins) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMaxDistance) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT flMaxDistance, DWORD dwApply ); @@ -982,7 +990,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMaxDistance) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMinDistance) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT flMaxDistance, DWORD dwApply ); @@ -992,7 +1000,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMinDistance) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetRolloffFactor) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT flRolloffFactor, DWORD dwApply ); @@ -1002,7 +1010,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetRolloffFactor) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetDistanceFactor) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT flDistanceFactor, DWORD dwApply ); @@ -1012,7 +1020,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetDistanceFactor) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeAngles) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwInsideConeAngle, DWORD dwOutsideConeAngle, DWORD dwApply @@ -1023,7 +1031,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeAngles) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeOrientation) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT x, FLOAT y, FLOAT z, @@ -1035,7 +1043,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeOrientation) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeOutsideVolume) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, LONG lConeOutsideVolume, DWORD dwApply ); @@ -1045,7 +1053,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeOutsideVolume) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPosition) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT x, FLOAT y, FLOAT z, @@ -1057,7 +1065,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPosition) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVelocity) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT x, FLOAT y, FLOAT z, @@ -1069,7 +1077,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVelocity) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetDopplerFactor) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT flDopplerFactor, DWORD dwApply ); @@ -1079,7 +1087,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetDopplerFactor) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetI3DL2Source) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, X_DSI3DL2BUFFER* pds3db, DWORD dwApply ); @@ -1090,7 +1098,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetI3DL2Source) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMode) ( - X_CDirectSoundBuffer* pBuffer, + XbHybridDSBuffer* pHybridThis, DWORD dwMode, DWORD dwApply ); @@ -1100,7 +1108,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMode) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetFormat) ( - X_CDirectSoundBuffer *pBuffer, + XbHybridDSBuffer* pHybridThis, LPCWAVEFORMATEX pwfxFormat ); @@ -1129,8 +1137,8 @@ void WINAPI EMUPATCH(DirectSoundUseLightHRTF4Channel)(void); // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetLFO) ( - LPDIRECTSOUNDBUFFER8 pThis, - LPCDSLFODESC pLFODesc + XbHybridDSBuffer* pHybridThis, + LPCDSLFODESC pLFODesc ); // ****************************************************************** @@ -1157,7 +1165,7 @@ VOID WINAPI EMUPATCH(XAudioCreateAdpcmFormat) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetRolloffCurve) ( - LPDIRECTSOUNDBUFFER8 pThis, + XbHybridDSBuffer* pHybridThis, const FLOAT* pflPoints, DWORD dwPointCount, DWORD dwApply @@ -1186,7 +1194,7 @@ HRESULT WINAPI EMUPATCH(IDirectSound_EnableHeadphones) // ****************************************************************** ULONG WINAPI EMUPATCH(IDirectSoundBuffer_AddRef) ( - X_CDirectSoundBuffer* pThis + XbHybridDSBuffer* pHybridThis ); // ****************************************************************** @@ -1194,7 +1202,7 @@ ULONG WINAPI EMUPATCH(IDirectSoundBuffer_AddRef) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Pause) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwPause ); @@ -1203,7 +1211,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Pause) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_PauseEx) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, REFERENCE_TIME rtTimestamp, DWORD dwPause ); @@ -1263,8 +1271,8 @@ HRESULT WINAPI EMUPATCH(XAudioDownloadEffectsImage) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetFilter) ( - LPVOID pThis, - X_DSFILTERDESC* pFilterDesc + XbHybridDSBuffer* pHybridThis, + X_DSFILTERDESC* pFilterDesc ); // ****************************************************************** @@ -1333,7 +1341,7 @@ HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetI3DL2Source) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetAllParameters) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, X_DS3DBUFFER* pc3DBufferParameters, DWORD dwApply ); @@ -1352,8 +1360,8 @@ HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetFormat) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetOutputBuffer) ( - X_CDirectSoundBuffer* pThis, - X_CDirectSoundBuffer* pOutputBuffer + XbHybridDSBuffer* pHybridThis, + XbHybridDSBuffer* pOutputBuffer ); // ****************************************************************** @@ -1362,7 +1370,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetOutputBuffer) HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetOutputBuffer) ( X_CDirectSoundStream* pThis, - X_CDirectSoundBuffer* pOutputBuffer + XbHybridDSBuffer* pOutputBuffer ); // ****************************************************************** @@ -1389,7 +1397,7 @@ HRESULT WINAPI EMUPATCH(XWaveFileCreateMediaObject) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetEG) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, X_DSENVOLOPEDESC* pEnvelopeDesc ); @@ -1410,8 +1418,8 @@ HRESULT WINAPI EMUPATCH(IDirectSound_GetEffectData) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetNotificationPositions) ( - X_CDirectSoundBuffer* pThis, - DWORD dwNotifyCount, + XbHybridDSBuffer* pHybridThis, + DWORD dwNotifyCount, LPCDSBPOSITIONNOTIFY paNotifies ); @@ -1444,8 +1452,8 @@ HRESULT WINAPI EMUPATCH(IDirectSound_SetEffectData) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Use3DVoiceData) ( - LPVOID pThis, - LPUNKNOWN pUnknown + XbHybridDSBuffer* pHybridThis, + LPUNKNOWN pUnknown ); // ****************************************************************** @@ -1597,7 +1605,7 @@ HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetDopplerFactor) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_GetVoiceProperties) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, OUT X_DSVOICEPROPS* pVoiceProps); // ****************************************************************** @@ -1696,7 +1704,7 @@ VOID WINAPI EMUPATCH(CDirectSound3DCalculator_GetVoiceData) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Set3DVoiceData) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD a2); // ****************************************************************** diff --git a/src/core/hle/DSOUND/DirectSound/DirectSoundBuffer.cpp b/src/core/hle/DSOUND/DirectSound/DirectSoundBuffer.cpp index 828376920..a3053c4e7 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSoundBuffer.cpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSoundBuffer.cpp @@ -64,10 +64,10 @@ void DirectSoundDoWork_Buffer(xboxkrnl::LARGE_INTEGER &time) vector_ds_buffer::iterator ppDSBuffer = g_pDSoundBufferCache.begin(); for (; ppDSBuffer != g_pDSoundBufferCache.end(); ppDSBuffer++) { - if ((*ppDSBuffer)->Host_lock.pLockPtr1 == nullptr || (*ppDSBuffer)->EmuBufferToggle != XTL::X_DSB_TOGGLE_DEFAULT) { + XTL::EmuDirectSoundBuffer* pThis = ((*ppDSBuffer)->emuDSBuffer); + if (pThis->Host_lock.pLockPtr1 == nullptr || pThis->EmuBufferToggle != XTL::X_DSB_TOGGLE_DEFAULT) { continue; } - XTL::X_CDirectSoundBuffer* pThis = *ppDSBuffer; // However there's a chance of locked buffers has been set which needs to be unlock. DSoundGenericUnlock(pThis->EmuFlags, pThis->EmuDirectSoundBuffer8, @@ -97,11 +97,12 @@ void DirectSoundDoWork_Buffer(xboxkrnl::LARGE_INTEGER &time) // ****************************************************************** ULONG WINAPI XTL::EMUPATCH(IDirectSoundBuffer_AddRef) ( - X_CDirectSoundBuffer* pThis) + XbHybridDSBuffer* pHybridThis) { DSoundMutexGuardLock; - LOG_FUNC_ONE_ARG(pThis); + LOG_FUNC_ONE_ARG(pHybridThis); + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; ULONG uRet = HybridDirectSoundBuffer_AddRef(pThis->EmuDirectSoundBuffer8); @@ -113,13 +114,14 @@ ULONG WINAPI XTL::EMUPATCH(IDirectSoundBuffer_AddRef) // ****************************************************************** ULONG WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Release) ( - X_CDirectSoundBuffer* pThis) + XbHybridDSBuffer* pHybridThis) { DSoundMutexGuardLock; - LOG_FUNC_ONE_ARG(pThis); + LOG_FUNC_ONE_ARG(pHybridThis); ULONG uRet = 0; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; //if (!(pThis->EmuFlags & DSE_FLAG_RECIEVEDATA)) { uRet = pThis->EmuDirectSoundBuffer8->Release(); @@ -130,7 +132,7 @@ ULONG WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Release) } // remove cache entry - vector_ds_buffer::iterator ppDSBuffer = std::find(g_pDSoundBufferCache.begin(), g_pDSoundBufferCache.end(), pThis); + vector_ds_buffer::iterator ppDSBuffer = std::find(g_pDSoundBufferCache.begin(), g_pDSoundBufferCache.end(), pHybridThis); if (ppDSBuffer != g_pDSoundBufferCache.end()) { g_pDSoundBufferCache.erase(ppDSBuffer); } @@ -143,7 +145,10 @@ ULONG WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Release) DSoundSGEMemDealloc(pThis->X_BufferCacheSize); } - delete pThis; + size_t size = sizeof(SharedDSBuffer) - sizeof(XbHybridDSBuffer); + SharedDSBuffer* pSharedThis = reinterpret_cast(reinterpret_cast(pHybridThis) - size); + delete pSharedThis->emuDSBuffer; + delete pSharedThis; } //} @@ -156,7 +161,7 @@ ULONG WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Release) HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateBuffer) ( X_DSBUFFERDESC* pdsbd, - OUT X_CDirectSoundBuffer** ppBuffer) + OUT XbHybridDSBuffer** ppBuffer) { DSoundMutexGuardLock; @@ -203,22 +208,26 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateBuffer) } // TODO: Garbage Collection - *ppBuffer = new X_CDirectSoundBuffer(); + SharedDSBuffer* pBuffer = new SharedDSBuffer((DSBufferDesc.dwFlags & DSBCAPS_CTRL3D) != 0); + XbHybridDSBuffer* pHybridBuffer = reinterpret_cast(&pBuffer->dsb_i); + *ppBuffer = pHybridBuffer; + EmuDirectSoundBuffer* pEmuBuffer = pBuffer->emuDSBuffer; - DSoundBufferSetDefault((*ppBuffer), 0, pdsbd->dwFlags); - (*ppBuffer)->Host_lock = { 0 }; - (*ppBuffer)->Xb_rtStopEx = 0LL; + DSoundBufferSetDefault(pEmuBuffer, 0, pdsbd->dwFlags); + pEmuBuffer->Host_lock = { 0 }; + pEmuBuffer->Xb_rtStopEx = 0LL; - DSoundBufferRegionSetDefault(*ppBuffer); + DSoundBufferRegionSetDefault(pEmuBuffer); // We have to set DSBufferDesc last due to EmuFlags must be either 0 or previously written value to preserve other flags. - GeneratePCMFormat(DSBufferDesc, pdsbd->lpwfxFormat, pdsbd->dwFlags, (*ppBuffer)->EmuFlags, pdsbd->dwBufferBytes, - &(*ppBuffer)->X_BufferCache, (*ppBuffer)->X_BufferCacheSize, (*ppBuffer)->Xb_VoiceProperties, pdsbd->lpMixBinsOutput); - (*ppBuffer)->EmuBufferDesc = DSBufferDesc; + GeneratePCMFormat(DSBufferDesc, pdsbd->lpwfxFormat, pdsbd->dwFlags, pEmuBuffer->EmuFlags, pdsbd->dwBufferBytes, + &pEmuBuffer->X_BufferCache, pEmuBuffer->X_BufferCacheSize, pEmuBuffer->Xb_VoiceProperties, pdsbd->lpMixBinsOutput, + pHybridBuffer->p_CDSVoice); + pEmuBuffer->EmuBufferDesc = DSBufferDesc; - EmuLog(LOG_LEVEL::DEBUG, "DirectSoundCreateBuffer, *ppBuffer := 0x%08X, bytes := 0x%08X", *ppBuffer, (*ppBuffer)->EmuBufferDesc.dwBufferBytes); + EmuLog(LOG_LEVEL::DEBUG, "DirectSoundCreateBuffer, *ppBuffer := 0x%08X, bytes := 0x%08X", *ppBuffer, pEmuBuffer->EmuBufferDesc.dwBufferBytes); - hRet = DSoundBufferCreate(&DSBufferDesc, (*ppBuffer)->EmuDirectSoundBuffer8); + hRet = DSoundBufferCreate(&DSBufferDesc, pEmuBuffer->EmuDirectSoundBuffer8); if (FAILED(hRet)) { std::stringstream output; output << "Xbox:\n" << pdsbd; @@ -230,17 +239,17 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateBuffer) } else { if (pdsbd->dwFlags & DSBCAPS_CTRL3D) { - DSound3DBufferCreate((*ppBuffer)->EmuDirectSoundBuffer8, (*ppBuffer)->EmuDirectSound3DBuffer8); - (*ppBuffer)->Xb_dwHeadroom = 0; // Default for 3D + DSound3DBufferCreate(pEmuBuffer->EmuDirectSoundBuffer8, pEmuBuffer->EmuDirectSound3DBuffer8); + pEmuBuffer->Xb_dwHeadroom = 0; // Default for 3D } - DSoundDebugMuteFlag((*ppBuffer)->X_BufferCacheSize, (*ppBuffer)->EmuFlags); + DSoundDebugMuteFlag(pEmuBuffer->X_BufferCacheSize, pEmuBuffer->EmuFlags); // Pre-set volume to enforce silence if one of audio codec is disabled. - HybridDirectSoundBuffer_SetVolume((*ppBuffer)->EmuDirectSoundBuffer8, 0L, (*ppBuffer)->EmuFlags, nullptr, - (*ppBuffer)->Xb_VolumeMixbin, (*ppBuffer)->Xb_dwHeadroom); + HybridDirectSoundBuffer_SetVolume(pEmuBuffer->EmuDirectSoundBuffer8, 0L, pEmuBuffer->EmuFlags, nullptr, + pEmuBuffer->Xb_VolumeMixbin, pEmuBuffer->Xb_dwHeadroom, pHybridBuffer->p_CDSVoice); - g_pDSoundBufferCache.push_back(*ppBuffer); + g_pDSoundBufferCache.push_back(pHybridBuffer); } } @@ -254,7 +263,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSound_CreateSoundBuffer) ( LPDIRECTSOUND8 pThis, X_DSBUFFERDESC* pdsbd, - OUT X_CDirectSoundBuffer** ppBuffer, + OUT XbHybridDSBuffer** ppBuffer, LPUNKNOWN pUnkOuter) { DSoundMutexGuardLock; @@ -273,18 +282,19 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSound_CreateSoundBuffer) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_GetCurrentPosition) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, OUT PDWORD pdwCurrentPlayCursor, OUT PDWORD pdwCurrentWriteCursor) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG_OUT(pdwCurrentPlayCursor) LOG_FUNC_ARG_OUT(pdwCurrentWriteCursor) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = HybridDirectSoundBuffer_GetCurrentPosition(pThis->EmuDirectSoundBuffer8, pdwCurrentPlayCursor, pdwCurrentWriteCursor, pThis->EmuFlags); return hRet; @@ -295,16 +305,17 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_GetCurrentPosition) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetCurrentPosition) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwNewPosition) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(dwNewPosition) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; dwNewPosition = DSoundBufferGetPCMBufferSize(pThis->EmuFlags, dwNewPosition); // NOTE: TODO: This call *will* (by MSDN) fail on primary buffers! @@ -322,16 +333,17 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetCurrentPosition) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_GetStatus) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, OUT LPDWORD pdwStatus) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG_OUT(pdwStatus) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; DWORD dwStatusXbox = 0, dwStatusHost; HRESULT hRet = pThis->EmuDirectSoundBuffer8->GetStatus(&dwStatusHost); @@ -361,13 +373,13 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_GetStatus) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_GetVoiceProperties) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, OUT X_DSVOICEPROPS* pVoiceProps) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG_OUT(pVoiceProps) LOG_FUNC_END; @@ -376,6 +388,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_GetVoiceProperties) RETURN(DS_OK); } + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = HybridDirectSoundBuffer_GetVoiceProperties(pThis->Xb_VoiceProperties, pVoiceProps); return hRet; @@ -386,7 +399,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_GetVoiceProperties) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Lock) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwOffset, DWORD dwBytes, LPVOID* ppvAudioPtr1, @@ -398,7 +411,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Lock) DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(dwOffset) LOG_FUNC_ARG(dwBytes) LOG_FUNC_ARG(ppvAudioPtr1) @@ -408,6 +421,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Lock) LOG_FUNC_ARG(dwFlags) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = D3D_OK; DWORD pcmSize = DSoundBufferGetPCMBufferSize(pThis->EmuFlags, dwBytes); DWORD pcmOffset = DSoundBufferGetPCMBufferSize(pThis->EmuFlags, dwOffset); @@ -458,7 +472,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Lock) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Unlock) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, LPVOID ppvAudioPtr1, DWORD pdwAudioBytes1, LPVOID ppvAudioPtr2, @@ -468,13 +482,14 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Unlock) DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(ppvAudioPtr1) LOG_FUNC_ARG(pdwAudioBytes1) LOG_FUNC_ARG(ppvAudioPtr2) LOG_FUNC_ARG(pdwAudioBytes2) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; // TODO: Find out why pThis->EmuLockPtr1 is nullptr... (workaround atm is to check if it is not a nullptr.) if (pThis->X_BufferCache != xbnullptr && pThis->Host_lock.pLockPtr1 != nullptr) { @@ -506,16 +521,17 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Unlock) // Introduced in XDK 4721 revision. HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Pause) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwPause) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(dwPause) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; DSoundGenericUnlock(pThis->EmuFlags, pThis->EmuDirectSoundBuffer8, pThis->EmuBufferDesc, @@ -537,18 +553,19 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Pause) // Introduced in XDK 4721 revision. HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_PauseEx) ( - X_CDirectSoundBuffer *pThis, + XbHybridDSBuffer* pHybridThis, REFERENCE_TIME rtTimestamp, DWORD dwPause) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(rtTimestamp) LOG_FUNC_ARG(dwPause) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = HybridDirectSoundBuffer_Pause(pThis->EmuDirectSoundBuffer8, dwPause, pThis->EmuFlags, pThis->EmuPlayFlags, 1, rtTimestamp, pThis->Xb_rtPauseEx); @@ -560,7 +577,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_PauseEx) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Play) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwReserved1, DWORD dwReserved2, DWORD dwFlags) @@ -568,12 +585,13 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Play) DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(dwReserved1) LOG_FUNC_ARG(dwReserved2) LOG_FUNC_ARG(dwFlags) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; DSoundGenericUnlock(pThis->EmuFlags, pThis->EmuDirectSoundBuffer8, pThis->EmuBufferDesc, @@ -602,7 +620,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Play) pThis->EmuPlayFlags ^= X_DSBPLAY_SYNCHPLAYBACK; } - DSoundBufferUpdate(pThis, dwFlags, hRet); + DSoundBufferUpdate(pHybridThis, dwFlags, hRet); if (hRet == DS_OK) { if (dwFlags & X_DSBPLAY_FROMSTART) { @@ -623,7 +641,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Play) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_PlayEx) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pThis, REFERENCE_TIME rtTimeStamp, DWORD dwFlags) { @@ -650,18 +668,19 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_PlayEx) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetAllParameters) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, X_DS3DBUFFER* pc3DBufferParameters, DWORD dwApply) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(pc3DBufferParameters) LOG_FUNC_ARG(dwApply) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = HybridDirectSound3DBuffer_SetAllParameters(pThis->EmuDirectSound3DBuffer8, pc3DBufferParameters, dwApply); return hRet; @@ -672,19 +691,20 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetAllParameters) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetBufferData) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, LPVOID pvBufferData, DWORD dwBufferBytes) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(pvBufferData) LOG_FUNC_ARG(dwBufferBytes) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; // Release old buffer if exists, this is needed in order to set lock pointer buffer to nullptr. if (pThis->Host_lock.pLockPtr1 != nullptr) { @@ -729,7 +749,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetBufferData) DSoundDebugMuteFlag(pThis->X_BufferCacheSize, pThis->EmuFlags); // Only perform a resize, for lock emulation purpose. - DSoundBufferResizeSetSize(pThis, hRet, dwBufferBytes); + DSoundBufferResizeSetSize(pHybridThis, hRet, dwBufferBytes); } else if (pvBufferData != xbnullptr) { // Free internal buffer cache if exist @@ -744,7 +764,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetBufferData) DSoundDebugMuteFlag(pThis->X_BufferCacheSize, pThis->EmuFlags); // Only perform a resize, for lock emulation purpose. - DSoundBufferResizeSetSize(pThis, hRet, dwBufferBytes); + DSoundBufferResizeSetSize(pHybridThis, hRet, dwBufferBytes); } @@ -756,7 +776,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetBufferData) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetConeAngles) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwInsideConeAngle, DWORD dwOutsideConeAngle, DWORD dwApply) @@ -764,12 +784,13 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetConeAngles) DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(dwInsideConeAngle) LOG_FUNC_ARG(dwOutsideConeAngle) LOG_FUNC_ARG(dwApply) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = HybridDirectSound3DBuffer_SetConeAngles(pThis->EmuDirectSound3DBuffer8, dwInsideConeAngle, dwOutsideConeAngle, dwApply); return hRet; @@ -780,7 +801,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetConeAngles) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetConeOrientation) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT x, FLOAT y, FLOAT z, @@ -789,13 +810,14 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetConeOrientation) DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(x) LOG_FUNC_ARG(y) LOG_FUNC_ARG(z) LOG_FUNC_ARG(dwApply) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = HybridDirectSound3DBuffer_SetConeOrientation(pThis->EmuDirectSound3DBuffer8, x, y, z, dwApply); return hRet; @@ -806,18 +828,19 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetConeOrientation) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetConeOutsideVolume) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, LONG lConeOutsideVolume, DWORD dwApply) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(lConeOutsideVolume) LOG_FUNC_ARG(dwApply) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = HybridDirectSound3DBuffer_SetConeOutsideVolume(pThis->EmuDirectSound3DBuffer8, lConeOutsideVolume, dwApply); return hRet; @@ -828,14 +851,14 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetConeOutsideVolume) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetDistanceFactor) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT flDistanceFactor, DWORD dwApply) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(flDistanceFactor) LOG_FUNC_ARG(dwApply) LOG_FUNC_END; @@ -850,7 +873,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetDistanceFactor) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetDopplerFactor) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pThis, FLOAT flDopplerFactor, DWORD dwApply) { @@ -872,13 +895,13 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetDopplerFactor) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetEG) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, X_DSENVOLOPEDESC* pEnvelopeDesc) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(pEnvelopeDesc) LOG_FUNC_END; @@ -886,6 +909,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetEG) LOG_NOT_SUPPORTED(); + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; pThis->Xb_EnvolopeDesc = *pEnvelopeDesc; return S_OK; @@ -896,13 +920,13 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetEG) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetFilter) ( - LPVOID pThis, - X_DSFILTERDESC* pFilterDesc) + XbHybridDSBuffer* pHybridThis, + X_DSFILTERDESC* pFilterDesc) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(pFilterDesc) LOG_FUNC_END; @@ -919,21 +943,22 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetFilter) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetFormat) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, LPCWAVEFORMATEX pwfxFormat) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(pwfxFormat) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = HybridDirectSoundBuffer_SetFormat(pThis->EmuDirectSoundBuffer8, pwfxFormat, pThis->Xb_Flags, pThis->EmuBufferDesc, pThis->EmuFlags, pThis->EmuPlayFlags, pThis->EmuDirectSound3DBuffer8, 0, pThis->X_BufferCache, pThis->X_BufferCacheSize, - pThis->Xb_VoiceProperties, xbnullptr, pThis->Xb_Frequency); + pThis->Xb_VoiceProperties, xbnullptr, pHybridThis->p_CDSVoice); return hRet; } @@ -943,17 +968,19 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetFormat) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetFrequency) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwFrequency) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(dwFrequency) LOG_FUNC_END; - HRESULT hRet = HybridDirectSoundBuffer_SetFrequency(pThis->EmuDirectSoundBuffer8, dwFrequency, pThis->Xb_Frequency); + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; + HRESULT hRet = HybridDirectSoundBuffer_SetFrequency(pThis->EmuDirectSoundBuffer8, dwFrequency, + pHybridThis->p_CDSVoice); return hRet; } @@ -963,18 +990,20 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetFrequency) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetHeadroom) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwHeadroom) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(dwHeadroom) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = HybridDirectSoundBuffer_SetHeadroom(pThis->EmuDirectSoundBuffer8, dwHeadroom, pThis->Xb_dwHeadroom, - pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->EmuFlags); + pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->EmuFlags, + pHybridThis->p_CDSVoice); return hRet; } @@ -984,14 +1013,14 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetHeadroom) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetI3DL2Source) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, X_DSI3DL2BUFFER* pds3db, DWORD dwApply) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(pds3db) LOG_FUNC_ARG(dwApply) LOG_FUNC_END; @@ -1010,13 +1039,13 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetI3DL2Source) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetLFO) //Low Frequency Oscillators ( - LPDIRECTSOUNDBUFFER8 pThis, + XbHybridDSBuffer* pHybridThis, LPCDSLFODESC pLFODesc) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(pLFODesc) LOG_FUNC_END; @@ -1032,14 +1061,14 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetLFO) //Low Frequency Oscillat // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetLoopRegion) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwLoopStart, DWORD dwLoopLength) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(dwLoopStart) LOG_FUNC_ARG(dwLoopLength) LOG_FUNC_END; @@ -1047,6 +1076,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetLoopRegion) // TODO: Ensure that 4627 & 4361 are intercepting far enough back // (otherwise pThis is manipulated!) + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; pThis->EmuRegionLoopStartOffset = dwLoopStart; pThis->EmuRegionLoopLength = dwLoopLength; pThis->EmuBufferToggle = X_DSB_TOGGLE_LOOP; @@ -1058,7 +1088,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetLoopRegion) if ((dwStatus & DSBSTATUS_PLAYING) > 0) { if ((dwStatus & DSBSTATUS_LOOPING) > 0) { pThis->EmuDirectSoundBuffer8->Stop(); - DSoundBufferUpdate(pThis, pThis->EmuPlayFlags, hRet); + DSoundBufferUpdate(pHybridThis, pThis->EmuPlayFlags, hRet); pThis->EmuDirectSoundBuffer8->SetCurrentPosition(0); pThis->EmuDirectSoundBuffer8->Play(0, 0, pThis->EmuPlayFlags); } @@ -1073,18 +1103,19 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetLoopRegion) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMaxDistance) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT flMaxDistance, DWORD dwApply) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(flMaxDistance) LOG_FUNC_ARG(dwApply) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = HybridDirectSound3DBuffer_SetMaxDistance(pThis->EmuDirectSound3DBuffer8, flMaxDistance, dwApply); return hRet; @@ -1095,18 +1126,19 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMaxDistance) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMinDistance) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT flMinDistance, DWORD dwApply) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(flMinDistance) LOG_FUNC_ARG(dwApply) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = HybridDirectSound3DBuffer_SetMinDistance(pThis->EmuDirectSound3DBuffer8, flMinDistance, dwApply); return hRet; @@ -1117,7 +1149,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMinDistance) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMixBins) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwMixBinMask) { DSoundMutexGuardLock; @@ -1126,7 +1158,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMixBins) if (g_LibVersion_DSOUND < 4039) { LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(dwMixBinMask) LOG_FUNC_END; @@ -1134,10 +1166,11 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMixBins) } else { LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(pMixBins) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; hRet = HybridDirectSoundBuffer_SetMixBins(pThis->Xb_VoiceProperties, pMixBins, pThis->EmuBufferDesc.lpwfxFormat, pThis->EmuBufferDesc); } @@ -1150,14 +1183,14 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMixBins) // This revision API was used in XDK 3911 until API had changed in XDK 4039. HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMixBinVolumes_12) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwMixBinMask, const LONG* alVolumes) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(dwMixBinMask) LOG_FUNC_ARG(alVolumes) LOG_FUNC_END; @@ -1176,18 +1209,20 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMixBinVolumes_12) // This revision is only used in XDK 4039 and higher. HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMixBinVolumes_8) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, X_LPDSMIXBINS pMixBins) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(pMixBins) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = HybridDirectSoundBuffer_SetMixBinVolumes_8(pThis->EmuDirectSoundBuffer8, pMixBins, pThis->Xb_VoiceProperties, - pThis->EmuFlags, pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom); + pThis->EmuFlags, pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom, + pHybridThis->p_CDSVoice); return hRet; } @@ -1197,18 +1232,19 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMixBinVolumes_8) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMode) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwMode, DWORD dwApply) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(dwMode) LOG_FUNC_ARG(dwApply) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = HybridDirectSound3DBuffer_SetMode(pThis->EmuDirectSound3DBuffer8, dwMode, dwApply); return hRet; @@ -1219,18 +1255,19 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMode) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetNotificationPositions) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwNotifyCount, LPCDSBPOSITIONNOTIFY paNotifies) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(dwNotifyCount) LOG_FUNC_ARG(paNotifies) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = DSERR_INVALIDPARAM; // If we have a valid buffer, query a PC IDirectSoundNotify pointer and @@ -1264,13 +1301,13 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetNotificationPositions) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetOutputBuffer) ( - X_CDirectSoundBuffer* pThis, - X_CDirectSoundBuffer* pOutputBuffer) + XbHybridDSBuffer* pHybridThis, + XbHybridDSBuffer* pOutputBuffer) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(pOutputBuffer) LOG_FUNC_END; @@ -1288,17 +1325,19 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetOutputBuffer) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetPitch) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, LONG lPitch) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(lPitch) LOG_FUNC_END; - HRESULT hRet = HybridDirectSoundBuffer_SetPitch(pThis->EmuDirectSoundBuffer8, lPitch, pThis->Xb_Frequency); + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; + HRESULT hRet = HybridDirectSoundBuffer_SetPitch(pThis->EmuDirectSoundBuffer8, lPitch, + pHybridThis->p_CDSVoice); return hRet; } @@ -1308,14 +1347,14 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetPitch) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetPlayRegion) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwPlayStart, DWORD dwPlayLength) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(dwPlayStart) LOG_FUNC_ARG(dwPlayLength) LOG_FUNC_END; @@ -1323,6 +1362,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetPlayRegion) // TODO: Ensure that 4627 & 4361 are intercepting far enough back // (otherwise pThis is manipulated!) + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; pThis->EmuBufferToggle = X_DSB_TOGGLE_PLAY; pThis->EmuRegionPlayStartOffset = dwPlayStart; pThis->EmuRegionPlayLength = dwPlayLength; @@ -1338,7 +1378,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetPlayRegion) if ((dwStatus & DSBSTATUS_PLAYING) > 0) { if ((dwStatus & DSBSTATUS_LOOPING) == 0) { pThis->EmuDirectSoundBuffer8->Stop(); - DSoundBufferUpdate(pThis, pThis->EmuPlayFlags, hRet); + DSoundBufferUpdate(pHybridThis, pThis->EmuPlayFlags, hRet); pThis->EmuDirectSoundBuffer8->SetCurrentPosition(0); pThis->EmuDirectSoundBuffer8->Play(0, 0, pThis->EmuPlayFlags); } @@ -1352,7 +1392,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetPlayRegion) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetPosition) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT x, FLOAT y, FLOAT z, @@ -1361,13 +1401,14 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetPosition) DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(x) LOG_FUNC_ARG(y) LOG_FUNC_ARG(z) LOG_FUNC_ARG(dwApply) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = HybridDirectSound3DBuffer_SetPosition(pThis->EmuDirectSound3DBuffer8, x, y, z, dwApply); return hRet; @@ -1378,7 +1419,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetPosition) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetRolloffCurve) ( - LPDIRECTSOUNDBUFFER8 pThis, + XbHybridDSBuffer* pHybridThis, const FLOAT* pflPoints, DWORD dwPointCount, DWORD dwApply) @@ -1386,7 +1427,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetRolloffCurve) DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(pflPoints) LOG_FUNC_ARG(dwPointCount) LOG_FUNC_ARG(dwApply) @@ -1404,14 +1445,14 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetRolloffCurve) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetRolloffFactor) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT flRolloffFactor, DWORD dwApply) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(flRolloffFactor) LOG_FUNC_ARG(dwApply) LOG_FUNC_END; @@ -1428,7 +1469,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetRolloffFactor) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetVelocity) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT x, FLOAT y, FLOAT z, @@ -1437,13 +1478,14 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetVelocity) DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(x) LOG_FUNC_ARG(y) LOG_FUNC_ARG(z) LOG_FUNC_ARG(dwApply) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = HybridDirectSound3DBuffer_SetVelocity(pThis->EmuDirectSound3DBuffer8, x, y, z, dwApply); return hRet; @@ -1454,18 +1496,19 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetVelocity) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetVolume) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, LONG lVolume) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(lVolume) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = HybridDirectSoundBuffer_SetVolume(pThis->EmuDirectSoundBuffer8, lVolume, pThis->EmuFlags, &pThis->Xb_Volume, - pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom); + pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom, pHybridThis->p_CDSVoice); return hRet; } @@ -1475,16 +1518,17 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetVolume) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Stop) ( - X_CDirectSoundBuffer* pThis) + XbHybridDSBuffer* pHybridThis) { DSoundMutexGuardLock; - LOG_FUNC_ONE_ARG(pThis); + LOG_FUNC_ONE_ARG(pHybridThis); HRESULT hRet = D3D_OK; - if (pThis != nullptr) { + if (pHybridThis != nullptr) { // TODO : Test Stop (emulated via Stop + SetCurrentPosition(0)) : + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; hRet = pThis->EmuDirectSoundBuffer8->Stop(); pThis->EmuDirectSoundBuffer8->SetCurrentPosition(0); } @@ -1497,18 +1541,19 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Stop) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_StopEx) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, REFERENCE_TIME rtTimeStamp, DWORD dwFlags) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(rtTimeStamp) LOG_FUNC_ARG(dwFlags) LOG_FUNC_END; + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = DS_OK; //TODO: RadWolfie - Rayman 3 crash at end of first intro for this issue... @@ -1561,7 +1606,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_StopEx) pThis->EmuDirectSoundBuffer8->GetCurrentPosition(nullptr, &dwValue); hRet = pThis->EmuDirectSoundBuffer8->Stop(); - DSoundBufferResizeUpdate(pThis, pThis->EmuPlayFlags, hRet, 0, pThis->X_BufferCacheSize); + DSoundBufferResizeUpdate(pHybridThis, pThis->EmuPlayFlags, hRet, 0, pThis->X_BufferCacheSize); dwValue += pThis->EmuRegionPlayStartOffset; if (isLooping) { @@ -1590,14 +1635,14 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_StopEx) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Set3DVoiceData) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD a2 ) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(a2) LOG_FUNC_END; @@ -1611,13 +1656,13 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Set3DVoiceData) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Use3DVoiceData) ( - LPVOID pThis, - LPUNKNOWN pUnknown) + XbHybridDSBuffer* pHybridThis, + LPUNKNOWN pUnknown) { DSoundMutexGuardLock; LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pHybridThis) LOG_FUNC_ARG(pUnknown) LOG_FUNC_END; diff --git a/src/core/hle/DSOUND/DirectSound/DirectSoundGlobal.hpp b/src/core/hle/DSOUND/DirectSound/DirectSoundGlobal.hpp index 5d9acadd7..c6aabc64a 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSoundGlobal.hpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSoundGlobal.hpp @@ -45,7 +45,7 @@ extern std::recursive_mutex g_DSoundMutex; // Xbox maximum synch playback audio #define DSOUND_MAX_SYNCHPLAYBACK_AUDIO 29 -#define vector_ds_buffer std::vector +#define vector_ds_buffer std::vector #define vector_ds_stream std::vector extern vector_ds_buffer g_pDSoundBufferCache; extern vector_ds_stream g_pDSoundStreamCache; diff --git a/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp b/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp index 6c45375c6..f648d9abb 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp @@ -254,7 +254,8 @@ static inline void GeneratePCMFormat( LPVOID* X_BufferCache, DWORD &X_BufferCacheSize, XTL::X_DSVOICEPROPS& Xb_VoiceProperties, - XTL::X_LPDSMIXBINS mixbins_output) + XTL::X_LPDSMIXBINS mixbins_output, + XTL::CDirectSoundVoice* Xb_Voice) { bool bIsSpecial = false; @@ -396,7 +397,6 @@ static inline void DSound3DBufferCreate(LPDIRECTSOUNDBUFFER8 pDSBuffer, LPDIRECT pThis->Xb_dwHeadroom = 600; /* default for 2D voice */ \ pThis->Xb_EnvolopeDesc = { 0 }; \ InitVoiceProperties(pThis->Xb_VoiceProperties); /* The rest will initialize in GeneratePCMFormat to GenerateMixBinDefault. */ \ - pThis->Xb_Frequency = XTL_DSXFREQUENCY_ORIGINAL; \ pThis->Xb_Flags = Xb_dwFlags; //pThis->EmuBufferDesc = { 0 }; // Enable this when become necessary. /* @@ -405,7 +405,7 @@ static inline void DSound3DBufferCreate(LPDIRECTSOUNDBUFFER8 pDSBuffer, LPDIRECT pThis->EmuLockPtr2 = xbnullptr; \ pThis->EmuLockBytes2 = 0; \ */ -static inline void DSoundBufferRegionSetDefault(XTL::X_CDirectSoundBuffer *pThis) { +static inline void DSoundBufferRegionSetDefault(XTL::EmuDirectSoundBuffer *pThis) { pThis->EmuBufferToggle = XTL::X_DSB_TOGGLE_DEFAULT; pThis->EmuRegionLoopStartOffset = 0; pThis->EmuRegionLoopLength = 0; @@ -419,7 +419,7 @@ static inline void DSoundBufferTransferSettings( LPDIRECTSOUNDBUFFER8 &pDSBufferNew, LPDIRECTSOUND3DBUFFER8 &pDS3DBufferOld, LPDIRECTSOUND3DBUFFER8 &pDS3DBufferNew, - DWORD Xb_Frequency) + XTL::CDirectSoundVoice* Xb_Voice) { LONG lVolume, lPan; DS3DBUFFER ds3dBuffer; @@ -428,7 +428,9 @@ static inline void DSoundBufferTransferSettings( return; } - pDSBufferNew->SetFrequency(Xb_Frequency); + // if sync current frequency used (then use pitch only). + uint32_t freq = XTL::converter_pitch2freq(Xb_Voice->GetPitch(Xb_Voice)); + pDSBufferNew->SetFrequency(freq); pDSBufferOld->GetVolume(&lVolume); pDSBufferNew->SetVolume(lVolume); @@ -449,7 +451,7 @@ static inline void DSoundBufferReCreate( LPDIRECTSOUND3DBUFFER8 &pDS3DBuffer, LPDIRECTSOUNDBUFFER8 &pDSBufferNew, LPDIRECTSOUND3DBUFFER8 &pDS3DBufferNew, - DWORD Xb_Frequency) { + XTL::CDirectSoundVoice* Xb_Voice) { DSoundBufferCreate(&DSBufferDesc, pDSBufferNew); @@ -458,7 +460,7 @@ static inline void DSoundBufferReCreate( DSound3DBufferCreate(pDSBufferNew, pDS3DBufferNew); } - DSoundBufferTransferSettings(pDSBuffer, pDSBufferNew, pDS3DBuffer, pDS3DBufferNew, Xb_Frequency); + DSoundBufferTransferSettings(pDSBuffer, pDSBufferNew, pDS3DBuffer, pDS3DBufferNew, Xb_Voice); } static inline void DSoundBufferRelease( @@ -484,10 +486,11 @@ static inline void DSoundBufferRelease( } static inline void DSoundBufferResizeSetSize( - XTL::X_CDirectSoundBuffer* pThis, + XTL::XbHybridDSBuffer* pHybridThis, HRESULT &hRet, DWORD Xb_dwByteLength) { + XTL::EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; // General return OK, nothing needs to set as invalid for now. hRet = DS_OK; @@ -508,7 +511,7 @@ static inline void DSoundBufferResizeSetSize( LPDIRECTSOUND3DBUFFER8 pDS3DBufferNew = nullptr; DSoundBufferReCreate(pThis->EmuDirectSoundBuffer8, pThis->EmuBufferDesc, pThis->EmuDirectSound3DBuffer8, - pDSBufferNew, pDS3DBufferNew, pThis->Xb_Frequency); + pDSBufferNew, pDS3DBufferNew, pHybridThis->p_CDSVoice); // release old buffer DSoundBufferRelease(pThis->EmuDirectSoundBuffer8, pThis->EmuDirectSound3DBuffer8, refCount); @@ -522,13 +525,14 @@ static inline void DSoundBufferResizeSetSize( } static inline void DSoundBufferResizeUpdate( - XTL::X_CDirectSoundBuffer* pThis, + XTL::XbHybridDSBuffer* pHybridThis, DWORD dwPlayFlags, HRESULT &hRet, DWORD Xb_dwStartOffset, DWORD Xb_dwByteLength) { - DSoundBufferResizeSetSize(pThis, hRet, Xb_dwByteLength); + XTL::EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; + DSoundBufferResizeSetSize(pHybridThis, hRet, Xb_dwByteLength); hRet = pThis->EmuDirectSoundBuffer8->Lock(0, 0, &pThis->Host_lock.pLockPtr1, &pThis->Host_lock.dwLockBytes1, nullptr, nullptr, DSBLOCK_ENTIREBUFFER); @@ -546,11 +550,13 @@ static inline void DSoundBufferResizeUpdate( } static inline void DSoundBufferRegionCurrentLocation( - XTL::X_CDirectSoundBuffer* pThis, + XTL::XbHybridDSBuffer* pHybridThis, DWORD dwPlayFlags, HRESULT &hRet, DWORD &Xb_dwStartOffset, - DWORD &Xb_dwByteLength) { + DWORD &Xb_dwByteLength) +{ + XTL::EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; if ((dwPlayFlags & X_DSBPLAY_LOOPING) > 0) { Xb_dwStartOffset = pThis->EmuRegionPlayStartOffset + pThis->EmuRegionLoopStartOffset; @@ -577,7 +583,7 @@ static inline void DSoundBufferRegionCurrentLocation( } static inline void DSoundBufferUpdate( - XTL::X_CDirectSoundBuffer* pThis, + XTL::XbHybridDSBuffer* pHybridThis, DWORD dwPlayFlags, HRESULT &hRet) { @@ -585,24 +591,24 @@ static inline void DSoundBufferUpdate( DWORD Xb_dwByteLength; DWORD Xb_dwStartOffset; - DSoundBufferRegionCurrentLocation(pThis, dwPlayFlags, hRet, Xb_dwStartOffset, Xb_dwByteLength); + DSoundBufferRegionCurrentLocation(pHybridThis, dwPlayFlags, hRet, Xb_dwStartOffset, Xb_dwByteLength); - DSoundBufferResizeUpdate(pThis, dwPlayFlags, hRet, Xb_dwStartOffset, Xb_dwByteLength); + DSoundBufferResizeUpdate(pHybridThis, dwPlayFlags, hRet, Xb_dwStartOffset, Xb_dwByteLength); } -static inline void DSoundBufferReplace( +static inline void DSoundBufferRegenWithNewFormat( LPDIRECTSOUNDBUFFER8 &pDSBuffer, DSBUFFERDESC &DSBufferDesc, DWORD PlayFlags, LPDIRECTSOUND3DBUFFER8 &pDS3DBuffer, - DWORD Xb_Frequency) + XTL::CDirectSoundVoice* Xb_Voice) { DWORD refCount, dwPlayCursor, dwStatus; LPDIRECTSOUNDBUFFER8 pDSBufferNew = nullptr; LPDIRECTSOUND3DBUFFER8 pDS3DBufferNew = nullptr; DSoundBufferReCreate(pDSBuffer, DSBufferDesc, pDS3DBuffer, - pDSBufferNew, pDS3DBufferNew, Xb_Frequency); + pDSBufferNew, pDS3DBufferNew, Xb_Voice); HRESULT hRet = pDSBuffer->GetStatus(&dwStatus); @@ -1082,15 +1088,17 @@ static inline HRESULT HybridDirectSoundBuffer_SetFormat( DWORD &X_BufferCacheSize, XTL::X_DSVOICEPROPS &Xb_VoiceProperties, XTL::X_LPDSMIXBINS mixbins_output, - DWORD Xb_Frequency) + XTL::CDirectSoundVoice* Xb_Voice) { pDSBuffer->Stop(); if (X_BufferAllocate) { - GeneratePCMFormat(BufferDesc, Xb_pwfxFormat, Xb_flags, dwEmuFlags, X_BufferCacheSize, xbnullptr, X_BufferCacheSize, Xb_VoiceProperties, mixbins_output); + GeneratePCMFormat(BufferDesc, Xb_pwfxFormat, Xb_flags, dwEmuFlags, X_BufferCacheSize, + xbnullptr, X_BufferCacheSize, Xb_VoiceProperties, mixbins_output, Xb_Voice); // Don't allocate for DS Stream class, it is using straight from the source. } else { - GeneratePCMFormat(BufferDesc, Xb_pwfxFormat, Xb_flags, dwEmuFlags, 0, xbnullptr, X_BufferCacheSize, Xb_VoiceProperties, mixbins_output); + GeneratePCMFormat(BufferDesc, Xb_pwfxFormat, Xb_flags, dwEmuFlags, 0, + xbnullptr, X_BufferCacheSize, Xb_VoiceProperties, mixbins_output, Xb_Voice); } HRESULT hRet = DS_OK; if ((void*)g_pDSoundPrimaryBuffer == (void*)pDSBuffer) { @@ -1101,28 +1109,31 @@ static inline HRESULT HybridDirectSoundBuffer_SetFormat( // Allocate at least 5 second worth of bytes in PCM format. BufferDesc.dwBufferBytes = BufferDesc.lpwfxFormat->nAvgBytesPerSec * 5; } - DSoundBufferReplace(pDSBuffer, BufferDesc, dwPlayFlags, pDS3DBuffer, Xb_Frequency); + DSoundBufferRegenWithNewFormat(pDSBuffer, BufferDesc, dwPlayFlags, pDS3DBuffer, Xb_Voice); } RETURN_RESULT_CHECK(hRet); } +static HRESULT HybridDirectSoundBuffer_SetPitch(LPDIRECTSOUNDBUFFER8, LONG, XTL::CDirectSoundVoice*); + //IDirectSoundStream //IDirectSoundBuffer static inline HRESULT HybridDirectSoundBuffer_SetFrequency( LPDIRECTSOUNDBUFFER8 pDSBuffer, DWORD dwFrequency, - DWORD &Xb_Frequency) + XTL::CDirectSoundVoice* Xb_Voice) { HRESULT hRet = S_OK; - Xb_Frequency = dwFrequency; - hRet = pDSBuffer->SetFrequency(dwFrequency); + int32_t pitch = XTL::converter_freq2pitch((dwFrequency!=0 ? dwFrequency : Xb_Voice->GetFrequencyDefault(Xb_Voice))); + + hRet = HybridDirectSoundBuffer_SetPitch(pDSBuffer, pitch, Xb_Voice); RETURN_RESULT_CHECK(hRet); } -static HRESULT HybridDirectSoundBuffer_SetVolume(LPDIRECTSOUNDBUFFER8, LONG, DWORD, LPLONG, LONG, DWORD); +static HRESULT HybridDirectSoundBuffer_SetVolume(LPDIRECTSOUNDBUFFER8, LONG, DWORD, LPLONG, LONG, DWORD, XTL::CDirectSoundVoice*); //IDirectSoundStream //IDirectSoundBuffer @@ -1133,7 +1144,8 @@ static inline HRESULT HybridDirectSoundBuffer_SetHeadroom( DWORD &Xb_dwHeadroom, LONG Xb_volume, LONG Xb_volumeMixbin, - DWORD dwEmuFlags) + DWORD dwEmuFlags, + XTL::CDirectSoundVoice* Xb_Voice) { HRESULT hRet; if (dwHeadroom > 10000) { @@ -1141,7 +1153,7 @@ static inline HRESULT HybridDirectSoundBuffer_SetHeadroom( } else { Xb_dwHeadroom = dwHeadroom; hRet = DS_OK; - HybridDirectSoundBuffer_SetVolume(pDSBuffer, Xb_volume, dwEmuFlags, xbnullptr, Xb_volumeMixbin, dwHeadroom); + HybridDirectSoundBuffer_SetVolume(pDSBuffer, Xb_volume, dwEmuFlags, xbnullptr, Xb_volumeMixbin, dwHeadroom, Xb_Voice); } return DS_OK; @@ -1233,7 +1245,8 @@ static inline HRESULT HybridDirectSoundBuffer_SetMixBinVolumes_8( DWORD EmuFlags, LONG Xb_volume, LONG &Xb_volumeMixBin, - DWORD Xb_dwHeadroom) + DWORD Xb_dwHeadroom, + XTL::CDirectSoundVoice* Xb_Voice) { HRESULT hRet = DSERR_INVALIDPARAM; @@ -1274,7 +1287,7 @@ static inline HRESULT HybridDirectSoundBuffer_SetMixBinVolumes_8( if (counter > 0) { Xb_volumeMixBin = volume / (LONG)counter; hRet = HybridDirectSoundBuffer_SetVolume(pDSBuffer, Xb_volume, EmuFlags, nullptr, - Xb_volumeMixBin, Xb_dwHeadroom); + Xb_volumeMixBin, Xb_dwHeadroom, Xb_Voice); } else { hRet = DS_OK; } @@ -1326,27 +1339,14 @@ static inline HRESULT HybridDirectSoundBuffer_SetOutputBuffer( static inline HRESULT HybridDirectSoundBuffer_SetPitch( LPDIRECTSOUNDBUFFER8 pDSBuffer, LONG lPitch, - DWORD &Xb_Frequency) + XTL::CDirectSoundVoice* Xb_Voice) { + Xb_Voice->SetPitch(Xb_Voice, lPitch); // Convert pitch back to frequency - // NOTE: pitch = 0 is equal to 48 KHz. - Xb_Frequency = static_cast(exp((lPitch / 4096.0f) * log(2)) * 48000.0f); + uint32_t setFrequency = XTL::converter_pitch2freq(lPitch); - /* For research purpose of how to convert frequency to pitch and back to frequency. - // Edit hertz variable to see the result. - float hertz = 12000.0f; - - float hertzRatio = 48000.0f; - float pitchRatio = 4096.0f; - - // Convert hertz to pitch - float pitch = log2(hertz / hertzRatio) * pitchRatio; - - // Convert pitch to hertz - hertz = exp((pitch / pitchRatio) * log(2)) * hertzRatio;*/ - - RETURN_RESULT_CHECK(pDSBuffer->SetFrequency(Xb_Frequency)); + RETURN_RESULT_CHECK(pDSBuffer->SetFrequency(setFrequency)); } /* //Only has one function, this is not a requirement. @@ -1431,7 +1431,8 @@ static inline HRESULT HybridDirectSoundBuffer_SetVolume( DWORD dwEmuFlags, LPLONG Xb_lpVolume, LONG Xb_volumeMixbin, - DWORD Xb_dwHeadroom) + DWORD Xb_dwHeadroom, + XTL::CDirectSoundVoice* Xb_Voice) { // Preserve original volume if (Xb_lpVolume != xbnullptr) { diff --git a/src/core/hle/DSOUND/DirectSound/DirectSoundStream.cpp b/src/core/hle/DSOUND/DirectSound/DirectSoundStream.cpp index 2291875f6..7617ffc00 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSoundStream.cpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSoundStream.cpp @@ -70,9 +70,9 @@ XTL::X_CDirectSoundStream::_vtbl XTL::X_CDirectSoundStream::vtbl = &XTL::EMUPATCH(CDirectSoundStream_Process), // 0x10 &XTL::EMUPATCH(CDirectSoundStream_Discontinuity), // 0x14 &XTL::EMUPATCH(CDirectSoundStream_Flush), // 0x18 - 0xBEEFB003, // 0x1C - 0xBEEFB004, // 0x20 - 0xBEEFB005, // 0x24 + 0xBEEFB003, // 0x1C // unknown function + 0xBEEFB004, // 0x20 // DS_CRefCount_AddRef + 0xBEEFB005, // 0x24 // DS_CRefCount_Release 0xBEEFB006, // 0x28 0xBEEFB007, // 0x2C 0xBEEFB008, // 0x30 @@ -208,8 +208,6 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateStream) hRet = DSERR_OUTOFMEMORY; *ppStream = xbnullptr; } else { - // TODO: Garbage Collection - *ppStream = new X_CDirectSoundStream(); DSBUFFERDESC DSBufferDesc = { 0 }; @@ -230,12 +228,16 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateStream) DSBufferDesc.dwFlags |= DSBCAPS_CTRLPAN; } + // TODO: Garbage Collection + *ppStream = new X_CDirectSoundStream((DSBufferDesc.dwFlags & DSBCAPS_CTRL3D) != 0); + DSoundBufferSetDefault((*ppStream), DSBPLAY_LOOPING, pdssd->dwFlags); (*ppStream)->Xb_rtFlushEx = 0LL; // We have to set DSBufferDesc last due to EmuFlags must be either 0 or previously written value to preserve other flags. GeneratePCMFormat(DSBufferDesc, pdssd->lpwfxFormat, pdssd->dwFlags, (*ppStream)->EmuFlags, 0, - xbnullptr, (*ppStream)->X_BufferCacheSize, (*ppStream)->Xb_VoiceProperties, pdssd->lpMixBinsOutput); + xbnullptr, (*ppStream)->X_BufferCacheSize, (*ppStream)->Xb_VoiceProperties, pdssd->lpMixBinsOutput, + &(*ppStream)->Xb_Voice); // Test case: Star Wars: KotOR has one packet greater than 5 seconds worth. Increasing to 10 seconds allow stream to work until // another test case below proven host's buffer size does not matter since packet's size can be greater than host's buffer size. @@ -276,7 +278,7 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateStream) // Pre-set volume to enforce silence if one of audio codec is disabled. HybridDirectSoundBuffer_SetVolume((*ppStream)->EmuDirectSoundBuffer8, 0L, (*ppStream)->EmuFlags, nullptr, - (*ppStream)->Xb_VolumeMixbin, (*ppStream)->Xb_dwHeadroom); + (*ppStream)->Xb_VolumeMixbin, (*ppStream)->Xb_dwHeadroom, &(*ppStream)->Xb_Voice); g_pDSoundStreamCache.push_back(*ppStream); } @@ -912,7 +914,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetFormat) pThis->EmuBufferDesc, pThis->EmuFlags, pThis->EmuPlayFlags, pThis->EmuDirectSound3DBuffer8, 0, pThis->X_BufferCache, pThis->X_BufferCacheSize, pThis->Xb_VoiceProperties, - xbnullptr, pThis->Xb_Frequency); + xbnullptr, &pThis->Xb_Voice); return hRet; } @@ -932,7 +934,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetFrequency) LOG_FUNC_ARG(dwFrequency) LOG_FUNC_END; - HRESULT hRet = HybridDirectSoundBuffer_SetFrequency(pThis->EmuDirectSoundBuffer8, dwFrequency, pThis->Xb_Frequency); + HRESULT hRet = HybridDirectSoundBuffer_SetFrequency(pThis->EmuDirectSoundBuffer8, dwFrequency, &pThis->Xb_Voice); return hRet; } @@ -968,7 +970,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetHeadroom) LOG_FUNC_END; HRESULT hRet = HybridDirectSoundBuffer_SetHeadroom(pThis->EmuDirectSoundBuffer8, dwHeadroom, pThis->Xb_dwHeadroom, - pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->EmuFlags); + pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->EmuFlags, &pThis->Xb_Voice); return hRet; } @@ -1208,7 +1210,8 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetMixBinVolumes_8) LOG_FUNC_END; HRESULT hRet = HybridDirectSoundBuffer_SetMixBinVolumes_8(pThis->EmuDirectSoundBuffer8, pMixBins, pThis->Xb_VoiceProperties, - pThis->EmuFlags, pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom); + pThis->EmuFlags, pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom, + &pThis->Xb_Voice); return hRet; } @@ -1219,7 +1222,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetMixBinVolumes_8) HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetOutputBuffer) ( X_CDirectSoundStream* pThis, - X_CDirectSoundBuffer* pOutputBuffer) + XbHybridDSBuffer* pOutputBuffer) { DSoundMutexGuardLock; @@ -1252,7 +1255,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetPitch) LOG_FUNC_ARG(lPitch) LOG_FUNC_END; - HRESULT hRet = HybridDirectSoundBuffer_SetPitch(pThis->EmuDirectSoundBuffer8, lPitch, pThis->Xb_Frequency); + HRESULT hRet = HybridDirectSoundBuffer_SetPitch(pThis->EmuDirectSoundBuffer8, lPitch, &pThis->Xb_Voice); return hRet; } @@ -1388,7 +1391,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetVolume) LOG_FUNC_END; HRESULT hRet = HybridDirectSoundBuffer_SetVolume(pThis->EmuDirectSoundBuffer8, lVolume, pThis->EmuFlags, &pThis->Xb_Volume, - pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom); + pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom, &pThis->Xb_Voice); return hRet; } diff --git a/src/core/hle/DSOUND/XbDSoundTypes.h b/src/core/hle/DSOUND/XbDSoundTypes.h index 62ea3a782..b86fdef36 100644 --- a/src/core/hle/DSOUND/XbDSoundTypes.h +++ b/src/core/hle/DSOUND/XbDSoundTypes.h @@ -369,6 +369,30 @@ struct X_DSVOICEPROPS { LONG lI3DL2DirectVolume; LONG lI3DL2RoomVolume; }; + +// Convert frequency to pitch helper +static inline int32_t converter_freq2pitch(uint32_t freq) { + // NOTE: pitch = 0 is equal to 48 KHz. + /* For research purpose of how to convert frequency to pitch and back to frequency. + // Edit hertz variable to see the result. + float hertz = 12000.0f; + + float hertzRatio = 48000.0f; + float pitchRatio = 4096.0f; + + // Convert hertz to pitch + float pitch = log2(hertz / hertzRatio) * pitchRatio; + + // Convert pitch to hertz + hertz = exp((pitch / pitchRatio) * log(2)) * hertzRatio;*/ + return static_cast(log2(freq / 48000.0f) * 4096.0f); +} + +// Convert pitch to frequency helper +static inline uint32_t converter_pitch2freq(int32_t pitch) { + //* See research documentation above for conversion example. + return static_cast(exp((pitch / 4096.0f) * log(2)) * 48000.0f); +} } // end of namespace XTL diff --git a/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp b/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp new file mode 100644 index 000000000..caec8e570 --- /dev/null +++ b/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp @@ -0,0 +1,272 @@ +// ****************************************************************** +// * +// * This file is part of the Cxbx project. +// * +// * Cxbx and Cxbe are free software; you can redistribute them +// * and/or modify them under the terms of the GNU General Public +// * License as published by the Free Software Foundation; either +// * version 2 of the license, or (at your option) any later version. +// * +// * This program 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 General Public License for more details. +// * +// * You should have recieved a copy of the GNU General Public License +// * along with this program; see the file COPYING. +// * If not, write to the Free Software Foundation, Inc., +// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// * +// * (c) 2020 RadWolfie +// * +// * All rights reserved +// * +// ****************************************************************** + +#include "common\Settings.hpp" // for g_LibVersion_DSOUND +#include "XbInternalStruct.hpp" + +// Interface for get format +void GetFormat_4034_lower(XTL::CDirectSoundVoice::_u& u, XTL::audio_format& format) +{ + format.audio_codec = u.settings_4034_lower.p_audio_format->wfx.wFormatTag = format.audio_codec; + format.nChannels = u.settings_4034_lower.p_audio_format->wfx.nChannels; + format.cbSize = u.settings_4034_lower.p_audio_format->wfx.cbSize; + format.nSamplesPerSec = u.settings_4034_lower.p_audio_format->wfx.nSamplesPerSec; + format.bitsPerSample = u.settings_4034_lower.p_audio_format->wfx.wBitsPerSample; +} +void GetFormat_4039_only(XTL::CDirectSoundVoice::_u& u, XTL::audio_format& format) +{ + format.audio_codec = u.settings_4039_only.audio_codec; + format.nChannels = u.settings_4039_only.nChannels; + format.cbSize = u.settings_4039_only.cbSize; + format.nSamplesPerSec = u.settings_4039_only.nSamplesPerSec_default; + format.bitsPerSample = u.settings_4039_only.bitsPerSample; +} +void GetFormat_4134_upper(XTL::CDirectSoundVoice::_u& u, XTL::audio_format& format) +{ + format.audio_codec = u.settings_4134_upper.audio_codec; + format.nChannels = u.settings_4134_upper.nChannels; + format.cbSize = u.settings_4134_upper.cbSize; + format.nSamplesPerSec = u.settings_4134_upper.nSamplesPerSec_default; + format.bitsPerSample = u.settings_4134_upper.bitsPerSample; +} + +// Interface for set format +void SetFormat_4034_lower(XTL::CDirectSoundVoice::_u& u, XTL::audio_format format) +{ + u.settings_4034_lower.p_audio_format->wfx.wFormatTag = format.audio_codec; + u.settings_4034_lower.p_audio_format->wfx.nChannels = static_cast(format.nChannels); + u.settings_4034_lower.p_audio_format->wfx.cbSize = static_cast(format.cbSize); + u.settings_4034_lower.p_audio_format->wfx.nSamplesPerSec = format.nSamplesPerSec; + u.settings_4034_lower.p_audio_format->wfx.wBitsPerSample = static_cast(format.bitsPerSample); + if (format.audio_codec == WAVE_FORMAT_XBOX_ADPCM) { + u.settings_4034_lower.p_audio_format->wSamplesPerBlock = 64; + } + u.settings_4039_only.pitch = XTL::converter_freq2pitch(format.nSamplesPerSec); +} +void SetFormat_4039_only(XTL::CDirectSoundVoice::_u& u, XTL::audio_format format) +{ + u.settings_4039_only.audio_codec = format.audio_codec; + u.settings_4039_only.nChannels = format.nChannels; + u.settings_4039_only.cbSize = format.cbSize; + u.settings_4039_only.nSamplesPerSec_default = format.nSamplesPerSec; + u.settings_4039_only.bitsPerSample = format.bitsPerSample; + u.settings_4039_only.pitch = XTL::converter_freq2pitch(format.nSamplesPerSec); +} +void SetFormat_4134_upper(XTL::CDirectSoundVoice::_u& u, XTL::audio_format format) +{ + u.settings_4134_upper.audio_codec = static_cast(format.audio_codec); + u.settings_4134_upper.nChannels = static_cast(format.nChannels); + u.settings_4134_upper.cbSize = static_cast(format.cbSize); + u.settings_4134_upper.nSamplesPerSec_default = format.nSamplesPerSec; + u.settings_4134_upper.bitsPerSample = format.bitsPerSample; + u.settings_4134_upper.pitch = XTL::converter_freq2pitch(format.nSamplesPerSec); +} + +// Interface for get frequency +uint32_t GetFrequencyDefault_4034_lower(XTL::CDirectSoundVoice::_u& u) +{ + return u.settings_4034_lower.p_audio_format->wfx.nSamplesPerSec; +} +uint32_t GetFrequencyDefault_4039_only(XTL::CDirectSoundVoice::_u& u) +{ + return u.settings_4039_only.nSamplesPerSec_default; +} +uint32_t GetFrequencyDefault_4134_upper(XTL::CDirectSoundVoice::_u& u) +{ + return u.settings_4134_upper.nSamplesPerSec_default; +} + +// Interface for get pitch +int32_t GetPitch_4034_lower(XTL::CDirectSoundVoice::_u& u) +{ + return u.settings_4034_lower.pitch; +} +int32_t GetPitch_4039_only(XTL::CDirectSoundVoice::_u& u) +{ + return u.settings_4039_only.pitch; +} +int32_t GetPitch_4134_upper(XTL::CDirectSoundVoice::_u& u) +{ + return u.settings_4134_upper.pitch; +} + +// Interface for set pitch +void SetPitch_4034_lower(XTL::CDirectSoundVoice::_u& u, int32_t pitch) +{ + u.settings_4034_lower.pitch = pitch; +} +void SetPitch_4039_only(XTL::CDirectSoundVoice::_u& u, int32_t pitch) +{ + u.settings_4039_only.pitch = pitch; +} +void SetPitch_4134_upper(XTL::CDirectSoundVoice::_u& u, int32_t pitch) +{ + u.settings_4134_upper.pitch = pitch; +} + +// Interface for get volume +uint32_t GetVolume_4034_lower(XTL::CDirectSoundVoice::_u& u) +{ + return u.settings_4034_lower.volume; +} +uint32_t GetVolume_4039_only(XTL::CDirectSoundVoice::_u& u) +{ + return u.settings_4039_only.volume; +} +uint32_t GetVolume_4134_upper(XTL::CDirectSoundVoice::_u& u) +{ + return u.settings_4134_upper.volume; +} + +void SetVolume_calc(uint32_t& cur_volume, uint32_t headroom, uint32_t set_volume) +{ + cur_volume = set_volume - headroom; +} +// Interface for set volume +void SetVolume_4034_lower(XTL::CDirectSoundVoice::_u& u, uint32_t volume) +{ + SetVolume_calc(u.settings_4034_lower.volume, u.settings_4034_lower.headroom, volume); +} +void SetVolume_4039_only(XTL::CDirectSoundVoice::_u& u, uint32_t volume) +{ + SetVolume_calc(u.settings_4039_only.volume, u.settings_4039_only.headroom, volume); +} +void SetVolume_4134_upper(XTL::CDirectSoundVoice::_u& u, uint32_t volume) +{ + SetVolume_calc(u.settings_4134_upper.volume, u.settings_4134_upper.headroom, volume); +} + +// Interface for get headroom +uint32_t GetHeadroom_4034_lower(XTL::CDirectSoundVoice::_u& u) +{ + return u.settings_4034_lower.headroom; +} +uint32_t GetHeadroom_4039_only(XTL::CDirectSoundVoice::_u& u) +{ + return u.settings_4039_only.headroom; +} +uint32_t GetHeadroom_4134_upper(XTL::CDirectSoundVoice::_u& u) +{ + return u.settings_4134_upper.headroom; +} + +void SetHeadroom_calc(uint32_t& cur_headroom, uint32_t& volume, uint32_t set_headroom) +{ + volume = volume - set_headroom - cur_headroom; + cur_headroom = set_headroom; +} +// Interface for set headroom +void SetHeadroom_4034_lower(XTL::CDirectSoundVoice::_u& u, uint32_t headroom) +{ + SetHeadroom_calc(u.settings_4034_lower.headroom, u.settings_4034_lower.volume, headroom); +} +void SetHeadroom_4039_only(XTL::CDirectSoundVoice::_u& u, uint32_t headroom) +{ + SetHeadroom_calc(u.settings_4039_only.headroom, u.settings_4039_only.volume, headroom); +} +void SetHeadroom_4134_upper(XTL::CDirectSoundVoice::_u& u, uint32_t headroom) +{ + SetHeadroom_calc(u.settings_4134_upper.headroom, u.settings_4134_upper.volume, headroom); +} + +void Init_Headroom(uint32_t& headroom, bool is3D) +{ + headroom = is3D? 0 : 600; +} +void Init_4034_lower(XTL::CDirectSoundVoice::_u::_settings_4034_lower& settings, bool is3D) +{ + Init_Headroom(settings.headroom, is3D); + settings.volume = 0 - settings.headroom; +} +void Init_4039_only(XTL::CDirectSoundVoice::_u::_settings_4039_only& settings, bool is3D) +{ + Init_Headroom(settings.headroom, is3D); + settings.volume = 0 - settings.headroom; +} +void Init_4134_upper(XTL::CDirectSoundVoice::_u::_settings_4134_upper& settings, bool is3D) +{ + Init_Headroom(settings.headroom, is3D); + settings.volume = 0 - settings.headroom; +} + +XTL::CDirectSoundVoice::CDirectSoundVoice(bool is3D) +{ + memset(u.settings_interface.unknown_08, 0, sizeof(u.settings_interface)); + + if (g_LibVersion_DSOUND < 4039) { + u.settings_4034_lower.p_audio_format = new XBOXADPCMWAVEFORMAT; + memset(&u.settings_4034_lower.p_audio_format->wfx, 0, sizeof(XBOXADPCMWAVEFORMAT)); + + Init_4034_lower(u.settings_4034_lower, is3D); + + funcs.GetFormat = GetFormat_4034_lower; + funcs.SetFormat = SetFormat_4034_lower; + funcs.GetFrequencyDefault = GetFrequencyDefault_4034_lower; + funcs.GetPitch = GetPitch_4034_lower; + funcs.SetPitch = SetPitch_4034_lower; + funcs.GetVolume = GetVolume_4034_lower; + funcs.SetVolume = SetVolume_4034_lower; + funcs.GetHeadroom = GetHeadroom_4034_lower; + funcs.SetHeadroom = SetHeadroom_4034_lower; + } + else if (g_LibVersion_DSOUND == 4039) { + + Init_4039_only(u.settings_4039_only, is3D); + + funcs.GetFormat = GetFormat_4039_only; + funcs.SetFormat = SetFormat_4039_only; + funcs.GetFrequencyDefault = GetFrequencyDefault_4039_only; + funcs.GetPitch = GetPitch_4039_only; + funcs.SetPitch = SetPitch_4039_only; + funcs.GetVolume = GetVolume_4039_only; + funcs.SetVolume = SetVolume_4039_only; + funcs.GetHeadroom = GetHeadroom_4039_only; + funcs.SetHeadroom = SetHeadroom_4039_only; + } + else { + + Init_4134_upper(u.settings_4134_upper, is3D); + + funcs.GetFormat = GetFormat_4134_upper; + funcs.SetFormat = SetFormat_4134_upper; + funcs.GetFrequencyDefault = GetFrequencyDefault_4134_upper; + funcs.GetPitch = GetPitch_4134_upper; + funcs.SetPitch = SetPitch_4134_upper; + funcs.GetVolume = GetVolume_4134_upper; + funcs.SetVolume = SetVolume_4134_upper; + funcs.GetHeadroom = GetHeadroom_4134_upper; + funcs.SetHeadroom = SetHeadroom_4134_upper; + } +} + +XTL::CDirectSoundVoice::~CDirectSoundVoice() +{ + if (g_LibVersion_DSOUND < 4039) { + if (!u.settings_4034_lower.p_audio_format) { + delete u.settings_4034_lower.p_audio_format; + u.settings_4034_lower.p_audio_format = nullptr; + } + } +} diff --git a/src/core/hle/DSOUND/common/XbInternalStruct.cpp b/src/core/hle/DSOUND/common/XbInternalStruct.cpp new file mode 100644 index 000000000..251a62e1b --- /dev/null +++ b/src/core/hle/DSOUND/common/XbInternalStruct.cpp @@ -0,0 +1,34 @@ +// ****************************************************************** +// * +// * This file is part of the Cxbx project. +// * +// * Cxbx and Cxbe are free software; you can redistribute them +// * and/or modify them under the terms of the GNU General Public +// * License as published by the Free Software Foundation; either +// * version 2 of the license, or (at your option) any later version. +// * +// * This program 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 General Public License for more details. +// * +// * You should have recieved a copy of the GNU General Public License +// * along with this program; see the file COPYING. +// * If not, write to the Free Software Foundation, Inc., +// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// * +// * (c) 2020 RadWolfie +// * +// * All rights reserved +// * +// ****************************************************************** + +#include "XbInternalStruct.hpp" + +XTL::CUnknownTemplate::CUnknownTemplate() { ref_count = 1; } + +XTL::CMcpxVoiceClient::_settings XTL::CMcpxVoiceClient::default_settings = +{ + 0, // 0x08 + // ... +}; diff --git a/src/core/hle/DSOUND/common/XbInternalStruct.hpp b/src/core/hle/DSOUND/common/XbInternalStruct.hpp new file mode 100644 index 000000000..58481151c --- /dev/null +++ b/src/core/hle/DSOUND/common/XbInternalStruct.hpp @@ -0,0 +1,227 @@ +// ****************************************************************** +// * +// * This file is part of the Cxbx project. +// * +// * Cxbx and Cxbe are free software; you can redistribute them +// * and/or modify them under the terms of the GNU General Public +// * License as published by the Free Software Foundation; either +// * version 2 of the license, or (at your option) any later version. +// * +// * This program 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 General Public License for more details. +// * +// * You should have recieved a copy of the GNU General Public License +// * along with this program; see the file COPYING. +// * If not, write to the Free Software Foundation, Inc., +// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// * +// * (c) 2020 RadWolfie +// * +// * All rights reserved +// * +// ****************************************************************** +#pragma once + +#include "Cxbx.h" +#include "core\hle\DSOUND\XbDSoundTypes.h" + +namespace XTL { + +// TODO: Everything, only small portions had been implemented. + +struct audio_format { + uint32_t audio_codec; + uint32_t nChannels; + uint32_t cbSize; + int32_t nSamplesPerSec; + uint32_t bitsPerSample; +}; + +struct CUnknownGenericManager { + // construct vtable (or grab ptr to existing) + CUnknownGenericManager() : ref_count(1) {} + + // all virtual functions are stored in local offset 0x00's pointer + virtual ~CUnknownGenericManager() {}; // 0x00 + virtual uint32_t WINAPI AddRef() { return ++ref_count; }; // 0x04 + virtual uint32_t WINAPI Release() { return --ref_count; }; // 0x08 + + uint32_t ref_count; // 0x04 +}; +static_assert(sizeof(CUnknownGenericManager) == 0x08); + +struct CUnknownTemplate { + // construct vtable (or grab ptr to existing) + CUnknownTemplate(); + + virtual ~CUnknownTemplate() {}; // 0x00 + virtual void WINAPI pUnknown_04() { throw std::exception("pUnknown_04"); }; // 0x04 + virtual void WINAPI pUnknown_08() { throw std::exception("pUnknown_08"); }; // 0x08 + virtual void WINAPI pUnknown_0C() { throw std::exception("pUnknown_0C"); }; // 0x0C + virtual void WINAPI pUnknown_10() { throw std::exception("pUnknown_10"); }; // 0x10 + virtual void WINAPI pUnknown_14() { throw std::exception("pUnknown_14"); }; // 0x14 + virtual void WINAPI pUnknown_18() { throw std::exception("pUnknown_18"); }; // 0x18 + virtual void WINAPI pUnknown_1C() { throw std::exception("pUnknown_1C"); }; // 0x1C + // If need to add more virtual functions, add them above here. + uint32_t ref_count; // 0x04 +}; +static_assert(sizeof(CUnknownTemplate) == 0x08); + +struct CMcpxVoiceClient: CUnknownTemplate { + CMcpxVoiceClient() : settings(default_settings) {}; + // all virtual functions are stored in local offset 0x00's pointer + virtual ~CMcpxVoiceClient() {}; + + // CUnknownTemplate // 0x00 - ??? + struct _settings + { + uint32_t Unknown2[(0x300-8)/4]; // 0x08 - ??? + } + settings; + + // global _settings for this class + static _settings default_settings; +}; +static_assert(sizeof(CMcpxVoiceClient) == 0x300); + +struct CDirectSoundVoice : CUnknownGenericManager { + CDirectSoundVoice(bool is3D); + // all virtual functions are stored in local offset 0x00's pointer + virtual ~CDirectSoundVoice(); + + // CUnknownGenericManager // 0x00 - ??? + union _u { + struct _settings_interface + { + uint32_t unknown_08[0x300 / 4]; // 0x000 - 0x300 (unknown size, likely over 0x200 size. + } settings_interface; + + struct _settings_4034_lower { + xbaddr p_unknown_08; // 0x008 + uint16_t unknown_0C; // 0x00C // zero'd - unknown + XBOXADPCMWAVEFORMAT* p_audio_format; // 0x010 // Same as XBOXADPCMWAVEFORMAT / WAVEFORMATEX structure + uint32_t pitch; // 0x014 // Always init and custom pitch from SetFrequency, SetPitch, SetFormat, etc calls. + uint32_t volume; // 0x018 // default: (set volume - headroom) + uint32_t headroom; // 0x01C // default: (set headroom then update volume) + } settings_4034_lower; + + struct _settings_4039_only { + uint32_t unknown_08; // 0x008 + uint32_t audio_codec; // 0x00C // Setter is 32 bit, yet getter is 16 bit integer reader + uint32_t nChannels; // 0x010 + uint32_t cbSize; // 0x014 + int32_t nSamplesPerSec_default; // 0x018 // Always original frequency for check if SetFrequency is given with 0 then use original one. + uint32_t bitsPerSample; // 0x01C + uint32_t pitch; // 0x020 // Always init and custom pitch from SetFrequency, SetPitch, SetFormat, etc calls. + uint32_t volume; // 0x024 // (set volume - headroom) + uint32_t headroom; // 0x028 // (set headroom then update volume) + uint32_t unknown_2C[(0x300 - 0x2C) / 4]; // 0x02C - 0x300 (unknown size, likely over 0x200 size. + } settings_4039_only; + + struct _settings_4134_upper { + uint32_t unknown_08; // 0x008 + uint16_t audio_codec; // 0x00C + uint8_t nChannels; // 0x00E + uint8_t cbSize; // 0x00F + uint32_t nSamplesPerSec_default; // 0x010 // Always original frequency for check if SetFrequency is given with 0 then use original one. + uint32_t bitsPerSample; // 0x014 + int32_t pitch; // 0x018 // Always init and custom pitch from SetFrequency, SetPitch, SetFormat, etc calls. + uint32_t volume; // 0x01C // (set volume - headroom) + uint32_t headroom; // 0x020 // (set headroom then update volume) + uint32_t unknown_24[(0x300 - 0x24) / 4]; // 0x024 - 0x300 (unknown size, likely over 0x200 size. + } settings_4134_upper; + } u; + static_assert(sizeof(_u) == 0x300); + + struct { + void (*GetFormat)(_u& u, audio_format& format); + void (*SetFormat)(_u& u, audio_format format); + uint32_t (*GetFrequencyDefault)(_u& u); + int32_t (*GetPitch)(_u& u); + void (*SetPitch)(_u& u, int32_t pitch); + uint32_t (*GetVolume)(_u& u); + void (*SetVolume)(_u& u, uint32_t volume); + uint32_t (*GetHeadroom)(_u& u); + void (*SetHeadroom)(_u& u, uint32_t headroom); + } funcs; + static_assert(sizeof(funcs) == 0x24); + + static inline void GetFormat(CDirectSoundVoice* pThis, audio_format& format) { + pThis->funcs.GetFormat(pThis->u, format); + }; + static inline void SetFormat(CDirectSoundVoice* pThis, audio_format format) { + pThis->funcs.SetFormat(pThis->u, format); + }; + static inline uint32_t GetFrequencyDefault(CDirectSoundVoice* pThis) { + return pThis->funcs.GetFrequencyDefault(pThis->u); + }; + static inline int32_t GetPitch(CDirectSoundVoice* pThis) { + return pThis->funcs.GetPitch(pThis->u); + }; + static inline void SetPitch(CDirectSoundVoice* pThis, int32_t pitch) { + pThis->funcs.SetPitch(pThis->u, pitch); + }; + static inline uint32_t GetVolume(CDirectSoundVoice* pThis) { + return pThis->funcs.GetVolume(pThis->u); + }; + static inline void SetVolume(CDirectSoundVoice* pThis, uint32_t volume) { + pThis->funcs.SetVolume(pThis->u, volume); + }; + static inline uint32_t GetHeadroom(CDirectSoundVoice* pThis) { + return pThis->funcs.GetHeadroom(pThis->u); + }; + static inline void SetHeadroom(CDirectSoundVoice* pThis, uint32_t headroom) { + pThis->funcs.SetHeadroom(pThis->u, headroom); + }; +}; +static_assert(sizeof(CDirectSoundVoice) == sizeof(CUnknownGenericManager) + sizeof(CDirectSoundVoice::_u) + sizeof(CDirectSoundVoice::funcs)); + +struct DSBUFFER_S : CUnknownTemplate { + + // CUnknownTemplate unknown_00; // Offset 0x00 // -0x1C + struct DSBUFFER_C { + uint32_t unknown_08; // Offset 0x08 // -0x14 + CMcpxVoiceClient* p_CMcpxVoiceClient; // Offset 0x0C // -0x10 + CDirectSoundVoice* p_CDSVoice; // Offset 0x10 // -0x0C + xbaddr p_unknown_14; // Offset 0x14 // -0x08 // (points to this address) + xbaddr p_unknown_18; // Offset 0x18 // -0x04 // (points to above address) + } dsb_c; + static_assert(sizeof(DSBUFFER_C) == 0x14); + + struct DSBUFFER_I { + CDirectSoundVoice* p_CDSVoice; // Offset 0x1C // 0x00 // Same as p_CDSVoice (above); pThis + CMcpxVoiceClient* p_CMcpxVoiceClient; // Offset 0x20 // 0x04 // Same as p_CMcpxVoiceClient (above) + xbaddr p_unknown_24; // Offset 0x24 // 0x08 + xbaddr p_unknown_28; // Offset 0x28 // 0x0C + uint32_t unknown_2C; // Offset 0x2C // 0x10 // was integer, later shift to offset 0x30 + uint32_t unknown_30; // Offset 0x30 // 0x14 // later shifted from offset 0x2C; integer + } dsb_i; + static_assert(sizeof(DSBUFFER_I) == 0x18); + + DSBUFFER_S(bool is3D) { + init(is3D); + } + virtual ~DSBUFFER_S() { + delete dsb_c.p_CMcpxVoiceClient; + delete dsb_c.p_CDSVoice; + } + virtual void init_member() { + dsb_c.unknown_08 = 0; + dsb_i.p_unknown_24 = xbnull; + dsb_i.p_unknown_28 = xbnull; + dsb_i.unknown_2C = xbnull; + dsb_i.unknown_30 = xbnull; + } + virtual void init(bool is3D) { + init_member(); + dsb_c.p_CMcpxVoiceClient = new CMcpxVoiceClient(); dsb_i.p_CMcpxVoiceClient = dsb_c.p_CMcpxVoiceClient; + dsb_c.p_CDSVoice = new CDirectSoundVoice(is3D); dsb_i.p_CDSVoice = dsb_c.p_CDSVoice; + dsb_c.p_unknown_18 = reinterpret_cast(&dsb_c.p_unknown_14); + dsb_c.p_unknown_14 = dsb_c.p_unknown_18; + } +}; +static_assert(sizeof(DSBUFFER_S) == 0x34); + +} From ab142abd693fe5c7e65cb31f087cb727416b519b Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Fri, 1 May 2020 06:26:08 -0500 Subject: [PATCH 03/19] forward headroom setter to voice --- .../hle/DSOUND/DirectSound/DirectSound.hpp | 6 ++--- .../DSOUND/DirectSound/DirectSoundBuffer.cpp | 13 +++++----- .../DSOUND/DirectSound/DirectSoundInline.hpp | 24 +++++++------------ .../DSOUND/DirectSound/DirectSoundStream.cpp | 13 +++++----- 4 files changed, 23 insertions(+), 33 deletions(-) diff --git a/src/core/hle/DSOUND/DirectSound/DirectSound.hpp b/src/core/hle/DSOUND/DirectSound/DirectSound.hpp index 68ecebf82..ceac24f95 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSound.hpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSound.hpp @@ -104,8 +104,7 @@ struct EmuDirectSoundBuffer REFERENCE_TIME Xb_rtPauseEx; REFERENCE_TIME Xb_rtStopEx; LONG Xb_Volume; - LONG Xb_VolumeMixbin; - DWORD Xb_dwHeadroom; + LONG Xb_VolumeMixbin; X_DSENVOLOPEDESC Xb_EnvolopeDesc; X_DSVOICEPROPS Xb_VoiceProperties; DWORD Xb_Flags; @@ -273,8 +272,7 @@ class X_CDirectSoundStream REFERENCE_TIME Xb_rtFlushEx; REFERENCE_TIME Xb_rtPauseEx; LONG Xb_Volume; - LONG Xb_VolumeMixbin; - DWORD Xb_dwHeadroom; + LONG Xb_VolumeMixbin; X_DSENVOLOPEDESC Xb_EnvolopeDesc; X_DSVOICEPROPS Xb_VoiceProperties; DWORD Host_dwLastWritePos; diff --git a/src/core/hle/DSOUND/DirectSound/DirectSoundBuffer.cpp b/src/core/hle/DSOUND/DirectSound/DirectSoundBuffer.cpp index a3053c4e7..6af783082 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSoundBuffer.cpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSoundBuffer.cpp @@ -240,14 +240,13 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateBuffer) else { if (pdsbd->dwFlags & DSBCAPS_CTRL3D) { DSound3DBufferCreate(pEmuBuffer->EmuDirectSoundBuffer8, pEmuBuffer->EmuDirectSound3DBuffer8); - pEmuBuffer->Xb_dwHeadroom = 0; // Default for 3D } DSoundDebugMuteFlag(pEmuBuffer->X_BufferCacheSize, pEmuBuffer->EmuFlags); // Pre-set volume to enforce silence if one of audio codec is disabled. - HybridDirectSoundBuffer_SetVolume(pEmuBuffer->EmuDirectSoundBuffer8, 0L, pEmuBuffer->EmuFlags, nullptr, - pEmuBuffer->Xb_VolumeMixbin, pEmuBuffer->Xb_dwHeadroom, pHybridBuffer->p_CDSVoice); + HybridDirectSoundBuffer_SetVolume(pEmuBuffer->EmuDirectSoundBuffer8, 0L, pEmuBuffer->EmuFlags, + pEmuBuffer->Xb_VolumeMixbin, pHybridBuffer->p_CDSVoice); g_pDSoundBufferCache.push_back(pHybridBuffer); } @@ -1001,7 +1000,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetHeadroom) LOG_FUNC_END; EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; - HRESULT hRet = HybridDirectSoundBuffer_SetHeadroom(pThis->EmuDirectSoundBuffer8, dwHeadroom, pThis->Xb_dwHeadroom, + HRESULT hRet = HybridDirectSoundBuffer_SetHeadroom(pThis->EmuDirectSoundBuffer8, dwHeadroom, pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->EmuFlags, pHybridThis->p_CDSVoice); @@ -1221,7 +1220,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMixBinVolumes_8) EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = HybridDirectSoundBuffer_SetMixBinVolumes_8(pThis->EmuDirectSoundBuffer8, pMixBins, pThis->Xb_VoiceProperties, - pThis->EmuFlags, pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom, + pThis->EmuFlags, pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pHybridThis->p_CDSVoice); return hRet; @@ -1507,8 +1506,8 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetVolume) LOG_FUNC_END; EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; - HRESULT hRet = HybridDirectSoundBuffer_SetVolume(pThis->EmuDirectSoundBuffer8, lVolume, pThis->EmuFlags, &pThis->Xb_Volume, - pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom, pHybridThis->p_CDSVoice); + HRESULT hRet = HybridDirectSoundBuffer_SetVolume(pThis->EmuDirectSoundBuffer8, lVolume, pThis->EmuFlags, + pThis->Xb_VolumeMixbin, pHybridThis->p_CDSVoice); return hRet; } diff --git a/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp b/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp index f648d9abb..9bedb165c 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp @@ -394,7 +394,6 @@ static inline void DSound3DBufferCreate(LPDIRECTSOUNDBUFFER8 pDSBuffer, LPDIRECT pThis->Xb_rtPauseEx = 0LL; \ pThis->Xb_Volume = 0L; \ pThis->Xb_VolumeMixbin = 0L; \ - pThis->Xb_dwHeadroom = 600; /* default for 2D voice */ \ pThis->Xb_EnvolopeDesc = { 0 }; \ InitVoiceProperties(pThis->Xb_VoiceProperties); /* The rest will initialize in GeneratePCMFormat to GenerateMixBinDefault. */ \ pThis->Xb_Flags = Xb_dwFlags; @@ -1133,7 +1132,7 @@ static inline HRESULT HybridDirectSoundBuffer_SetFrequency( RETURN_RESULT_CHECK(hRet); } -static HRESULT HybridDirectSoundBuffer_SetVolume(LPDIRECTSOUNDBUFFER8, LONG, DWORD, LPLONG, LONG, DWORD, XTL::CDirectSoundVoice*); +static HRESULT HybridDirectSoundBuffer_SetVolume(LPDIRECTSOUNDBUFFER8, LONG, DWORD, LONG, XTL::CDirectSoundVoice*); //IDirectSoundStream //IDirectSoundBuffer @@ -1141,7 +1140,6 @@ static HRESULT HybridDirectSoundBuffer_SetVolume(LPDIRECTSOUNDBUFFER8, LONG, DWO static inline HRESULT HybridDirectSoundBuffer_SetHeadroom( LPDIRECTSOUNDBUFFER8 pDSBuffer, DWORD dwHeadroom, - DWORD &Xb_dwHeadroom, LONG Xb_volume, LONG Xb_volumeMixbin, DWORD dwEmuFlags, @@ -1151,9 +1149,10 @@ static inline HRESULT HybridDirectSoundBuffer_SetHeadroom( if (dwHeadroom > 10000) { hRet = DSERR_INVALIDPARAM; } else { - Xb_dwHeadroom = dwHeadroom; hRet = DS_OK; - HybridDirectSoundBuffer_SetVolume(pDSBuffer, Xb_volume, dwEmuFlags, xbnullptr, Xb_volumeMixbin, dwHeadroom, Xb_Voice); + Xb_Voice->SetHeadroom(Xb_Voice, dwHeadroom); + uint32_t volume = Xb_Voice->GetVolume(Xb_Voice); + pDSBuffer->SetVolume(volume); } return DS_OK; @@ -1245,7 +1244,6 @@ static inline HRESULT HybridDirectSoundBuffer_SetMixBinVolumes_8( DWORD EmuFlags, LONG Xb_volume, LONG &Xb_volumeMixBin, - DWORD Xb_dwHeadroom, XTL::CDirectSoundVoice* Xb_Voice) { HRESULT hRet = DSERR_INVALIDPARAM; @@ -1286,8 +1284,8 @@ static inline HRESULT HybridDirectSoundBuffer_SetMixBinVolumes_8( } if (counter > 0) { Xb_volumeMixBin = volume / (LONG)counter; - hRet = HybridDirectSoundBuffer_SetVolume(pDSBuffer, Xb_volume, EmuFlags, nullptr, - Xb_volumeMixBin, Xb_dwHeadroom, Xb_Voice); + hRet = HybridDirectSoundBuffer_SetVolume(pDSBuffer, Xb_volume, EmuFlags, + Xb_volumeMixBin, Xb_Voice); } else { hRet = DS_OK; } @@ -1429,22 +1427,18 @@ static inline HRESULT HybridDirectSoundBuffer_SetVolume( LPDIRECTSOUNDBUFFER8 pDSBuffer, LONG lVolume, DWORD dwEmuFlags, - LPLONG Xb_lpVolume, LONG Xb_volumeMixbin, - DWORD Xb_dwHeadroom, XTL::CDirectSoundVoice* Xb_Voice) { - // Preserve original volume - if (Xb_lpVolume != xbnullptr) { - *Xb_lpVolume = lVolume; - } #if 0 // TODO: Restore it once DSound work update comes up // For time being, this log is kept in case of something changed somewhere making a wrong input into the API. printf("DEBUG: SetVolume | lVolume = %ld | volumeMixbin = %ld | dwHeadroom = %8u\n", lVolume, Xb_volumeMixbin, Xb_dwHeadroom); #endif - lVolume += Xb_volumeMixbin - Xb_dwHeadroom; + Xb_Voice->SetVolume(Xb_Voice, lVolume); + lVolume = Xb_Voice->GetVolume(Xb_Voice); + lVolume += Xb_volumeMixbin; if ((dwEmuFlags & DSE_FLAG_PCM) > 0) { if (!g_XBAudio.codec_pcm) { diff --git a/src/core/hle/DSOUND/DirectSound/DirectSoundStream.cpp b/src/core/hle/DSOUND/DirectSound/DirectSoundStream.cpp index 7617ffc00..1a8261317 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSoundStream.cpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSoundStream.cpp @@ -271,14 +271,13 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateStream) else { if (DSBufferDesc.dwFlags & DSBCAPS_CTRL3D) { DSound3DBufferCreate((*ppStream)->EmuDirectSoundBuffer8, (*ppStream)->EmuDirectSound3DBuffer8); - (*ppStream)->Xb_dwHeadroom = 0; // Default for 3D } DSoundDebugMuteFlag((*ppStream)->EmuBufferDesc.dwBufferBytes, (*ppStream)->EmuFlags); // Pre-set volume to enforce silence if one of audio codec is disabled. - HybridDirectSoundBuffer_SetVolume((*ppStream)->EmuDirectSoundBuffer8, 0L, (*ppStream)->EmuFlags, nullptr, - (*ppStream)->Xb_VolumeMixbin, (*ppStream)->Xb_dwHeadroom, &(*ppStream)->Xb_Voice); + HybridDirectSoundBuffer_SetVolume((*ppStream)->EmuDirectSoundBuffer8, 0L, (*ppStream)->EmuFlags, + (*ppStream)->Xb_VolumeMixbin, &(*ppStream)->Xb_Voice); g_pDSoundStreamCache.push_back(*ppStream); } @@ -969,7 +968,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetHeadroom) LOG_FUNC_ARG(dwHeadroom) LOG_FUNC_END; - HRESULT hRet = HybridDirectSoundBuffer_SetHeadroom(pThis->EmuDirectSoundBuffer8, dwHeadroom, pThis->Xb_dwHeadroom, + HRESULT hRet = HybridDirectSoundBuffer_SetHeadroom(pThis->EmuDirectSoundBuffer8, dwHeadroom, pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->EmuFlags, &pThis->Xb_Voice); return hRet; @@ -1210,7 +1209,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetMixBinVolumes_8) LOG_FUNC_END; HRESULT hRet = HybridDirectSoundBuffer_SetMixBinVolumes_8(pThis->EmuDirectSoundBuffer8, pMixBins, pThis->Xb_VoiceProperties, - pThis->EmuFlags, pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom, + pThis->EmuFlags, pThis->Xb_Volume, pThis->Xb_VolumeMixbin, &pThis->Xb_Voice); return hRet; @@ -1390,8 +1389,8 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetVolume) LOG_FUNC_ARG(lVolume) LOG_FUNC_END; - HRESULT hRet = HybridDirectSoundBuffer_SetVolume(pThis->EmuDirectSoundBuffer8, lVolume, pThis->EmuFlags, &pThis->Xb_Volume, - pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom, &pThis->Xb_Voice); + HRESULT hRet = HybridDirectSoundBuffer_SetVolume(pThis->EmuDirectSoundBuffer8, lVolume, pThis->EmuFlags, + pThis->Xb_VolumeMixbin, &pThis->Xb_Voice); return hRet; } From 18a22cd934adf939cdd1397930f8f1ed706c9a3c Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Fri, 1 May 2020 06:26:13 -0500 Subject: [PATCH 04/19] fix spacing --- src/core/hle/DSOUND/DirectSound/DirectSound.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/hle/DSOUND/DirectSound/DirectSound.hpp b/src/core/hle/DSOUND/DirectSound/DirectSound.hpp index ceac24f95..32e50ae48 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSound.hpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSound.hpp @@ -705,8 +705,8 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Stop) HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_StopEx) ( XbHybridDSBuffer* pHybridThis, - REFERENCE_TIME rtTimeStamp, - DWORD dwFlags + REFERENCE_TIME rtTimeStamp, + DWORD dwFlags ); // ****************************************************************** @@ -1008,7 +1008,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetRolloffFactor) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetDistanceFactor) ( - XbHybridDSBuffer* pHybridThis, + XbHybridDSBuffer* pHybridThis, FLOAT flDistanceFactor, DWORD dwApply ); @@ -1367,7 +1367,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetOutputBuffer) // ****************************************************************** HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetOutputBuffer) ( - X_CDirectSoundStream* pThis, + X_CDirectSoundStream* pThis, XbHybridDSBuffer* pOutputBuffer ); @@ -1396,7 +1396,7 @@ HRESULT WINAPI EMUPATCH(XWaveFileCreateMediaObject) HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetEG) ( XbHybridDSBuffer* pHybridThis, - X_DSENVOLOPEDESC* pEnvelopeDesc + X_DSENVOLOPEDESC* pEnvelopeDesc ); // ****************************************************************** From 04dce78f53844bca276d02a5473a68078d065ab5 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Fri, 1 May 2020 06:26:17 -0500 Subject: [PATCH 05/19] forward xbox audio format to internal voice class --- .../DSOUND/DirectSound/DirectSoundInline.hpp | 4 ++-- .../hle/DSOUND/common/windows/WFXformat.hpp | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp b/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp index 9bedb165c..cc591eaf2 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp @@ -290,7 +290,7 @@ static inline void GeneratePCMFormat( dwEmuFlags = dwEmuFlags & ~DSE_FLAG_AUDIO_CODECS; - CODEC_FORMAT cf_audio = WFXformat_SyncHostFormat(DSBufferDesc.lpwfxFormat, Xb_lpwfxFormat, X_BufferSizeRequest, Xb_flags); + CODEC_FORMAT cf_audio = WFXformat_SyncHostFormat(DSBufferDesc.lpwfxFormat, Xb_lpwfxFormat, X_BufferSizeRequest, Xb_flags, Xb_Voice); if (cf_audio == CF_PCM) { dwEmuFlags |= DSE_FLAG_PCM; } @@ -304,7 +304,7 @@ static inline void GeneratePCMFormat( } else { dwEmuFlags |= DSE_FLAG_RECIEVEDATA; - (void)WFXformat_SyncHostFormat(DSBufferDesc.lpwfxFormat, Xb_lpwfxFormat, X_BufferSizeRequest, Xb_flags); + (void)WFXformat_SyncHostFormat(DSBufferDesc.lpwfxFormat, Xb_lpwfxFormat, X_BufferSizeRequest, Xb_flags, Xb_Voice); DSBufferDesc.dwFlags = DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY; DSBufferDesc.dwBufferBytes = 5 * DSBufferDesc.lpwfxFormat->nAvgBytesPerSec; diff --git a/src/core/hle/DSOUND/common/windows/WFXformat.hpp b/src/core/hle/DSOUND/common/windows/WFXformat.hpp index 9118a996a..ac81e54ae 100644 --- a/src/core/hle/DSOUND/common/windows/WFXformat.hpp +++ b/src/core/hle/DSOUND/common/windows/WFXformat.hpp @@ -251,15 +251,17 @@ static void WFXformat_SanityFix( } static CODEC_FORMAT WFXformat_SyncHostFormat( - void* Host_wfx_ptr, - const void* Xb_wfx_ptr, - uint32_t Xb_buffer_request_size, - uint32_t Xb_flags) + void* Host_wfx_ptr, + const void* Xb_wfx_ptr, + uint32_t Xb_buffer_request_size, + uint32_t Xb_flags, + XTL::CDirectSoundVoice* Xb_Voice) { PWAVEFORMATEXTENSIBLE Xb_wfxFormat = (PWAVEFORMATEXTENSIBLE)Xb_wfx_ptr; PWAVEFORMATEXTENSIBLE Host_wfxFormat = (PWAVEFORMATEXTENSIBLE)Host_wfx_ptr; CODEC_FORMAT codec_format_ret = CF_PCM; bool require_validate = true; + XTL::audio_format xb_format; // If no format is provided, then use default. if (Xb_wfx_ptr == xbnullptr) { @@ -332,5 +334,13 @@ static CODEC_FORMAT WFXformat_SyncHostFormat( WFXformat_GeneratePCMFormat(2, 44100, 16, Host_wfxFormat); } } + // Forward xbox format to internal XTL::CDirectSoundVoice class. + xb_format.audio_codec = (codec_format_ret == CF_XADPCM ? WAVE_FORMAT_XBOX_ADPCM : WAVE_FORMAT_PCM); + xb_format.nChannels = Host_wfxFormat->Format.nChannels; + xb_format.cbSize = (codec_format_ret == CF_XADPCM ? 4 : 0); + xb_format.nSamplesPerSec = Host_wfxFormat->Format.nSamplesPerSec; + xb_format.bitsPerSample = (codec_format_ret == CF_XADPCM ? 4 : Host_wfxFormat->Format.wBitsPerSample); + Xb_Voice->SetFormat(Xb_Voice, xb_format); + return codec_format_ret; } From e91d1bf23c7577f105d23166b8b80c580a4f59d2 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Fri, 1 May 2020 07:57:45 -0500 Subject: [PATCH 06/19] finally clean up redundant codes --- .../DSOUND/DirectSound/DirectSoundInline.hpp | 14 +- .../hle/DSOUND/common/XbInternalDSVoice.cpp | 257 +++++++----------- .../hle/DSOUND/common/XbInternalStruct.hpp | 36 +-- .../hle/DSOUND/common/windows/WFXformat.hpp | 2 +- 4 files changed, 123 insertions(+), 186 deletions(-) diff --git a/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp b/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp index cc591eaf2..25ebb8681 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp @@ -428,7 +428,7 @@ static inline void DSoundBufferTransferSettings( } // if sync current frequency used (then use pitch only). - uint32_t freq = XTL::converter_pitch2freq(Xb_Voice->GetPitch(Xb_Voice)); + uint32_t freq = XTL::converter_pitch2freq(Xb_Voice->GetPitch()); pDSBufferNew->SetFrequency(freq); pDSBufferOld->GetVolume(&lVolume); @@ -1125,7 +1125,7 @@ static inline HRESULT HybridDirectSoundBuffer_SetFrequency( { HRESULT hRet = S_OK; - int32_t pitch = XTL::converter_freq2pitch((dwFrequency!=0 ? dwFrequency : Xb_Voice->GetFrequencyDefault(Xb_Voice))); + int32_t pitch = XTL::converter_freq2pitch((dwFrequency!=0 ? dwFrequency : Xb_Voice->GetFrequencyDefault())); hRet = HybridDirectSoundBuffer_SetPitch(pDSBuffer, pitch, Xb_Voice); @@ -1150,8 +1150,8 @@ static inline HRESULT HybridDirectSoundBuffer_SetHeadroom( hRet = DSERR_INVALIDPARAM; } else { hRet = DS_OK; - Xb_Voice->SetHeadroom(Xb_Voice, dwHeadroom); - uint32_t volume = Xb_Voice->GetVolume(Xb_Voice); + Xb_Voice->SetHeadroom(dwHeadroom); + uint32_t volume = Xb_Voice->GetVolume(); pDSBuffer->SetVolume(volume); } @@ -1340,7 +1340,7 @@ static inline HRESULT HybridDirectSoundBuffer_SetPitch( XTL::CDirectSoundVoice* Xb_Voice) { - Xb_Voice->SetPitch(Xb_Voice, lPitch); + Xb_Voice->SetPitch(lPitch); // Convert pitch back to frequency uint32_t setFrequency = XTL::converter_pitch2freq(lPitch); @@ -1436,8 +1436,8 @@ static inline HRESULT HybridDirectSoundBuffer_SetVolume( printf("DEBUG: SetVolume | lVolume = %ld | volumeMixbin = %ld | dwHeadroom = %8u\n", lVolume, Xb_volumeMixbin, Xb_dwHeadroom); #endif - Xb_Voice->SetVolume(Xb_Voice, lVolume); - lVolume = Xb_Voice->GetVolume(Xb_Voice); + Xb_Voice->SetVolume(lVolume); + lVolume = Xb_Voice->GetVolume(); lVolume += Xb_volumeMixbin; if ((dwEmuFlags & DSE_FLAG_PCM) > 0) { diff --git a/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp b/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp index caec8e570..ff06033e7 100644 --- a/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp +++ b/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp @@ -27,237 +27,174 @@ #include "XbInternalStruct.hpp" // Interface for get format -void GetFormat_4034_lower(XTL::CDirectSoundVoice::_u& u, XTL::audio_format& format) +template +void GetFormat_4034_lower(T& settings, XTL::audio_format& format) { - format.audio_codec = u.settings_4034_lower.p_audio_format->wfx.wFormatTag = format.audio_codec; - format.nChannels = u.settings_4034_lower.p_audio_format->wfx.nChannels; - format.cbSize = u.settings_4034_lower.p_audio_format->wfx.cbSize; - format.nSamplesPerSec = u.settings_4034_lower.p_audio_format->wfx.nSamplesPerSec; - format.bitsPerSample = u.settings_4034_lower.p_audio_format->wfx.wBitsPerSample; + format.audio_codec = settings.p_audio_format->wfx.wFormatTag = format.audio_codec; + format.nChannels = settings.p_audio_format->wfx.nChannels; + format.cbSize = settings.p_audio_format->wfx.cbSize; + format.nSamplesPerSec = settings.p_audio_format->wfx.nSamplesPerSec; + format.bitsPerSample = settings.p_audio_format->wfx.wBitsPerSample; } -void GetFormat_4039_only(XTL::CDirectSoundVoice::_u& u, XTL::audio_format& format) +template +void GetFormat_4039_upper(T& settings, XTL::audio_format& format) { - format.audio_codec = u.settings_4039_only.audio_codec; - format.nChannels = u.settings_4039_only.nChannels; - format.cbSize = u.settings_4039_only.cbSize; - format.nSamplesPerSec = u.settings_4039_only.nSamplesPerSec_default; - format.bitsPerSample = u.settings_4039_only.bitsPerSample; -} -void GetFormat_4134_upper(XTL::CDirectSoundVoice::_u& u, XTL::audio_format& format) -{ - format.audio_codec = u.settings_4134_upper.audio_codec; - format.nChannels = u.settings_4134_upper.nChannels; - format.cbSize = u.settings_4134_upper.cbSize; - format.nSamplesPerSec = u.settings_4134_upper.nSamplesPerSec_default; - format.bitsPerSample = u.settings_4134_upper.bitsPerSample; + format.audio_codec = settings.audio_codec; + format.nChannels = settings.nChannels; + format.cbSize = settings.cbSize; + format.nSamplesPerSec = settings.nSamplesPerSec_default; + format.bitsPerSample = settings.bitsPerSample; } // Interface for set format -void SetFormat_4034_lower(XTL::CDirectSoundVoice::_u& u, XTL::audio_format format) +template +void SetFormat_4034_lower(T& settings, XTL::audio_format format) { - u.settings_4034_lower.p_audio_format->wfx.wFormatTag = format.audio_codec; - u.settings_4034_lower.p_audio_format->wfx.nChannels = static_cast(format.nChannels); - u.settings_4034_lower.p_audio_format->wfx.cbSize = static_cast(format.cbSize); - u.settings_4034_lower.p_audio_format->wfx.nSamplesPerSec = format.nSamplesPerSec; - u.settings_4034_lower.p_audio_format->wfx.wBitsPerSample = static_cast(format.bitsPerSample); + settings.p_audio_format->wfx.wFormatTag = format.audio_codec; + settings.p_audio_format->wfx.nChannels = static_cast(format.nChannels); + settings.p_audio_format->wfx.cbSize = static_cast(format.cbSize); + settings.p_audio_format->wfx.nSamplesPerSec = format.nSamplesPerSec; + settings.p_audio_format->wfx.wBitsPerSample = static_cast(format.bitsPerSample); if (format.audio_codec == WAVE_FORMAT_XBOX_ADPCM) { - u.settings_4034_lower.p_audio_format->wSamplesPerBlock = 64; + settings.p_audio_format->wSamplesPerBlock = 64; } - u.settings_4039_only.pitch = XTL::converter_freq2pitch(format.nSamplesPerSec); + settings.pitch = XTL::converter_freq2pitch(format.nSamplesPerSec); } -void SetFormat_4039_only(XTL::CDirectSoundVoice::_u& u, XTL::audio_format format) +template +void SetFormat_4039_only(T& settings, XTL::audio_format format) { - u.settings_4039_only.audio_codec = format.audio_codec; - u.settings_4039_only.nChannels = format.nChannels; - u.settings_4039_only.cbSize = format.cbSize; - u.settings_4039_only.nSamplesPerSec_default = format.nSamplesPerSec; - u.settings_4039_only.bitsPerSample = format.bitsPerSample; - u.settings_4039_only.pitch = XTL::converter_freq2pitch(format.nSamplesPerSec); + settings.audio_codec = format.audio_codec; + settings.nChannels = format.nChannels; + settings.cbSize = format.cbSize; + settings.nSamplesPerSec_default = format.nSamplesPerSec; + settings.bitsPerSample = format.bitsPerSample; + settings.pitch = XTL::converter_freq2pitch(format.nSamplesPerSec); } -void SetFormat_4134_upper(XTL::CDirectSoundVoice::_u& u, XTL::audio_format format) +template +void SetFormat_4134_upper(T& settings, XTL::audio_format format) { - u.settings_4134_upper.audio_codec = static_cast(format.audio_codec); - u.settings_4134_upper.nChannels = static_cast(format.nChannels); - u.settings_4134_upper.cbSize = static_cast(format.cbSize); - u.settings_4134_upper.nSamplesPerSec_default = format.nSamplesPerSec; - u.settings_4134_upper.bitsPerSample = format.bitsPerSample; - u.settings_4134_upper.pitch = XTL::converter_freq2pitch(format.nSamplesPerSec); + settings.audio_codec = static_cast(format.audio_codec); + settings.nChannels = static_cast(format.nChannels); + settings.cbSize = static_cast(format.cbSize); + settings.nSamplesPerSec_default = format.nSamplesPerSec; + settings.bitsPerSample = format.bitsPerSample; + settings.pitch = XTL::converter_freq2pitch(format.nSamplesPerSec); } // Interface for get frequency -uint32_t GetFrequencyDefault_4034_lower(XTL::CDirectSoundVoice::_u& u) +template +uint32_t GetFrequencyDefault_4034_lower(T& settings) { - return u.settings_4034_lower.p_audio_format->wfx.nSamplesPerSec; + return settings.p_audio_format->wfx.nSamplesPerSec; } -uint32_t GetFrequencyDefault_4039_only(XTL::CDirectSoundVoice::_u& u) +template +uint32_t GetFrequencyDefault_4039_upper(T& settings) { - return u.settings_4039_only.nSamplesPerSec_default; -} -uint32_t GetFrequencyDefault_4134_upper(XTL::CDirectSoundVoice::_u& u) -{ - return u.settings_4134_upper.nSamplesPerSec_default; + return settings.nSamplesPerSec_default; } // Interface for get pitch -int32_t GetPitch_4034_lower(XTL::CDirectSoundVoice::_u& u) +template +int32_t GetPitch(T& settings) { - return u.settings_4034_lower.pitch; -} -int32_t GetPitch_4039_only(XTL::CDirectSoundVoice::_u& u) -{ - return u.settings_4039_only.pitch; -} -int32_t GetPitch_4134_upper(XTL::CDirectSoundVoice::_u& u) -{ - return u.settings_4134_upper.pitch; + return settings.pitch; } // Interface for set pitch -void SetPitch_4034_lower(XTL::CDirectSoundVoice::_u& u, int32_t pitch) +template +void SetPitch(T& settings, int32_t pitch) { - u.settings_4034_lower.pitch = pitch; -} -void SetPitch_4039_only(XTL::CDirectSoundVoice::_u& u, int32_t pitch) -{ - u.settings_4039_only.pitch = pitch; -} -void SetPitch_4134_upper(XTL::CDirectSoundVoice::_u& u, int32_t pitch) -{ - u.settings_4134_upper.pitch = pitch; + settings.pitch = pitch; } // Interface for get volume -uint32_t GetVolume_4034_lower(XTL::CDirectSoundVoice::_u& u) +template +uint32_t GetVolume(T& settings) { - return u.settings_4034_lower.volume; -} -uint32_t GetVolume_4039_only(XTL::CDirectSoundVoice::_u& u) -{ - return u.settings_4039_only.volume; -} -uint32_t GetVolume_4134_upper(XTL::CDirectSoundVoice::_u& u) -{ - return u.settings_4134_upper.volume; + return settings.volume; } -void SetVolume_calc(uint32_t& cur_volume, uint32_t headroom, uint32_t set_volume) -{ - cur_volume = set_volume - headroom; -} // Interface for set volume -void SetVolume_4034_lower(XTL::CDirectSoundVoice::_u& u, uint32_t volume) +template +void SetVolume(T& settings, uint32_t volume) { - SetVolume_calc(u.settings_4034_lower.volume, u.settings_4034_lower.headroom, volume); -} -void SetVolume_4039_only(XTL::CDirectSoundVoice::_u& u, uint32_t volume) -{ - SetVolume_calc(u.settings_4039_only.volume, u.settings_4039_only.headroom, volume); -} -void SetVolume_4134_upper(XTL::CDirectSoundVoice::_u& u, uint32_t volume) -{ - SetVolume_calc(u.settings_4134_upper.volume, u.settings_4134_upper.headroom, volume); + settings.volume = volume - settings.headroom; } // Interface for get headroom -uint32_t GetHeadroom_4034_lower(XTL::CDirectSoundVoice::_u& u) +template +uint32_t GetHeadroom(T& settings) { - return u.settings_4034_lower.headroom; -} -uint32_t GetHeadroom_4039_only(XTL::CDirectSoundVoice::_u& u) -{ - return u.settings_4039_only.headroom; -} -uint32_t GetHeadroom_4134_upper(XTL::CDirectSoundVoice::_u& u) -{ - return u.settings_4134_upper.headroom; + return settings.headroom; } -void SetHeadroom_calc(uint32_t& cur_headroom, uint32_t& volume, uint32_t set_headroom) -{ - volume = volume - set_headroom - cur_headroom; - cur_headroom = set_headroom; -} // Interface for set headroom -void SetHeadroom_4034_lower(XTL::CDirectSoundVoice::_u& u, uint32_t headroom) +template +void SetHeadroom(T& settings, uint32_t set_headroom) { - SetHeadroom_calc(u.settings_4034_lower.headroom, u.settings_4034_lower.volume, headroom); -} -void SetHeadroom_4039_only(XTL::CDirectSoundVoice::_u& u, uint32_t headroom) -{ - SetHeadroom_calc(u.settings_4039_only.headroom, u.settings_4039_only.volume, headroom); -} -void SetHeadroom_4134_upper(XTL::CDirectSoundVoice::_u& u, uint32_t headroom) -{ - SetHeadroom_calc(u.settings_4134_upper.headroom, u.settings_4134_upper.volume, headroom); + settings.volume = settings.volume - set_headroom - settings.headroom; + settings.headroom = set_headroom; } void Init_Headroom(uint32_t& headroom, bool is3D) { headroom = is3D? 0 : 600; } -void Init_4034_lower(XTL::CDirectSoundVoice::_u::_settings_4034_lower& settings, bool is3D) +template +void Init(T& settings, bool is3D) { Init_Headroom(settings.headroom, is3D); settings.volume = 0 - settings.headroom; -} -void Init_4039_only(XTL::CDirectSoundVoice::_u::_settings_4039_only& settings, bool is3D) -{ - Init_Headroom(settings.headroom, is3D); - settings.volume = 0 - settings.headroom; -} -void Init_4134_upper(XTL::CDirectSoundVoice::_u::_settings_4134_upper& settings, bool is3D) -{ - Init_Headroom(settings.headroom, is3D); settings.volume = 0 - settings.headroom; } XTL::CDirectSoundVoice::CDirectSoundVoice(bool is3D) { - memset(u.settings_interface.unknown_08, 0, sizeof(u.settings_interface)); + u = { 0 }; if (g_LibVersion_DSOUND < 4039) { u.settings_4034_lower.p_audio_format = new XBOXADPCMWAVEFORMAT; memset(&u.settings_4034_lower.p_audio_format->wfx, 0, sizeof(XBOXADPCMWAVEFORMAT)); - Init_4034_lower(u.settings_4034_lower, is3D); + Init<_u::_settings_4034_lower>(u.settings_4034_lower, is3D); - funcs.GetFormat = GetFormat_4034_lower; - funcs.SetFormat = SetFormat_4034_lower; - funcs.GetFrequencyDefault = GetFrequencyDefault_4034_lower; - funcs.GetPitch = GetPitch_4034_lower; - funcs.SetPitch = SetPitch_4034_lower; - funcs.GetVolume = GetVolume_4034_lower; - funcs.SetVolume = SetVolume_4034_lower; - funcs.GetHeadroom = GetHeadroom_4034_lower; - funcs.SetHeadroom = SetHeadroom_4034_lower; + funcs.GetFormat = reinterpret_cast(::GetFormat_4034_lower<_u::_settings_4034_lower>); + funcs.SetFormat = reinterpret_cast(::SetFormat_4034_lower<_u::_settings_4034_lower>); + funcs.GetFrequencyDefault = reinterpret_cast(::GetFrequencyDefault_4034_lower<_u::_settings_4034_lower>); + funcs.GetPitch = reinterpret_cast(::GetPitch<_u::_settings_4034_lower>); + funcs.SetPitch = reinterpret_cast(::SetPitch<_u::_settings_4034_lower>); + funcs.GetVolume = reinterpret_cast(::GetVolume<_u::_settings_4034_lower>); + funcs.SetVolume = reinterpret_cast(::SetVolume<_u::_settings_4034_lower>); + funcs.GetHeadroom = reinterpret_cast(::GetHeadroom<_u::_settings_4034_lower>); + funcs.SetHeadroom = reinterpret_cast(::SetHeadroom<_u::_settings_4034_lower>); } else if (g_LibVersion_DSOUND == 4039) { - Init_4039_only(u.settings_4039_only, is3D); + Init<_u::_settings_4039_only>(u.settings_4039_only, is3D); - funcs.GetFormat = GetFormat_4039_only; - funcs.SetFormat = SetFormat_4039_only; - funcs.GetFrequencyDefault = GetFrequencyDefault_4039_only; - funcs.GetPitch = GetPitch_4039_only; - funcs.SetPitch = SetPitch_4039_only; - funcs.GetVolume = GetVolume_4039_only; - funcs.SetVolume = SetVolume_4039_only; - funcs.GetHeadroom = GetHeadroom_4039_only; - funcs.SetHeadroom = SetHeadroom_4039_only; + funcs.GetFormat = reinterpret_cast(::GetFormat_4039_upper<_u::_settings_4039_only>); + funcs.SetFormat = reinterpret_cast(::SetFormat_4039_only<_u::_settings_4039_only>); + funcs.GetFrequencyDefault = reinterpret_cast(::GetFrequencyDefault_4039_upper<_u::_settings_4039_only>); + funcs.GetPitch = reinterpret_cast(::GetPitch<_u::_settings_4039_only>); + funcs.SetPitch = reinterpret_cast(::SetPitch<_u::_settings_4039_only>); + funcs.GetVolume = reinterpret_cast(::GetVolume<_u::_settings_4039_only>); + funcs.SetVolume = reinterpret_cast(::SetVolume<_u::_settings_4039_only>); + funcs.GetHeadroom = reinterpret_cast(::GetHeadroom<_u::_settings_4039_only>); + funcs.SetHeadroom = reinterpret_cast(::SetHeadroom<_u::_settings_4039_only>); } else { - Init_4134_upper(u.settings_4134_upper, is3D); + Init<_u::_settings_4134_upper>(u.settings_4134_upper, is3D); - funcs.GetFormat = GetFormat_4134_upper; - funcs.SetFormat = SetFormat_4134_upper; - funcs.GetFrequencyDefault = GetFrequencyDefault_4134_upper; - funcs.GetPitch = GetPitch_4134_upper; - funcs.SetPitch = SetPitch_4134_upper; - funcs.GetVolume = GetVolume_4134_upper; - funcs.SetVolume = SetVolume_4134_upper; - funcs.GetHeadroom = GetHeadroom_4134_upper; - funcs.SetHeadroom = SetHeadroom_4134_upper; + funcs.GetFormat = reinterpret_cast(::GetFormat_4039_upper<_u::_settings_4134_upper>); + funcs.SetFormat = reinterpret_cast(::SetFormat_4134_upper<_u::_settings_4134_upper>); + funcs.GetFrequencyDefault = reinterpret_cast(::GetFrequencyDefault_4039_upper<_u::_settings_4134_upper>); + funcs.GetPitch = reinterpret_cast(::GetPitch<_u::_settings_4134_upper>); + funcs.SetPitch = reinterpret_cast(::SetPitch<_u::_settings_4134_upper>); + funcs.GetVolume = reinterpret_cast(::GetVolume<_u::_settings_4134_upper>); + funcs.SetVolume = reinterpret_cast(::SetVolume<_u::_settings_4134_upper>); + funcs.GetHeadroom = reinterpret_cast(::GetHeadroom<_u::_settings_4134_upper>); + funcs.SetHeadroom = reinterpret_cast(::SetHeadroom<_u::_settings_4134_upper>); } } diff --git a/src/core/hle/DSOUND/common/XbInternalStruct.hpp b/src/core/hle/DSOUND/common/XbInternalStruct.hpp index 58481151c..e5031a000 100644 --- a/src/core/hle/DSOUND/common/XbInternalStruct.hpp +++ b/src/core/hle/DSOUND/common/XbInternalStruct.hpp @@ -148,32 +148,32 @@ struct CDirectSoundVoice : CUnknownGenericManager { } funcs; static_assert(sizeof(funcs) == 0x24); - static inline void GetFormat(CDirectSoundVoice* pThis, audio_format& format) { - pThis->funcs.GetFormat(pThis->u, format); + inline void GetFormat(audio_format& format) { + funcs.GetFormat(u, format); }; - static inline void SetFormat(CDirectSoundVoice* pThis, audio_format format) { - pThis->funcs.SetFormat(pThis->u, format); + inline void SetFormat(audio_format format) { + funcs.SetFormat(u, format); }; - static inline uint32_t GetFrequencyDefault(CDirectSoundVoice* pThis) { - return pThis->funcs.GetFrequencyDefault(pThis->u); + inline uint32_t GetFrequencyDefault() { + return funcs.GetFrequencyDefault(u); }; - static inline int32_t GetPitch(CDirectSoundVoice* pThis) { - return pThis->funcs.GetPitch(pThis->u); + inline int32_t GetPitch() { + return funcs.GetPitch(u); }; - static inline void SetPitch(CDirectSoundVoice* pThis, int32_t pitch) { - pThis->funcs.SetPitch(pThis->u, pitch); + inline void SetPitch(int32_t pitch) { + funcs.SetPitch(u, pitch); }; - static inline uint32_t GetVolume(CDirectSoundVoice* pThis) { - return pThis->funcs.GetVolume(pThis->u); + inline uint32_t GetVolume() { + return funcs.GetVolume(u); }; - static inline void SetVolume(CDirectSoundVoice* pThis, uint32_t volume) { - pThis->funcs.SetVolume(pThis->u, volume); + inline void SetVolume(uint32_t volume) { + funcs.SetVolume(u, volume); }; - static inline uint32_t GetHeadroom(CDirectSoundVoice* pThis) { - return pThis->funcs.GetHeadroom(pThis->u); + inline uint32_t GetHeadroom() { + return funcs.GetHeadroom(u); }; - static inline void SetHeadroom(CDirectSoundVoice* pThis, uint32_t headroom) { - pThis->funcs.SetHeadroom(pThis->u, headroom); + inline void SetHeadroom(uint32_t headroom) { + funcs.SetHeadroom(u, headroom); }; }; static_assert(sizeof(CDirectSoundVoice) == sizeof(CUnknownGenericManager) + sizeof(CDirectSoundVoice::_u) + sizeof(CDirectSoundVoice::funcs)); diff --git a/src/core/hle/DSOUND/common/windows/WFXformat.hpp b/src/core/hle/DSOUND/common/windows/WFXformat.hpp index ac81e54ae..fc33d8f80 100644 --- a/src/core/hle/DSOUND/common/windows/WFXformat.hpp +++ b/src/core/hle/DSOUND/common/windows/WFXformat.hpp @@ -340,7 +340,7 @@ static CODEC_FORMAT WFXformat_SyncHostFormat( xb_format.cbSize = (codec_format_ret == CF_XADPCM ? 4 : 0); xb_format.nSamplesPerSec = Host_wfxFormat->Format.nSamplesPerSec; xb_format.bitsPerSample = (codec_format_ret == CF_XADPCM ? 4 : Host_wfxFormat->Format.wBitsPerSample); - Xb_Voice->SetFormat(Xb_Voice, xb_format); + Xb_Voice->SetFormat(xb_format); return codec_format_ret; } From 72401c44d41bef7ccb92d3e9fac7408a7ea5a1a0 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 10 May 2020 18:46:30 -0500 Subject: [PATCH 07/19] use typedef function pointers for better readability and remove redundant --- .../hle/DSOUND/common/XbInternalDSVoice.cpp | 54 +++++++++---------- .../hle/DSOUND/common/XbInternalStruct.hpp | 25 +++++---- 2 files changed, 43 insertions(+), 36 deletions(-) diff --git a/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp b/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp index ff06033e7..5b68ae8ae 100644 --- a/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp +++ b/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp @@ -158,43 +158,43 @@ XTL::CDirectSoundVoice::CDirectSoundVoice(bool is3D) Init<_u::_settings_4034_lower>(u.settings_4034_lower, is3D); - funcs.GetFormat = reinterpret_cast(::GetFormat_4034_lower<_u::_settings_4034_lower>); - funcs.SetFormat = reinterpret_cast(::SetFormat_4034_lower<_u::_settings_4034_lower>); - funcs.GetFrequencyDefault = reinterpret_cast(::GetFrequencyDefault_4034_lower<_u::_settings_4034_lower>); - funcs.GetPitch = reinterpret_cast(::GetPitch<_u::_settings_4034_lower>); - funcs.SetPitch = reinterpret_cast(::SetPitch<_u::_settings_4034_lower>); - funcs.GetVolume = reinterpret_cast(::GetVolume<_u::_settings_4034_lower>); - funcs.SetVolume = reinterpret_cast(::SetVolume<_u::_settings_4034_lower>); - funcs.GetHeadroom = reinterpret_cast(::GetHeadroom<_u::_settings_4034_lower>); - funcs.SetHeadroom = reinterpret_cast(::SetHeadroom<_u::_settings_4034_lower>); + funcs.GetFormat = reinterpret_cast(::GetFormat_4034_lower<_u::_settings_4034_lower>); + funcs.SetFormat = reinterpret_cast(::SetFormat_4034_lower<_u::_settings_4034_lower>); + funcs.GetFrequencyDefault = reinterpret_cast(::GetFrequencyDefault_4034_lower<_u::_settings_4034_lower>); + funcs.GetPitch = reinterpret_cast(::GetPitch<_u::_settings_4034_lower>); + funcs.SetPitch = reinterpret_cast(::SetPitch<_u::_settings_4034_lower>); + funcs.GetVolume = reinterpret_cast(::GetVolume<_u::_settings_4034_lower>); + funcs.SetVolume = reinterpret_cast(::SetVolume<_u::_settings_4034_lower>); + funcs.GetHeadroom = reinterpret_cast(::GetHeadroom<_u::_settings_4034_lower>); + funcs.SetHeadroom = reinterpret_cast(::SetHeadroom<_u::_settings_4034_lower>); } else if (g_LibVersion_DSOUND == 4039) { Init<_u::_settings_4039_only>(u.settings_4039_only, is3D); - funcs.GetFormat = reinterpret_cast(::GetFormat_4039_upper<_u::_settings_4039_only>); - funcs.SetFormat = reinterpret_cast(::SetFormat_4039_only<_u::_settings_4039_only>); - funcs.GetFrequencyDefault = reinterpret_cast(::GetFrequencyDefault_4039_upper<_u::_settings_4039_only>); - funcs.GetPitch = reinterpret_cast(::GetPitch<_u::_settings_4039_only>); - funcs.SetPitch = reinterpret_cast(::SetPitch<_u::_settings_4039_only>); - funcs.GetVolume = reinterpret_cast(::GetVolume<_u::_settings_4039_only>); - funcs.SetVolume = reinterpret_cast(::SetVolume<_u::_settings_4039_only>); - funcs.GetHeadroom = reinterpret_cast(::GetHeadroom<_u::_settings_4039_only>); - funcs.SetHeadroom = reinterpret_cast(::SetHeadroom<_u::_settings_4039_only>); + funcs.GetFormat = reinterpret_cast(::GetFormat_4039_upper<_u::_settings_4039_only>); + funcs.SetFormat = reinterpret_cast(::SetFormat_4039_only<_u::_settings_4039_only>); + funcs.GetFrequencyDefault = reinterpret_cast(::GetFrequencyDefault_4039_upper<_u::_settings_4039_only>); + funcs.GetPitch = reinterpret_cast(::GetPitch<_u::_settings_4039_only>); + funcs.SetPitch = reinterpret_cast(::SetPitch<_u::_settings_4039_only>); + funcs.GetVolume = reinterpret_cast(::GetVolume<_u::_settings_4039_only>); + funcs.SetVolume = reinterpret_cast(::SetVolume<_u::_settings_4039_only>); + funcs.GetHeadroom = reinterpret_cast(::GetHeadroom<_u::_settings_4039_only>); + funcs.SetHeadroom = reinterpret_cast(::SetHeadroom<_u::_settings_4039_only>); } else { Init<_u::_settings_4134_upper>(u.settings_4134_upper, is3D); - funcs.GetFormat = reinterpret_cast(::GetFormat_4039_upper<_u::_settings_4134_upper>); - funcs.SetFormat = reinterpret_cast(::SetFormat_4134_upper<_u::_settings_4134_upper>); - funcs.GetFrequencyDefault = reinterpret_cast(::GetFrequencyDefault_4039_upper<_u::_settings_4134_upper>); - funcs.GetPitch = reinterpret_cast(::GetPitch<_u::_settings_4134_upper>); - funcs.SetPitch = reinterpret_cast(::SetPitch<_u::_settings_4134_upper>); - funcs.GetVolume = reinterpret_cast(::GetVolume<_u::_settings_4134_upper>); - funcs.SetVolume = reinterpret_cast(::SetVolume<_u::_settings_4134_upper>); - funcs.GetHeadroom = reinterpret_cast(::GetHeadroom<_u::_settings_4134_upper>); - funcs.SetHeadroom = reinterpret_cast(::SetHeadroom<_u::_settings_4134_upper>); + funcs.GetFormat = reinterpret_cast(::GetFormat_4039_upper<_u::_settings_4134_upper>); + funcs.SetFormat = reinterpret_cast(::SetFormat_4134_upper<_u::_settings_4134_upper>); + funcs.GetFrequencyDefault = reinterpret_cast(::GetFrequencyDefault_4039_upper<_u::_settings_4134_upper>); + funcs.GetPitch = reinterpret_cast(::GetPitch<_u::_settings_4134_upper>); + funcs.SetPitch = reinterpret_cast(::SetPitch<_u::_settings_4134_upper>); + funcs.GetVolume = reinterpret_cast(::GetVolume<_u::_settings_4134_upper>); + funcs.SetVolume = reinterpret_cast(::SetVolume<_u::_settings_4134_upper>); + funcs.GetHeadroom = reinterpret_cast(::GetHeadroom<_u::_settings_4134_upper>); + funcs.SetHeadroom = reinterpret_cast(::SetHeadroom<_u::_settings_4134_upper>); } } diff --git a/src/core/hle/DSOUND/common/XbInternalStruct.hpp b/src/core/hle/DSOUND/common/XbInternalStruct.hpp index e5031a000..5b8ff0c35 100644 --- a/src/core/hle/DSOUND/common/XbInternalStruct.hpp +++ b/src/core/hle/DSOUND/common/XbInternalStruct.hpp @@ -135,16 +135,23 @@ struct CDirectSoundVoice : CUnknownGenericManager { } u; static_assert(sizeof(_u) == 0x300); + // Generic interface without need to check xdk's build revision every time. + typedef void (*pGetFormat)(_u& u, audio_format& format); + typedef void (*pSetFormat)(_u& u, audio_format format); + typedef uint32_t (*pGetUint32)(_u& u); + typedef void (*pSetUint32)(_u& u, uint32_t value); + typedef int32_t (*pGetInt32)(_u& u); + typedef void (*pSetInt32)(_u& u, int32_t value); struct { - void (*GetFormat)(_u& u, audio_format& format); - void (*SetFormat)(_u& u, audio_format format); - uint32_t (*GetFrequencyDefault)(_u& u); - int32_t (*GetPitch)(_u& u); - void (*SetPitch)(_u& u, int32_t pitch); - uint32_t (*GetVolume)(_u& u); - void (*SetVolume)(_u& u, uint32_t volume); - uint32_t (*GetHeadroom)(_u& u); - void (*SetHeadroom)(_u& u, uint32_t headroom); + pGetFormat GetFormat; + pSetFormat SetFormat; + pGetUint32 GetFrequencyDefault; + pGetInt32 GetPitch; + pSetInt32 SetPitch; + pGetUint32 GetVolume; + pSetUint32 SetVolume; + pGetUint32 GetHeadroom; + pSetUint32 SetHeadroom; } funcs; static_assert(sizeof(funcs) == 0x24); From ee4856a06d745704816a64eaf4bec652c7a82ef3 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 10 May 2020 18:51:24 -0500 Subject: [PATCH 08/19] add comments --- src/core/hle/DSOUND/common/XbInternalStruct.hpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/core/hle/DSOUND/common/XbInternalStruct.hpp b/src/core/hle/DSOUND/common/XbInternalStruct.hpp index 5b8ff0c35..23cfa109c 100644 --- a/src/core/hle/DSOUND/common/XbInternalStruct.hpp +++ b/src/core/hle/DSOUND/common/XbInternalStruct.hpp @@ -31,6 +31,11 @@ namespace XTL { // TODO: Everything, only small portions had been implemented. +// Note to all maintainers, make sure structure's class-like are not misalign. +// There is always a virtual function pointer to vtable list at offset 0 (uint32_t size). +// Afterward are depending on what internal data are placed. So, whenever implementing a functions. +// Whenever implementing functional codes, make sure they are at the bottom of the xbox's structure. Thanks! + struct audio_format { uint32_t audio_codec; uint32_t nChannels; @@ -50,6 +55,7 @@ struct CUnknownGenericManager { uint32_t ref_count; // 0x04 }; +// Require to verify there is no other unknown additional data by compiler itself. static_assert(sizeof(CUnknownGenericManager) == 0x08); struct CUnknownTemplate { @@ -67,6 +73,7 @@ struct CUnknownTemplate { // If need to add more virtual functions, add them above here. uint32_t ref_count; // 0x04 }; +// Require to verify there is no other unknown additional data by compiler itself. static_assert(sizeof(CUnknownTemplate) == 0x08); struct CMcpxVoiceClient: CUnknownTemplate { @@ -84,6 +91,7 @@ struct CMcpxVoiceClient: CUnknownTemplate { // global _settings for this class static _settings default_settings; }; +// Require to verify there is no other unknown additional data by compiler itself. static_assert(sizeof(CMcpxVoiceClient) == 0x300); struct CDirectSoundVoice : CUnknownGenericManager { @@ -133,7 +141,7 @@ struct CDirectSoundVoice : CUnknownGenericManager { uint32_t unknown_24[(0x300 - 0x24) / 4]; // 0x024 - 0x300 (unknown size, likely over 0x200 size. } settings_4134_upper; } u; - static_assert(sizeof(_u) == 0x300); + static_assert(sizeof(_u) == 0x300); // Not really require // Generic interface without need to check xdk's build revision every time. typedef void (*pGetFormat)(_u& u, audio_format& format); @@ -153,7 +161,7 @@ struct CDirectSoundVoice : CUnknownGenericManager { pGetUint32 GetHeadroom; pSetUint32 SetHeadroom; } funcs; - static_assert(sizeof(funcs) == 0x24); + static_assert(sizeof(funcs) == 0x24); // Not really require inline void GetFormat(audio_format& format) { funcs.GetFormat(u, format); @@ -183,6 +191,7 @@ struct CDirectSoundVoice : CUnknownGenericManager { funcs.SetHeadroom(u, headroom); }; }; +// Require to verify there is no other unknown additional data by compiler itself. static_assert(sizeof(CDirectSoundVoice) == sizeof(CUnknownGenericManager) + sizeof(CDirectSoundVoice::_u) + sizeof(CDirectSoundVoice::funcs)); struct DSBUFFER_S : CUnknownTemplate { @@ -229,6 +238,7 @@ struct DSBUFFER_S : CUnknownTemplate { dsb_c.p_unknown_14 = dsb_c.p_unknown_18; } }; +// Require to verify there is no other unknown additional data by compiler itself. static_assert(sizeof(DSBUFFER_S) == 0x34); } From 8b780f2d5c6aa23d77fd44469a7d6d68178c33d9 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 10 May 2020 19:17:00 -0500 Subject: [PATCH 09/19] remove Xb_Volume member from host's structure --- .../hle/DSOUND/DirectSound/DirectSound.hpp | 2 - .../DSOUND/DirectSound/DirectSoundBuffer.cpp | 5 +- .../DSOUND/DirectSound/DirectSoundInline.hpp | 65 +++++++++++-------- .../DSOUND/DirectSound/DirectSoundStream.cpp | 5 +- 4 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/core/hle/DSOUND/DirectSound/DirectSound.hpp b/src/core/hle/DSOUND/DirectSound/DirectSound.hpp index 32e50ae48..0a6cf8a19 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSound.hpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSound.hpp @@ -103,7 +103,6 @@ struct EmuDirectSoundBuffer DSoundBuffer_Lock X_lock; REFERENCE_TIME Xb_rtPauseEx; REFERENCE_TIME Xb_rtStopEx; - LONG Xb_Volume; LONG Xb_VolumeMixbin; X_DSENVOLOPEDESC Xb_EnvolopeDesc; X_DSVOICEPROPS Xb_VoiceProperties; @@ -271,7 +270,6 @@ class X_CDirectSoundStream LPVOID Xb_lpvContext; REFERENCE_TIME Xb_rtFlushEx; REFERENCE_TIME Xb_rtPauseEx; - LONG Xb_Volume; LONG Xb_VolumeMixbin; X_DSENVOLOPEDESC Xb_EnvolopeDesc; X_DSVOICEPROPS Xb_VoiceProperties; diff --git a/src/core/hle/DSOUND/DirectSound/DirectSoundBuffer.cpp b/src/core/hle/DSOUND/DirectSound/DirectSoundBuffer.cpp index 6af783082..1a44f4f16 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSoundBuffer.cpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSoundBuffer.cpp @@ -1001,7 +1001,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetHeadroom) EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = HybridDirectSoundBuffer_SetHeadroom(pThis->EmuDirectSoundBuffer8, dwHeadroom, - pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->EmuFlags, + pThis->Xb_VolumeMixbin, pThis->EmuFlags, pHybridThis->p_CDSVoice); return hRet; @@ -1220,8 +1220,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMixBinVolumes_8) EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; HRESULT hRet = HybridDirectSoundBuffer_SetMixBinVolumes_8(pThis->EmuDirectSoundBuffer8, pMixBins, pThis->Xb_VoiceProperties, - pThis->EmuFlags, pThis->Xb_Volume, pThis->Xb_VolumeMixbin, - pHybridThis->p_CDSVoice); + pThis->EmuFlags, pThis->Xb_VolumeMixbin, pHybridThis->p_CDSVoice); return hRet; } diff --git a/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp b/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp index 25ebb8681..3a7533239 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp @@ -392,7 +392,6 @@ static inline void DSound3DBufferCreate(LPDIRECTSOUNDBUFFER8 pDSBuffer, LPDIRECT pThis->EmuPlayFlags = dwEmuPlayFlags; \ pThis->X_BufferCacheSize = 0; \ pThis->Xb_rtPauseEx = 0LL; \ - pThis->Xb_Volume = 0L; \ pThis->Xb_VolumeMixbin = 0L; \ pThis->Xb_EnvolopeDesc = { 0 }; \ InitVoiceProperties(pThis->Xb_VoiceProperties); /* The rest will initialize in GeneratePCMFormat to GenerateMixBinDefault. */ \ @@ -685,6 +684,40 @@ static inline HRESULT DSoundBufferSynchPlaybackFlagAdd( return DS_OK; } +static inline HRESULT DSoundBufferUpdateHostVolume( + LPDIRECTSOUNDBUFFER8 pDSBuffer, + uint32_t dwEmuFlags, + uint32_t volume + + ) +{ + + if ((dwEmuFlags & DSE_FLAG_PCM) > 0) { + if (!g_XBAudio.codec_pcm) { + volume = DSBVOLUME_MIN; + } + } else if ((dwEmuFlags & DSE_FLAG_XADPCM) > 0) { + if (!g_XBAudio.codec_xadpcm) { + volume = DSBVOLUME_MIN; + } + } else if ((dwEmuFlags & DSE_FLAG_PCM_UNKNOWN) > 0) { + if (!g_XBAudio.codec_unknown) { + volume = DSBVOLUME_MIN; + } + } + if (volume <= -6400 && volume != DSBVOLUME_MIN) { + volume = DSBVOLUME_MIN; + } else if (volume > 0) { + EmuLog(LOG_LEVEL::WARNING, "volume has received greater than 0: %ld", volume); + volume = 0; + } + if ((dwEmuFlags & DSE_FLAG_DEBUG_MUTE) > 0) { + volume = DSBVOLUME_MIN; + } + + return pDSBuffer->SetVolume(volume); +} + //TODO: RadWolfie - Need to implement DirectSoundBuffer create support. Or not able to do so due to all three classes function differently. //IDirectSound //IDirectSoundStream @@ -1140,7 +1173,6 @@ static HRESULT HybridDirectSoundBuffer_SetVolume(LPDIRECTSOUNDBUFFER8, LONG, DWO static inline HRESULT HybridDirectSoundBuffer_SetHeadroom( LPDIRECTSOUNDBUFFER8 pDSBuffer, DWORD dwHeadroom, - LONG Xb_volume, LONG Xb_volumeMixbin, DWORD dwEmuFlags, XTL::CDirectSoundVoice* Xb_Voice) @@ -1152,7 +1184,7 @@ static inline HRESULT HybridDirectSoundBuffer_SetHeadroom( hRet = DS_OK; Xb_Voice->SetHeadroom(dwHeadroom); uint32_t volume = Xb_Voice->GetVolume(); - pDSBuffer->SetVolume(volume); + hRet = DSoundBufferUpdateHostVolume(pDSBuffer, dwEmuFlags, volume); } return DS_OK; @@ -1242,7 +1274,6 @@ static inline HRESULT HybridDirectSoundBuffer_SetMixBinVolumes_8( XTL::X_LPDSMIXBINS pMixBins, XTL::X_DSVOICEPROPS& Xb_VoiceProperties, DWORD EmuFlags, - LONG Xb_volume, LONG &Xb_volumeMixBin, XTL::CDirectSoundVoice* Xb_Voice) { @@ -1284,6 +1315,7 @@ static inline HRESULT HybridDirectSoundBuffer_SetMixBinVolumes_8( } if (counter > 0) { Xb_volumeMixBin = volume / (LONG)counter; + uint32_t Xb_volume = Xb_Voice->GetVolume(); hRet = HybridDirectSoundBuffer_SetVolume(pDSBuffer, Xb_volume, EmuFlags, Xb_volumeMixBin, Xb_Voice); } else { @@ -1440,30 +1472,7 @@ static inline HRESULT HybridDirectSoundBuffer_SetVolume( lVolume = Xb_Voice->GetVolume(); lVolume += Xb_volumeMixbin; - if ((dwEmuFlags & DSE_FLAG_PCM) > 0) { - if (!g_XBAudio.codec_pcm) { - lVolume = DSBVOLUME_MIN; - } - } else if ((dwEmuFlags & DSE_FLAG_XADPCM) > 0) { - if (!g_XBAudio.codec_xadpcm) { - lVolume = DSBVOLUME_MIN; - } - } else if ((dwEmuFlags & DSE_FLAG_PCM_UNKNOWN) > 0) { - if (!g_XBAudio.codec_unknown) { - lVolume = DSBVOLUME_MIN; - } - } - if (lVolume <= -6400 && lVolume != DSBVOLUME_MIN) { - lVolume = DSBVOLUME_MIN; - } else if (lVolume > 0) { - EmuLog(LOG_LEVEL::WARNING, "HybridDirectSoundBuffer_SetVolume has received greater than 0: %ld", lVolume); - lVolume = 0; - } - if ((dwEmuFlags & DSE_FLAG_DEBUG_MUTE) > 0) { - lVolume = DSBVOLUME_MIN; - } - - HRESULT hRet = pDSBuffer->SetVolume(lVolume); + HRESULT hRet = DSoundBufferUpdateHostVolume(pDSBuffer, dwEmuFlags, lVolume); RETURN_RESULT_CHECK(hRet); } diff --git a/src/core/hle/DSOUND/DirectSound/DirectSoundStream.cpp b/src/core/hle/DSOUND/DirectSound/DirectSoundStream.cpp index 1a8261317..4625c0044 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSoundStream.cpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSoundStream.cpp @@ -969,7 +969,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetHeadroom) LOG_FUNC_END; HRESULT hRet = HybridDirectSoundBuffer_SetHeadroom(pThis->EmuDirectSoundBuffer8, dwHeadroom, - pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->EmuFlags, &pThis->Xb_Voice); + pThis->Xb_VolumeMixbin, pThis->EmuFlags, &pThis->Xb_Voice); return hRet; } @@ -1209,8 +1209,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetMixBinVolumes_8) LOG_FUNC_END; HRESULT hRet = HybridDirectSoundBuffer_SetMixBinVolumes_8(pThis->EmuDirectSoundBuffer8, pMixBins, pThis->Xb_VoiceProperties, - pThis->EmuFlags, pThis->Xb_Volume, pThis->Xb_VolumeMixbin, - &pThis->Xb_Voice); + pThis->EmuFlags, pThis->Xb_VolumeMixbin, &pThis->Xb_Voice); return hRet; } From ce0e35b05273d902c8bbc79b11835f7ca1eab141 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 10 May 2020 22:05:20 -0500 Subject: [PATCH 10/19] oops, volume is signed integer --- .../hle/DSOUND/DirectSound/DirectSoundInline.hpp | 6 +++--- src/core/hle/DSOUND/common/XbInternalDSVoice.cpp | 12 ++++++------ src/core/hle/DSOUND/common/XbInternalStruct.hpp | 14 +++++++------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp b/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp index 3a7533239..714a28219 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp @@ -687,7 +687,7 @@ static inline HRESULT DSoundBufferSynchPlaybackFlagAdd( static inline HRESULT DSoundBufferUpdateHostVolume( LPDIRECTSOUNDBUFFER8 pDSBuffer, uint32_t dwEmuFlags, - uint32_t volume + int32_t volume ) { @@ -1183,7 +1183,7 @@ static inline HRESULT HybridDirectSoundBuffer_SetHeadroom( } else { hRet = DS_OK; Xb_Voice->SetHeadroom(dwHeadroom); - uint32_t volume = Xb_Voice->GetVolume(); + int32_t volume = Xb_Voice->GetVolume(); hRet = DSoundBufferUpdateHostVolume(pDSBuffer, dwEmuFlags, volume); } @@ -1315,7 +1315,7 @@ static inline HRESULT HybridDirectSoundBuffer_SetMixBinVolumes_8( } if (counter > 0) { Xb_volumeMixBin = volume / (LONG)counter; - uint32_t Xb_volume = Xb_Voice->GetVolume(); + int32_t Xb_volume = Xb_Voice->GetVolume(); hRet = HybridDirectSoundBuffer_SetVolume(pDSBuffer, Xb_volume, EmuFlags, Xb_volumeMixBin, Xb_Voice); } else { diff --git a/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp b/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp index 5b68ae8ae..d4ae3b2e3 100644 --- a/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp +++ b/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp @@ -163,8 +163,8 @@ XTL::CDirectSoundVoice::CDirectSoundVoice(bool is3D) funcs.GetFrequencyDefault = reinterpret_cast(::GetFrequencyDefault_4034_lower<_u::_settings_4034_lower>); funcs.GetPitch = reinterpret_cast(::GetPitch<_u::_settings_4034_lower>); funcs.SetPitch = reinterpret_cast(::SetPitch<_u::_settings_4034_lower>); - funcs.GetVolume = reinterpret_cast(::GetVolume<_u::_settings_4034_lower>); - funcs.SetVolume = reinterpret_cast(::SetVolume<_u::_settings_4034_lower>); + funcs.GetVolume = reinterpret_cast(::GetVolume<_u::_settings_4034_lower>); + funcs.SetVolume = reinterpret_cast(::SetVolume<_u::_settings_4034_lower>); funcs.GetHeadroom = reinterpret_cast(::GetHeadroom<_u::_settings_4034_lower>); funcs.SetHeadroom = reinterpret_cast(::SetHeadroom<_u::_settings_4034_lower>); } @@ -177,8 +177,8 @@ XTL::CDirectSoundVoice::CDirectSoundVoice(bool is3D) funcs.GetFrequencyDefault = reinterpret_cast(::GetFrequencyDefault_4039_upper<_u::_settings_4039_only>); funcs.GetPitch = reinterpret_cast(::GetPitch<_u::_settings_4039_only>); funcs.SetPitch = reinterpret_cast(::SetPitch<_u::_settings_4039_only>); - funcs.GetVolume = reinterpret_cast(::GetVolume<_u::_settings_4039_only>); - funcs.SetVolume = reinterpret_cast(::SetVolume<_u::_settings_4039_only>); + funcs.GetVolume = reinterpret_cast(::GetVolume<_u::_settings_4039_only>); + funcs.SetVolume = reinterpret_cast(::SetVolume<_u::_settings_4039_only>); funcs.GetHeadroom = reinterpret_cast(::GetHeadroom<_u::_settings_4039_only>); funcs.SetHeadroom = reinterpret_cast(::SetHeadroom<_u::_settings_4039_only>); } @@ -191,8 +191,8 @@ XTL::CDirectSoundVoice::CDirectSoundVoice(bool is3D) funcs.GetFrequencyDefault = reinterpret_cast(::GetFrequencyDefault_4039_upper<_u::_settings_4134_upper>); funcs.GetPitch = reinterpret_cast(::GetPitch<_u::_settings_4134_upper>); funcs.SetPitch = reinterpret_cast(::SetPitch<_u::_settings_4134_upper>); - funcs.GetVolume = reinterpret_cast(::GetVolume<_u::_settings_4134_upper>); - funcs.SetVolume = reinterpret_cast(::SetVolume<_u::_settings_4134_upper>); + funcs.GetVolume = reinterpret_cast(::GetVolume<_u::_settings_4134_upper>); + funcs.SetVolume = reinterpret_cast(::SetVolume<_u::_settings_4134_upper>); funcs.GetHeadroom = reinterpret_cast(::GetHeadroom<_u::_settings_4134_upper>); funcs.SetHeadroom = reinterpret_cast(::SetHeadroom<_u::_settings_4134_upper>); } diff --git a/src/core/hle/DSOUND/common/XbInternalStruct.hpp b/src/core/hle/DSOUND/common/XbInternalStruct.hpp index 23cfa109c..cb9dc9bb1 100644 --- a/src/core/hle/DSOUND/common/XbInternalStruct.hpp +++ b/src/core/hle/DSOUND/common/XbInternalStruct.hpp @@ -111,7 +111,7 @@ struct CDirectSoundVoice : CUnknownGenericManager { uint16_t unknown_0C; // 0x00C // zero'd - unknown XBOXADPCMWAVEFORMAT* p_audio_format; // 0x010 // Same as XBOXADPCMWAVEFORMAT / WAVEFORMATEX structure uint32_t pitch; // 0x014 // Always init and custom pitch from SetFrequency, SetPitch, SetFormat, etc calls. - uint32_t volume; // 0x018 // default: (set volume - headroom) + int32_t volume; // 0x018 // default: (set volume - headroom) uint32_t headroom; // 0x01C // default: (set headroom then update volume) } settings_4034_lower; @@ -123,7 +123,7 @@ struct CDirectSoundVoice : CUnknownGenericManager { int32_t nSamplesPerSec_default; // 0x018 // Always original frequency for check if SetFrequency is given with 0 then use original one. uint32_t bitsPerSample; // 0x01C uint32_t pitch; // 0x020 // Always init and custom pitch from SetFrequency, SetPitch, SetFormat, etc calls. - uint32_t volume; // 0x024 // (set volume - headroom) + int32_t volume; // 0x024 // (set volume - headroom) uint32_t headroom; // 0x028 // (set headroom then update volume) uint32_t unknown_2C[(0x300 - 0x2C) / 4]; // 0x02C - 0x300 (unknown size, likely over 0x200 size. } settings_4039_only; @@ -136,7 +136,7 @@ struct CDirectSoundVoice : CUnknownGenericManager { uint32_t nSamplesPerSec_default; // 0x010 // Always original frequency for check if SetFrequency is given with 0 then use original one. uint32_t bitsPerSample; // 0x014 int32_t pitch; // 0x018 // Always init and custom pitch from SetFrequency, SetPitch, SetFormat, etc calls. - uint32_t volume; // 0x01C // (set volume - headroom) + int32_t volume; // 0x01C // (set volume - headroom) uint32_t headroom; // 0x020 // (set headroom then update volume) uint32_t unknown_24[(0x300 - 0x24) / 4]; // 0x024 - 0x300 (unknown size, likely over 0x200 size. } settings_4134_upper; @@ -156,8 +156,8 @@ struct CDirectSoundVoice : CUnknownGenericManager { pGetUint32 GetFrequencyDefault; pGetInt32 GetPitch; pSetInt32 SetPitch; - pGetUint32 GetVolume; - pSetUint32 SetVolume; + pGetInt32 GetVolume; + pSetInt32 SetVolume; pGetUint32 GetHeadroom; pSetUint32 SetHeadroom; } funcs; @@ -178,10 +178,10 @@ struct CDirectSoundVoice : CUnknownGenericManager { inline void SetPitch(int32_t pitch) { funcs.SetPitch(u, pitch); }; - inline uint32_t GetVolume() { + inline int32_t GetVolume() { return funcs.GetVolume(u); }; - inline void SetVolume(uint32_t volume) { + inline void SetVolume(int32_t volume) { funcs.SetVolume(u, volume); }; inline uint32_t GetHeadroom() { From 06af046c132cfab40730020909a8e9871cc72bc3 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 10 May 2020 22:20:47 -0500 Subject: [PATCH 11/19] also another fixup for pitch type --- src/core/hle/DSOUND/common/XbInternalStruct.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/hle/DSOUND/common/XbInternalStruct.hpp b/src/core/hle/DSOUND/common/XbInternalStruct.hpp index cb9dc9bb1..f66db3490 100644 --- a/src/core/hle/DSOUND/common/XbInternalStruct.hpp +++ b/src/core/hle/DSOUND/common/XbInternalStruct.hpp @@ -110,7 +110,7 @@ struct CDirectSoundVoice : CUnknownGenericManager { xbaddr p_unknown_08; // 0x008 uint16_t unknown_0C; // 0x00C // zero'd - unknown XBOXADPCMWAVEFORMAT* p_audio_format; // 0x010 // Same as XBOXADPCMWAVEFORMAT / WAVEFORMATEX structure - uint32_t pitch; // 0x014 // Always init and custom pitch from SetFrequency, SetPitch, SetFormat, etc calls. + int32_t pitch; // 0x014 // Always init and custom pitch from SetFrequency, SetPitch, SetFormat, etc calls. int32_t volume; // 0x018 // default: (set volume - headroom) uint32_t headroom; // 0x01C // default: (set headroom then update volume) } settings_4034_lower; @@ -122,7 +122,7 @@ struct CDirectSoundVoice : CUnknownGenericManager { uint32_t cbSize; // 0x014 int32_t nSamplesPerSec_default; // 0x018 // Always original frequency for check if SetFrequency is given with 0 then use original one. uint32_t bitsPerSample; // 0x01C - uint32_t pitch; // 0x020 // Always init and custom pitch from SetFrequency, SetPitch, SetFormat, etc calls. + int32_t pitch; // 0x020 // Always init and custom pitch from SetFrequency, SetPitch, SetFormat, etc calls. int32_t volume; // 0x024 // (set volume - headroom) uint32_t headroom; // 0x028 // (set headroom then update volume) uint32_t unknown_2C[(0x300 - 0x2C) / 4]; // 0x02C - 0x300 (unknown size, likely over 0x200 size. From 0c5117dc06f40d396d821f5c207429c9b33aa367 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 10 May 2020 22:51:39 -0500 Subject: [PATCH 12/19] reword union data for better readability --- .../hle/DSOUND/common/XbInternalDSVoice.cpp | 75 ++++++++++--------- .../hle/DSOUND/common/XbInternalStruct.hpp | 54 ++++++------- 2 files changed, 66 insertions(+), 63 deletions(-) diff --git a/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp b/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp index d4ae3b2e3..717230387 100644 --- a/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp +++ b/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp @@ -150,60 +150,63 @@ void Init(T& settings, bool is3D) XTL::CDirectSoundVoice::CDirectSoundVoice(bool is3D) { - u = { 0 }; + settings = { 0 }; if (g_LibVersion_DSOUND < 4039) { - u.settings_4034_lower.p_audio_format = new XBOXADPCMWAVEFORMAT; - memset(&u.settings_4034_lower.p_audio_format->wfx, 0, sizeof(XBOXADPCMWAVEFORMAT)); + settings.r4034_lower.p_audio_format = new XBOXADPCMWAVEFORMAT; + memset(&settings.r4034_lower.p_audio_format->wfx, 0, sizeof(XBOXADPCMWAVEFORMAT)); - Init<_u::_settings_4034_lower>(u.settings_4034_lower, is3D); + using settings_template = _settings::_r4034_lower; + Init(settings.r4034_lower, is3D); - funcs.GetFormat = reinterpret_cast(::GetFormat_4034_lower<_u::_settings_4034_lower>); - funcs.SetFormat = reinterpret_cast(::SetFormat_4034_lower<_u::_settings_4034_lower>); - funcs.GetFrequencyDefault = reinterpret_cast(::GetFrequencyDefault_4034_lower<_u::_settings_4034_lower>); - funcs.GetPitch = reinterpret_cast(::GetPitch<_u::_settings_4034_lower>); - funcs.SetPitch = reinterpret_cast(::SetPitch<_u::_settings_4034_lower>); - funcs.GetVolume = reinterpret_cast(::GetVolume<_u::_settings_4034_lower>); - funcs.SetVolume = reinterpret_cast(::SetVolume<_u::_settings_4034_lower>); - funcs.GetHeadroom = reinterpret_cast(::GetHeadroom<_u::_settings_4034_lower>); - funcs.SetHeadroom = reinterpret_cast(::SetHeadroom<_u::_settings_4034_lower>); + funcs.GetFormat = reinterpret_cast(::GetFormat_4034_lower); + funcs.SetFormat = reinterpret_cast(::SetFormat_4034_lower); + funcs.GetFrequencyDefault = reinterpret_cast(::GetFrequencyDefault_4034_lower); + funcs.GetPitch = reinterpret_cast(::GetPitch); + funcs.SetPitch = reinterpret_cast(::SetPitch); + funcs.GetVolume = reinterpret_cast(::GetVolume); + funcs.SetVolume = reinterpret_cast(::SetVolume); + funcs.GetHeadroom = reinterpret_cast(::GetHeadroom); + funcs.SetHeadroom = reinterpret_cast(::SetHeadroom); } else if (g_LibVersion_DSOUND == 4039) { - Init<_u::_settings_4039_only>(u.settings_4039_only, is3D); + using settings_template = _settings::_r4039_only; + Init(settings.r4039_only, is3D); - funcs.GetFormat = reinterpret_cast(::GetFormat_4039_upper<_u::_settings_4039_only>); - funcs.SetFormat = reinterpret_cast(::SetFormat_4039_only<_u::_settings_4039_only>); - funcs.GetFrequencyDefault = reinterpret_cast(::GetFrequencyDefault_4039_upper<_u::_settings_4039_only>); - funcs.GetPitch = reinterpret_cast(::GetPitch<_u::_settings_4039_only>); - funcs.SetPitch = reinterpret_cast(::SetPitch<_u::_settings_4039_only>); - funcs.GetVolume = reinterpret_cast(::GetVolume<_u::_settings_4039_only>); - funcs.SetVolume = reinterpret_cast(::SetVolume<_u::_settings_4039_only>); - funcs.GetHeadroom = reinterpret_cast(::GetHeadroom<_u::_settings_4039_only>); - funcs.SetHeadroom = reinterpret_cast(::SetHeadroom<_u::_settings_4039_only>); + funcs.GetFormat = reinterpret_cast(::GetFormat_4039_upper); + funcs.SetFormat = reinterpret_cast(::SetFormat_4039_only); + funcs.GetFrequencyDefault = reinterpret_cast(::GetFrequencyDefault_4039_upper); + funcs.GetPitch = reinterpret_cast(::GetPitch); + funcs.SetPitch = reinterpret_cast(::SetPitch); + funcs.GetVolume = reinterpret_cast(::GetVolume); + funcs.SetVolume = reinterpret_cast(::SetVolume); + funcs.GetHeadroom = reinterpret_cast(::GetHeadroom); + funcs.SetHeadroom = reinterpret_cast(::SetHeadroom); } else { - Init<_u::_settings_4134_upper>(u.settings_4134_upper, is3D); + using settings_template = _settings::_r4134_upper; + Init(settings.r4134_upper, is3D); - funcs.GetFormat = reinterpret_cast(::GetFormat_4039_upper<_u::_settings_4134_upper>); - funcs.SetFormat = reinterpret_cast(::SetFormat_4134_upper<_u::_settings_4134_upper>); - funcs.GetFrequencyDefault = reinterpret_cast(::GetFrequencyDefault_4039_upper<_u::_settings_4134_upper>); - funcs.GetPitch = reinterpret_cast(::GetPitch<_u::_settings_4134_upper>); - funcs.SetPitch = reinterpret_cast(::SetPitch<_u::_settings_4134_upper>); - funcs.GetVolume = reinterpret_cast(::GetVolume<_u::_settings_4134_upper>); - funcs.SetVolume = reinterpret_cast(::SetVolume<_u::_settings_4134_upper>); - funcs.GetHeadroom = reinterpret_cast(::GetHeadroom<_u::_settings_4134_upper>); - funcs.SetHeadroom = reinterpret_cast(::SetHeadroom<_u::_settings_4134_upper>); + funcs.GetFormat = reinterpret_cast(::GetFormat_4039_upper); + funcs.SetFormat = reinterpret_cast(::SetFormat_4134_upper); + funcs.GetFrequencyDefault = reinterpret_cast(::GetFrequencyDefault_4039_upper); + funcs.GetPitch = reinterpret_cast(::GetPitch); + funcs.SetPitch = reinterpret_cast(::SetPitch); + funcs.GetVolume = reinterpret_cast(::GetVolume); + funcs.SetVolume = reinterpret_cast(::SetVolume); + funcs.GetHeadroom = reinterpret_cast(::GetHeadroom); + funcs.SetHeadroom = reinterpret_cast(::SetHeadroom); } } XTL::CDirectSoundVoice::~CDirectSoundVoice() { if (g_LibVersion_DSOUND < 4039) { - if (!u.settings_4034_lower.p_audio_format) { - delete u.settings_4034_lower.p_audio_format; - u.settings_4034_lower.p_audio_format = nullptr; + if (!settings.r4034_lower.p_audio_format) { + delete settings.r4034_lower.p_audio_format; + settings.r4034_lower.p_audio_format = nullptr; } } } diff --git a/src/core/hle/DSOUND/common/XbInternalStruct.hpp b/src/core/hle/DSOUND/common/XbInternalStruct.hpp index f66db3490..2b1aef6a5 100644 --- a/src/core/hle/DSOUND/common/XbInternalStruct.hpp +++ b/src/core/hle/DSOUND/common/XbInternalStruct.hpp @@ -100,22 +100,22 @@ struct CDirectSoundVoice : CUnknownGenericManager { virtual ~CDirectSoundVoice(); // CUnknownGenericManager // 0x00 - ??? - union _u { - struct _settings_interface + union _settings { + struct _unknown { uint32_t unknown_08[0x300 / 4]; // 0x000 - 0x300 (unknown size, likely over 0x200 size. - } settings_interface; + } unknown; - struct _settings_4034_lower { + struct _r4034_lower { xbaddr p_unknown_08; // 0x008 uint16_t unknown_0C; // 0x00C // zero'd - unknown XBOXADPCMWAVEFORMAT* p_audio_format; // 0x010 // Same as XBOXADPCMWAVEFORMAT / WAVEFORMATEX structure int32_t pitch; // 0x014 // Always init and custom pitch from SetFrequency, SetPitch, SetFormat, etc calls. int32_t volume; // 0x018 // default: (set volume - headroom) uint32_t headroom; // 0x01C // default: (set headroom then update volume) - } settings_4034_lower; + } r4034_lower; - struct _settings_4039_only { + struct _r4039_only { uint32_t unknown_08; // 0x008 uint32_t audio_codec; // 0x00C // Setter is 32 bit, yet getter is 16 bit integer reader uint32_t nChannels; // 0x010 @@ -126,9 +126,9 @@ struct CDirectSoundVoice : CUnknownGenericManager { int32_t volume; // 0x024 // (set volume - headroom) uint32_t headroom; // 0x028 // (set headroom then update volume) uint32_t unknown_2C[(0x300 - 0x2C) / 4]; // 0x02C - 0x300 (unknown size, likely over 0x200 size. - } settings_4039_only; + } r4039_only; - struct _settings_4134_upper { + struct _r4134_upper { uint32_t unknown_08; // 0x008 uint16_t audio_codec; // 0x00C uint8_t nChannels; // 0x00E @@ -139,17 +139,17 @@ struct CDirectSoundVoice : CUnknownGenericManager { int32_t volume; // 0x01C // (set volume - headroom) uint32_t headroom; // 0x020 // (set headroom then update volume) uint32_t unknown_24[(0x300 - 0x24) / 4]; // 0x024 - 0x300 (unknown size, likely over 0x200 size. - } settings_4134_upper; - } u; - static_assert(sizeof(_u) == 0x300); // Not really require + } r4134_upper; + } settings; + static_assert(sizeof(_settings) == 0x300); // Not really require // Generic interface without need to check xdk's build revision every time. - typedef void (*pGetFormat)(_u& u, audio_format& format); - typedef void (*pSetFormat)(_u& u, audio_format format); - typedef uint32_t (*pGetUint32)(_u& u); - typedef void (*pSetUint32)(_u& u, uint32_t value); - typedef int32_t (*pGetInt32)(_u& u); - typedef void (*pSetInt32)(_u& u, int32_t value); + typedef void (*pGetFormat)(_settings& settings, audio_format& format); + typedef void (*pSetFormat)(_settings& settings, audio_format format); + typedef uint32_t (*pGetUint32)(_settings& settings); + typedef void (*pSetUint32)(_settings& settings, uint32_t value); + typedef int32_t (*pGetInt32)(_settings& settings); + typedef void (*pSetInt32)(_settings& settings, int32_t value); struct { pGetFormat GetFormat; pSetFormat SetFormat; @@ -164,35 +164,35 @@ struct CDirectSoundVoice : CUnknownGenericManager { static_assert(sizeof(funcs) == 0x24); // Not really require inline void GetFormat(audio_format& format) { - funcs.GetFormat(u, format); + funcs.GetFormat(settings, format); }; inline void SetFormat(audio_format format) { - funcs.SetFormat(u, format); + funcs.SetFormat(settings, format); }; inline uint32_t GetFrequencyDefault() { - return funcs.GetFrequencyDefault(u); + return funcs.GetFrequencyDefault(settings); }; inline int32_t GetPitch() { - return funcs.GetPitch(u); + return funcs.GetPitch(settings); }; inline void SetPitch(int32_t pitch) { - funcs.SetPitch(u, pitch); + funcs.SetPitch(settings, pitch); }; inline int32_t GetVolume() { - return funcs.GetVolume(u); + return funcs.GetVolume(settings); }; inline void SetVolume(int32_t volume) { - funcs.SetVolume(u, volume); + funcs.SetVolume(settings, volume); }; inline uint32_t GetHeadroom() { - return funcs.GetHeadroom(u); + return funcs.GetHeadroom(settings); }; inline void SetHeadroom(uint32_t headroom) { - funcs.SetHeadroom(u, headroom); + funcs.SetHeadroom(settings, headroom); }; }; // Require to verify there is no other unknown additional data by compiler itself. -static_assert(sizeof(CDirectSoundVoice) == sizeof(CUnknownGenericManager) + sizeof(CDirectSoundVoice::_u) + sizeof(CDirectSoundVoice::funcs)); +static_assert(sizeof(CDirectSoundVoice) == sizeof(CUnknownGenericManager) + sizeof(CDirectSoundVoice::_settings) + sizeof(CDirectSoundVoice::funcs)); struct DSBUFFER_S : CUnknownTemplate { From fad467196a266c92aae83ecb8f8027d8a7913359 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 10 May 2020 23:06:12 -0500 Subject: [PATCH 13/19] add test case comment --- src/core/hle/DSOUND/common/XbInternalDSVoice.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp b/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp index 717230387..44de79958 100644 --- a/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp +++ b/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp @@ -93,6 +93,7 @@ uint32_t GetFrequencyDefault_4039_upper(T& settings) return settings.nSamplesPerSec_default; } +// test case: WWE RAW 2's rdata section will directly access pitch value then call IDirectSoundBuffer_SetPitch. // Interface for get pitch template int32_t GetPitch(T& settings) From ada86a42b5f2538286e84a7b9b4924acb1fdaf09 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Thu, 14 May 2020 18:38:05 -0500 Subject: [PATCH 14/19] create gc for EmuDirectSoundBuffer destructor --- .../hle/DSOUND/DirectSound/DirectSound.hpp | 8 ++++ .../DSOUND/DirectSound/DirectSoundBuffer.cpp | 44 +++++++++++-------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/core/hle/DSOUND/DirectSound/DirectSound.hpp b/src/core/hle/DSOUND/DirectSound/DirectSound.hpp index 0a6cf8a19..c5f3be1cd 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSound.hpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSound.hpp @@ -74,8 +74,12 @@ typedef struct _DSoundBuffer_Lock { // ****************************************************************** // * X_CDirectSoundBuffer // ****************************************************************** +struct XbHybridDSBuffer; struct EmuDirectSoundBuffer { + virtual ~EmuDirectSoundBuffer(); + XbHybridDSBuffer* pHybridThis; + union { PVOID pMpcxBuffer; @@ -118,6 +122,10 @@ struct SharedDSBuffer : DSBUFFER_S { emuDSBuffer = new EmuDirectSoundBuffer(); } EmuDirectSoundBuffer* emuDSBuffer; + + virtual ~SharedDSBuffer() { + delete emuDSBuffer; + } }; //Custom flags (4 bytes support up to 31 shifts,starting from 0) diff --git a/src/core/hle/DSOUND/DirectSound/DirectSoundBuffer.cpp b/src/core/hle/DSOUND/DirectSound/DirectSoundBuffer.cpp index 1a44f4f16..b0547dc63 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSoundBuffer.cpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSoundBuffer.cpp @@ -109,6 +109,30 @@ ULONG WINAPI XTL::EMUPATCH(IDirectSoundBuffer_AddRef) return uRet; } +// ****************************************************************** +// * EmuDirectSoundBuffer destructor handler +// ****************************************************************** +XTL::EmuDirectSoundBuffer::~EmuDirectSoundBuffer() +{ + if (this->EmuDirectSound3DBuffer8 != nullptr) { + this->EmuDirectSound3DBuffer8->Release(); + } + + // remove cache entry + vector_ds_buffer::iterator ppDSBuffer = std::find(g_pDSoundBufferCache.begin(), g_pDSoundBufferCache.end(), this->pHybridThis); + if (ppDSBuffer != g_pDSoundBufferCache.end()) { + g_pDSoundBufferCache.erase(ppDSBuffer); + } + + if (this->EmuBufferDesc.lpwfxFormat != nullptr) { + free(this->EmuBufferDesc.lpwfxFormat); + } + if (this->X_BufferCache != xbnullptr && (this->EmuFlags & DSE_FLAG_BUFFER_EXTERNAL) == 0) { + free(this->X_BufferCache); + DSoundSGEMemDealloc(this->X_BufferCacheSize); + } +} + // ****************************************************************** // * patch: IDirectSoundBuffer_Release // ****************************************************************** @@ -127,27 +151,8 @@ ULONG WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Release) uRet = pThis->EmuDirectSoundBuffer8->Release(); if (uRet == 0) { - if (pThis->EmuDirectSound3DBuffer8 != nullptr) { - pThis->EmuDirectSound3DBuffer8->Release(); - } - - // remove cache entry - vector_ds_buffer::iterator ppDSBuffer = std::find(g_pDSoundBufferCache.begin(), g_pDSoundBufferCache.end(), pHybridThis); - if (ppDSBuffer != g_pDSoundBufferCache.end()) { - g_pDSoundBufferCache.erase(ppDSBuffer); - } - - if (pThis->EmuBufferDesc.lpwfxFormat != nullptr) { - free(pThis->EmuBufferDesc.lpwfxFormat); - } - if (pThis->X_BufferCache != xbnullptr && (pThis->EmuFlags & DSE_FLAG_BUFFER_EXTERNAL) == 0) { - free(pThis->X_BufferCache); - DSoundSGEMemDealloc(pThis->X_BufferCacheSize); - } - size_t size = sizeof(SharedDSBuffer) - sizeof(XbHybridDSBuffer); SharedDSBuffer* pSharedThis = reinterpret_cast(reinterpret_cast(pHybridThis) - size); - delete pSharedThis->emuDSBuffer; delete pSharedThis; } //} @@ -212,6 +217,7 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateBuffer) XbHybridDSBuffer* pHybridBuffer = reinterpret_cast(&pBuffer->dsb_i); *ppBuffer = pHybridBuffer; EmuDirectSoundBuffer* pEmuBuffer = pBuffer->emuDSBuffer; + pEmuBuffer->pHybridThis = pHybridBuffer; DSoundBufferSetDefault(pEmuBuffer, 0, pdsbd->dwFlags); pEmuBuffer->Host_lock = { 0 }; From 97abbd0a7c1fb4e70b5cf2d4ba7a584290221a7f Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Thu, 14 May 2020 18:43:44 -0500 Subject: [PATCH 15/19] replace virtual functions to VMT comments --- .../hle/DSOUND/common/XbInternalStruct.hpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/core/hle/DSOUND/common/XbInternalStruct.hpp b/src/core/hle/DSOUND/common/XbInternalStruct.hpp index 2b1aef6a5..ede81073f 100644 --- a/src/core/hle/DSOUND/common/XbInternalStruct.hpp +++ b/src/core/hle/DSOUND/common/XbInternalStruct.hpp @@ -32,7 +32,7 @@ namespace XTL { // TODO: Everything, only small portions had been implemented. // Note to all maintainers, make sure structure's class-like are not misalign. -// There is always a virtual function pointer to vtable list at offset 0 (uint32_t size). +// There is always a VMT (Virtual Method Table) pointer at offset 0x00 (uint32_t size). // Afterward are depending on what internal data are placed. So, whenever implementing a functions. // Whenever implementing functional codes, make sure they are at the bottom of the xbox's structure. Thanks! @@ -48,10 +48,10 @@ struct CUnknownGenericManager { // construct vtable (or grab ptr to existing) CUnknownGenericManager() : ref_count(1) {} - // all virtual functions are stored in local offset 0x00's pointer - virtual ~CUnknownGenericManager() {}; // 0x00 - virtual uint32_t WINAPI AddRef() { return ++ref_count; }; // 0x04 - virtual uint32_t WINAPI Release() { return --ref_count; }; // 0x08 + // all VMT (Virtual Method Table) are stored in local offset 0x00's pointer + virtual ~CUnknownGenericManager() {}; // 0x00 + virtual uint32_t WINAPI AddRef() { return ++ref_count; }; // 0x04 + virtual uint32_t WINAPI Release() { return --ref_count; }; // 0x08 uint32_t ref_count; // 0x04 }; @@ -62,7 +62,7 @@ struct CUnknownTemplate { // construct vtable (or grab ptr to existing) CUnknownTemplate(); - virtual ~CUnknownTemplate() {}; // 0x00 + virtual ~CUnknownTemplate() {}; // 0x00 virtual void WINAPI pUnknown_04() { throw std::exception("pUnknown_04"); }; // 0x04 virtual void WINAPI pUnknown_08() { throw std::exception("pUnknown_08"); }; // 0x08 virtual void WINAPI pUnknown_0C() { throw std::exception("pUnknown_0C"); }; // 0x0C @@ -70,7 +70,7 @@ struct CUnknownTemplate { virtual void WINAPI pUnknown_14() { throw std::exception("pUnknown_14"); }; // 0x14 virtual void WINAPI pUnknown_18() { throw std::exception("pUnknown_18"); }; // 0x18 virtual void WINAPI pUnknown_1C() { throw std::exception("pUnknown_1C"); }; // 0x1C - // If need to add more virtual functions, add them above here. + // If need to add more VMT (Virtual Method Table), add them above here. uint32_t ref_count; // 0x04 }; // Require to verify there is no other unknown additional data by compiler itself. @@ -78,7 +78,7 @@ static_assert(sizeof(CUnknownTemplate) == 0x08); struct CMcpxVoiceClient: CUnknownTemplate { CMcpxVoiceClient() : settings(default_settings) {}; - // all virtual functions are stored in local offset 0x00's pointer + // all VMT (Virtual Method Table) are stored in local offset 0x00's pointer virtual ~CMcpxVoiceClient() {}; // CUnknownTemplate // 0x00 - ??? @@ -96,7 +96,7 @@ static_assert(sizeof(CMcpxVoiceClient) == 0x300); struct CDirectSoundVoice : CUnknownGenericManager { CDirectSoundVoice(bool is3D); - // all virtual functions are stored in local offset 0x00's pointer + // all VMT (Virtual Method Table) are stored in local offset 0x00's pointer virtual ~CDirectSoundVoice(); // CUnknownGenericManager // 0x00 - ??? From 95e8642970d0e528cbac111155fd8169117ba8e3 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Thu, 14 May 2020 18:46:16 -0500 Subject: [PATCH 16/19] fix placeholder reference counter --- src/core/hle/DSOUND/common/XbInternalStruct.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/hle/DSOUND/common/XbInternalStruct.hpp b/src/core/hle/DSOUND/common/XbInternalStruct.hpp index ede81073f..d8389db0b 100644 --- a/src/core/hle/DSOUND/common/XbInternalStruct.hpp +++ b/src/core/hle/DSOUND/common/XbInternalStruct.hpp @@ -50,8 +50,8 @@ struct CUnknownGenericManager { // all VMT (Virtual Method Table) are stored in local offset 0x00's pointer virtual ~CUnknownGenericManager() {}; // 0x00 - virtual uint32_t WINAPI AddRef() { return ++ref_count; }; // 0x04 - virtual uint32_t WINAPI Release() { return --ref_count; }; // 0x08 + virtual uint32_t WINAPI AddRef() { return ref_count++; }; // 0x04 + virtual uint32_t WINAPI Release() { return ref_count--; }; // 0x08 uint32_t ref_count; // 0x04 }; From 9871b25fa87c9ca656b862b8e5033e0d1e9bf295 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Thu, 14 May 2020 19:09:19 -0500 Subject: [PATCH 17/19] move audio converter helper --- CMakeLists.txt | 1 + src/common/audio/converter.hpp | 51 +++++++++++++++++++ .../DSOUND/DirectSound/DirectSoundInline.hpp | 6 +-- src/core/hle/DSOUND/XbDSoundTypes.h | 24 --------- .../hle/DSOUND/common/XbInternalDSVoice.cpp | 6 +-- .../hle/DSOUND/common/XbInternalStruct.hpp | 1 + 6 files changed, 59 insertions(+), 30 deletions(-) create mode 100644 src/common/audio/converter.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4297f44ad..dbb211c5d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,6 +130,7 @@ file (GLOB CXBXR_HEADER_GUIv1 # Emulator (module) file (GLOB CXBXR_HEADER_EMU "${CXBXR_ROOT_DIR}/src/common/AddressRanges.h" + "${CXBXR_ROOT_DIR}/src/common/audio/converter.hpp" "${CXBXR_ROOT_DIR}/src/common/util/gloffscreen/glextensions.h" "${CXBXR_ROOT_DIR}/src/common/util/gloffscreen/gloffscreen.h" "${CXBXR_ROOT_DIR}/src/common/XADPCM.h" diff --git a/src/common/audio/converter.hpp b/src/common/audio/converter.hpp new file mode 100644 index 000000000..9c45e12bb --- /dev/null +++ b/src/common/audio/converter.hpp @@ -0,0 +1,51 @@ +// ****************************************************************** +// * +// * This file is part of the Cxbx project. +// * +// * Cxbx and Cxbe are free software; you can redistribute them +// * and/or modify them under the terms of the GNU General Public +// * License as published by the Free Software Foundation; either +// * version 2 of the license, or (at your option) any later version. +// * +// * This program 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 General Public License for more details. +// * +// * You should have recieved a copy of the GNU General Public License +// * along with this program; see the file COPYING. +// * If not, write to the Free Software Foundation, Inc., +// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// * +// * (c) 2020 RadWolfie +// * +// * All rights reserved +// * +// ****************************************************************** +#pragma once + +#include + +// Convert frequency to pitch helper +static inline int32_t converter_freq2pitch(uint32_t freq) { + // NOTE: pitch = 0 is equal to 48 KHz. + /* For research purpose of how to convert frequency to pitch and back to frequency. + // Edit hertz variable to see the result. + float hertz = 12000.0f; + + float hertzRatio = 48000.0f; + float pitchRatio = 4096.0f; + + // Convert hertz to pitch + float pitch = log2(hertz / hertzRatio) * pitchRatio; + + // Convert pitch to hertz + hertz = exp((pitch / pitchRatio) * log(2)) * hertzRatio;*/ + return static_cast(log2(freq / 48000.0f) * 4096.0f); +} + +// Convert pitch to frequency helper +static inline uint32_t converter_pitch2freq(int32_t pitch) { + //* See research documentation above for conversion example. + return static_cast(exp((pitch / 4096.0f) * log(2)) * 48000.0f); +} diff --git a/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp b/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp index 714a28219..8376df2f6 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp @@ -427,7 +427,7 @@ static inline void DSoundBufferTransferSettings( } // if sync current frequency used (then use pitch only). - uint32_t freq = XTL::converter_pitch2freq(Xb_Voice->GetPitch()); + uint32_t freq = converter_pitch2freq(Xb_Voice->GetPitch()); pDSBufferNew->SetFrequency(freq); pDSBufferOld->GetVolume(&lVolume); @@ -1158,7 +1158,7 @@ static inline HRESULT HybridDirectSoundBuffer_SetFrequency( { HRESULT hRet = S_OK; - int32_t pitch = XTL::converter_freq2pitch((dwFrequency!=0 ? dwFrequency : Xb_Voice->GetFrequencyDefault())); + int32_t pitch = converter_freq2pitch((dwFrequency!=0 ? dwFrequency : Xb_Voice->GetFrequencyDefault())); hRet = HybridDirectSoundBuffer_SetPitch(pDSBuffer, pitch, Xb_Voice); @@ -1374,7 +1374,7 @@ static inline HRESULT HybridDirectSoundBuffer_SetPitch( Xb_Voice->SetPitch(lPitch); // Convert pitch back to frequency - uint32_t setFrequency = XTL::converter_pitch2freq(lPitch); + uint32_t setFrequency = converter_pitch2freq(lPitch); RETURN_RESULT_CHECK(pDSBuffer->SetFrequency(setFrequency)); } diff --git a/src/core/hle/DSOUND/XbDSoundTypes.h b/src/core/hle/DSOUND/XbDSoundTypes.h index b86fdef36..62ea3a782 100644 --- a/src/core/hle/DSOUND/XbDSoundTypes.h +++ b/src/core/hle/DSOUND/XbDSoundTypes.h @@ -369,30 +369,6 @@ struct X_DSVOICEPROPS { LONG lI3DL2DirectVolume; LONG lI3DL2RoomVolume; }; - -// Convert frequency to pitch helper -static inline int32_t converter_freq2pitch(uint32_t freq) { - // NOTE: pitch = 0 is equal to 48 KHz. - /* For research purpose of how to convert frequency to pitch and back to frequency. - // Edit hertz variable to see the result. - float hertz = 12000.0f; - - float hertzRatio = 48000.0f; - float pitchRatio = 4096.0f; - - // Convert hertz to pitch - float pitch = log2(hertz / hertzRatio) * pitchRatio; - - // Convert pitch to hertz - hertz = exp((pitch / pitchRatio) * log(2)) * hertzRatio;*/ - return static_cast(log2(freq / 48000.0f) * 4096.0f); -} - -// Convert pitch to frequency helper -static inline uint32_t converter_pitch2freq(int32_t pitch) { - //* See research documentation above for conversion example. - return static_cast(exp((pitch / 4096.0f) * log(2)) * 48000.0f); -} } // end of namespace XTL diff --git a/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp b/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp index 44de79958..bbbe49cbf 100644 --- a/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp +++ b/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp @@ -58,7 +58,7 @@ void SetFormat_4034_lower(T& settings, XTL::audio_format format) if (format.audio_codec == WAVE_FORMAT_XBOX_ADPCM) { settings.p_audio_format->wSamplesPerBlock = 64; } - settings.pitch = XTL::converter_freq2pitch(format.nSamplesPerSec); + settings.pitch = converter_freq2pitch(format.nSamplesPerSec); } template void SetFormat_4039_only(T& settings, XTL::audio_format format) @@ -68,7 +68,7 @@ void SetFormat_4039_only(T& settings, XTL::audio_format format) settings.cbSize = format.cbSize; settings.nSamplesPerSec_default = format.nSamplesPerSec; settings.bitsPerSample = format.bitsPerSample; - settings.pitch = XTL::converter_freq2pitch(format.nSamplesPerSec); + settings.pitch = converter_freq2pitch(format.nSamplesPerSec); } template void SetFormat_4134_upper(T& settings, XTL::audio_format format) @@ -78,7 +78,7 @@ void SetFormat_4134_upper(T& settings, XTL::audio_format format) settings.cbSize = static_cast(format.cbSize); settings.nSamplesPerSec_default = format.nSamplesPerSec; settings.bitsPerSample = format.bitsPerSample; - settings.pitch = XTL::converter_freq2pitch(format.nSamplesPerSec); + settings.pitch = converter_freq2pitch(format.nSamplesPerSec); } // Interface for get frequency diff --git a/src/core/hle/DSOUND/common/XbInternalStruct.hpp b/src/core/hle/DSOUND/common/XbInternalStruct.hpp index d8389db0b..1368ebb30 100644 --- a/src/core/hle/DSOUND/common/XbInternalStruct.hpp +++ b/src/core/hle/DSOUND/common/XbInternalStruct.hpp @@ -26,6 +26,7 @@ #include "Cxbx.h" #include "core\hle\DSOUND\XbDSoundTypes.h" +#include "common/audio/converter.hpp" namespace XTL { From 772e6ed18e172ff9f14883e48934e5c5c1c6da6d Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Thu, 14 May 2020 19:12:37 -0500 Subject: [PATCH 18/19] add PatrickvL comments --- src/common/audio/converter.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/audio/converter.hpp b/src/common/audio/converter.hpp index 9c45e12bb..75dc1b965 100644 --- a/src/common/audio/converter.hpp +++ b/src/common/audio/converter.hpp @@ -33,8 +33,8 @@ static inline int32_t converter_freq2pitch(uint32_t freq) { // Edit hertz variable to see the result. float hertz = 12000.0f; - float hertzRatio = 48000.0f; - float pitchRatio = 4096.0f; + float hertzRatio = 48000.0f; // base frequency + float pitchRatio = 4096.0f; // pitch per octave // Convert hertz to pitch float pitch = log2(hertz / hertzRatio) * pitchRatio; From ba8adc04f4ed7ca253b4472f6cea1bdec1c70663 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Fri, 15 May 2020 04:01:06 -0500 Subject: [PATCH 19/19] add todo comment --- src/core/hle/DSOUND/common/XbInternalStruct.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/hle/DSOUND/common/XbInternalStruct.hpp b/src/core/hle/DSOUND/common/XbInternalStruct.hpp index 1368ebb30..a026f1a20 100644 --- a/src/core/hle/DSOUND/common/XbInternalStruct.hpp +++ b/src/core/hle/DSOUND/common/XbInternalStruct.hpp @@ -50,6 +50,7 @@ struct CUnknownGenericManager { CUnknownGenericManager() : ref_count(1) {} // all VMT (Virtual Method Table) are stored in local offset 0x00's pointer + // TODO: Implement to use derived's override AddRef/Release. Also, each class has its own ref counter and is not shareable. virtual ~CUnknownGenericManager() {}; // 0x00 virtual uint32_t WINAPI AddRef() { return ref_count++; }; // 0x04 virtual uint32_t WINAPI Release() { return ref_count--; }; // 0x08