DSPHLE/AX: Reload resampling coefficients on savestate load if necessary.

This commit is contained in:
Admiral H. Curtiss 2021-08-27 03:07:27 +02:00
parent a4d4dc82d4
commit f592565532
4 changed files with 53 additions and 28 deletions

View File

@ -5,14 +5,17 @@
#include <algorithm>
#include <array>
#include <cstring>
#include <iterator>
#include "Common/ChunkFile.h"
#include "Common/CommonTypes.h"
#include "Common/FileUtil.h"
#include "Common/Hash.h"
#include "Common/IOFile.h"
#include "Common/Logging/Log.h"
#include "Common/Swap.h"
#include "Core/Core.h"
#include "Core/DolphinAnalytics.h"
#include "Core/HW/DSP.h"
#include "Core/HW/DSPHLE/DSPHLE.h"
@ -38,41 +41,44 @@ void AXUCode::Initialize()
{
m_mail_handler.PushMail(DSP_INIT, true);
LoadResamplingCoefficients();
LoadResamplingCoefficients(false, 0);
}
void AXUCode::LoadResamplingCoefficients()
bool AXUCode::LoadResamplingCoefficients(bool require_same_checksum, u32 desired_checksum)
{
m_coeffs_available = false;
constexpr size_t raw_coeffs_size = 0x800 * 2;
m_coeffs_checksum = std::nullopt;
const std::array<std::string, 2> filenames{
File::GetUserPath(D_GCUSER_IDX) + "dsp_coef.bin",
File::GetSysDirectory() + "/GC/dsp_coef.bin",
};
size_t fidx;
std::string filename;
for (fidx = 0; fidx < filenames.size(); ++fidx)
for (const std::string& filename : filenames)
{
filename = filenames[fidx];
if (File::GetSize(filename) != 0x1000)
INFO_LOG_FMT(DSPHLE, "Checking for polyphase resampling coeffs at {}", filename);
if (File::GetSize(filename) != raw_coeffs_size)
continue;
break;
File::IOFile fp(filename, "rb");
std::array<u8, raw_coeffs_size> raw_coeffs;
fp.ReadBytes(raw_coeffs.data(), raw_coeffs_size);
u32 checksum = Common::HashAdler32(raw_coeffs.data(), raw_coeffs_size);
if (require_same_checksum && checksum != desired_checksum)
continue;
std::memcpy(m_coeffs.data(), raw_coeffs.data(), raw_coeffs_size);
for (auto& coef : m_coeffs)
coef = Common::swap16(coef);
INFO_LOG_FMT(DSPHLE, "Using polyphase resampling coeffs from {}", filename);
m_coeffs_checksum = checksum;
return true;
}
if (fidx >= filenames.size())
return;
INFO_LOG_FMT(DSPHLE, "Loading polyphase resampling coeffs from {}", filename);
File::IOFile fp(filename, "rb");
fp.ReadBytes(m_coeffs, 0x1000);
for (auto& coef : m_coeffs)
coef = Common::swap16(coef);
m_coeffs_available = true;
return false;
}
void AXUCode::SignalWorkEnd()
@ -432,7 +438,7 @@ void AXUCode::ProcessPBList(u32 pb_addr)
ApplyUpdatesForMs(curr_ms, pb, pb.updates.num_updates, updates);
ProcessVoice(pb, buffers, spms, ConvertMixerControl(pb.mixer_control),
m_coeffs_available ? m_coeffs : nullptr);
m_coeffs_checksum ? m_coeffs.data() : nullptr);
// Forward the buffers
for (auto& ptr : buffers.ptrs)
@ -749,6 +755,22 @@ void AXUCode::DoAXState(PointerWrap& p)
p.Do(m_samples_auxB_right);
p.Do(m_samples_auxB_surround);
auto old_checksum = m_coeffs_checksum;
p.Do(m_coeffs_checksum);
if (p.GetMode() == PointerWrap::MODE_READ && m_coeffs_checksum &&
old_checksum != m_coeffs_checksum)
{
if (!LoadResamplingCoefficients(true, *m_coeffs_checksum))
{
Core::DisplayMessage("Could not find the DSP polyphase resampling coefficients used by the "
"savestate. Aborting load state.",
3000);
p.SetMode(PointerWrap::MODE_VERIFY);
return;
}
}
p.Do(m_compressor_pos);
}

View File

@ -11,6 +11,9 @@
#pragma once
#include <array>
#include <optional>
#include "Common/BitUtils.h"
#include "Common/CommonTypes.h"
#include "Common/Swap.h"
@ -95,12 +98,12 @@ protected:
// Table of coefficients for polyphase sample rate conversion.
// The coefficients aren't always available (they are part of the DSP DROM)
// so we also need to know if they are valid or not.
bool m_coeffs_available = false;
s16 m_coeffs[0x800];
std::optional<u32> m_coeffs_checksum = std::nullopt;
std::array<s16, 0x800> m_coeffs;
u16 m_compressor_pos = 0;
void LoadResamplingCoefficients();
bool LoadResamplingCoefficients(bool require_same_checksum, u32 desired_checksum);
// Copy a command list from memory to our temp buffer
void CopyCmdList(u32 addr, u16 size);

View File

@ -472,7 +472,7 @@ void AXWiiUCode::ProcessPBList(u32 pb_addr)
{
ApplyUpdatesForMs(curr_ms, pb, num_updates, updates);
ProcessVoice(pb, buffers, spms, ConvertMixerControl(HILO_TO_32(pb.mixer_control)),
m_coeffs_available ? m_coeffs : nullptr);
m_coeffs_checksum ? m_coeffs.data() : nullptr);
// Forward the buffers
for (auto& ptr : buffers.ptrs)
@ -483,7 +483,7 @@ void AXWiiUCode::ProcessPBList(u32 pb_addr)
else
{
ProcessVoice(pb, buffers, 96, ConvertMixerControl(HILO_TO_32(pb.mixer_control)),
m_coeffs_available ? m_coeffs : nullptr);
m_coeffs_checksum ? m_coeffs.data() : nullptr);
}
WritePB(pb_addr, pb, m_crc);

View File

@ -73,7 +73,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
static std::thread g_save_thread;
// Don't forget to increase this after doing changes on the savestate system
constexpr u32 STATE_VERSION = 135; // Last changed in PR 9976
constexpr u32 STATE_VERSION = 136; // Last changed in PR 10058
// Maps savestate versions to Dolphin versions.
// Versions after 42 don't need to be added to this list,