connect APIs to the mixbin functions

This commit is contained in:
RadWolfie 2019-07-03 12:10:30 -05:00 committed by PatrickvL
parent c0c21253ec
commit c5b374e110
2 changed files with 43 additions and 65 deletions

View File

@ -719,11 +719,11 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMixBins)
LOG_FUNC_ARG(pMixBins)
LOG_FUNC_END;
LOG_UNIMPLEMENTED();
HRESULT hRet = HybridDirectSoundBuffer_SetMixBins(pThis->Xb_VoiceProperties, pMixBins, pThis->EmuBufferDesc.lpwfxFormat, pThis->EmuBufferDesc);
leaveCriticalSection;
return DS_OK;
return hRet;
}
// ******************************************************************
@ -768,7 +768,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMixBinVolumes_8)
LOG_FUNC_ARG(pMixBins)
LOG_FUNC_END;
return HybridDirectSoundBuffer_SetMixBinVolumes_8(pThis->EmuDirectSoundBuffer8, pMixBins, pThis->EmuFlags, pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom);
return HybridDirectSoundBuffer_SetMixBinVolumes_8(pThis->EmuDirectSoundBuffer8, pMixBins, pThis->Xb_VoiceProperties, pThis->EmuFlags, pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom);
}
// ******************************************************************
@ -932,7 +932,8 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateBuffer)
DSoundBufferRegionSetDefault(*ppBuffer);
// 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, (*ppBuffer)->EmuFlags, pdsbd->dwBufferBytes, &(*ppBuffer)->X_BufferCache, (*ppBuffer)->X_BufferCacheSize);
GeneratePCMFormat(DSBufferDesc, pdsbd->lpwfxFormat, (*ppBuffer)->EmuFlags, pdsbd->dwBufferBytes,
&(*ppBuffer)->X_BufferCache, (*ppBuffer)->X_BufferCacheSize, (*ppBuffer)->Xb_VoiceProperties, pdsbd->lpMixBinsOutput);
(*ppBuffer)->EmuBufferDesc = DSBufferDesc;
EmuLog(LOG_LEVEL::DEBUG, "DirectSoundCreateBuffer, *ppBuffer := 0x%08X, bytes := 0x%08X", *ppBuffer, (*ppBuffer)->EmuBufferDesc.dwBufferBytes);
@ -1727,7 +1728,8 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateStream)
(*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, (*ppStream)->EmuFlags, 0, xbnullptr, (*ppStream)->X_BufferCacheSize);
GeneratePCMFormat(DSBufferDesc, pdssd->lpwfxFormat, (*ppStream)->EmuFlags, 0,
xbnullptr, (*ppStream)->X_BufferCacheSize, (*ppStream)->Xb_VoiceProperties, pdssd->lpMixBinsOutput);
// Test case: Star Wars: KotOR has one packet greater than 5 seconds worth. Increasing to 10 seconds works out fine, can increase more if need to.
// Allocate at least 10 second worth of bytes in PCM format.
@ -2409,11 +2411,11 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetMixBins)
LOG_FUNC_ARG(pMixBins)
LOG_FUNC_END;
LOG_UNIMPLEMENTED();
HRESULT hRet = HybridDirectSoundBuffer_SetMixBins(pThis->Xb_VoiceProperties, pMixBins, pThis->EmuBufferDesc.lpwfxFormat, pThis->EmuBufferDesc);
leaveCriticalSection;
return S_OK;
return hRet;
}
// s+
@ -2688,7 +2690,8 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetFormat)
HRESULT hRet = HybridDirectSoundBuffer_SetFormat(pThis->EmuDirectSoundBuffer8, pwfxFormat,
pThis->EmuBufferDesc, pThis->EmuFlags,
pThis->EmuPlayFlags, pThis->EmuDirectSound3DBuffer8,
0, pThis->X_BufferCache, pThis->X_BufferCacheSize);
0, pThis->X_BufferCache, pThis->X_BufferCacheSize,
pThis->Xb_VoiceProperties, xbnullptr);
leaveCriticalSection;
@ -3285,7 +3288,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetMixBinVolumes_8)
LOG_FUNC_ARG(pMixBins)
LOG_FUNC_END;
return HybridDirectSoundBuffer_SetMixBinVolumes_8(pThis->EmuDirectSoundBuffer8, pMixBins, pThis->EmuFlags, pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom);
return HybridDirectSoundBuffer_SetMixBinVolumes_8(pThis->EmuDirectSoundBuffer8, pMixBins, pThis->Xb_VoiceProperties, pThis->EmuFlags, pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom);
}
// ******************************************************************
@ -3359,7 +3362,8 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetFormat)
HRESULT hRet = HybridDirectSoundBuffer_SetFormat(pThis->EmuDirectSoundBuffer8, pwfxFormat, pThis->EmuBufferDesc,
pThis->EmuFlags, pThis->EmuPlayFlags, pThis->EmuDirectSound3DBuffer8,
0, pThis->X_BufferCache, pThis->X_BufferCacheSize);
0, pThis->X_BufferCache, pThis->X_BufferCacheSize,
pThis->Xb_VoiceProperties, xbnullptr);
leaveCriticalSection;
@ -4105,8 +4109,6 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_GetVoiceProperties)
X_CDirectSoundBuffer* pThis,
OUT X_DSVOICEPROPS* pVoiceProps)
{
enterCriticalSection;
LOG_FUNC_BEGIN
LOG_FUNC_ARG(pThis)
LOG_FUNC_ARG_OUT(pVoiceProps)
@ -4116,30 +4118,8 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_GetVoiceProperties)
LOG_TEST_CASE("pVoiceProps == xbnullptr");
RETURN(DS_OK);
}
// HACK: Set values that are known to prevent crashes/hangs
// TODO: Investigate and implement proper mixbin functionality
pVoiceProps->dwMixBinCount = 2;
pVoiceProps->l3DConeVolume = 0;
pVoiceProps->l3DDistanceVolume = 0;
pVoiceProps->l3DDopplerPitch = 0;
pVoiceProps->lI3DL2DirectVolume = 0;
pVoiceProps->lI3DL2RoomVolume = 0;
pVoiceProps->lPitch = -4597;
for (int i = 0; i < 8; i++) {
if (i < pVoiceProps->dwMixBinCount) {
pVoiceProps->MixBinVolumePairs[i].dwMixBin = i;
pVoiceProps->MixBinVolumePairs[i].lVolume = 0;
} else {
pVoiceProps->MixBinVolumePairs[i].dwMixBin = 0xFFFFFFFF;
pVoiceProps->MixBinVolumePairs[i].lVolume = -10000;
}
}
leaveCriticalSection;
return DS_OK;
return HybridDirectSoundBuffer_GetVoiceProperties(pThis->Xb_VoiceProperties, pVoiceProps);
}
// ******************************************************************
@ -4151,9 +4131,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_GetVoiceProperties)
OUT X_DSVOICEPROPS* pVoiceProps
)
{
enterCriticalSection;
LOG_FUNC_BEGIN
LOG_FUNC_BEGIN
LOG_FUNC_ARG(pThis)
LOG_FUNC_ARG_OUT(pVoiceProps)
LOG_FUNC_END;
@ -4163,29 +4141,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_GetVoiceProperties)
RETURN(DS_OK);
}
// HACK: Set values that are known to prevent crashes/hangs
// TODO: Investigate and implement proper mixbin functionality
pVoiceProps->dwMixBinCount = 2;
pVoiceProps->l3DConeVolume = 0;
pVoiceProps->l3DDistanceVolume = 0;
pVoiceProps->l3DDopplerPitch = 0;
pVoiceProps->lI3DL2DirectVolume = 0;
pVoiceProps->lI3DL2RoomVolume = 0;
pVoiceProps->lPitch = -4597;
for (int i = 0; i < 8; i++) {
if (i < pVoiceProps->dwMixBinCount) {
pVoiceProps->MixBinVolumePairs[i].dwMixBin = i;
pVoiceProps->MixBinVolumePairs[i].lVolume = 0;
} else {
pVoiceProps->MixBinVolumePairs[i].dwMixBin = 0xFFFFFFFF;
pVoiceProps->MixBinVolumePairs[i].lVolume = -10000;
}
}
leaveCriticalSection;
return DS_OK;
return HybridDirectSoundBuffer_GetVoiceProperties(pThis->Xb_VoiceProperties, pVoiceProps);
}
// ******************************************************************

View File

@ -316,10 +316,14 @@ inline void GeneratePCMFormat(
DWORD &dwEmuFlags,
DWORD X_BufferSizeRequest,
LPVOID* X_BufferCache,
DWORD &X_BufferCacheSize)
DWORD &X_BufferCacheSize,
XTL::X_DSVOICEPROPS& Xb_VoiceProperties,
XTL::X_LPDSMIXBINS mixbins_output)
{
bool bIsSpecial = false;
DWORD checkAvgBps;
GenerateMixBinDefault(Xb_VoiceProperties, lpwfxFormat, mixbins_output, ((DSBufferDesc.dwFlags & DSBCAPS_CTRL3D) > 0));
// convert from Xbox to PC DSound
{
@ -1475,7 +1479,9 @@ inline HRESULT HybridDirectSoundBuffer_SetFormat(
LPDIRECTSOUND3DBUFFER8 &pDS3DBuffer,
bool X_BufferAllocate,
LPVOID &X_BufferCache,
DWORD &X_BufferCacheSize)
DWORD &X_BufferCacheSize,
XTL::X_DSVOICEPROPS &Xb_VoiceProperties,
XTL::X_LPDSMIXBINS mixbins_output)
{
enterCriticalSection;
@ -1483,10 +1489,10 @@ inline HRESULT HybridDirectSoundBuffer_SetFormat(
pDSBuffer->Stop();
if (X_BufferAllocate) {
GeneratePCMFormat(BufferDesc, pwfxFormat, dwEmuFlags, X_BufferCacheSize, xbnullptr, X_BufferCacheSize);
GeneratePCMFormat(BufferDesc, pwfxFormat, dwEmuFlags, X_BufferCacheSize, xbnullptr, X_BufferCacheSize, Xb_VoiceProperties, mixbins_output);
// Don't allocate for DS Stream class, it is using straight from the source.
} else {
GeneratePCMFormat(BufferDesc, pwfxFormat, dwEmuFlags, 0, xbnullptr, X_BufferCacheSize);
GeneratePCMFormat(BufferDesc, pwfxFormat, dwEmuFlags, 0, xbnullptr, X_BufferCacheSize, Xb_VoiceProperties, mixbins_output);
}
HRESULT hRet = DS_OK;
if (g_pDSoundPrimaryBuffer == pDSBuffer) {
@ -1645,6 +1651,7 @@ inline HRESULT HybridDirectSoundBuffer_SetMixBins(
inline HRESULT HybridDirectSoundBuffer_SetMixBinVolumes_8(
LPDIRECTSOUNDBUFFER8 pDSBuffer,
XTL::X_LPDSMIXBINS pMixBins,
XTL::X_DSVOICEPROPS& Xb_VoiceProperties,
DWORD EmuFlags,
LONG Xb_volume,
LONG &Xb_volumeMixBin,
@ -1660,6 +1667,21 @@ inline HRESULT HybridDirectSoundBuffer_SetMixBinVolumes_8(
if (pMixBins->lpMixBinVolumePairs != xbnullptr) {
// Let's normalize audio level except for low frequency (subwoofer)
for (DWORD i = 0; i < count; i++) {
// Update the mixbin volume only, do not reassign volume pair array.
for (DWORD i = 0; i < count; i++) {
auto& it_in = pMixBins->lpMixBinVolumePairs[i];
for (DWORD ii = 0; ii < Xb_VoiceProperties.dwMixBinCount; ii++) {
auto& it_internal = Xb_VoiceProperties.MixBinVolumePairs[ii];
// Once found a match, set the volume.
// NOTE If titles input duplicate with different volume,
// it will override previous value.
if (it_in.dwMixBin == it_internal.dwMixBin) {
it_internal.lVolume = it_in.lVolume;
}
}
}
#if 0 // This code isn't ideal for DirectSound, since it's not possible to set volume for each speakers.
if (pMixBins->lpMixBinVolumePairs[i].dwMixBin != XDSMIXBIN_LOW_FREQUENCY
// We only want to focus on speaker volumes, nothing else.