diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp index dcdad5fb5e..43c0bad0ec 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp @@ -32,7 +32,16 @@ AXUCode::AXUCode(DSPHLE* dsphle, u32 crc) : UCodeInterface(dsphle, crc) INFO_LOG_FMT(DSPHLE, "Instantiating AXUCode: crc={:08x}", crc); } +AXUCode::~AXUCode() = default; + void AXUCode::Initialize() +{ + InitializeShared(); + + m_accelerator = std::make_unique(); +} + +void AXUCode::InitializeShared() { m_mail_handler.PushMail(DSP_INIT, true); @@ -421,7 +430,8 @@ void AXUCode::ProcessPBList(u32 pb_addr) { ApplyUpdatesForMs(curr_ms, pb, pb.updates.num_updates, updates); - ProcessVoice(pb, buffers, spms, ConvertMixerControl(pb.mixer_control), + ProcessVoice(static_cast(m_accelerator.get()), pb, buffers, spms, + ConvertMixerControl(pb.mixer_control), m_coeffs_checksum ? m_coeffs.data() : nullptr); // Forward the buffers @@ -778,6 +788,8 @@ void AXUCode::DoAXState(PointerWrap& p) } p.Do(m_compressor_pos); + + m_accelerator->DoState(p); } void AXUCode::DoState(PointerWrap& p) diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AX.h b/Source/Core/Core/HW/DSPHLE/UCodes/AX.h index 5b3e4be7af..1aabf2cc63 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AX.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AX.h @@ -12,6 +12,7 @@ #pragma once #include +#include #include #include "Common/BitUtils.h" @@ -21,6 +22,11 @@ #include "Core/HW/Memmap.h" #include "Core/System.h" +namespace DSP +{ +class Accelerator; +} + namespace DSP::HLE { class DSPHLE; @@ -67,6 +73,7 @@ class AXUCode /* not final: subclassed by AXWiiUCode */ : public UCodeInterface { public: AXUCode(DSPHLE* dsphle, u32 crc); + ~AXUCode() override; void Initialize() override; void HandleMail(u32 mail) override; @@ -100,6 +107,10 @@ protected: u16 m_compressor_pos = 0; + std::unique_ptr m_accelerator; + + void InitializeShared(); + bool LoadResamplingCoefficients(bool require_same_checksum, u32 desired_checksum); // Copy a command list from memory to our temp buffer diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h b/Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h index 177e1d00e8..77dbae95d5 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h @@ -353,24 +353,24 @@ u32 ResampleAudio(std::function input_callback, s16* output, u32 count // Read input samples from ARAM, decoding and converting rate // if required. -void GetInputSamples(PB_TYPE& pb, s16* samples, u16 count, const s16* coeffs) +void GetInputSamples(HLEAccelerator* accelerator, PB_TYPE& pb, s16* samples, u16 count, + const s16* coeffs) { - HLEAccelerator accelerator; - AcceleratorSetup(&accelerator, &pb); + AcceleratorSetup(accelerator, &pb); if (coeffs) coeffs += pb.coef_select * 0x200; - u32 curr_pos = ResampleAudio([&accelerator](u32) { return AcceleratorGetSample(&accelerator); }, + u32 curr_pos = ResampleAudio([accelerator](u32) { return AcceleratorGetSample(accelerator); }, samples, count, pb.src.last_samples, pb.src.cur_addr_frac, HILO_TO_32(pb.src.ratio), pb.src_type, coeffs); pb.src.cur_addr_frac = (curr_pos & 0xFFFF); // Update current position, YN1, YN2 and pred scale in the PB. - pb.audio_addr.cur_addr_hi = static_cast(accelerator.GetCurrentAddress() >> 16); - pb.audio_addr.cur_addr_lo = static_cast(accelerator.GetCurrentAddress()); - pb.adpcm.yn1 = accelerator.GetYn1(); - pb.adpcm.yn2 = accelerator.GetYn2(); - pb.adpcm.pred_scale = accelerator.GetPredScale(); + pb.audio_addr.cur_addr_hi = static_cast(accelerator->GetCurrentAddress() >> 16); + pb.audio_addr.cur_addr_lo = static_cast(accelerator->GetCurrentAddress()); + pb.adpcm.yn1 = accelerator->GetYn1(); + pb.adpcm.yn2 = accelerator->GetYn2(); + pb.adpcm.pred_scale = accelerator->GetPredScale(); } // Add samples to an output buffer, with optional volume ramping. @@ -410,8 +410,8 @@ s16 LowPassFilter(s16* samples, u32 count, s16 yn1, u16 a0, u16 b0) // Process 1ms of audio (for AX GC) or 3ms of audio (for AX Wii) from a PB and // mix it to the output buffers. -void ProcessVoice(PB_TYPE& pb, const AXBuffers& buffers, u16 count, AXMixControl mctrl, - const s16* coeffs) +void ProcessVoice(HLEAccelerator* accelerator, PB_TYPE& pb, const AXBuffers& buffers, u16 count, + AXMixControl mctrl, const s16* coeffs) { // If the voice is not running, nothing to do. if (pb.running != 1) @@ -419,7 +419,7 @@ void ProcessVoice(PB_TYPE& pb, const AXBuffers& buffers, u16 count, AXMixControl // Read input samples, performing sample rate conversion if needed. s16 samples[MAX_SAMPLES_PER_FRAME]; - GetInputSamples(pb, samples, count, coeffs); + GetInputSamples(accelerator, pb, samples, count, coeffs); // Apply a global volume ramp using the volume envelope parameters. for (u32 i = 0; i < count; ++i) diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp index 1c4709af16..cde059a716 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp @@ -30,6 +30,13 @@ AXWiiUCode::AXWiiUCode(DSPHLE* dsphle, u32 crc) : AXUCode(dsphle, crc), m_last_m m_old_axwii = (crc == 0xfa450138) || (crc == 0x7699af32); } +void AXWiiUCode::Initialize() +{ + InitializeShared(); + + m_accelerator = std::make_unique(); +} + void AXWiiUCode::HandleCommandList() { // Temp variables for addresses computation @@ -436,7 +443,8 @@ void AXWiiUCode::ProcessPBList(u32 pb_addr) for (int curr_ms = 0; curr_ms < 3; ++curr_ms) { ApplyUpdatesForMs(curr_ms, pb, num_updates, updates); - ProcessVoice(pb, buffers, spms, ConvertMixerControl(HILO_TO_32(pb.mixer_control)), + ProcessVoice(static_cast(m_accelerator.get()), pb, buffers, spms, + ConvertMixerControl(HILO_TO_32(pb.mixer_control)), m_coeffs_checksum ? m_coeffs.data() : nullptr); // Forward the buffers @@ -447,7 +455,8 @@ void AXWiiUCode::ProcessPBList(u32 pb_addr) } else { - ProcessVoice(pb, buffers, 96, ConvertMixerControl(HILO_TO_32(pb.mixer_control)), + ProcessVoice(static_cast(m_accelerator.get()), pb, buffers, 96, + ConvertMixerControl(HILO_TO_32(pb.mixer_control)), m_coeffs_checksum ? m_coeffs.data() : nullptr); } diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.h b/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.h index e024ee87ad..aa69ae9637 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.h @@ -16,6 +16,7 @@ class AXWiiUCode final : public AXUCode public: AXWiiUCode(DSPHLE* dsphle, u32 crc); + void Initialize() override; void DoState(PointerWrap& p) override; protected: diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index ba65b2b0c9..95a431366f 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -95,7 +95,7 @@ static size_t s_state_writes_in_queue; static std::condition_variable s_state_write_queue_is_empty; // Don't forget to increase this after doing changes on the savestate system -constexpr u32 STATE_VERSION = 165; // Last changed in PR 12328 +constexpr u32 STATE_VERSION = 166; // Last changed in PR 12487 // Increase this if the StateExtendedHeader definition changes constexpr u32 EXTENDED_HEADER_VERSION = 1; // Last changed in PR 12217