From b2a01dc348138f2faf1335002e102aadabc436cf Mon Sep 17 00:00:00 2001 From: skidau Date: Mon, 22 Oct 2012 22:59:35 +1100 Subject: [PATCH 1/2] Changed the loop end address detection to an exact match with the current address for ADPCM audio. Fixes the non-looping music in PN03. Fixes issue 3998. --- Source/Core/Core/Src/DSP/DSPAccelerator.cpp | 6 +++++- Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX_Voice.h | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/Src/DSP/DSPAccelerator.cpp b/Source/Core/Core/Src/DSP/DSPAccelerator.cpp index b1452c249c..92651205a9 100644 --- a/Source/Core/Core/Src/DSP/DSPAccelerator.cpp +++ b/Source/Core/Core/Src/DSP/DSPAccelerator.cpp @@ -165,7 +165,11 @@ u16 dsp_read_accelerator() // Somehow, YN1 and YN2 must be initialized with their "loop" values, // so yeah, it seems likely that we should raise an exception to let // the DSP program do that, at least if DSP_FORMAT == 0x0A. - if (Address >= EndAddress) + + if (Address > EndAddress && g_dsp.ifx_regs[DSP_FORMAT] != 0x00) // PCM audio + Address = EndAddress; + + if (Address == EndAddress) { // Set address back to start address. Address = (g_dsp.ifx_regs[DSP_ACSAH] << 16) | g_dsp.ifx_regs[DSP_ACSAL]; diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX_Voice.h b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX_Voice.h index e6ee063ae3..7649a53091 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX_Voice.h +++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX_Voice.h @@ -232,7 +232,8 @@ inline void MixAddVoice(ParamBlockType &pb, temprbuffer[s] += right; // Control the behavior when we reach the end of the sample - if (samplePos >= sampleEnd) + if ((pb.audio_addr.sample_format != AUDIOFORMAT_ADPCM && samplePos >= sampleEnd) || + (pb.audio_addr.sample_format == AUDIOFORMAT_ADPCM && samplePos == sampleEnd)) { if (pb.audio_addr.looping == 1) { From 421a75493cd2cd15ca72e9bc254812a6c4f7aa25 Mon Sep 17 00:00:00 2001 From: skidau Date: Tue, 23 Oct 2012 00:30:01 +1100 Subject: [PATCH 2/2] Removed the fake DMA wait time as it is no longer needed after the aram-dma-fixes branch is merged. This fixes the Resident Evil 2/3 cutscene audio in DSP LLE mode. Fixes issue 2723. Removed the ADPCM format detection from the previous commit as it broke the audio looping in Knockout Kings 2003. --- Source/Core/Core/Src/DSP/DSPAccelerator.cpp | 9 +++------ Source/Core/Core/Src/HW/DSP.cpp | 6 ++---- Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX_Voice.h | 6 +++--- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/Source/Core/Core/Src/DSP/DSPAccelerator.cpp b/Source/Core/Core/Src/DSP/DSPAccelerator.cpp index 92651205a9..525750fc7d 100644 --- a/Source/Core/Core/Src/DSP/DSPAccelerator.cpp +++ b/Source/Core/Core/Src/DSP/DSPAccelerator.cpp @@ -165,14 +165,11 @@ u16 dsp_read_accelerator() // Somehow, YN1 and YN2 must be initialized with their "loop" values, // so yeah, it seems likely that we should raise an exception to let // the DSP program do that, at least if DSP_FORMAT == 0x0A. - - if (Address > EndAddress && g_dsp.ifx_regs[DSP_FORMAT] != 0x00) // PCM audio - Address = EndAddress; - - if (Address == EndAddress) + if (Address >= EndAddress) { // Set address back to start address. - Address = (g_dsp.ifx_regs[DSP_ACSAH] << 16) | g_dsp.ifx_regs[DSP_ACSAL]; + if (Address == EndAddress) + Address = (g_dsp.ifx_regs[DSP_ACSAH] << 16) | g_dsp.ifx_regs[DSP_ACSAL]; DSPCore_SetException(EXP_ACCOV); } diff --git a/Source/Core/Core/Src/HW/DSP.cpp b/Source/Core/Core/Src/HW/DSP.cpp index f2509555ed..e86231db43 100644 --- a/Source/Core/Core/Src/HW/DSP.cpp +++ b/Source/Core/Core/Src/HW/DSP.cpp @@ -697,14 +697,12 @@ void UpdateAudioDMA() void Do_ARAM_DMA() { - // Fake the DMA taking time to complete. The delay is not accurate, but - // seems like a good estimate - CoreTiming::ScheduleEvent_Threadsafe(g_arDMA.Cnt.count >> 1, et_GenerateDSPInterrupt, INT_ARAM | (1<<16)); - // Emulating the DMA wait time fixes Knockout Kings 2003 in DSP HLE mode if (!GetDSPEmulator()->IsLLE()) g_dspState.DSPControl.DMAState = 1; + GenerateDSPInterrupt(INT_ARAM, true); + // Real hardware DMAs in 32byte chunks, but we can get by with 8byte chunks if (g_arDMA.Cnt.dir) { diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX_Voice.h b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX_Voice.h index 7649a53091..9a058afb83 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX_Voice.h +++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX_Voice.h @@ -232,12 +232,12 @@ inline void MixAddVoice(ParamBlockType &pb, temprbuffer[s] += right; // Control the behavior when we reach the end of the sample - if ((pb.audio_addr.sample_format != AUDIOFORMAT_ADPCM && samplePos >= sampleEnd) || - (pb.audio_addr.sample_format == AUDIOFORMAT_ADPCM && samplePos == sampleEnd)) + if (samplePos >= sampleEnd) { if (pb.audio_addr.looping == 1) { - samplePos = loopPos; + if (samplePos == sampleEnd || (pb.audio_addr.sample_format != AUDIOFORMAT_ADPCM)) + samplePos = loopPos; if ((!pb.is_stream) && (pb.audio_addr.sample_format == AUDIOFORMAT_ADPCM)) { pb.adpcm.yn1 = pb.adpcm_loop_info.yn1;