diff --git a/Data/Sys/GameSettings/GLR.ini b/Data/Sys/GameSettings/GLR.ini index da08587250..45cfeeb4bb 100644 --- a/Data/Sys/GameSettings/GLR.ini +++ b/Data/Sys/GameSettings/GLR.ini @@ -3,17 +3,11 @@ [Core] # Values set here will override the main Dolphin settings. MMU = 1 -# LLE audio enabled by default for a listenable output -DSPHLE = False - -[DSP] -# Ensure the LLE recompiler gets selected and not interpreter. -EnableJIT = True [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 4 -EmulationIssues = Needs LLE audio for proper sound. +EmulationIssues = [OnLoad] # Add memory patches to be loaded once on boot here. diff --git a/Data/Sys/GameSettings/GSW.ini b/Data/Sys/GameSettings/GSW.ini index fc25dbad95..f6aa412284 100644 --- a/Data/Sys/GameSettings/GSW.ini +++ b/Data/Sys/GameSettings/GSW.ini @@ -3,16 +3,10 @@ [Core] # Values set here will override the main Dolphin settings. MMU = 1 -# LLE audio enabled by default for a listenable output -DSPHLE = False - -[DSP] -# Ensure the LLE recompiler gets selected and not interpreter. -EnableJIT = True [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationIssues = Needs LLE audio for proper sound. +EmulationIssues = EmulationStateId = 4 [OnLoad] diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp index 7d8e4522f2..7c9e745fd1 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp @@ -422,7 +422,7 @@ void AXUCode::ProcessPBList(u32 pb_addr) m_samples_auxA_right, m_samples_auxA_surround, m_samples_auxB_left, m_samples_auxB_right, m_samples_auxB_surround}}; - ReadPB(pb_addr, pb); + ReadPB(pb_addr, pb, m_crc); u32 updates_addr = HILO_TO_32(pb.updates.data); u16* updates = (u16*)HLEMemory_Get_Pointer(updates_addr); @@ -439,7 +439,7 @@ void AXUCode::ProcessPBList(u32 pb_addr) buffers.ptrs[i] += spms; } - WritePB(pb_addr, pb); + WritePB(pb_addr, pb, m_crc); pb_addr = HILO_TO_32(pb.next_pb); } } diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AXStructs.h b/Source/Core/Core/HW/DSPHLE/UCodes/AXStructs.h index 6ba6b794c7..098e05073f 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AXStructs.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AXStructs.h @@ -252,9 +252,10 @@ struct AXPB PBADPCMInfo adpcm; PBSampleRateConverter src; PBADPCMLoopInfo adpcm_loop_info; - PBLowPassFilter lpf; + PBLowPassFilter lpf; // Skipped when writing to/reading from MRAM/ARAM for certain AX UCodes + u16 loop_counter; - u16 padding[25]; + u16 padding[24]; }; struct PBBiquadFilter diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h b/Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h index f4f6c4898e..b7fca29356 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h @@ -80,18 +80,63 @@ union AXBuffers #endif }; -// Read a PB from MRAM/ARAM -void ReadPB(u32 addr, PB_TYPE& pb) +// Determines if this version of the UCode has a PBLowPassFilter in its AXPB layout. +bool HasLpf(u32 crc) { - u16* dst = (u16*)&pb; - Memory::CopyFromEmuSwapped(dst, addr, sizeof(pb)); + switch (crc) + { + case 0x4E8A8B21: + return false; + default: + return true; + } +} + +// Read a PB from MRAM/ARAM +void ReadPB(u32 addr, PB_TYPE& pb, u32 crc) +{ + if (HasLpf(crc)) + { + u16* dst = (u16*)&pb; + Memory::CopyFromEmuSwapped(dst, addr, sizeof(pb)); + } + else + { + // The below is a terrible hack in order to support two different AXPB layouts. + // We skip lpf in this layout. + + char* dst = (char*)&pb; + + constexpr size_t lpf_off = offsetof(AXPB, lpf); + constexpr size_t lc_off = offsetof(AXPB, loop_counter); + + Memory::CopyFromEmuSwapped((u16*)dst, addr, lpf_off); + memset(dst + lpf_off, 0, lc_off - lpf_off); + Memory::CopyFromEmuSwapped((u16*)(dst + lc_off), addr + lpf_off, sizeof(pb) - lc_off); + } } // Write a PB back to MRAM/ARAM -void WritePB(u32 addr, const PB_TYPE& pb) +void WritePB(u32 addr, const PB_TYPE& pb, u32 crc) { - const u16* src = (const u16*)&pb; - Memory::CopyToEmuSwapped(addr, src, sizeof(pb)); + if (HasLpf(crc)) + { + const u16* src = (const u16*)&pb; + Memory::CopyToEmuSwapped(addr, src, sizeof(pb)); + } + else + { + // The below is a terrible hack in order to support two different AXPB layouts. + // We skip lpf in this layout. + + const char* src = (const char*)&pb; + + constexpr size_t lpf_off = offsetof(AXPB, lpf); + constexpr size_t lc_off = offsetof(AXPB, loop_counter); + + Memory::CopyToEmuSwapped(addr, (const u16*)src, lpf_off); + Memory::CopyToEmuSwapped(addr + lpf_off, (const u16*)(src + lc_off), sizeof(pb) - lc_off); + } } #if 0 @@ -234,6 +279,13 @@ u16 AcceleratorGetSample() acc_pb->adpcm.yn1 = acc_pb->adpcm_loop_info.yn1; acc_pb->adpcm.yn2 = acc_pb->adpcm_loop_info.yn2; } +#ifdef AX_GC + else + { + // If we're streaming, increment the loop counter. + acc_pb->loop_counter++; + } +#endif } else { diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp index 22e2268168..4c77f35224 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp @@ -451,7 +451,7 @@ void AXWiiUCode::ProcessPBList(u32 pb_addr) m_samples_aux1, m_samples_wm2, m_samples_aux2, m_samples_wm3, m_samples_aux3}}; - ReadPB(pb_addr, pb); + ReadPB(pb_addr, pb, m_crc); u16 num_updates[3]; u16 updates[1024]; @@ -476,7 +476,7 @@ void AXWiiUCode::ProcessPBList(u32 pb_addr) m_coeffs_available ? m_coeffs : nullptr); } - WritePB(pb_addr, pb); + WritePB(pb_addr, pb, m_crc); pb_addr = HILO_TO_32(pb.next_pb); } }