Introduce DirectSoundStream fixes
XADPCM audio are much better now, need tester's ears to verify the errors. Test cases: - Battlestar Galactica (sit back and enjoy the intro video! Get popcorns too!) - Rayman Arena (sounds about the same as original intended, before fps was fixed) - Ghost Recon (PCM, sound like no change) - Taz: Wanted (sound like it is normal?) - Turok Evolution (sound fine but video is little bit too slow?) Testers, please test this for ANY functional intro videos (which uses DirectSoundStream 85% of the time).
This commit is contained in:
parent
b5be48c4a1
commit
db19158254
|
@ -460,13 +460,13 @@ VOID WINAPI XTL::EMUPATCH(DirectSoundDoWork)()
|
|||
//TODO: This need a lock in each frame. I think it does not wait for each frame.
|
||||
XTL::X_CDirectSoundBuffer* *pDSBuffer = g_pDSoundBufferCache;
|
||||
for (int v = 0; v < SOUNDBUFFER_CACHE_SIZE; v++, pDSBuffer++) {
|
||||
if ((*pDSBuffer) == nullptr || (*pDSBuffer)->EmuBuffer == nullptr || (*pDSBuffer)->EmuBufferToggle != X_DSB_TOGGLE_DEFAULT) {
|
||||
if ((*pDSBuffer) == nullptr || (*pDSBuffer)->X_BufferCache == xbnullptr || (*pDSBuffer)->EmuBufferToggle != X_DSB_TOGGLE_DEFAULT) {
|
||||
continue;
|
||||
}
|
||||
/* Bypass Update buffer, audio appear to be working just fine without need to update audio.
|
||||
DSoundBufferUpdate((*pDSBuffer)->EmuDirectSoundBuffer8,
|
||||
(*pDSBuffer)->EmuBufferDesc,
|
||||
(*pDSBuffer)->EmuBuffer,
|
||||
(*pDSBuffer)->X_BufferCache,
|
||||
(*pDSBuffer)->EmuFlags,
|
||||
(*pDSBuffer)->EmuLockOffset,
|
||||
(*pDSBuffer)->EmuLockPtr1,
|
||||
|
@ -491,12 +491,12 @@ VOID WINAPI XTL::EMUPATCH(DirectSoundDoWork)()
|
|||
/*
|
||||
XTL::X_CDirectSoundStream* *pDSStream = g_pDSoundStreamCache;
|
||||
for (int v = 0; v < SOUNDSTREAM_CACHE_SIZE; v++, pDSStream++) {
|
||||
if ((*pDSStream) == nullptr || (*pDSStream)->EmuBuffer == nullptr) {
|
||||
if ((*pDSStream) == nullptr || (*pDSStream)->X_BufferCache == nullptr) {
|
||||
continue;
|
||||
}
|
||||
DSoundBufferUpdate((*pDSStream)->EmuDirectSoundBuffer8,
|
||||
(*pDSStream)->EmuBufferDesc,
|
||||
(*pDSStream)->EmuBuffer,
|
||||
(*pDSStream)->X_BufferCache,
|
||||
(*pDSStream)->EmuFlags,
|
||||
0,
|
||||
(*pDSStream)->EmuLockPtr1,
|
||||
|
@ -1004,12 +1004,15 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetBufferData)
|
|||
if (pThis->EmuLockPtr1 != xbnullptr) {
|
||||
memcpy(pThis->EmuLockPtr1, pvBufferData, pThis->EmuLockBytes1);
|
||||
|
||||
// TODO: We could reduce allocate and free buffer if the size is the same.
|
||||
if (pThis->EmuBuffer != xbnullptr) {
|
||||
free(pThis->EmuBuffer);
|
||||
// Increase allocate memory size only.
|
||||
if (pThis->X_BufferCacheSize < dwBufferBytes) {
|
||||
if (pThis->X_BufferCache != xbnullptr) {
|
||||
free(pThis->X_BufferCache);
|
||||
}
|
||||
pThis->X_BufferCache = malloc(dwBufferBytes);
|
||||
pThis->X_BufferCacheSize = dwBufferBytes;
|
||||
}
|
||||
pThis->EmuBuffer = malloc(dwBufferBytes);
|
||||
memcpy(pThis->EmuBuffer, pvBufferData, dwBufferBytes);
|
||||
memcpy(pThis->X_BufferCache, pvBufferData, dwBufferBytes);
|
||||
}
|
||||
|
||||
DSoundGenericUnlock(pThis->EmuFlags,
|
||||
|
@ -1089,11 +1092,19 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Lock)
|
|||
|
||||
HRESULT hRet = D3D_OK;
|
||||
|
||||
if (dwBytes > pThis->EmuBufferDesc->dwBufferBytes) {
|
||||
if (pThis->EmuBuffer != xbnullptr) {
|
||||
free(pThis->EmuBuffer);
|
||||
pThis->EmuBuffer = xbnullptr;
|
||||
if (dwBytes > pThis->X_BufferCacheSize) {
|
||||
PVOID X_tempBuffer = pThis->X_BufferCache;
|
||||
pThis->X_BufferCache = malloc(dwBytes);
|
||||
|
||||
if (X_tempBuffer != xbnullptr) {
|
||||
memcpy(pThis->X_BufferCache, X_tempBuffer, pThis->X_BufferCacheSize);
|
||||
free(X_tempBuffer);
|
||||
}
|
||||
|
||||
pThis->X_BufferCacheSize = dwBytes;
|
||||
}
|
||||
|
||||
if (dwBytes > pThis->EmuBufferDesc->dwBufferBytes) {
|
||||
ResizeIDirectSoundBuffer(pThis->EmuDirectSoundBuffer8, pThis->EmuBufferDesc,
|
||||
pThis->EmuPlayFlags, dwBytes, pThis->EmuDirectSound3DBuffer8);
|
||||
DSoundBufferRegionRelease(pThis);
|
||||
|
@ -1151,8 +1162,8 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Unlock)
|
|||
LOG_FUNC_ARG(pdwAudioBytes2)
|
||||
LOG_FUNC_END;
|
||||
|
||||
if (pThis->EmuBuffer != xbnullptr) {
|
||||
memcpy_s((PBYTE)pThis->EmuBuffer + pThis->EmuLockOffset,
|
||||
if (pThis->X_BufferCache != xbnullptr) {
|
||||
memcpy_s((PBYTE)pThis->X_BufferCache + pThis->EmuLockOffset,
|
||||
pThis->EmuBufferDesc->dwBufferBytes - pThis->EmuLockOffset,
|
||||
pThis->EmuLockPtr1,
|
||||
pThis->EmuLockBytes1);
|
||||
|
@ -1263,8 +1274,9 @@ ULONG WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Release)
|
|||
if (pThis->EmuBufferDesc->lpwfxFormat != nullptr) {
|
||||
free(pThis->EmuBufferDesc->lpwfxFormat);
|
||||
}
|
||||
if (pThis->EmuBuffer != xbnullptr) {
|
||||
free(pThis->EmuBuffer);
|
||||
if (pThis->X_BufferCache != xbnullptr) {
|
||||
free(pThis->X_BufferCache);
|
||||
pThis->X_BufferCacheSize = 0;
|
||||
}
|
||||
if (pThis->EmuDirectSoundBuffer8Region != nullptr) {
|
||||
pThis->EmuDirectSoundBuffer8Region->Release();
|
||||
|
@ -1469,7 +1481,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Play)
|
|||
CxbxKrnlCleanup("Unable to lock region buffer!");
|
||||
}
|
||||
if (pThis->EmuLockPtr1 != xbnullptr) {
|
||||
memcpy_s(pThis->EmuLockPtr1, pThis->EmuLockBytes1, (PVOID)((PBYTE)pThis->EmuBuffer + startOffset), byteLength);
|
||||
memcpy_s(pThis->EmuLockPtr1, pThis->EmuLockBytes1, (PVOID)((PBYTE)pThis->X_BufferCache + startOffset), byteLength);
|
||||
if (pThis->EmuFlags & DSB_FLAG_XADPCM) {
|
||||
DSoundBufferXboxAdpcmDecoder(pThis->EmuDirectSoundBuffer8Region,
|
||||
emuBufferDescRegion, 0, pThis->EmuLockPtr1,
|
||||
|
@ -1840,7 +1852,7 @@ ULONG WINAPI XTL::EMUPATCH(CDirectSoundStream_Release)
|
|||
if (pThis->EmuBufferDesc->lpwfxFormat != NULL) {
|
||||
free(pThis->EmuBufferDesc->lpwfxFormat);
|
||||
}
|
||||
// NOTE: Do not release EmuBuffer! EmuBuffer is using xbox buffer.
|
||||
// NOTE: Do not release X_BufferCache! X_BufferCache is using xbox buffer.
|
||||
free(pThis->EmuBufferDesc);
|
||||
|
||||
delete pThis;
|
||||
|
@ -1923,17 +1935,17 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_Process)
|
|||
|
||||
if (pThis->EmuDirectSoundBuffer8 != nullptr) {
|
||||
// update buffer data cache
|
||||
pThis->EmuBuffer = pInputBuffer->pvBuffer;
|
||||
pThis->X_BufferCache = pInputBuffer->pvBuffer;
|
||||
|
||||
ResizeIDirectSoundBuffer(pThis->EmuDirectSoundBuffer8, pThis->EmuBufferDesc,
|
||||
pThis->EmuPlayFlags, pInputBuffer->dwMaxSize, pThis->EmuDirectSound3DBuffer8);
|
||||
pThis->EmuPlayFlags, DSoundBufferGetPCMBufferSize(pThis, pInputBuffer->dwMaxSize), pThis->EmuDirectSound3DBuffer8);
|
||||
|
||||
if (pInputBuffer->pdwStatus != 0) {
|
||||
*pInputBuffer->pdwStatus = S_OK;
|
||||
}
|
||||
|
||||
PVOID pAudioPtr, pAudioPtr2;
|
||||
DWORD dwAudioBytes, dwAudioBytes2;
|
||||
PVOID pAudioPtr;
|
||||
DWORD dwAudioBytes;
|
||||
HRESULT hRet;
|
||||
|
||||
|
||||
|
@ -1943,7 +1955,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_Process)
|
|||
DSoundBufferXboxAdpcmDecoder(pThis->EmuDirectSoundBuffer8,
|
||||
pThis->EmuBufferDesc,
|
||||
0,
|
||||
pThis->EmuBuffer,
|
||||
pThis->X_BufferCache,
|
||||
pInputBuffer->dwMaxSize,
|
||||
0,
|
||||
0,
|
||||
|
@ -1951,17 +1963,14 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_Process)
|
|||
|
||||
} else {
|
||||
hRet = pThis->EmuDirectSoundBuffer8->Lock(0, pThis->EmuBufferDesc->dwBufferBytes, &pAudioPtr, &dwAudioBytes,
|
||||
&pAudioPtr2, &dwAudioBytes2, 0);
|
||||
nullptr, nullptr, 0);
|
||||
|
||||
if (hRet == DS_OK) {
|
||||
|
||||
if (pAudioPtr != 0) {
|
||||
memcpy(pAudioPtr, pThis->EmuBuffer, dwAudioBytes);
|
||||
DSoundBufferOutputXBtoPC(pThis->EmuFlags, pThis->EmuBufferDesc, pThis->X_BufferCache, pInputBuffer->dwMaxSize, pAudioPtr, dwAudioBytes);
|
||||
}
|
||||
if (pAudioPtr2 != 0) {
|
||||
memcpy(pAudioPtr2, (PVOID)((DWORD)pThis->EmuBuffer + dwAudioBytes), dwAudioBytes2);
|
||||
}
|
||||
pThis->EmuDirectSoundBuffer8->Unlock(pAudioPtr, dwAudioBytes, pAudioPtr2, dwAudioBytes2);
|
||||
pThis->EmuDirectSoundBuffer8->Unlock(pAudioPtr, dwAudioBytes, nullptr, 0);
|
||||
}
|
||||
}
|
||||
//TODO: RadWolfie - If remove this part, XADPCM audio will stay running, Rayman Arena, except...
|
||||
|
@ -2046,7 +2055,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSound_SynchPlayback)
|
|||
|
||||
XTL::X_CDirectSoundBuffer* *pDSBuffer = g_pDSoundBufferCache;
|
||||
for (int v = 0; v < SOUNDBUFFER_CACHE_SIZE; v++, pDSBuffer++) {
|
||||
if ((*pDSBuffer) == nullptr || (*pDSBuffer)->EmuBuffer == nullptr) {
|
||||
if ((*pDSBuffer) == nullptr || (*pDSBuffer)->X_BufferCache == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2060,7 +2069,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSound_SynchPlayback)
|
|||
|
||||
XTL::X_CDirectSoundStream* *pDSStream = g_pDSoundStreamCache;
|
||||
for (int v = 0; v < SOUNDSTREAM_CACHE_SIZE; v++, pDSStream++) {
|
||||
if ((*pDSStream) == nullptr || (*pDSStream)->EmuBuffer == nullptr) {
|
||||
if ((*pDSStream) == nullptr || (*pDSStream)->X_BufferCache == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if ((*pDSStream)->EmuFlags & DSB_FLAG_SYNCHPLAYBACK_CONTROL) {
|
||||
|
|
|
@ -305,7 +305,7 @@ struct X_CDirectSoundBuffer
|
|||
};
|
||||
|
||||
BYTE UnknownB[0x0C]; // Offset: 0x24
|
||||
PVOID EmuBuffer; // Offset: 0x28
|
||||
PVOID X_BufferCache; // Offset: 0x28
|
||||
DSBUFFERDESC* EmuBufferDesc; // Offset: 0x2C
|
||||
PVOID EmuLockPtr1; // Offset: 0x30
|
||||
DWORD EmuLockBytes1; // Offset: 0x34
|
||||
|
@ -324,6 +324,7 @@ struct X_CDirectSoundBuffer
|
|||
DWORD EmuRegionPlayLength;
|
||||
LPDIRECTSOUNDBUFFER8 EmuDirectSoundBuffer8Region;
|
||||
LPDIRECTSOUND3DBUFFER8 EmuDirectSound3DBuffer8Region;
|
||||
DWORD X_BufferCacheSize;
|
||||
};
|
||||
|
||||
#define WAVE_FORMAT_XBOX_ADPCM 0x0069
|
||||
|
@ -439,7 +440,7 @@ class X_CDirectSoundStream
|
|||
// cached data
|
||||
LPDIRECTSOUNDBUFFER8 EmuDirectSoundBuffer8;
|
||||
LPDIRECTSOUND3DBUFFER8 EmuDirectSound3DBuffer8;
|
||||
PVOID EmuBuffer;
|
||||
PVOID X_BufferCache;
|
||||
LPDSBUFFERDESC EmuBufferDesc;
|
||||
PVOID EmuLockPtr1;
|
||||
DWORD EmuLockBytes1;
|
||||
|
@ -447,6 +448,7 @@ class X_CDirectSoundStream
|
|||
DWORD EmuLockBytes2;
|
||||
DWORD EmuPlayFlags;
|
||||
DWORD EmuFlags;
|
||||
DWORD X_BufferCacheSize;
|
||||
};
|
||||
|
||||
// ******************************************************************
|
||||
|
|
|
@ -89,9 +89,9 @@ void DSoundBufferXboxAdpcmDecoder(
|
|||
}
|
||||
// Attempt to decode Xbox ADPCM data to PCM
|
||||
//EmuWarning( "Guessing output size to be 0x%X bytes as opposed to 0x%X bytes.", TXboxAdpcmDecoder_guess_output_size(dwAudioBytes), dwAudioBytes );
|
||||
TXboxAdpcmDecoder_Decode_Memory((uint8_t*)pAudioPtr, dwAudioBytes, &buffer1[0], pDSBufferDesc->lpwfxFormat->nChannels);
|
||||
TXboxAdpcmDecoder_Decode_Memory((uint8_t*)pAudioPtr, dwAudioBytes, buffer1, pDSBufferDesc->lpwfxFormat->nChannels);
|
||||
if (dwAudioBytes2 != 0) {
|
||||
TXboxAdpcmDecoder_Decode_Memory((uint8_t*)pAudioPtr2, dwAudioBytes2, &buffer2[0], pDSBufferDesc->lpwfxFormat->nChannels);
|
||||
TXboxAdpcmDecoder_Decode_Memory((uint8_t*)pAudioPtr2, dwAudioBytes2, buffer2, pDSBufferDesc->lpwfxFormat->nChannels);
|
||||
}
|
||||
// Lock this Xbox ADPCM buffer
|
||||
void* pPtrX = xbnullptr, *pPtrX2 = xbnullptr;
|
||||
|
@ -134,6 +134,22 @@ void DSoundBufferXboxAdpcmDecoder(
|
|||
if (buffer2) free(buffer2);
|
||||
}
|
||||
|
||||
#define DSoundBufferGetPCMBufferSize(pThis, size) (pThis->EmuFlags & DSB_FLAG_XADPCM) > 0 ? TXboxAdpcmDecoder_guess_output_size(size) : size
|
||||
|
||||
void DSoundBufferOutputXBtoPC(DWORD emuFlags, DSBUFFERDESC* pDSBufferDesc, LPVOID pXBaudioPtr, DWORD dwXBAudioBytes, LPVOID pPCaudioPtr, DWORD dwPCMAudioBytes) {
|
||||
if ((emuFlags & DSB_FLAG_XADPCM) > 0) {
|
||||
DWORD dwDecodedAudioBytes = TXboxAdpcmDecoder_guess_output_size(dwXBAudioBytes) * pDSBufferDesc->lpwfxFormat->nChannels;
|
||||
|
||||
if (dwDecodedAudioBytes > dwPCMAudioBytes) dwDecodedAudioBytes = dwPCMAudioBytes;
|
||||
|
||||
TXboxAdpcmDecoder_Decode_Memory((uint8_t*)pXBaudioPtr, dwXBAudioBytes / pDSBufferDesc->lpwfxFormat->nChannels, (uint8_t*)pPCaudioPtr, pDSBufferDesc->lpwfxFormat->nChannels);
|
||||
|
||||
// PCM format, no changes requirement.
|
||||
} else {
|
||||
memcpy_s(pPCaudioPtr, dwPCMAudioBytes, pXBaudioPtr, dwPCMAudioBytes);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert XADPCM to PCM format helper function
|
||||
inline void XADPCM2PCMFormat(LPWAVEFORMATEX lpwfxFormat)
|
||||
{
|
||||
|
@ -399,14 +415,15 @@ inline void DSound3DBufferCreate(LPDIRECTSOUNDBUFFER8 pDSBuffer, LPDIRECTSOUND3D
|
|||
#define DSoundBufferSetDefault(pThis, pdsd, dwEmuFlags, dwEmuPlayFlags) \
|
||||
pThis->EmuDirectSoundBuffer8 = nullptr; \
|
||||
pThis->EmuDirectSound3DBuffer8 = nullptr; \
|
||||
pThis->EmuBuffer = xbnullptr; \
|
||||
pThis->X_BufferCache = xbnullptr; \
|
||||
pThis->EmuBufferDesc = pdsd; \
|
||||
pThis->EmuLockPtr1 = xbnullptr; \
|
||||
pThis->EmuLockBytes1 = 0; \
|
||||
pThis->EmuLockPtr2 = xbnullptr; \
|
||||
pThis->EmuLockBytes2 = 0; \
|
||||
pThis->EmuFlags = dwEmuFlags; \
|
||||
pThis->EmuPlayFlags = dwEmuPlayFlags;
|
||||
pThis->EmuPlayFlags = dwEmuPlayFlags; \
|
||||
pThis->X_BufferCacheSize = 0;
|
||||
|
||||
inline void DSoundBufferRegionSetDefault(XTL::X_CDirectSoundBuffer *pThis) {
|
||||
pThis->EmuBufferToggle = XTL::X_DSB_TOGGLE_DEFAULT;
|
||||
|
|
Loading…
Reference in New Issue