implement hybrid buffer for partial internal exposure

This commit is contained in:
RadWolfie 2020-05-01 06:25:54 -05:00
parent dab7a608c2
commit d7d1d781d8
11 changed files with 896 additions and 278 deletions

View File

@ -154,6 +154,7 @@ file (GLOB CXBXR_HEADER_EMU
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/DirectSound/DSStream_PacketManager.hpp"
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/XbDSoundLogging.hpp"
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/XbDSoundTypes.h"
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/common/XbInternalStruct.hpp"
"${CXBXR_ROOT_DIR}/src/core/hle/Intercept.hpp"
"${CXBXR_ROOT_DIR}/src/core/hle/Patches.hpp"
"${CXBXR_ROOT_DIR}/src/core/hle/XACTENG/XactEng.h"
@ -296,6 +297,8 @@ file (GLOB CXBXR_SOURCE_EMU
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/DirectSound/DSStream_PacketManager.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/XbDSoundLogging.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/common/XbInternalStruct.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/Intercept.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/Patches.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/XACTENG/XactEng.cpp"

View File

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

View File

@ -28,6 +28,7 @@
#include "core\kernel\init\CxbxKrnl.h"
#include "core\hle\DSOUND\XbDSoundTypes.h"
#include "core\hle\DSOUND\common\XbInternalStruct.hpp"
typedef struct IDirectSound3DListener8* LPDIRECTSOUND3DLISTENER8;
typedef struct IDirectSound3DBuffer8* LPDIRECTSOUND3DBUFFER8;
@ -73,25 +74,21 @@ typedef struct _DSoundBuffer_Lock {
// ******************************************************************
// * X_CDirectSoundBuffer
// ******************************************************************
struct X_CDirectSoundBuffer
struct EmuDirectSoundBuffer
{
BYTE UnknownA[0x20]; // Offset: 0x00
union // Offset: 0x20
union
{
PVOID pMpcxBuffer;
LPDIRECTSOUNDBUFFER8 EmuDirectSoundBuffer8;
};
BYTE UnknownB[0x0C]; // Offset: 0x24
LPVOID X_BufferCache; // Offset: 0x28
DSBUFFERDESC EmuBufferDesc; // Offset: 0x2C
/*LPVOID EmuLockPtr1; // Offset: 0x30
DWORD EmuLockBytes1; // Offset: 0x34
LPVOID EmuLockPtr2; // Offset: 0x38
DWORD EmuLockBytes2; // Offset: 0x3C*/
DWORD EmuPlayFlags; // Offset: 0x40
DWORD EmuFlags; // Offset: 0x44
LPVOID X_BufferCache;
DSBUFFERDESC EmuBufferDesc;
/*LPVOID EmuLockPtr1;
DWORD EmuLockBytes1;
LPVOID EmuLockPtr2;
DWORD EmuLockBytes2;*/
DWORD EmuPlayFlags;
DWORD EmuFlags;
LPDIRECTSOUND3DBUFFER8 EmuDirectSound3DBuffer8;
//DWORD EmuLockOffset;
//DWORD EmuLockFlags;
@ -111,9 +108,19 @@ struct X_CDirectSoundBuffer
DWORD Xb_dwHeadroom;
X_DSENVOLOPEDESC Xb_EnvolopeDesc;
X_DSVOICEPROPS Xb_VoiceProperties;
DWORD Xb_Frequency;
DWORD Xb_Flags;
};
struct XbHybridDSBuffer : DSBUFFER_S::DSBUFFER_I {
EmuDirectSoundBuffer* emuDSBuffer;
};
struct SharedDSBuffer : DSBUFFER_S {
SharedDSBuffer(bool is3D) : DSBUFFER_S(is3D) {
emuDSBuffer = new EmuDirectSoundBuffer();
}
EmuDirectSoundBuffer* emuDSBuffer;
};
//Custom flags (4 bytes support up to 31 shifts,starting from 0)
#define DSE_FLAG_PCM (1 << 0)
@ -188,7 +195,7 @@ class X_CDirectSoundStream
{
public:
// construct vtable (or grab ptr to existing)
X_CDirectSoundStream() : pVtbl(&vtbl) { pMcpxStream = new X_CMcpxStream(this); };
X_CDirectSoundStream(bool is3D) : pVtbl(&vtbl), Xb_Voice(is3D) { pMcpxStream = new X_CMcpxStream(this); };
private:
// vtable (cached by each instance, via constructor)
@ -243,6 +250,8 @@ class X_CDirectSoundStream
#endif
public:
// Placeholder until have positive offset
CDirectSoundVoice Xb_Voice;
// cached data
LPDIRECTSOUNDBUFFER8 EmuDirectSoundBuffer8;
LPDIRECTSOUND3DBUFFER8 EmuDirectSound3DBuffer8;
@ -268,7 +277,6 @@ class X_CDirectSoundStream
DWORD Xb_dwHeadroom;
X_DSENVOLOPEDESC Xb_EnvolopeDesc;
X_DSVOICEPROPS Xb_VoiceProperties;
DWORD Xb_Frequency;
DWORD Host_dwLastWritePos;
DWORD Xb_Flags;
DWORD Xb_Status;
@ -481,7 +489,7 @@ HRESULT WINAPI EMUPATCH(IDirectSound_SetMixBinHeadroom)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMixBins)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
DWORD dwMixBinMask
);
@ -490,7 +498,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMixBins)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMixBinVolumes_12)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
DWORD dwMixBinMask,
const LONG* alVolumes
);
@ -500,7 +508,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMixBinVolumes_12)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMixBinVolumes_8)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
X_LPDSMIXBINS pMixBins
);
@ -551,10 +559,10 @@ HRESULT WINAPI EMUPATCH(CDirectSound_CommitDeferredSettings)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSound_CreateSoundBuffer)
(
LPDIRECTSOUND8 pThis,
X_DSBUFFERDESC* pdsbd,
X_CDirectSoundBuffer** ppBuffer,
LPUNKNOWN pUnkOuter
LPDIRECTSOUND8 pThis,
X_DSBUFFERDESC* pdsbd,
XbHybridDSBuffer** ppBuffer,
LPUNKNOWN pUnkOuter
);
// ******************************************************************
@ -562,8 +570,8 @@ HRESULT WINAPI EMUPATCH(IDirectSound_CreateSoundBuffer)
// ******************************************************************
HRESULT WINAPI EMUPATCH(DirectSoundCreateBuffer)
(
X_DSBUFFERDESC* pdsbd,
X_CDirectSoundBuffer** ppBuffer
X_DSBUFFERDESC* pdsbd,
XbHybridDSBuffer** ppBuffer
);
// ******************************************************************
@ -571,9 +579,9 @@ HRESULT WINAPI EMUPATCH(DirectSoundCreateBuffer)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetBufferData)
(
X_CDirectSoundBuffer* pThis,
LPVOID pvBufferData,
DWORD dwBufferBytes
XbHybridDSBuffer* pHybridThis,
LPVOID pvBufferData,
DWORD dwBufferBytes
);
// ******************************************************************
@ -581,9 +589,9 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetBufferData)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPlayRegion)
(
X_CDirectSoundBuffer* pThis,
DWORD dwPlayStart,
DWORD dwPlayLength
XbHybridDSBuffer* pHybridThis,
DWORD dwPlayStart,
DWORD dwPlayLength
);
// ******************************************************************
@ -591,7 +599,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPlayRegion)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Lock)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
DWORD dwOffset,
DWORD dwBytes,
LPVOID* ppvAudioPtr1,
@ -605,7 +613,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Lock)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Unlock)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
LPVOID ppvAudioPtr1,
DWORD pdwAudioBytes1,
LPVOID ppvAudioPtr2,
@ -617,7 +625,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Unlock)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetHeadroom)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
DWORD dwHeadroom
);
@ -626,7 +634,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetHeadroom)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetLoopRegion)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
DWORD dwLoopStart,
DWORD dwLoopLength
);
@ -636,7 +644,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetLoopRegion)
// ******************************************************************
ULONG WINAPI EMUPATCH(IDirectSoundBuffer_Release)
(
X_CDirectSoundBuffer* pThis
XbHybridDSBuffer* pHybridThis
);
// ******************************************************************
@ -644,7 +652,7 @@ ULONG WINAPI EMUPATCH(IDirectSoundBuffer_Release)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPitch)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
LONG lPitch
);
@ -653,7 +661,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPitch)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_GetStatus)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
LPDWORD pdwStatus
);
@ -662,7 +670,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_GetStatus)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVolume)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
LONG lVolume
);
@ -671,7 +679,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVolume)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetCurrentPosition)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
DWORD dwNewPosition
);
@ -680,7 +688,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetCurrentPosition)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_GetCurrentPosition)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
PDWORD pdwCurrentPlayCursor,
PDWORD pdwCurrentWriteCursor
);
@ -690,7 +698,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_GetCurrentPosition)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Stop)
(
X_CDirectSoundBuffer* pThis
XbHybridDSBuffer* pHybridThis
);
// ******************************************************************
@ -698,7 +706,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Stop)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_StopEx)
(
X_CDirectSoundBuffer *pBuffer,
XbHybridDSBuffer* pHybridThis,
REFERENCE_TIME rtTimeStamp,
DWORD dwFlags
);
@ -708,7 +716,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_StopEx)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Play)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
DWORD dwReserved1,
DWORD dwReserved2,
DWORD dwFlags
@ -719,7 +727,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Play)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_PlayEx)
(
X_CDirectSoundBuffer* pBuffer,
XbHybridDSBuffer* pHybridThis,
REFERENCE_TIME rtTimeStamp,
DWORD dwFlags
);
@ -729,7 +737,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_PlayEx)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVolume)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
LONG lVolume
);
@ -738,7 +746,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVolume)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetFrequency)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
DWORD dwFrequency
);
@ -972,7 +980,7 @@ HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetMixBins)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMaxDistance)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
FLOAT flMaxDistance,
DWORD dwApply
);
@ -982,7 +990,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMaxDistance)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMinDistance)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
FLOAT flMaxDistance,
DWORD dwApply
);
@ -992,7 +1000,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMinDistance)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetRolloffFactor)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
FLOAT flRolloffFactor,
DWORD dwApply
);
@ -1002,7 +1010,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetRolloffFactor)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetDistanceFactor)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
FLOAT flDistanceFactor,
DWORD dwApply
);
@ -1012,7 +1020,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetDistanceFactor)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeAngles)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
DWORD dwInsideConeAngle,
DWORD dwOutsideConeAngle,
DWORD dwApply
@ -1023,7 +1031,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeAngles)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeOrientation)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
FLOAT x,
FLOAT y,
FLOAT z,
@ -1035,7 +1043,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeOrientation)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeOutsideVolume)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
LONG lConeOutsideVolume,
DWORD dwApply
);
@ -1045,7 +1053,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeOutsideVolume)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPosition)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
FLOAT x,
FLOAT y,
FLOAT z,
@ -1057,7 +1065,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPosition)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVelocity)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
FLOAT x,
FLOAT y,
FLOAT z,
@ -1069,7 +1077,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVelocity)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetDopplerFactor)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
FLOAT flDopplerFactor,
DWORD dwApply
);
@ -1079,7 +1087,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetDopplerFactor)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetI3DL2Source)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
X_DSI3DL2BUFFER* pds3db,
DWORD dwApply
);
@ -1090,7 +1098,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetI3DL2Source)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMode)
(
X_CDirectSoundBuffer* pBuffer,
XbHybridDSBuffer* pHybridThis,
DWORD dwMode,
DWORD dwApply
);
@ -1100,7 +1108,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMode)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetFormat)
(
X_CDirectSoundBuffer *pBuffer,
XbHybridDSBuffer* pHybridThis,
LPCWAVEFORMATEX pwfxFormat
);
@ -1129,8 +1137,8 @@ void WINAPI EMUPATCH(DirectSoundUseLightHRTF4Channel)(void);
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetLFO)
(
LPDIRECTSOUNDBUFFER8 pThis,
LPCDSLFODESC pLFODesc
XbHybridDSBuffer* pHybridThis,
LPCDSLFODESC pLFODesc
);
// ******************************************************************
@ -1157,7 +1165,7 @@ VOID WINAPI EMUPATCH(XAudioCreateAdpcmFormat)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetRolloffCurve)
(
LPDIRECTSOUNDBUFFER8 pThis,
XbHybridDSBuffer* pHybridThis,
const FLOAT* pflPoints,
DWORD dwPointCount,
DWORD dwApply
@ -1186,7 +1194,7 @@ HRESULT WINAPI EMUPATCH(IDirectSound_EnableHeadphones)
// ******************************************************************
ULONG WINAPI EMUPATCH(IDirectSoundBuffer_AddRef)
(
X_CDirectSoundBuffer* pThis
XbHybridDSBuffer* pHybridThis
);
// ******************************************************************
@ -1194,7 +1202,7 @@ ULONG WINAPI EMUPATCH(IDirectSoundBuffer_AddRef)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Pause)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
DWORD dwPause
);
@ -1203,7 +1211,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Pause)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_PauseEx)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
REFERENCE_TIME rtTimestamp,
DWORD dwPause
);
@ -1263,8 +1271,8 @@ HRESULT WINAPI EMUPATCH(XAudioDownloadEffectsImage)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetFilter)
(
LPVOID pThis,
X_DSFILTERDESC* pFilterDesc
XbHybridDSBuffer* pHybridThis,
X_DSFILTERDESC* pFilterDesc
);
// ******************************************************************
@ -1333,7 +1341,7 @@ HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetI3DL2Source)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetAllParameters)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
X_DS3DBUFFER* pc3DBufferParameters,
DWORD dwApply
);
@ -1352,8 +1360,8 @@ HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetFormat)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetOutputBuffer)
(
X_CDirectSoundBuffer* pThis,
X_CDirectSoundBuffer* pOutputBuffer
XbHybridDSBuffer* pHybridThis,
XbHybridDSBuffer* pOutputBuffer
);
// ******************************************************************
@ -1362,7 +1370,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetOutputBuffer)
HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetOutputBuffer)
(
X_CDirectSoundStream* pThis,
X_CDirectSoundBuffer* pOutputBuffer
XbHybridDSBuffer* pOutputBuffer
);
// ******************************************************************
@ -1389,7 +1397,7 @@ HRESULT WINAPI EMUPATCH(XWaveFileCreateMediaObject)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetEG)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
X_DSENVOLOPEDESC* pEnvelopeDesc
);
@ -1410,8 +1418,8 @@ HRESULT WINAPI EMUPATCH(IDirectSound_GetEffectData)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetNotificationPositions)
(
X_CDirectSoundBuffer* pThis,
DWORD dwNotifyCount,
XbHybridDSBuffer* pHybridThis,
DWORD dwNotifyCount,
LPCDSBPOSITIONNOTIFY paNotifies
);
@ -1444,8 +1452,8 @@ HRESULT WINAPI EMUPATCH(IDirectSound_SetEffectData)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Use3DVoiceData)
(
LPVOID pThis,
LPUNKNOWN pUnknown
XbHybridDSBuffer* pHybridThis,
LPUNKNOWN pUnknown
);
// ******************************************************************
@ -1597,7 +1605,7 @@ HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetDopplerFactor)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_GetVoiceProperties)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
OUT X_DSVOICEPROPS* pVoiceProps);
// ******************************************************************
@ -1696,7 +1704,7 @@ VOID WINAPI EMUPATCH(CDirectSound3DCalculator_GetVoiceData)
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Set3DVoiceData)
(
X_CDirectSoundBuffer* pThis,
XbHybridDSBuffer* pHybridThis,
DWORD a2);
// ******************************************************************

File diff suppressed because it is too large Load Diff

View File

@ -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<XTL::X_CDirectSoundBuffer*>
#define vector_ds_buffer std::vector<XTL::XbHybridDSBuffer*>
#define vector_ds_stream std::vector<XTL::X_CDirectSoundStream*>
extern vector_ds_buffer g_pDSoundBufferCache;
extern vector_ds_stream g_pDSoundStreamCache;

View File

@ -254,7 +254,8 @@ static inline void GeneratePCMFormat(
LPVOID* X_BufferCache,
DWORD &X_BufferCacheSize,
XTL::X_DSVOICEPROPS& Xb_VoiceProperties,
XTL::X_LPDSMIXBINS mixbins_output)
XTL::X_LPDSMIXBINS mixbins_output,
XTL::CDirectSoundVoice* Xb_Voice)
{
bool bIsSpecial = false;
@ -396,7 +397,6 @@ static inline void DSound3DBufferCreate(LPDIRECTSOUNDBUFFER8 pDSBuffer, LPDIRECT
pThis->Xb_dwHeadroom = 600; /* default for 2D voice */ \
pThis->Xb_EnvolopeDesc = { 0 }; \
InitVoiceProperties(pThis->Xb_VoiceProperties); /* The rest will initialize in GeneratePCMFormat to GenerateMixBinDefault. */ \
pThis->Xb_Frequency = XTL_DSXFREQUENCY_ORIGINAL; \
pThis->Xb_Flags = Xb_dwFlags;
//pThis->EmuBufferDesc = { 0 }; // Enable this when become necessary.
/*
@ -405,7 +405,7 @@ static inline void DSound3DBufferCreate(LPDIRECTSOUNDBUFFER8 pDSBuffer, LPDIRECT
pThis->EmuLockPtr2 = xbnullptr; \
pThis->EmuLockBytes2 = 0; \ */
static inline void DSoundBufferRegionSetDefault(XTL::X_CDirectSoundBuffer *pThis) {
static inline void DSoundBufferRegionSetDefault(XTL::EmuDirectSoundBuffer *pThis) {
pThis->EmuBufferToggle = XTL::X_DSB_TOGGLE_DEFAULT;
pThis->EmuRegionLoopStartOffset = 0;
pThis->EmuRegionLoopLength = 0;
@ -419,7 +419,7 @@ static inline void DSoundBufferTransferSettings(
LPDIRECTSOUNDBUFFER8 &pDSBufferNew,
LPDIRECTSOUND3DBUFFER8 &pDS3DBufferOld,
LPDIRECTSOUND3DBUFFER8 &pDS3DBufferNew,
DWORD Xb_Frequency)
XTL::CDirectSoundVoice* Xb_Voice)
{
LONG lVolume, lPan;
DS3DBUFFER ds3dBuffer;
@ -428,7 +428,9 @@ static inline void DSoundBufferTransferSettings(
return;
}
pDSBufferNew->SetFrequency(Xb_Frequency);
// if sync current frequency used (then use pitch only).
uint32_t freq = XTL::converter_pitch2freq(Xb_Voice->GetPitch(Xb_Voice));
pDSBufferNew->SetFrequency(freq);
pDSBufferOld->GetVolume(&lVolume);
pDSBufferNew->SetVolume(lVolume);
@ -449,7 +451,7 @@ static inline void DSoundBufferReCreate(
LPDIRECTSOUND3DBUFFER8 &pDS3DBuffer,
LPDIRECTSOUNDBUFFER8 &pDSBufferNew,
LPDIRECTSOUND3DBUFFER8 &pDS3DBufferNew,
DWORD Xb_Frequency) {
XTL::CDirectSoundVoice* Xb_Voice) {
DSoundBufferCreate(&DSBufferDesc, pDSBufferNew);
@ -458,7 +460,7 @@ static inline void DSoundBufferReCreate(
DSound3DBufferCreate(pDSBufferNew, pDS3DBufferNew);
}
DSoundBufferTransferSettings(pDSBuffer, pDSBufferNew, pDS3DBuffer, pDS3DBufferNew, Xb_Frequency);
DSoundBufferTransferSettings(pDSBuffer, pDSBufferNew, pDS3DBuffer, pDS3DBufferNew, Xb_Voice);
}
static inline void DSoundBufferRelease(
@ -484,10 +486,11 @@ static inline void DSoundBufferRelease(
}
static inline void DSoundBufferResizeSetSize(
XTL::X_CDirectSoundBuffer* pThis,
XTL::XbHybridDSBuffer* pHybridThis,
HRESULT &hRet,
DWORD Xb_dwByteLength) {
XTL::EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer;
// General return OK, nothing needs to set as invalid for now.
hRet = DS_OK;
@ -508,7 +511,7 @@ static inline void DSoundBufferResizeSetSize(
LPDIRECTSOUND3DBUFFER8 pDS3DBufferNew = nullptr;
DSoundBufferReCreate(pThis->EmuDirectSoundBuffer8, pThis->EmuBufferDesc, pThis->EmuDirectSound3DBuffer8,
pDSBufferNew, pDS3DBufferNew, pThis->Xb_Frequency);
pDSBufferNew, pDS3DBufferNew, pHybridThis->p_CDSVoice);
// release old buffer
DSoundBufferRelease(pThis->EmuDirectSoundBuffer8, pThis->EmuDirectSound3DBuffer8, refCount);
@ -522,13 +525,14 @@ static inline void DSoundBufferResizeSetSize(
}
static inline void DSoundBufferResizeUpdate(
XTL::X_CDirectSoundBuffer* pThis,
XTL::XbHybridDSBuffer* pHybridThis,
DWORD dwPlayFlags,
HRESULT &hRet,
DWORD Xb_dwStartOffset,
DWORD Xb_dwByteLength) {
DSoundBufferResizeSetSize(pThis, hRet, Xb_dwByteLength);
XTL::EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer;
DSoundBufferResizeSetSize(pHybridThis, hRet, Xb_dwByteLength);
hRet = pThis->EmuDirectSoundBuffer8->Lock(0, 0, &pThis->Host_lock.pLockPtr1, &pThis->Host_lock.dwLockBytes1,
nullptr, nullptr, DSBLOCK_ENTIREBUFFER);
@ -546,11 +550,13 @@ static inline void DSoundBufferResizeUpdate(
}
static inline void DSoundBufferRegionCurrentLocation(
XTL::X_CDirectSoundBuffer* pThis,
XTL::XbHybridDSBuffer* pHybridThis,
DWORD dwPlayFlags,
HRESULT &hRet,
DWORD &Xb_dwStartOffset,
DWORD &Xb_dwByteLength) {
DWORD &Xb_dwByteLength)
{
XTL::EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer;
if ((dwPlayFlags & X_DSBPLAY_LOOPING) > 0) {
Xb_dwStartOffset = pThis->EmuRegionPlayStartOffset + pThis->EmuRegionLoopStartOffset;
@ -577,7 +583,7 @@ static inline void DSoundBufferRegionCurrentLocation(
}
static inline void DSoundBufferUpdate(
XTL::X_CDirectSoundBuffer* pThis,
XTL::XbHybridDSBuffer* pHybridThis,
DWORD dwPlayFlags,
HRESULT &hRet) {
@ -585,24 +591,24 @@ static inline void DSoundBufferUpdate(
DWORD Xb_dwByteLength;
DWORD Xb_dwStartOffset;
DSoundBufferRegionCurrentLocation(pThis, dwPlayFlags, hRet, Xb_dwStartOffset, Xb_dwByteLength);
DSoundBufferRegionCurrentLocation(pHybridThis, dwPlayFlags, hRet, Xb_dwStartOffset, Xb_dwByteLength);
DSoundBufferResizeUpdate(pThis, dwPlayFlags, hRet, Xb_dwStartOffset, Xb_dwByteLength);
DSoundBufferResizeUpdate(pHybridThis, dwPlayFlags, hRet, Xb_dwStartOffset, Xb_dwByteLength);
}
static inline void DSoundBufferReplace(
static inline void DSoundBufferRegenWithNewFormat(
LPDIRECTSOUNDBUFFER8 &pDSBuffer,
DSBUFFERDESC &DSBufferDesc,
DWORD PlayFlags,
LPDIRECTSOUND3DBUFFER8 &pDS3DBuffer,
DWORD Xb_Frequency)
XTL::CDirectSoundVoice* Xb_Voice)
{
DWORD refCount, dwPlayCursor, dwStatus;
LPDIRECTSOUNDBUFFER8 pDSBufferNew = nullptr;
LPDIRECTSOUND3DBUFFER8 pDS3DBufferNew = nullptr;
DSoundBufferReCreate(pDSBuffer, DSBufferDesc, pDS3DBuffer,
pDSBufferNew, pDS3DBufferNew, Xb_Frequency);
pDSBufferNew, pDS3DBufferNew, Xb_Voice);
HRESULT hRet = pDSBuffer->GetStatus(&dwStatus);
@ -1082,15 +1088,17 @@ static inline HRESULT HybridDirectSoundBuffer_SetFormat(
DWORD &X_BufferCacheSize,
XTL::X_DSVOICEPROPS &Xb_VoiceProperties,
XTL::X_LPDSMIXBINS mixbins_output,
DWORD Xb_Frequency)
XTL::CDirectSoundVoice* Xb_Voice)
{
pDSBuffer->Stop();
if (X_BufferAllocate) {
GeneratePCMFormat(BufferDesc, Xb_pwfxFormat, Xb_flags, dwEmuFlags, X_BufferCacheSize, xbnullptr, X_BufferCacheSize, Xb_VoiceProperties, mixbins_output);
GeneratePCMFormat(BufferDesc, Xb_pwfxFormat, Xb_flags, dwEmuFlags, X_BufferCacheSize,
xbnullptr, X_BufferCacheSize, Xb_VoiceProperties, mixbins_output, Xb_Voice);
// Don't allocate for DS Stream class, it is using straight from the source.
} else {
GeneratePCMFormat(BufferDesc, Xb_pwfxFormat, Xb_flags, dwEmuFlags, 0, xbnullptr, X_BufferCacheSize, Xb_VoiceProperties, mixbins_output);
GeneratePCMFormat(BufferDesc, Xb_pwfxFormat, Xb_flags, dwEmuFlags, 0,
xbnullptr, X_BufferCacheSize, Xb_VoiceProperties, mixbins_output, Xb_Voice);
}
HRESULT hRet = DS_OK;
if ((void*)g_pDSoundPrimaryBuffer == (void*)pDSBuffer) {
@ -1101,28 +1109,31 @@ static inline HRESULT HybridDirectSoundBuffer_SetFormat(
// Allocate at least 5 second worth of bytes in PCM format.
BufferDesc.dwBufferBytes = BufferDesc.lpwfxFormat->nAvgBytesPerSec * 5;
}
DSoundBufferReplace(pDSBuffer, BufferDesc, dwPlayFlags, pDS3DBuffer, Xb_Frequency);
DSoundBufferRegenWithNewFormat(pDSBuffer, BufferDesc, dwPlayFlags, pDS3DBuffer, Xb_Voice);
}
RETURN_RESULT_CHECK(hRet);
}
static HRESULT HybridDirectSoundBuffer_SetPitch(LPDIRECTSOUNDBUFFER8, LONG, XTL::CDirectSoundVoice*);
//IDirectSoundStream
//IDirectSoundBuffer
static inline HRESULT HybridDirectSoundBuffer_SetFrequency(
LPDIRECTSOUNDBUFFER8 pDSBuffer,
DWORD dwFrequency,
DWORD &Xb_Frequency)
XTL::CDirectSoundVoice* Xb_Voice)
{
HRESULT hRet = S_OK;
Xb_Frequency = dwFrequency;
hRet = pDSBuffer->SetFrequency(dwFrequency);
int32_t pitch = XTL::converter_freq2pitch((dwFrequency!=0 ? dwFrequency : Xb_Voice->GetFrequencyDefault(Xb_Voice)));
hRet = HybridDirectSoundBuffer_SetPitch(pDSBuffer, pitch, Xb_Voice);
RETURN_RESULT_CHECK(hRet);
}
static HRESULT HybridDirectSoundBuffer_SetVolume(LPDIRECTSOUNDBUFFER8, LONG, DWORD, LPLONG, LONG, DWORD);
static HRESULT HybridDirectSoundBuffer_SetVolume(LPDIRECTSOUNDBUFFER8, LONG, DWORD, LPLONG, LONG, DWORD, XTL::CDirectSoundVoice*);
//IDirectSoundStream
//IDirectSoundBuffer
@ -1133,7 +1144,8 @@ static inline HRESULT HybridDirectSoundBuffer_SetHeadroom(
DWORD &Xb_dwHeadroom,
LONG Xb_volume,
LONG Xb_volumeMixbin,
DWORD dwEmuFlags)
DWORD dwEmuFlags,
XTL::CDirectSoundVoice* Xb_Voice)
{
HRESULT hRet;
if (dwHeadroom > 10000) {
@ -1141,7 +1153,7 @@ static inline HRESULT HybridDirectSoundBuffer_SetHeadroom(
} else {
Xb_dwHeadroom = dwHeadroom;
hRet = DS_OK;
HybridDirectSoundBuffer_SetVolume(pDSBuffer, Xb_volume, dwEmuFlags, xbnullptr, Xb_volumeMixbin, dwHeadroom);
HybridDirectSoundBuffer_SetVolume(pDSBuffer, Xb_volume, dwEmuFlags, xbnullptr, Xb_volumeMixbin, dwHeadroom, Xb_Voice);
}
return DS_OK;
@ -1233,7 +1245,8 @@ static inline HRESULT HybridDirectSoundBuffer_SetMixBinVolumes_8(
DWORD EmuFlags,
LONG Xb_volume,
LONG &Xb_volumeMixBin,
DWORD Xb_dwHeadroom)
DWORD Xb_dwHeadroom,
XTL::CDirectSoundVoice* Xb_Voice)
{
HRESULT hRet = DSERR_INVALIDPARAM;
@ -1274,7 +1287,7 @@ static inline HRESULT HybridDirectSoundBuffer_SetMixBinVolumes_8(
if (counter > 0) {
Xb_volumeMixBin = volume / (LONG)counter;
hRet = HybridDirectSoundBuffer_SetVolume(pDSBuffer, Xb_volume, EmuFlags, nullptr,
Xb_volumeMixBin, Xb_dwHeadroom);
Xb_volumeMixBin, Xb_dwHeadroom, Xb_Voice);
} else {
hRet = DS_OK;
}
@ -1326,27 +1339,14 @@ static inline HRESULT HybridDirectSoundBuffer_SetOutputBuffer(
static inline HRESULT HybridDirectSoundBuffer_SetPitch(
LPDIRECTSOUNDBUFFER8 pDSBuffer,
LONG lPitch,
DWORD &Xb_Frequency)
XTL::CDirectSoundVoice* Xb_Voice)
{
Xb_Voice->SetPitch(Xb_Voice, lPitch);
// Convert pitch back to frequency
// NOTE: pitch = 0 is equal to 48 KHz.
Xb_Frequency = static_cast<DWORD>(exp((lPitch / 4096.0f) * log(2)) * 48000.0f);
uint32_t setFrequency = XTL::converter_pitch2freq(lPitch);
/* For research purpose of how to convert frequency to pitch and back to frequency.
// Edit hertz variable to see the result.
float hertz = 12000.0f;
float hertzRatio = 48000.0f;
float pitchRatio = 4096.0f;
// Convert hertz to pitch
float pitch = log2(hertz / hertzRatio) * pitchRatio;
// Convert pitch to hertz
hertz = exp((pitch / pitchRatio) * log(2)) * hertzRatio;*/
RETURN_RESULT_CHECK(pDSBuffer->SetFrequency(Xb_Frequency));
RETURN_RESULT_CHECK(pDSBuffer->SetFrequency(setFrequency));
}
/*
//Only has one function, this is not a requirement.
@ -1431,7 +1431,8 @@ static inline HRESULT HybridDirectSoundBuffer_SetVolume(
DWORD dwEmuFlags,
LPLONG Xb_lpVolume,
LONG Xb_volumeMixbin,
DWORD Xb_dwHeadroom)
DWORD Xb_dwHeadroom,
XTL::CDirectSoundVoice* Xb_Voice)
{
// Preserve original volume
if (Xb_lpVolume != xbnullptr) {

View File

@ -70,9 +70,9 @@ XTL::X_CDirectSoundStream::_vtbl XTL::X_CDirectSoundStream::vtbl =
&XTL::EMUPATCH(CDirectSoundStream_Process), // 0x10
&XTL::EMUPATCH(CDirectSoundStream_Discontinuity), // 0x14
&XTL::EMUPATCH(CDirectSoundStream_Flush), // 0x18
0xBEEFB003, // 0x1C
0xBEEFB004, // 0x20
0xBEEFB005, // 0x24
0xBEEFB003, // 0x1C // unknown function
0xBEEFB004, // 0x20 // DS_CRefCount_AddRef
0xBEEFB005, // 0x24 // DS_CRefCount_Release
0xBEEFB006, // 0x28
0xBEEFB007, // 0x2C
0xBEEFB008, // 0x30
@ -208,8 +208,6 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateStream)
hRet = DSERR_OUTOFMEMORY;
*ppStream = xbnullptr;
} else {
// TODO: Garbage Collection
*ppStream = new X_CDirectSoundStream();
DSBUFFERDESC DSBufferDesc = { 0 };
@ -230,12 +228,16 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateStream)
DSBufferDesc.dwFlags |= DSBCAPS_CTRLPAN;
}
// TODO: Garbage Collection
*ppStream = new X_CDirectSoundStream((DSBufferDesc.dwFlags & DSBCAPS_CTRL3D) != 0);
DSoundBufferSetDefault((*ppStream), DSBPLAY_LOOPING, pdssd->dwFlags);
(*ppStream)->Xb_rtFlushEx = 0LL;
// We have to set DSBufferDesc last due to EmuFlags must be either 0 or previously written value to preserve other flags.
GeneratePCMFormat(DSBufferDesc, pdssd->lpwfxFormat, pdssd->dwFlags, (*ppStream)->EmuFlags, 0,
xbnullptr, (*ppStream)->X_BufferCacheSize, (*ppStream)->Xb_VoiceProperties, pdssd->lpMixBinsOutput);
xbnullptr, (*ppStream)->X_BufferCacheSize, (*ppStream)->Xb_VoiceProperties, pdssd->lpMixBinsOutput,
&(*ppStream)->Xb_Voice);
// Test case: Star Wars: KotOR has one packet greater than 5 seconds worth. Increasing to 10 seconds allow stream to work until
// another test case below proven host's buffer size does not matter since packet's size can be greater than host's buffer size.
@ -276,7 +278,7 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateStream)
// Pre-set volume to enforce silence if one of audio codec is disabled.
HybridDirectSoundBuffer_SetVolume((*ppStream)->EmuDirectSoundBuffer8, 0L, (*ppStream)->EmuFlags, nullptr,
(*ppStream)->Xb_VolumeMixbin, (*ppStream)->Xb_dwHeadroom);
(*ppStream)->Xb_VolumeMixbin, (*ppStream)->Xb_dwHeadroom, &(*ppStream)->Xb_Voice);
g_pDSoundStreamCache.push_back(*ppStream);
}
@ -912,7 +914,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetFormat)
pThis->EmuBufferDesc, pThis->EmuFlags, pThis->EmuPlayFlags,
pThis->EmuDirectSound3DBuffer8, 0, pThis->X_BufferCache,
pThis->X_BufferCacheSize, pThis->Xb_VoiceProperties,
xbnullptr, pThis->Xb_Frequency);
xbnullptr, &pThis->Xb_Voice);
return hRet;
}
@ -932,7 +934,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetFrequency)
LOG_FUNC_ARG(dwFrequency)
LOG_FUNC_END;
HRESULT hRet = HybridDirectSoundBuffer_SetFrequency(pThis->EmuDirectSoundBuffer8, dwFrequency, pThis->Xb_Frequency);
HRESULT hRet = HybridDirectSoundBuffer_SetFrequency(pThis->EmuDirectSoundBuffer8, dwFrequency, &pThis->Xb_Voice);
return hRet;
}
@ -968,7 +970,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetHeadroom)
LOG_FUNC_END;
HRESULT hRet = HybridDirectSoundBuffer_SetHeadroom(pThis->EmuDirectSoundBuffer8, dwHeadroom, pThis->Xb_dwHeadroom,
pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->EmuFlags);
pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->EmuFlags, &pThis->Xb_Voice);
return hRet;
}
@ -1208,7 +1210,8 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetMixBinVolumes_8)
LOG_FUNC_END;
HRESULT hRet = HybridDirectSoundBuffer_SetMixBinVolumes_8(pThis->EmuDirectSoundBuffer8, pMixBins, pThis->Xb_VoiceProperties,
pThis->EmuFlags, pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom);
pThis->EmuFlags, pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom,
&pThis->Xb_Voice);
return hRet;
}
@ -1219,7 +1222,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetMixBinVolumes_8)
HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetOutputBuffer)
(
X_CDirectSoundStream* pThis,
X_CDirectSoundBuffer* pOutputBuffer)
XbHybridDSBuffer* pOutputBuffer)
{
DSoundMutexGuardLock;
@ -1252,7 +1255,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetPitch)
LOG_FUNC_ARG(lPitch)
LOG_FUNC_END;
HRESULT hRet = HybridDirectSoundBuffer_SetPitch(pThis->EmuDirectSoundBuffer8, lPitch, pThis->Xb_Frequency);
HRESULT hRet = HybridDirectSoundBuffer_SetPitch(pThis->EmuDirectSoundBuffer8, lPitch, &pThis->Xb_Voice);
return hRet;
}
@ -1388,7 +1391,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetVolume)
LOG_FUNC_END;
HRESULT hRet = HybridDirectSoundBuffer_SetVolume(pThis->EmuDirectSoundBuffer8, lVolume, pThis->EmuFlags, &pThis->Xb_Volume,
pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom);
pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom, &pThis->Xb_Voice);
return hRet;
}

View File

@ -369,6 +369,30 @@ struct X_DSVOICEPROPS {
LONG lI3DL2DirectVolume;
LONG lI3DL2RoomVolume;
};
// Convert frequency to pitch helper
static inline int32_t converter_freq2pitch(uint32_t freq) {
// NOTE: pitch = 0 is equal to 48 KHz.
/* For research purpose of how to convert frequency to pitch and back to frequency.
// Edit hertz variable to see the result.
float hertz = 12000.0f;
float hertzRatio = 48000.0f;
float pitchRatio = 4096.0f;
// Convert hertz to pitch
float pitch = log2(hertz / hertzRatio) * pitchRatio;
// Convert pitch to hertz
hertz = exp((pitch / pitchRatio) * log(2)) * hertzRatio;*/
return static_cast<int32_t>(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<uint32_t>(exp((pitch / 4096.0f) * log(2)) * 48000.0f);
}
} // end of namespace XTL

View File

@ -0,0 +1,272 @@
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// *
// * (c) 2020 RadWolfie
// *
// * All rights reserved
// *
// ******************************************************************
#include "common\Settings.hpp" // for g_LibVersion_DSOUND
#include "XbInternalStruct.hpp"
// Interface for get format
void GetFormat_4034_lower(XTL::CDirectSoundVoice::_u& u, XTL::audio_format& format)
{
format.audio_codec = u.settings_4034_lower.p_audio_format->wfx.wFormatTag = format.audio_codec;
format.nChannels = u.settings_4034_lower.p_audio_format->wfx.nChannels;
format.cbSize = u.settings_4034_lower.p_audio_format->wfx.cbSize;
format.nSamplesPerSec = u.settings_4034_lower.p_audio_format->wfx.nSamplesPerSec;
format.bitsPerSample = u.settings_4034_lower.p_audio_format->wfx.wBitsPerSample;
}
void GetFormat_4039_only(XTL::CDirectSoundVoice::_u& u, XTL::audio_format& format)
{
format.audio_codec = u.settings_4039_only.audio_codec;
format.nChannels = u.settings_4039_only.nChannels;
format.cbSize = u.settings_4039_only.cbSize;
format.nSamplesPerSec = u.settings_4039_only.nSamplesPerSec_default;
format.bitsPerSample = u.settings_4039_only.bitsPerSample;
}
void GetFormat_4134_upper(XTL::CDirectSoundVoice::_u& u, XTL::audio_format& format)
{
format.audio_codec = u.settings_4134_upper.audio_codec;
format.nChannels = u.settings_4134_upper.nChannels;
format.cbSize = u.settings_4134_upper.cbSize;
format.nSamplesPerSec = u.settings_4134_upper.nSamplesPerSec_default;
format.bitsPerSample = u.settings_4134_upper.bitsPerSample;
}
// Interface for set format
void SetFormat_4034_lower(XTL::CDirectSoundVoice::_u& u, XTL::audio_format format)
{
u.settings_4034_lower.p_audio_format->wfx.wFormatTag = format.audio_codec;
u.settings_4034_lower.p_audio_format->wfx.nChannels = static_cast<uint16_t>(format.nChannels);
u.settings_4034_lower.p_audio_format->wfx.cbSize = static_cast<uint16_t>(format.cbSize);
u.settings_4034_lower.p_audio_format->wfx.nSamplesPerSec = format.nSamplesPerSec;
u.settings_4034_lower.p_audio_format->wfx.wBitsPerSample = static_cast<uint16_t>(format.bitsPerSample);
if (format.audio_codec == WAVE_FORMAT_XBOX_ADPCM) {
u.settings_4034_lower.p_audio_format->wSamplesPerBlock = 64;
}
u.settings_4039_only.pitch = XTL::converter_freq2pitch(format.nSamplesPerSec);
}
void SetFormat_4039_only(XTL::CDirectSoundVoice::_u& u, XTL::audio_format format)
{
u.settings_4039_only.audio_codec = format.audio_codec;
u.settings_4039_only.nChannels = format.nChannels;
u.settings_4039_only.cbSize = format.cbSize;
u.settings_4039_only.nSamplesPerSec_default = format.nSamplesPerSec;
u.settings_4039_only.bitsPerSample = format.bitsPerSample;
u.settings_4039_only.pitch = XTL::converter_freq2pitch(format.nSamplesPerSec);
}
void SetFormat_4134_upper(XTL::CDirectSoundVoice::_u& u, XTL::audio_format format)
{
u.settings_4134_upper.audio_codec = static_cast<uint16_t>(format.audio_codec);
u.settings_4134_upper.nChannels = static_cast<uint8_t>(format.nChannels);
u.settings_4134_upper.cbSize = static_cast<uint8_t>(format.cbSize);
u.settings_4134_upper.nSamplesPerSec_default = format.nSamplesPerSec;
u.settings_4134_upper.bitsPerSample = format.bitsPerSample;
u.settings_4134_upper.pitch = XTL::converter_freq2pitch(format.nSamplesPerSec);
}
// Interface for get frequency
uint32_t GetFrequencyDefault_4034_lower(XTL::CDirectSoundVoice::_u& u)
{
return u.settings_4034_lower.p_audio_format->wfx.nSamplesPerSec;
}
uint32_t GetFrequencyDefault_4039_only(XTL::CDirectSoundVoice::_u& u)
{
return u.settings_4039_only.nSamplesPerSec_default;
}
uint32_t GetFrequencyDefault_4134_upper(XTL::CDirectSoundVoice::_u& u)
{
return u.settings_4134_upper.nSamplesPerSec_default;
}
// Interface for get pitch
int32_t GetPitch_4034_lower(XTL::CDirectSoundVoice::_u& u)
{
return u.settings_4034_lower.pitch;
}
int32_t GetPitch_4039_only(XTL::CDirectSoundVoice::_u& u)
{
return u.settings_4039_only.pitch;
}
int32_t GetPitch_4134_upper(XTL::CDirectSoundVoice::_u& u)
{
return u.settings_4134_upper.pitch;
}
// Interface for set pitch
void SetPitch_4034_lower(XTL::CDirectSoundVoice::_u& u, int32_t pitch)
{
u.settings_4034_lower.pitch = pitch;
}
void SetPitch_4039_only(XTL::CDirectSoundVoice::_u& u, int32_t pitch)
{
u.settings_4039_only.pitch = pitch;
}
void SetPitch_4134_upper(XTL::CDirectSoundVoice::_u& u, int32_t pitch)
{
u.settings_4134_upper.pitch = pitch;
}
// Interface for get volume
uint32_t GetVolume_4034_lower(XTL::CDirectSoundVoice::_u& u)
{
return u.settings_4034_lower.volume;
}
uint32_t GetVolume_4039_only(XTL::CDirectSoundVoice::_u& u)
{
return u.settings_4039_only.volume;
}
uint32_t GetVolume_4134_upper(XTL::CDirectSoundVoice::_u& u)
{
return u.settings_4134_upper.volume;
}
void SetVolume_calc(uint32_t& cur_volume, uint32_t headroom, uint32_t set_volume)
{
cur_volume = set_volume - headroom;
}
// Interface for set volume
void SetVolume_4034_lower(XTL::CDirectSoundVoice::_u& u, uint32_t volume)
{
SetVolume_calc(u.settings_4034_lower.volume, u.settings_4034_lower.headroom, volume);
}
void SetVolume_4039_only(XTL::CDirectSoundVoice::_u& u, uint32_t volume)
{
SetVolume_calc(u.settings_4039_only.volume, u.settings_4039_only.headroom, volume);
}
void SetVolume_4134_upper(XTL::CDirectSoundVoice::_u& u, uint32_t volume)
{
SetVolume_calc(u.settings_4134_upper.volume, u.settings_4134_upper.headroom, volume);
}
// Interface for get headroom
uint32_t GetHeadroom_4034_lower(XTL::CDirectSoundVoice::_u& u)
{
return u.settings_4034_lower.headroom;
}
uint32_t GetHeadroom_4039_only(XTL::CDirectSoundVoice::_u& u)
{
return u.settings_4039_only.headroom;
}
uint32_t GetHeadroom_4134_upper(XTL::CDirectSoundVoice::_u& u)
{
return u.settings_4134_upper.headroom;
}
void SetHeadroom_calc(uint32_t& cur_headroom, uint32_t& volume, uint32_t set_headroom)
{
volume = volume - set_headroom - cur_headroom;
cur_headroom = set_headroom;
}
// Interface for set headroom
void SetHeadroom_4034_lower(XTL::CDirectSoundVoice::_u& u, uint32_t headroom)
{
SetHeadroom_calc(u.settings_4034_lower.headroom, u.settings_4034_lower.volume, headroom);
}
void SetHeadroom_4039_only(XTL::CDirectSoundVoice::_u& u, uint32_t headroom)
{
SetHeadroom_calc(u.settings_4039_only.headroom, u.settings_4039_only.volume, headroom);
}
void SetHeadroom_4134_upper(XTL::CDirectSoundVoice::_u& u, uint32_t headroom)
{
SetHeadroom_calc(u.settings_4134_upper.headroom, u.settings_4134_upper.volume, headroom);
}
void Init_Headroom(uint32_t& headroom, bool is3D)
{
headroom = is3D? 0 : 600;
}
void Init_4034_lower(XTL::CDirectSoundVoice::_u::_settings_4034_lower& settings, bool is3D)
{
Init_Headroom(settings.headroom, is3D);
settings.volume = 0 - settings.headroom;
}
void Init_4039_only(XTL::CDirectSoundVoice::_u::_settings_4039_only& settings, bool is3D)
{
Init_Headroom(settings.headroom, is3D);
settings.volume = 0 - settings.headroom;
}
void Init_4134_upper(XTL::CDirectSoundVoice::_u::_settings_4134_upper& settings, bool is3D)
{
Init_Headroom(settings.headroom, is3D);
settings.volume = 0 - settings.headroom;
}
XTL::CDirectSoundVoice::CDirectSoundVoice(bool is3D)
{
memset(u.settings_interface.unknown_08, 0, sizeof(u.settings_interface));
if (g_LibVersion_DSOUND < 4039) {
u.settings_4034_lower.p_audio_format = new XBOXADPCMWAVEFORMAT;
memset(&u.settings_4034_lower.p_audio_format->wfx, 0, sizeof(XBOXADPCMWAVEFORMAT));
Init_4034_lower(u.settings_4034_lower, is3D);
funcs.GetFormat = GetFormat_4034_lower;
funcs.SetFormat = SetFormat_4034_lower;
funcs.GetFrequencyDefault = GetFrequencyDefault_4034_lower;
funcs.GetPitch = GetPitch_4034_lower;
funcs.SetPitch = SetPitch_4034_lower;
funcs.GetVolume = GetVolume_4034_lower;
funcs.SetVolume = SetVolume_4034_lower;
funcs.GetHeadroom = GetHeadroom_4034_lower;
funcs.SetHeadroom = SetHeadroom_4034_lower;
}
else if (g_LibVersion_DSOUND == 4039) {
Init_4039_only(u.settings_4039_only, is3D);
funcs.GetFormat = GetFormat_4039_only;
funcs.SetFormat = SetFormat_4039_only;
funcs.GetFrequencyDefault = GetFrequencyDefault_4039_only;
funcs.GetPitch = GetPitch_4039_only;
funcs.SetPitch = SetPitch_4039_only;
funcs.GetVolume = GetVolume_4039_only;
funcs.SetVolume = SetVolume_4039_only;
funcs.GetHeadroom = GetHeadroom_4039_only;
funcs.SetHeadroom = SetHeadroom_4039_only;
}
else {
Init_4134_upper(u.settings_4134_upper, is3D);
funcs.GetFormat = GetFormat_4134_upper;
funcs.SetFormat = SetFormat_4134_upper;
funcs.GetFrequencyDefault = GetFrequencyDefault_4134_upper;
funcs.GetPitch = GetPitch_4134_upper;
funcs.SetPitch = SetPitch_4134_upper;
funcs.GetVolume = GetVolume_4134_upper;
funcs.SetVolume = SetVolume_4134_upper;
funcs.GetHeadroom = GetHeadroom_4134_upper;
funcs.SetHeadroom = SetHeadroom_4134_upper;
}
}
XTL::CDirectSoundVoice::~CDirectSoundVoice()
{
if (g_LibVersion_DSOUND < 4039) {
if (!u.settings_4034_lower.p_audio_format) {
delete u.settings_4034_lower.p_audio_format;
u.settings_4034_lower.p_audio_format = nullptr;
}
}
}

View File

@ -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
// ...
};

View File

@ -0,0 +1,227 @@
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// *
// * (c) 2020 RadWolfie
// *
// * All rights reserved
// *
// ******************************************************************
#pragma once
#include "Cxbx.h"
#include "core\hle\DSOUND\XbDSoundTypes.h"
namespace XTL {
// TODO: Everything, only small portions had been implemented.
struct audio_format {
uint32_t audio_codec;
uint32_t nChannels;
uint32_t cbSize;
int32_t nSamplesPerSec;
uint32_t bitsPerSample;
};
struct CUnknownGenericManager {
// construct vtable (or grab ptr to existing)
CUnknownGenericManager() : ref_count(1) {}
// all virtual functions are stored in local offset 0x00's pointer
virtual ~CUnknownGenericManager() {}; // 0x00
virtual uint32_t WINAPI AddRef() { return ++ref_count; }; // 0x04
virtual uint32_t WINAPI Release() { return --ref_count; }; // 0x08
uint32_t ref_count; // 0x04
};
static_assert(sizeof(CUnknownGenericManager) == 0x08);
struct CUnknownTemplate {
// construct vtable (or grab ptr to existing)
CUnknownTemplate();
virtual ~CUnknownTemplate() {}; // 0x00
virtual void WINAPI pUnknown_04() { throw std::exception("pUnknown_04"); }; // 0x04
virtual void WINAPI pUnknown_08() { throw std::exception("pUnknown_08"); }; // 0x08
virtual void WINAPI pUnknown_0C() { throw std::exception("pUnknown_0C"); }; // 0x0C
virtual void WINAPI pUnknown_10() { throw std::exception("pUnknown_10"); }; // 0x10
virtual void WINAPI pUnknown_14() { throw std::exception("pUnknown_14"); }; // 0x14
virtual void WINAPI pUnknown_18() { throw std::exception("pUnknown_18"); }; // 0x18
virtual void WINAPI pUnknown_1C() { throw std::exception("pUnknown_1C"); }; // 0x1C
// If need to add more virtual functions, add them above here.
uint32_t ref_count; // 0x04
};
static_assert(sizeof(CUnknownTemplate) == 0x08);
struct CMcpxVoiceClient: CUnknownTemplate {
CMcpxVoiceClient() : settings(default_settings) {};
// all virtual functions are stored in local offset 0x00's pointer
virtual ~CMcpxVoiceClient() {};
// CUnknownTemplate // 0x00 - ???
struct _settings
{
uint32_t Unknown2[(0x300-8)/4]; // 0x08 - ???
}
settings;
// global _settings for this class
static _settings default_settings;
};
static_assert(sizeof(CMcpxVoiceClient) == 0x300);
struct CDirectSoundVoice : CUnknownGenericManager {
CDirectSoundVoice(bool is3D);
// all virtual functions are stored in local offset 0x00's pointer
virtual ~CDirectSoundVoice();
// CUnknownGenericManager // 0x00 - ???
union _u {
struct _settings_interface
{
uint32_t unknown_08[0x300 / 4]; // 0x000 - 0x300 (unknown size, likely over 0x200 size.
} settings_interface;
struct _settings_4034_lower {
xbaddr p_unknown_08; // 0x008
uint16_t unknown_0C; // 0x00C // zero'd - unknown
XBOXADPCMWAVEFORMAT* p_audio_format; // 0x010 // Same as XBOXADPCMWAVEFORMAT / WAVEFORMATEX structure
uint32_t pitch; // 0x014 // Always init and custom pitch from SetFrequency, SetPitch, SetFormat, etc calls.
uint32_t volume; // 0x018 // default: (set volume - headroom)
uint32_t headroom; // 0x01C // default: (set headroom then update volume)
} settings_4034_lower;
struct _settings_4039_only {
uint32_t unknown_08; // 0x008
uint32_t audio_codec; // 0x00C // Setter is 32 bit, yet getter is 16 bit integer reader
uint32_t nChannels; // 0x010
uint32_t cbSize; // 0x014
int32_t nSamplesPerSec_default; // 0x018 // Always original frequency for check if SetFrequency is given with 0 then use original one.
uint32_t bitsPerSample; // 0x01C
uint32_t pitch; // 0x020 // Always init and custom pitch from SetFrequency, SetPitch, SetFormat, etc calls.
uint32_t volume; // 0x024 // (set volume - headroom)
uint32_t headroom; // 0x028 // (set headroom then update volume)
uint32_t unknown_2C[(0x300 - 0x2C) / 4]; // 0x02C - 0x300 (unknown size, likely over 0x200 size.
} settings_4039_only;
struct _settings_4134_upper {
uint32_t unknown_08; // 0x008
uint16_t audio_codec; // 0x00C
uint8_t nChannels; // 0x00E
uint8_t cbSize; // 0x00F
uint32_t nSamplesPerSec_default; // 0x010 // Always original frequency for check if SetFrequency is given with 0 then use original one.
uint32_t bitsPerSample; // 0x014
int32_t pitch; // 0x018 // Always init and custom pitch from SetFrequency, SetPitch, SetFormat, etc calls.
uint32_t volume; // 0x01C // (set volume - headroom)
uint32_t headroom; // 0x020 // (set headroom then update volume)
uint32_t unknown_24[(0x300 - 0x24) / 4]; // 0x024 - 0x300 (unknown size, likely over 0x200 size.
} settings_4134_upper;
} u;
static_assert(sizeof(_u) == 0x300);
struct {
void (*GetFormat)(_u& u, audio_format& format);
void (*SetFormat)(_u& u, audio_format format);
uint32_t (*GetFrequencyDefault)(_u& u);
int32_t (*GetPitch)(_u& u);
void (*SetPitch)(_u& u, int32_t pitch);
uint32_t (*GetVolume)(_u& u);
void (*SetVolume)(_u& u, uint32_t volume);
uint32_t (*GetHeadroom)(_u& u);
void (*SetHeadroom)(_u& u, uint32_t headroom);
} funcs;
static_assert(sizeof(funcs) == 0x24);
static inline void GetFormat(CDirectSoundVoice* pThis, audio_format& format) {
pThis->funcs.GetFormat(pThis->u, format);
};
static inline void SetFormat(CDirectSoundVoice* pThis, audio_format format) {
pThis->funcs.SetFormat(pThis->u, format);
};
static inline uint32_t GetFrequencyDefault(CDirectSoundVoice* pThis) {
return pThis->funcs.GetFrequencyDefault(pThis->u);
};
static inline int32_t GetPitch(CDirectSoundVoice* pThis) {
return pThis->funcs.GetPitch(pThis->u);
};
static inline void SetPitch(CDirectSoundVoice* pThis, int32_t pitch) {
pThis->funcs.SetPitch(pThis->u, pitch);
};
static inline uint32_t GetVolume(CDirectSoundVoice* pThis) {
return pThis->funcs.GetVolume(pThis->u);
};
static inline void SetVolume(CDirectSoundVoice* pThis, uint32_t volume) {
pThis->funcs.SetVolume(pThis->u, volume);
};
static inline uint32_t GetHeadroom(CDirectSoundVoice* pThis) {
return pThis->funcs.GetHeadroom(pThis->u);
};
static inline void SetHeadroom(CDirectSoundVoice* pThis, uint32_t headroom) {
pThis->funcs.SetHeadroom(pThis->u, headroom);
};
};
static_assert(sizeof(CDirectSoundVoice) == sizeof(CUnknownGenericManager) + sizeof(CDirectSoundVoice::_u) + sizeof(CDirectSoundVoice::funcs));
struct DSBUFFER_S : CUnknownTemplate {
// CUnknownTemplate unknown_00; // Offset 0x00 // -0x1C
struct DSBUFFER_C {
uint32_t unknown_08; // Offset 0x08 // -0x14
CMcpxVoiceClient* p_CMcpxVoiceClient; // Offset 0x0C // -0x10
CDirectSoundVoice* p_CDSVoice; // Offset 0x10 // -0x0C
xbaddr p_unknown_14; // Offset 0x14 // -0x08 // (points to this address)
xbaddr p_unknown_18; // Offset 0x18 // -0x04 // (points to above address)
} dsb_c;
static_assert(sizeof(DSBUFFER_C) == 0x14);
struct DSBUFFER_I {
CDirectSoundVoice* p_CDSVoice; // Offset 0x1C // 0x00 // Same as p_CDSVoice (above); pThis
CMcpxVoiceClient* p_CMcpxVoiceClient; // Offset 0x20 // 0x04 // Same as p_CMcpxVoiceClient (above)
xbaddr p_unknown_24; // Offset 0x24 // 0x08
xbaddr p_unknown_28; // Offset 0x28 // 0x0C
uint32_t unknown_2C; // Offset 0x2C // 0x10 // was integer, later shift to offset 0x30
uint32_t unknown_30; // Offset 0x30 // 0x14 // later shifted from offset 0x2C; integer
} dsb_i;
static_assert(sizeof(DSBUFFER_I) == 0x18);
DSBUFFER_S(bool is3D) {
init(is3D);
}
virtual ~DSBUFFER_S() {
delete dsb_c.p_CMcpxVoiceClient;
delete dsb_c.p_CDSVoice;
}
virtual void init_member() {
dsb_c.unknown_08 = 0;
dsb_i.p_unknown_24 = xbnull;
dsb_i.p_unknown_28 = xbnull;
dsb_i.unknown_2C = xbnull;
dsb_i.unknown_30 = xbnull;
}
virtual void init(bool is3D) {
init_member();
dsb_c.p_CMcpxVoiceClient = new CMcpxVoiceClient(); dsb_i.p_CMcpxVoiceClient = dsb_c.p_CMcpxVoiceClient;
dsb_c.p_CDSVoice = new CDirectSoundVoice(is3D); dsb_i.p_CDSVoice = dsb_c.p_CDSVoice;
dsb_c.p_unknown_18 = reinterpret_cast<xbaddr>(&dsb_c.p_unknown_14);
dsb_c.p_unknown_14 = dsb_c.p_unknown_18;
}
};
static_assert(sizeof(DSBUFFER_S) == 0x34);
}