diff --git a/pcsx2/SPU2/ADSR.cpp b/pcsx2/SPU2/ADSR.cpp index cd8ba785b7..07a68626fa 100644 --- a/pcsx2/SPU2/ADSR.cpp +++ b/pcsx2/SPU2/ADSR.cpp @@ -14,17 +14,22 @@ */ #include "PrecompiledHeader.h" -#include "Global.h" + +#include "SPU2/Global.h" + #include "common/Assertions.h" +#include + static constexpr s32 ADSR_MAX_VOL = 0x7fffffff; static const int InvExpOffsets[] = {0, 4, 6, 8, 9, 10, 11, 12}; -static u32 PsxRates[160]; +using PSXRateTable = std::array; -void InitADSR() // INIT ADSR +static constexpr PSXRateTable ComputePSXRates() { + PSXRateTable rates = {}; for (int i = 0; i < (32 + 128); i++) { const int shift = (i - 32) >> 2; @@ -35,10 +40,13 @@ void InitADSR() // INIT ADSR rate <<= shift; // Maximum rate is 0x4000. - PsxRates[i] = (int)std::min(rate, (s64)0x40000000LL); + rates[i] = (int)std::min(rate, (s64)0x40000000LL); } + return rates; } +static constexpr const PSXRateTable PsxRates = ComputePSXRates(); + bool V_ADSR::Calculate() { pxAssume(Phase != 0); diff --git a/pcsx2/SPU2/Mixer.cpp b/pcsx2/SPU2/Mixer.cpp index 191c176531..e6dff6b010 100644 --- a/pcsx2/SPU2/Mixer.cpp +++ b/pcsx2/SPU2/Mixer.cpp @@ -113,7 +113,7 @@ static void __forceinline IncrementNextA(V_Core& thiscore, uint voiceidx) // decoded pcm data, used to cache the decoded data so that it needn't be decoded // multiple times. Cache chunks are decoded when the mixer requests the blocks, and // invalided when DMA transfers and memory writes are performed. -PcmCacheEntry* pcm_cache_data = nullptr; +PcmCacheEntry pcm_cache_data[pcm_BlockCount]; int g_counter_cache_hits = 0; int g_counter_cache_misses = 0; diff --git a/pcsx2/SPU2/RegTable.cpp b/pcsx2/SPU2/RegTable.cpp index 3a4db4e26b..3962d0d706 100644 --- a/pcsx2/SPU2/RegTable.cpp +++ b/pcsx2/SPU2/RegTable.cpp @@ -16,6 +16,11 @@ #include "PrecompiledHeader.h" #include "Global.h" +#define U16P(x) ((u16*)&(x)) + +// Returns the hiword of a 32 bit integer. +#define U16P_HI(x) (((u16*)&(x)) + 1) + #define PCORE(c, p) \ U16P(Cores[c].p) @@ -48,10 +53,10 @@ PCORE(c, Revb.n) + 1, \ PCORE(c, Revb.n) -u16* regtable[0x401]; - -u16 const* const regtable_original[0x401] = - { +static std::array ComputeRegTable() +{ + static const std::array orig_table = + {{ // Voice Params: 8 params, 24 voices = 0x180 bytes PVC(0, 0), PVC(0, 1), PVC(0, 2), PVC(0, 3), PVC(0, 4), PVC(0, 5), PVC(0, 6), PVC(0, 7), PVC(0, 8), PVC(0, 9), PVC(0, 10), PVC(0, 11), @@ -299,4 +304,19 @@ u16 const* const regtable_original[0x401] = PRAW(0x7F0), PRAW(0x7F2), PRAW(0x7F4), PRAW(0x7F6), PRAW(0x7F8), PRAW(0x7FA), PRAW(0x7FC), PRAW(0x7FE), - nullptr}; + nullptr}}; + + std::array table = orig_table; + for (uint mem = 0; mem < 0x800; mem++) + { + u16* ptr = table[mem >> 1]; + if (!ptr) + { + table[mem >> 1] = &(spu2Ru16(mem)); + } + } + + return table; +} + +const std::array regtable = ComputeRegTable(); diff --git a/pcsx2/SPU2/defs.h b/pcsx2/SPU2/defs.h index 3b02041698..69c659914a 100644 --- a/pcsx2/SPU2/defs.h +++ b/pcsx2/SPU2/defs.h @@ -15,9 +15,14 @@ #pragma once -#include "Mixer.h" -#include "SndOut.h" -#include "Global.h" +#include "SPU2/Mixer.h" +#include "SPU2/SndOut.h" +#include "SPU2/Global.h" + +// -------------------------------------------------------------------------------------- +// SPU2 Register Table LUT +// -------------------------------------------------------------------------------------- +extern const std::array regtable; // -------------------------------------------------------------------------------------- // SPU2 Memory Indexers @@ -560,15 +565,14 @@ extern u16 InputPos; // SPU Mixing Cycles ("Ticks mixed" counter) extern u32 Cycles; -extern s16* spu2regs; -extern s16* _spu2mem; +extern s16 spu2regs[0x010000 / sizeof(s16)]; +extern s16 _spu2mem[0x200000 / sizeof(s16)]; extern int PlayMode; extern void SetIrqCall(int core); extern void SetIrqCallDMA(int core); extern void StartVoices(int core, u32 value); extern void StopVoices(int core, u32 value); -extern void InitADSR(); extern void CalculateADSR(V_Voice& vc); extern void UpdateSpdifMode(); @@ -584,6 +588,11 @@ namespace SPU2Savestate // -------------------------------------------------------------------------------------- // ADPCM Decoder Cache // -------------------------------------------------------------------------------------- +// the cache data size is determined by taking the number of adpcm blocks +// (2MB / 16) and multiplying it by the decoded block size (28 samples). +// Thus: pcm_cache_data = 7,340,032 bytes (ouch!) +// Expanded: 16 bytes expands to 56 bytes [3.5:1 ratio] +// Resulting in 2MB * 3.5. // The SPU2 has a dynamic memory range which is used for several internal operations, such as // registers, CORE 1/2 mixing, AutoDMAs, and some other fancy stuff. We exclude this range @@ -607,4 +616,4 @@ struct PcmCacheEntry s32 Prev2; }; -extern PcmCacheEntry* pcm_cache_data; +extern PcmCacheEntry pcm_cache_data[pcm_BlockCount]; diff --git a/pcsx2/SPU2/regs.h b/pcsx2/SPU2/regs.h index d49d5b28e4..6cb322a913 100644 --- a/pcsx2/SPU2/regs.h +++ b/pcsx2/SPU2/regs.h @@ -178,16 +178,3 @@ Core attributes (SD_C) #define VOICE_ADDR_LSAX 0x4 // Loop point address #define VOICE_ADDR_NAX 0x8 // Waveform data that should be read next - - -// -------------------------------------------------------------------------------------- -// SPU2 Register Table LUT -// -------------------------------------------------------------------------------------- - -#define U16P(x) ((u16*)&(x)) - -// Returns the hiword of a 32 bit integer. -#define U16P_HI(x) (((u16*)&(x)) + 1) - -extern u16* regtable[0x401]; -extern u16 const* const regtable_original[0x401]; diff --git a/pcsx2/SPU2/spu2.cpp b/pcsx2/SPU2/spu2.cpp index 47c2477203..88700e4951 100644 --- a/pcsx2/SPU2/spu2.cpp +++ b/pcsx2/SPU2/spu2.cpp @@ -177,44 +177,6 @@ void SPU2::SetDeviceSampleRateMultiplier(double multiplier) UpdateSampleRate(); } -void SPU2::Initialize() -{ - pxAssert(regtable[0x400] == nullptr); - spu2regs = (s16*)malloc(0x010000); - _spu2mem = (s16*)malloc(0x200000); - - // adpcm decoder cache: - // the cache data size is determined by taking the number of adpcm blocks - // (2MB / 16) and multiplying it by the decoded block size (28 samples). - // Thus: pcm_cache_data = 7,340,032 bytes (ouch!) - // Expanded: 16 bytes expands to 56 bytes [3.5:1 ratio] - // Resulting in 2MB * 3.5. - - pcm_cache_data = (PcmCacheEntry*)calloc(pcm_BlockCount, sizeof(PcmCacheEntry)); - - if (!spu2regs || !_spu2mem || !pcm_cache_data) - { - // If these memory allocations fail, we have much bigger problems. - pxFailRel("Failed to allocate SPU2 memory"); - } - - // Patch up a copy of regtable that directly maps "nullptrs" to SPU2 memory. - - memcpy(regtable, regtable_original, sizeof(regtable)); - - for (uint mem = 0; mem < 0x800; mem++) - { - u16* ptr = regtable[mem >> 1]; - if (!ptr) - { - regtable[mem >> 1] = &(spu2Ru16(mem)); - } - } - - InitADSR(); -} - - bool SPU2::Open() { #ifdef PCSX2_DEVBUILD @@ -257,13 +219,6 @@ void SPU2::Close() #endif } -void SPU2::Shutdown() -{ - safe_free(spu2regs); - safe_free(_spu2mem); - safe_free(pcm_cache_data); -} - bool SPU2::IsRunningPSXMode() { return s_psxmode; diff --git a/pcsx2/SPU2/spu2.h b/pcsx2/SPU2/spu2.h index d7d9fe4af0..f0e5390100 100644 --- a/pcsx2/SPU2/spu2.h +++ b/pcsx2/SPU2/spu2.h @@ -23,10 +23,6 @@ struct Pcsx2Config; namespace SPU2 { -/// Initialization/cleanup, call at process startup/shutdown. -void Initialize(); -void Shutdown(); - /// Open/close, call at VM startup/shutdown. bool Open(); void Close(); diff --git a/pcsx2/SPU2/spu2freeze.cpp b/pcsx2/SPU2/spu2freeze.cpp index b22a66d343..e38f2484d9 100644 --- a/pcsx2/SPU2/spu2freeze.cpp +++ b/pcsx2/SPU2/spu2freeze.cpp @@ -54,12 +54,8 @@ s32 SPU2Savestate::FreezeIt(DataBlock& spud) spud.spu2id = SAVE_ID; spud.version = SAVE_VERSION; - pxAssertMsg(spu2regs && _spu2mem, "Looks like PCSX2 is trying to savestate while components are shut down. That's a no-no! It shouldn't crash, but the savestate will probably be corrupted."); - - if (spu2regs != nullptr) - memcpy(spud.unkregs, spu2regs, sizeof(spud.unkregs)); - if (_spu2mem != nullptr) - memcpy(spud.mem, _spu2mem, sizeof(spud.mem)); + memcpy(spud.unkregs, spu2regs, sizeof(spud.unkregs)); + memcpy(spud.mem, _spu2mem, sizeof(spud.mem)); memcpy(spud.Cores, Cores, sizeof(Cores)); memcpy(&spud.Spdif, &Spdif, sizeof(Spdif)); @@ -127,13 +123,8 @@ s32 SPU2Savestate::ThawIt(DataBlock& spud) { SndBuffer::ClearContents(); - pxAssertMsg(spu2regs && _spu2mem, "Looks like PCSX2 is trying to loadstate while components are shut down. That's a no-no! It shouldn't crash, but the savestate will probably be corrupted."); - - // base stuff - if (spu2regs) - memcpy(spu2regs, spud.unkregs, sizeof(spud.unkregs)); - if (_spu2mem) - memcpy(_spu2mem, spud.mem, sizeof(spud.mem)); + memcpy(spu2regs, spud.unkregs, sizeof(spud.unkregs)); + memcpy(_spu2mem, spud.mem, sizeof(spud.mem)); memcpy(Cores, spud.Cores, sizeof(Cores)); memcpy(&Spdif, &spud.Spdif, sizeof(Spdif)); diff --git a/pcsx2/SPU2/spu2sys.cpp b/pcsx2/SPU2/spu2sys.cpp index 651aab3d4d..78890ecfa7 100644 --- a/pcsx2/SPU2/spu2sys.cpp +++ b/pcsx2/SPU2/spu2sys.cpp @@ -21,17 +21,17 @@ #include "PrecompiledHeader.h" -#include "Global.h" -#include "Dma.h" -#include "IopDma.h" + #include "IopCounters.h" -#include "R3000A.h" +#include "IopDma.h" #include "IopHw.h" +#include "R3000A.h" +#include "SPU2/Dma.h" +#include "SPU2/Global.h" +#include "SPU2/spu2.h" -#include "spu2.h" // needed until I figure out a nice solution for irqcallback dependencies. - -s16* spu2regs = nullptr; -s16* _spu2mem = nullptr; +s16 spu2regs[0x010000 / sizeof(s16)]; +s16 _spu2mem[0x200000 / sizeof(s16)]; V_CoreDebug DebugCores[2]; V_Core Cores[2]; diff --git a/pcsx2/VMManager.cpp b/pcsx2/VMManager.cpp index 262539ac7a..6f3f916456 100644 --- a/pcsx2/VMManager.cpp +++ b/pcsx2/VMManager.cpp @@ -263,7 +263,6 @@ bool VMManager::Internal::InitializeGlobals() SysLogMachineCaps(); GSinit(); - SPU2::Initialize(); USBinit(); return true; @@ -272,7 +271,6 @@ bool VMManager::Internal::InitializeGlobals() void VMManager::Internal::ReleaseGlobals() { USBshutdown(); - SPU2::Shutdown(); GSshutdown(); #ifdef _WIN32