diff --git a/CMakeLists.txt b/CMakeLists.txt index 61264e9a9..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" @@ -154,6 +155,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 +298,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/common/audio/converter.hpp b/src/common/audio/converter.hpp new file mode 100644 index 000000000..75dc1b965 --- /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; // base frequency + float pitchRatio = 4096.0f; // pitch per octave + + // 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/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 e4d87f7ac..c5f3be1cd 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,25 @@ typedef struct _DSoundBuffer_Lock { // ****************************************************************** // * X_CDirectSoundBuffer // ****************************************************************** -struct X_CDirectSoundBuffer +struct XbHybridDSBuffer; +struct EmuDirectSoundBuffer { - BYTE UnknownA[0x20]; // Offset: 0x00 + virtual ~EmuDirectSoundBuffer(); + XbHybridDSBuffer* pHybridThis; - 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; @@ -106,14 +107,26 @@ struct X_CDirectSoundBuffer DSoundBuffer_Lock X_lock; 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_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; + + virtual ~SharedDSBuffer() { + delete emuDSBuffer; + } +}; //Custom flags (4 bytes support up to 31 shifts,starting from 0) #define DSE_FLAG_PCM (1 << 0) @@ -188,7 +201,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 +256,8 @@ class X_CDirectSoundStream #endif public: + // Placeholder until have positive offset + CDirectSoundVoice Xb_Voice; // cached data LPDIRECTSOUNDBUFFER8 EmuDirectSoundBuffer8; LPDIRECTSOUND3DBUFFER8 EmuDirectSound3DBuffer8; @@ -263,12 +278,9 @@ class X_CDirectSoundStream LPVOID Xb_lpvContext; 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 Xb_Frequency; DWORD Host_dwLastWritePos; DWORD Xb_Flags; DWORD Xb_Status; @@ -481,7 +493,7 @@ HRESULT WINAPI EMUPATCH(IDirectSound_SetMixBinHeadroom) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMixBins) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwMixBinMask ); @@ -490,7 +502,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMixBins) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMixBinVolumes_12) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwMixBinMask, const LONG* alVolumes ); @@ -500,7 +512,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMixBinVolumes_12) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMixBinVolumes_8) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, X_LPDSMIXBINS pMixBins ); @@ -551,10 +563,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 +574,8 @@ HRESULT WINAPI EMUPATCH(IDirectSound_CreateSoundBuffer) // ****************************************************************** HRESULT WINAPI EMUPATCH(DirectSoundCreateBuffer) ( - X_DSBUFFERDESC* pdsbd, - X_CDirectSoundBuffer** ppBuffer + X_DSBUFFERDESC* pdsbd, + XbHybridDSBuffer** ppBuffer ); // ****************************************************************** @@ -571,9 +583,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 +593,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 +603,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPlayRegion) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Lock) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwOffset, DWORD dwBytes, LPVOID* ppvAudioPtr1, @@ -605,7 +617,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Lock) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Unlock) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, LPVOID ppvAudioPtr1, DWORD pdwAudioBytes1, LPVOID ppvAudioPtr2, @@ -617,7 +629,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Unlock) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetHeadroom) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwHeadroom ); @@ -626,7 +638,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetHeadroom) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetLoopRegion) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwLoopStart, DWORD dwLoopLength ); @@ -636,7 +648,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetLoopRegion) // ****************************************************************** ULONG WINAPI EMUPATCH(IDirectSoundBuffer_Release) ( - X_CDirectSoundBuffer* pThis + XbHybridDSBuffer* pHybridThis ); // ****************************************************************** @@ -644,7 +656,7 @@ ULONG WINAPI EMUPATCH(IDirectSoundBuffer_Release) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPitch) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, LONG lPitch ); @@ -653,7 +665,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPitch) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_GetStatus) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, LPDWORD pdwStatus ); @@ -662,7 +674,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_GetStatus) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVolume) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, LONG lVolume ); @@ -671,7 +683,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVolume) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetCurrentPosition) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwNewPosition ); @@ -680,7 +692,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetCurrentPosition) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_GetCurrentPosition) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, PDWORD pdwCurrentPlayCursor, PDWORD pdwCurrentWriteCursor ); @@ -690,7 +702,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_GetCurrentPosition) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Stop) ( - X_CDirectSoundBuffer* pThis + XbHybridDSBuffer* pHybridThis ); // ****************************************************************** @@ -698,9 +710,9 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Stop) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_StopEx) ( - X_CDirectSoundBuffer *pBuffer, - REFERENCE_TIME rtTimeStamp, - DWORD dwFlags + XbHybridDSBuffer* pHybridThis, + REFERENCE_TIME rtTimeStamp, + DWORD dwFlags ); // ****************************************************************** @@ -708,7 +720,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_StopEx) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Play) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwReserved1, DWORD dwReserved2, DWORD dwFlags @@ -719,7 +731,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Play) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_PlayEx) ( - X_CDirectSoundBuffer* pBuffer, + XbHybridDSBuffer* pHybridThis, REFERENCE_TIME rtTimeStamp, DWORD dwFlags ); @@ -729,7 +741,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_PlayEx) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVolume) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, LONG lVolume ); @@ -738,7 +750,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVolume) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetFrequency) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwFrequency ); @@ -972,7 +984,7 @@ HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetMixBins) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMaxDistance) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT flMaxDistance, DWORD dwApply ); @@ -982,7 +994,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMaxDistance) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMinDistance) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT flMaxDistance, DWORD dwApply ); @@ -992,7 +1004,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMinDistance) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetRolloffFactor) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT flRolloffFactor, DWORD dwApply ); @@ -1002,7 +1014,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetRolloffFactor) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetDistanceFactor) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT flDistanceFactor, DWORD dwApply ); @@ -1012,7 +1024,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetDistanceFactor) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeAngles) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwInsideConeAngle, DWORD dwOutsideConeAngle, DWORD dwApply @@ -1023,7 +1035,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeAngles) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeOrientation) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT x, FLOAT y, FLOAT z, @@ -1035,7 +1047,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeOrientation) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeOutsideVolume) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, LONG lConeOutsideVolume, DWORD dwApply ); @@ -1045,7 +1057,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeOutsideVolume) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPosition) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT x, FLOAT y, FLOAT z, @@ -1057,7 +1069,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPosition) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVelocity) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT x, FLOAT y, FLOAT z, @@ -1069,7 +1081,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVelocity) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetDopplerFactor) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, FLOAT flDopplerFactor, DWORD dwApply ); @@ -1079,7 +1091,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetDopplerFactor) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetI3DL2Source) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, X_DSI3DL2BUFFER* pds3db, DWORD dwApply ); @@ -1090,7 +1102,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetI3DL2Source) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMode) ( - X_CDirectSoundBuffer* pBuffer, + XbHybridDSBuffer* pHybridThis, DWORD dwMode, DWORD dwApply ); @@ -1100,7 +1112,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMode) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetFormat) ( - X_CDirectSoundBuffer *pBuffer, + XbHybridDSBuffer* pHybridThis, LPCWAVEFORMATEX pwfxFormat ); @@ -1129,8 +1141,8 @@ void WINAPI EMUPATCH(DirectSoundUseLightHRTF4Channel)(void); // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetLFO) ( - LPDIRECTSOUNDBUFFER8 pThis, - LPCDSLFODESC pLFODesc + XbHybridDSBuffer* pHybridThis, + LPCDSLFODESC pLFODesc ); // ****************************************************************** @@ -1157,7 +1169,7 @@ VOID WINAPI EMUPATCH(XAudioCreateAdpcmFormat) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetRolloffCurve) ( - LPDIRECTSOUNDBUFFER8 pThis, + XbHybridDSBuffer* pHybridThis, const FLOAT* pflPoints, DWORD dwPointCount, DWORD dwApply @@ -1186,7 +1198,7 @@ HRESULT WINAPI EMUPATCH(IDirectSound_EnableHeadphones) // ****************************************************************** ULONG WINAPI EMUPATCH(IDirectSoundBuffer_AddRef) ( - X_CDirectSoundBuffer* pThis + XbHybridDSBuffer* pHybridThis ); // ****************************************************************** @@ -1194,7 +1206,7 @@ ULONG WINAPI EMUPATCH(IDirectSoundBuffer_AddRef) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Pause) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwPause ); @@ -1203,7 +1215,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Pause) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_PauseEx) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, REFERENCE_TIME rtTimestamp, DWORD dwPause ); @@ -1263,8 +1275,8 @@ HRESULT WINAPI EMUPATCH(XAudioDownloadEffectsImage) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetFilter) ( - LPVOID pThis, - X_DSFILTERDESC* pFilterDesc + XbHybridDSBuffer* pHybridThis, + X_DSFILTERDESC* pFilterDesc ); // ****************************************************************** @@ -1333,7 +1345,7 @@ HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetI3DL2Source) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetAllParameters) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, X_DS3DBUFFER* pc3DBufferParameters, DWORD dwApply ); @@ -1352,8 +1364,8 @@ HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetFormat) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetOutputBuffer) ( - X_CDirectSoundBuffer* pThis, - X_CDirectSoundBuffer* pOutputBuffer + XbHybridDSBuffer* pHybridThis, + XbHybridDSBuffer* pOutputBuffer ); // ****************************************************************** @@ -1361,8 +1373,8 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetOutputBuffer) // ****************************************************************** HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetOutputBuffer) ( - X_CDirectSoundStream* pThis, - X_CDirectSoundBuffer* pOutputBuffer + X_CDirectSoundStream* pThis, + XbHybridDSBuffer* pOutputBuffer ); // ****************************************************************** @@ -1389,8 +1401,8 @@ HRESULT WINAPI EMUPATCH(XWaveFileCreateMediaObject) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetEG) ( - X_CDirectSoundBuffer* pThis, - X_DSENVOLOPEDESC* pEnvelopeDesc + XbHybridDSBuffer* pHybridThis, + X_DSENVOLOPEDESC* pEnvelopeDesc ); // ****************************************************************** @@ -1410,8 +1422,8 @@ HRESULT WINAPI EMUPATCH(IDirectSound_GetEffectData) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetNotificationPositions) ( - X_CDirectSoundBuffer* pThis, - DWORD dwNotifyCount, + XbHybridDSBuffer* pHybridThis, + DWORD dwNotifyCount, LPCDSBPOSITIONNOTIFY paNotifies ); @@ -1420,7 +1432,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetNotificationPositions) // ****************************************************************** HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetRolloffCurve) ( - X_CDirectSoundBuffer* pThis, + X_CDirectSoundStream* pThis, const FLOAT* pflPoints, DWORD dwPointCount, DWORD dwApply @@ -1444,8 +1456,8 @@ HRESULT WINAPI EMUPATCH(IDirectSound_SetEffectData) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Use3DVoiceData) ( - LPVOID pThis, - LPUNKNOWN pUnknown + XbHybridDSBuffer* pHybridThis, + LPUNKNOWN pUnknown ); // ****************************************************************** @@ -1597,7 +1609,7 @@ HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetDopplerFactor) // ****************************************************************** HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_GetVoiceProperties) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, OUT X_DSVOICEPROPS* pVoiceProps); // ****************************************************************** @@ -1696,7 +1708,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..b0547dc63 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,53 +97,63 @@ 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); 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 // ****************************************************************** 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(); 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(), pThis); - 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); - } - - delete pThis; + size_t size = sizeof(SharedDSBuffer) - sizeof(XbHybridDSBuffer); + SharedDSBuffer* pSharedThis = reinterpret_cast(reinterpret_cast(pHybridThis) - size); + delete pSharedThis; } //} @@ -156,7 +166,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 +213,27 @@ 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; + pEmuBuffer->pHybridThis = pHybridBuffer; - 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 +245,16 @@ 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); } - 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, + pEmuBuffer->Xb_VolumeMixbin, pHybridBuffer->p_CDSVoice); - g_pDSoundBufferCache.push_back(*ppBuffer); + g_pDSoundBufferCache.push_back(pHybridBuffer); } } @@ -254,7 +268,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSound_CreateSoundBuffer) ( LPDIRECTSOUND8 pThis, X_DSBUFFERDESC* pdsbd, - OUT X_CDirectSoundBuffer** ppBuffer, + OUT XbHybridDSBuffer** ppBuffer, LPUNKNOWN pUnkOuter) { DSoundMutexGuardLock; @@ -273,18 +287,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 +310,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 +338,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 +378,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 +393,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 +404,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 +416,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 +426,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 +477,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 +487,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 +526,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 +558,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 +582,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 +590,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 +625,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 +646,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 +673,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 +696,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 +754,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 +769,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 +781,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 +789,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 +806,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 +815,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 +833,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 +856,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 +878,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetDistanceFactor) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetDopplerFactor) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pThis, FLOAT flDopplerFactor, DWORD dwApply) { @@ -872,13 +900,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 +914,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetEG) LOG_NOT_SUPPORTED(); + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; pThis->Xb_EnvolopeDesc = *pEnvelopeDesc; return S_OK; @@ -896,13 +925,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 +948,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 +973,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 +995,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; - HRESULT hRet = HybridDirectSoundBuffer_SetHeadroom(pThis->EmuDirectSoundBuffer8, dwHeadroom, pThis->Xb_dwHeadroom, - pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->EmuFlags); + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; + HRESULT hRet = HybridDirectSoundBuffer_SetHeadroom(pThis->EmuDirectSoundBuffer8, dwHeadroom, + pThis->Xb_VolumeMixbin, pThis->EmuFlags, + pHybridThis->p_CDSVoice); return hRet; } @@ -984,14 +1018,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 +1044,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 +1066,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 +1081,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 +1093,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 +1108,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 +1131,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 +1154,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMinDistance) // ****************************************************************** HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMixBins) ( - X_CDirectSoundBuffer* pThis, + XbHybridDSBuffer* pHybridThis, DWORD dwMixBinMask) { DSoundMutexGuardLock; @@ -1126,7 +1163,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 +1171,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 +1188,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 +1214,19 @@ 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_VolumeMixbin, pHybridThis->p_CDSVoice); return hRet; } @@ -1197,18 +1236,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 +1259,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 +1305,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 +1329,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 +1351,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 +1366,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 +1382,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 +1396,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 +1405,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 +1423,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 +1431,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 +1449,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 +1473,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 +1482,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 +1500,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; - HRESULT hRet = HybridDirectSoundBuffer_SetVolume(pThis->EmuDirectSoundBuffer8, lVolume, pThis->EmuFlags, &pThis->Xb_Volume, - pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom); + EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; + HRESULT hRet = HybridDirectSoundBuffer_SetVolume(pThis->EmuDirectSoundBuffer8, lVolume, pThis->EmuFlags, + pThis->Xb_VolumeMixbin, pHybridThis->p_CDSVoice); return hRet; } @@ -1475,16 +1522,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 +1545,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 +1610,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 +1639,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 +1660,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 7435c0575..8376df2f6 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; @@ -289,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; } @@ -303,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; @@ -391,12 +392,9 @@ 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_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 +403,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 +417,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 +426,9 @@ static inline void DSoundBufferTransferSettings( return; } - pDSBufferNew->SetFrequency(Xb_Frequency); + // if sync current frequency used (then use pitch only). + uint32_t freq = converter_pitch2freq(Xb_Voice->GetPitch()); + pDSBufferNew->SetFrequency(freq); pDSBufferOld->GetVolume(&lVolume); pDSBufferNew->SetVolume(lVolume); @@ -449,7 +449,7 @@ static inline void DSoundBufferReCreate( LPDIRECTSOUND3DBUFFER8 &pDS3DBuffer, LPDIRECTSOUNDBUFFER8 &pDSBufferNew, LPDIRECTSOUND3DBUFFER8 &pDS3DBufferNew, - DWORD Xb_Frequency) { + XTL::CDirectSoundVoice* Xb_Voice) { DSoundBufferCreate(&DSBufferDesc, pDSBufferNew); @@ -458,7 +458,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 +484,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 +509,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 +523,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 +548,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 +581,7 @@ static inline void DSoundBufferRegionCurrentLocation( } static inline void DSoundBufferUpdate( - XTL::X_CDirectSoundBuffer* pThis, + XTL::XbHybridDSBuffer* pHybridThis, DWORD dwPlayFlags, HRESULT &hRet) { @@ -585,24 +589,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); @@ -680,6 +684,40 @@ static inline HRESULT DSoundBufferSynchPlaybackFlagAdd( return DS_OK; } +static inline HRESULT DSoundBufferUpdateHostVolume( + LPDIRECTSOUNDBUFFER8 pDSBuffer, + uint32_t dwEmuFlags, + int32_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 @@ -1045,7 +1083,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 +1094,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( @@ -1082,15 +1120,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 +1141,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 = converter_freq2pitch((dwFrequency!=0 ? dwFrequency : Xb_Voice->GetFrequencyDefault())); + + 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, LONG, XTL::CDirectSoundVoice*); //IDirectSoundStream //IDirectSoundBuffer @@ -1130,18 +1173,18 @@ 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) + DWORD dwEmuFlags, + XTL::CDirectSoundVoice* Xb_Voice) { HRESULT hRet; 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->SetHeadroom(dwHeadroom); + int32_t volume = Xb_Voice->GetVolume(); + hRet = DSoundBufferUpdateHostVolume(pDSBuffer, dwEmuFlags, volume); } return DS_OK; @@ -1231,9 +1274,8 @@ static inline HRESULT HybridDirectSoundBuffer_SetMixBinVolumes_8( XTL::X_LPDSMIXBINS pMixBins, XTL::X_DSVOICEPROPS& Xb_VoiceProperties, DWORD EmuFlags, - LONG Xb_volume, LONG &Xb_volumeMixBin, - DWORD Xb_dwHeadroom) + XTL::CDirectSoundVoice* Xb_Voice) { HRESULT hRet = DSERR_INVALIDPARAM; @@ -1273,8 +1315,9 @@ 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); + int32_t Xb_volume = Xb_Voice->GetVolume(); + hRet = HybridDirectSoundBuffer_SetVolume(pDSBuffer, Xb_volume, EmuFlags, + Xb_volumeMixBin, Xb_Voice); } else { hRet = DS_OK; } @@ -1326,27 +1369,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(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 = 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. @@ -1429,46 +1459,20 @@ 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(lVolume); + 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 cf5c0e953..4625c0044 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. @@ -269,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); + HybridDirectSoundBuffer_SetVolume((*ppStream)->EmuDirectSoundBuffer8, 0L, (*ppStream)->EmuFlags, + (*ppStream)->Xb_VolumeMixbin, &(*ppStream)->Xb_Voice); g_pDSoundStreamCache.push_back(*ppStream); } @@ -912,7 +913,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 +933,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; } @@ -967,8 +968,8 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetHeadroom) LOG_FUNC_ARG(dwHeadroom) LOG_FUNC_END; - HRESULT hRet = HybridDirectSoundBuffer_SetHeadroom(pThis->EmuDirectSoundBuffer8, dwHeadroom, pThis->Xb_dwHeadroom, - pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->EmuFlags); + HRESULT hRet = HybridDirectSoundBuffer_SetHeadroom(pThis->EmuDirectSoundBuffer8, dwHeadroom, + pThis->Xb_VolumeMixbin, pThis->EmuFlags, &pThis->Xb_Voice); return hRet; } @@ -1208,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_VolumeMixbin, &pThis->Xb_Voice); return hRet; } @@ -1219,7 +1220,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 +1253,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; } @@ -1303,7 +1304,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) @@ -1387,8 +1388,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); + HRESULT hRet = HybridDirectSoundBuffer_SetVolume(pThis->EmuDirectSoundBuffer8, lVolume, pThis->EmuFlags, + pThis->Xb_VolumeMixbin, &pThis->Xb_Voice); return hRet; } diff --git a/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp b/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp new file mode 100644 index 000000000..bbbe49cbf --- /dev/null +++ b/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp @@ -0,0 +1,213 @@ +// ****************************************************************** +// * +// * 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 +template +void GetFormat_4034_lower(T& settings, XTL::audio_format& format) +{ + 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; +} +template +void GetFormat_4039_upper(T& settings, XTL::audio_format& format) +{ + 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 +template +void SetFormat_4034_lower(T& settings, XTL::audio_format format) +{ + 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) { + settings.p_audio_format->wSamplesPerBlock = 64; + } + settings.pitch = converter_freq2pitch(format.nSamplesPerSec); +} +template +void SetFormat_4039_only(T& settings, XTL::audio_format format) +{ + 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 = converter_freq2pitch(format.nSamplesPerSec); +} +template +void SetFormat_4134_upper(T& settings, XTL::audio_format format) +{ + 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 = converter_freq2pitch(format.nSamplesPerSec); +} + +// Interface for get frequency +template +uint32_t GetFrequencyDefault_4034_lower(T& settings) +{ + return settings.p_audio_format->wfx.nSamplesPerSec; +} +template +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) +{ + return settings.pitch; +} + +// Interface for set pitch +template +void SetPitch(T& settings, int32_t pitch) +{ + settings.pitch = pitch; +} + +// Interface for get volume +template +uint32_t GetVolume(T& settings) +{ + return settings.volume; +} + +// Interface for set volume +template +void SetVolume(T& settings, uint32_t volume) +{ + settings.volume = volume - settings.headroom; +} + +// Interface for get headroom +template +uint32_t GetHeadroom(T& settings) +{ + return settings.headroom; +} + +// Interface for set headroom +template +void SetHeadroom(T& settings, uint32_t set_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; +} +template +void Init(T& settings, bool is3D) +{ + Init_Headroom(settings.headroom, is3D); + settings.volume = 0 - settings.headroom; + settings.volume = 0 - settings.headroom; +} + +XTL::CDirectSoundVoice::CDirectSoundVoice(bool is3D) +{ + settings = { 0 }; + + if (g_LibVersion_DSOUND < 4039) { + settings.r4034_lower.p_audio_format = new XBOXADPCMWAVEFORMAT; + memset(&settings.r4034_lower.p_audio_format->wfx, 0, sizeof(XBOXADPCMWAVEFORMAT)); + + using settings_template = _settings::_r4034_lower; + Init(settings.r4034_lower, is3D); + + 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) { + + using settings_template = _settings::_r4039_only; + Init(settings.r4039_only, is3D); + + 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 { + + using settings_template = _settings::_r4134_upper; + Init(settings.r4134_upper, is3D); + + 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 (!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.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..a026f1a20 --- /dev/null +++ b/src/core/hle/DSOUND/common/XbInternalStruct.hpp @@ -0,0 +1,246 @@ +// ****************************************************************** +// * +// * 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" +#include "common/audio/converter.hpp" + +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 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! + +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 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 + + 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 { + // 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 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. +static_assert(sizeof(CUnknownTemplate) == 0x08); + +struct CMcpxVoiceClient: CUnknownTemplate { + CMcpxVoiceClient() : settings(default_settings) {}; + // all VMT (Virtual Method Table) 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; +}; +// Require to verify there is no other unknown additional data by compiler itself. +static_assert(sizeof(CMcpxVoiceClient) == 0x300); + +struct CDirectSoundVoice : CUnknownGenericManager { + CDirectSoundVoice(bool is3D); + // all VMT (Virtual Method Table) are stored in local offset 0x00's pointer + virtual ~CDirectSoundVoice(); + + // CUnknownGenericManager // 0x00 - ??? + union _settings { + struct _unknown + { + uint32_t unknown_08[0x300 / 4]; // 0x000 - 0x300 (unknown size, likely over 0x200 size. + } unknown; + + 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) + } r4034_lower; + + 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 + 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 + 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. + } r4039_only; + + struct _r4134_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. + 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. + } 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)(_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; + pGetUint32 GetFrequencyDefault; + pGetInt32 GetPitch; + pSetInt32 SetPitch; + pGetInt32 GetVolume; + pSetInt32 SetVolume; + pGetUint32 GetHeadroom; + pSetUint32 SetHeadroom; + } funcs; + static_assert(sizeof(funcs) == 0x24); // Not really require + + inline void GetFormat(audio_format& format) { + funcs.GetFormat(settings, format); + }; + inline void SetFormat(audio_format format) { + funcs.SetFormat(settings, format); + }; + inline uint32_t GetFrequencyDefault() { + return funcs.GetFrequencyDefault(settings); + }; + inline int32_t GetPitch() { + return funcs.GetPitch(settings); + }; + inline void SetPitch(int32_t pitch) { + funcs.SetPitch(settings, pitch); + }; + inline int32_t GetVolume() { + return funcs.GetVolume(settings); + }; + inline void SetVolume(int32_t volume) { + funcs.SetVolume(settings, volume); + }; + inline uint32_t GetHeadroom() { + return funcs.GetHeadroom(settings); + }; + inline void SetHeadroom(uint32_t 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::_settings) + 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; + } +}; +// Require to verify there is no other unknown additional data by compiler itself. +static_assert(sizeof(DSBUFFER_S) == 0x34); + +} diff --git a/src/core/hle/DSOUND/common/windows/WFXformat.hpp b/src/core/hle/DSOUND/common/windows/WFXformat.hpp index 9118a996a..fc33d8f80 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_format); + return codec_format_ret; }