diff --git a/src/audio/AudioLogic.cpp b/src/audio/AudioLogic.cpp index 4624d83a..e6401c54 100644 --- a/src/audio/AudioLogic.cpp +++ b/src/audio/AudioLogic.cpp @@ -6302,7 +6302,7 @@ cPedComments::Process() { case LOADING_STATUS_NOT_LOADED: SampleManager.LoadPedComment(sampleIndex); -#ifdef GTA_PS2 // on PC ped comment is loaded at once +#if defined(GTA_PS2) || defined(RW_DC) // on PC ped comment is loaded at once break; #endif case LOADING_STATUS_LOADED: diff --git a/src/audio/sampman_dc.cpp b/src/audio/sampman_dc.cpp index 0f48a4b8..142aca86 100644 --- a/src/audio/sampman_dc.cpp +++ b/src/audio/sampman_dc.cpp @@ -166,8 +166,12 @@ struct sfx_bank { std::map sfx_banks; int nPedSlotSfx[MAX_PEDSFX]; +uint32 nPedSlotSfxReqId[MAX_PEDSFX]; uintptr_t nPedSlotSfxAddr[MAX_PEDSFX]; uint8_t nCurrentPedSlot; +file_t fdPedSfx; +volatile uint32 nPedSfxReqReadId = 1; +volatile uint32 nPedSfxReqNextId = 1; struct WavHeader { // RIFF Header @@ -442,15 +446,22 @@ cSampleManager::Initialise(void) } }); + nPedSfxReqNextId = 1; + nPedSfxReqReadId = 1; for ( int32 i = 0; i < MAX_PEDSFX; i++ ) { nPedSlotSfx[i] = -1; + nPedSlotSfxReqId[i] = 0; nPedSlotSfxAddr[i] = snd_mem_malloc(PED_BLOCKSIZE_ADPCM); debugf("PedSlot %d buffer: %p\n", i, (void*)nPedSlotSfxAddr[i]); } nCurrentPedSlot = 0; + fdPedSfx = fs_open(SampleBankDataFilename, O_RDONLY); + + assert(fdPedSfx >= 0); + _dcAudioInitialized = true; return TRUE; } @@ -458,7 +469,7 @@ cSampleManager::Initialise(void) void cSampleManager::Terminate(void) { - + fs_close(fdPedSfx); } bool8 cSampleManager::CheckForAnAudioFileOnCD(void) @@ -637,7 +648,7 @@ cSampleManager::IsPedCommentLoaded(uint32 nComment) slot += ARRAY_SIZE(nPedSlotSfx); #endif if ( nComment == nPedSlotSfx[slot] ) - return LOADING_STATUS_LOADED; + return nPedSlotSfxReqId[slot] <= nPedSfxReqReadId ? LOADING_STATUS_LOADED : LOADING_STATUS_LOADING; } return LOADING_STATUS_NOT_LOADED; @@ -698,27 +709,28 @@ cSampleManager::LoadPedComment(uint32 nComment) assert(m_aSamples[nComment].nByteSize < PED_BLOCKSIZE_ADPCM); - file_t fd = fs_open(SampleBankDataFilename, O_RDONLY); - - assert(fd >= 0); - debugf("Loading ped comment %d, offset: %d, size: %d\n", nComment, m_aSamples[nComment].nFileOffset, m_aSamples[nComment].nByteSize); - fs_seek(fd, m_aSamples[nComment].nFileOffset, SEEK_SET); + CdStreamQueueAudioRead(nComment, (void*)nPedSlotSfxAddr[nCurrentPedSlot], m_aSamples[nComment].nByteSize, m_aSamples[nComment].nFileOffset, [](AudioReadCmd* cmd) { + debugf("Loading ped comment %d, offset: %d, size: %d\n", nComment, m_aSamples[nComment].nFileOffset, m_aSamples[nComment].nByteSize); + fs_seek(fdPedSfx, cmd->seek, SEEK_SET); - // TODO: When we can dma directly to AICA, we can use this instead - // fs_read(fd, SPU_BASE_U8 + nPedSlotSfxAddr[nCurrentPedSlot], sizeof(nPedSlotSfxAddr)); + // TODO: When we can dma directly to AICA, we can use this instead + // fs_read(fdPedSfx, SPU_BASE_U8 + (uintptr_t)cmd->dest, cmd->size); - void* stagingBuffer = memalign(32, m_aSamples[nComment].nByteSize); - assert(stagingBuffer != 0); - debugf("Allocated %d bytes at %p\n", m_aSamples[nComment].nByteSize, stagingBuffer); - int rs = fs_read(fd, stagingBuffer, m_aSamples[nComment].nByteSize); - debugf("Read %d bytes, expected %d\n", rs, m_aSamples[nComment].nByteSize); - assert(rs == m_aSamples[nComment].nByteSize); + void* stagingBuffer = memalign(32, cmd->size); + assert(stagingBuffer != 0); + debugf("Allocated %d bytes at %p\n", cmd->size, stagingBuffer); + int rs = fs_read(fdPedSfx, stagingBuffer, cmd->size); + debugf("Read %d bytes, expected %d\n", rs, cmd->size); + assert(rs == cmd->size); - fs_close(fd); + spu_memload((uintptr_t)cmd->dest, stagingBuffer, cmd->size); + free(stagingBuffer); + nPedSfxReqReadId = nPedSfxReqReadId + 1; + }); - spu_memload(nPedSlotSfxAddr[nCurrentPedSlot], stagingBuffer, m_aSamples[nComment].nByteSize); - free(stagingBuffer); + nPedSlotSfxReqId[nCurrentPedSlot] = ++nPedSfxReqNextId; + nPedSlotSfx[nCurrentPedSlot] = nComment; if ( ++nCurrentPedSlot >= MAX_PEDSFX ) diff --git a/src/core/CdStream.h b/src/core/CdStream.h index 420a3c8d..0a84d01a 100644 --- a/src/core/CdStream.h +++ b/src/core/CdStream.h @@ -1,4 +1,5 @@ #pragma once +#include #define CDSTREAM_SECTOR_SIZE 2048 @@ -43,7 +44,14 @@ char *CdStreamGetImageName(int32 cd); void CdStreamRemoveImages(void); int32 CdStreamGetNumImages(void); -void CdStreamQueueAudioRead(int fd, void* pBuffer, size_t bytes, size_t seek); +struct AudioReadCmd { + void* dest; + int fd; + size_t size; + size_t seek; + std::function callback; +}; +void CdStreamQueueAudioRead(int fd, void* pBuffer, size_t bytes, size_t seek, std::function callback = nullptr); void CdStreamDiscardAudioRead(int fd); #ifdef FLUSHABLE_STREAMING diff --git a/src/core/CdStreamDC.cpp b/src/core/CdStreamDC.cpp index 04c02327..ab83f872 100644 --- a/src/core/CdStreamDC.cpp +++ b/src/core/CdStreamDC.cpp @@ -26,12 +26,6 @@ #include "CdStream.h" #include "rwcore.h" #include "MemoryMgr.h" -struct AudioReadCmd { - void* dest; - int fd; - size_t size; - size_t seek; -}; #define CDDEBUG(f, ...) debug ("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__) #define CDTRACE(f, ...) printf("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__) @@ -489,8 +483,16 @@ std::vector pendingAudioReads; std::mutex pendingAudioReadsMutex; #endif // Will replace a previous read request for the same file descriptor -void CdStreamQueueAudioRead(int fd, void* pBuffer, size_t bytes, size_t seek) { +void CdStreamQueueAudioRead(int fd, void* pBuffer, size_t bytes, size_t seek, std::function callback) { AudioReadCmd cmd = { pBuffer, fd, bytes, seek}; + if (!callback) { + cmd.callback = [](AudioReadCmd* cmd){ + lseek(cmd->fd, cmd->seek, SEEK_SET); + read(cmd->fd, cmd->dest, cmd->size); + }; + } else { + cmd.callback = callback; + } { #if !defined(DC_SH4) std::lock_guard lock(pendingAudioReadsMutex); @@ -514,6 +516,7 @@ void CdStreamQueueAudioRead(int fd, void* pBuffer, size_t bytes, size_t seek) { sem_post(gCdStreamSema); } + void CdStreamDiscardAudioRead(int fd) { #if !defined(DC_SH4) std::lock_guard lock(pendingAudioReadsMutex); @@ -564,8 +567,7 @@ int read_loop(int fd, void* pBuffer, size_t bytes) { total_read += read_bytes; auto cmd = CdStreamNextAudioRead(); while (cmd.fd != -1) { - lseek(cmd.fd, cmd.seek, SEEK_SET); - read(cmd.fd, cmd.dest, cmd.size); + cmd.callback(&cmd); cmd = CdStreamNextAudioRead(); } } @@ -581,8 +583,7 @@ void *CdStreamThread(void *param) auto cmd = CdStreamNextAudioRead(); while (cmd.fd != -1) { - lseek(cmd.fd, cmd.seek, SEEK_SET); - read(cmd.fd, cmd.dest, cmd.size); + cmd.callback(&cmd); cmd = CdStreamNextAudioRead(); }