From 76976fef3038918ad01a9dbda4c0e5d9bebef9af Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 4 Nov 2023 14:20:58 +0100 Subject: convert SPU to OOP --- src/ARMJIT_Memory.cpp | 4 +- src/NDS.cpp | 55 +++++----- src/NDS.h | 4 +- src/SPI.cpp | 14 +-- src/SPU.cpp | 206 +++++++++++++++++-------------------- src/SPU.h | 118 +++++++++++++-------- src/frontend/qt_sdl/AudioInOut.cpp | 7 +- src/frontend/qt_sdl/main.cpp | 8 +- 8 files changed, 215 insertions(+), 201 deletions(-) diff --git a/src/ARMJIT_Memory.cpp b/src/ARMJIT_Memory.cpp index a37d7f8..7a1781e 100644 --- a/src/ARMJIT_Memory.cpp +++ b/src/ARMJIT_Memory.cpp @@ -1320,7 +1320,7 @@ void* GetFuncForAddr(ARM* cpu, u32 addr, bool store, int size) switch (addr & 0xFF800000) { case 0x04000000: - if (addr >= 0x04000400 && addr < 0x04000520) + /*if (addr >= 0x04000400 && addr < 0x04000520) { switch (size | store) { @@ -1331,7 +1331,7 @@ void* GetFuncForAddr(ARM* cpu, u32 addr, bool store, int size) case 32: return (void*)SPU::Read32; case 33: return (void*)SPU::Write32; } - } + }*/ if (NDS::ConsoleType == 0) { diff --git a/src/NDS.cpp b/src/NDS.cpp index 5a5ba34..3fd8f4c 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -178,7 +178,8 @@ u32 KeyInput; u16 KeyCnt[2]; u16 RCnt; -SPIHost* SPI; +class SPU* SPU; +class SPIHost* SPI; class RTC* RTC; bool Running; @@ -218,13 +219,13 @@ bool Init() DMAs[6] = new DMA(1, 2); DMAs[7] = new DMA(1, 3); - SPI = new SPIHost(); + SPU = new class SPU; + SPI = new class SPIHost(); RTC = new class RTC(); if (!NDSCart::Init()) return false; if (!GBACart::Init()) return false; if (!GPU::Init()) return false; - if (!SPU::Init()) return false; if (!Wifi::Init()) return false; if (!DSi::Init()) return false; @@ -240,11 +241,8 @@ void DeInit() ARMJIT::DeInit(); #endif - delete ARM9; - ARM9 = nullptr; - - delete ARM7; - ARM7 = nullptr; + delete ARM9; ARM9 = nullptr; + delete ARM7; ARM7 = nullptr; for (int i = 0; i < 8; i++) { @@ -252,16 +250,13 @@ void DeInit() DMAs[i] = nullptr; } - delete SPI; - SPI = nullptr; - - delete RTC; - RTC = nullptr; + delete SPU; SPU = nullptr; + delete SPI; SPI = nullptr; + delete RTC; RTC = nullptr; NDSCart::DeInit(); GBACart::DeInit(); GPU::DeInit(); - SPU::DeInit(); Wifi::DeInit(); DSi::DeInit(); @@ -529,7 +524,7 @@ void SetupDirectBoot(const std::string& romname) NDSCart::SPICnt = 0x8000; - SPU::SetBias(0x200); + SPU->SetBias(0x200); SetWifiWaitCnt(0x0030); } @@ -648,7 +643,7 @@ void Reset() NDSCart::Reset(); GBACart::Reset(); GPU::Reset(); - SPU::Reset(); + SPU->Reset(); SPI->Reset(); RTC->Reset(); Wifi::Reset(); @@ -656,7 +651,7 @@ void Reset() // TODO: move the SOUNDBIAS/degrade logic to SPU? // The SOUNDBIAS register does nothing on DSi - SPU::SetApplyBias(ConsoleType == 0); + SPU->SetApplyBias(ConsoleType == 0); bool degradeAudio = true; @@ -673,7 +668,7 @@ void Reset() else if (bitDepth == 2) // Always 16-bit degradeAudio = false; - SPU::SetDegrade10Bit(degradeAudio); + SPU->SetDegrade10Bit(degradeAudio); AREngine::Reset(); } @@ -722,7 +717,7 @@ void Stop(Platform::StopReason reason) Running = false; Platform::SignalStop(reason); GPU::Stop(); - SPU::Stop(); + SPU->Stop(); if (ConsoleType == 1) DSi::Stop(); @@ -850,7 +845,7 @@ bool DoSavestate(Savestate* file) if (ConsoleType == 0) GBACart::DoSavestate(file); GPU::DoSavestate(file); - SPU::DoSavestate(file); + SPU->DoSavestate(file); SPI->DoSavestate(file); RTC->DoSavestate(file); Wifi::DoSavestate(file); @@ -862,7 +857,7 @@ bool DoSavestate(Savestate* file) { GPU::SetPowerCnt(PowerControl9); - SPU::SetPowerCnt(PowerControl7 & 0x0001); + SPU->SetPowerCnt(PowerControl7 & 0x0001); Wifi::SetPowerCnt(PowerControl7 & 0x0002); } @@ -1193,7 +1188,7 @@ u32 RunFrame() ARM7Timestamp-SysTimestamp, GPU3D::Timestamp-SysTimestamp); #endif - SPU::TransferOutput(); + SPU->TransferOutput(); break; } @@ -3922,7 +3917,7 @@ u8 ARM7IORead8(u32 addr) if (addr >= 0x04000400 && addr < 0x04000520) { - return SPU::Read8(addr); + return SPU->Read8(addr); } if ((addr & 0xFFFFF000) != 0x04004000) @@ -4016,7 +4011,7 @@ u16 ARM7IORead16(u32 addr) if (addr >= 0x04000400 && addr < 0x04000520) { - return SPU::Read16(addr); + return SPU->Read16(addr); } if ((addr & 0xFFFFF000) != 0x04004000) @@ -4117,7 +4112,7 @@ u32 ARM7IORead32(u32 addr) if (addr >= 0x04000400 && addr < 0x04000520) { - return SPU::Read32(addr); + return SPU->Read32(addr); } if ((addr & 0xFFFFF000) != 0x04004000) @@ -4195,7 +4190,7 @@ void ARM7IOWrite8(u32 addr, u8 val) if (addr >= 0x04000400 && addr < 0x04000520) { - SPU::Write8(addr, val); + SPU->Write8(addr, val); return; } @@ -4336,7 +4331,7 @@ void ARM7IOWrite16(u32 addr, u16 val) { u16 change = PowerControl7 ^ val; PowerControl7 = val & 0x0003; - SPU::SetPowerCnt(val & 0x0001); + SPU->SetPowerCnt(val & 0x0001); Wifi::SetPowerCnt(val & 0x0002); if (change & 0x0002) UpdateWifiTimings(); } @@ -4350,7 +4345,7 @@ void ARM7IOWrite16(u32 addr, u16 val) if (addr >= 0x04000400 && addr < 0x04000520) { - SPU::Write16(addr, val); + SPU->Write16(addr, val); return; } @@ -4466,7 +4461,7 @@ void ARM7IOWrite32(u32 addr, u32 val) { u16 change = PowerControl7 ^ val; PowerControl7 = val & 0x0003; - SPU::SetPowerCnt(val & 0x0001); + SPU->SetPowerCnt(val & 0x0001); Wifi::SetPowerCnt(val & 0x0002); if (change & 0x0002) UpdateWifiTimings(); } @@ -4484,7 +4479,7 @@ void ARM7IOWrite32(u32 addr, u32 val) if (addr >= 0x04000400 && addr < 0x04000520) { - SPU::Write32(addr, val); + SPU->Write32(addr, val); return; } diff --git a/src/NDS.h b/src/NDS.h index b5d7227..cffcd5d 100644 --- a/src/NDS.h +++ b/src/NDS.h @@ -30,6 +30,7 @@ // with this enabled, to make sure it doesn't desync //#define DEBUG_CHECK_DESYNC +class SPU; class SPIHost; class RTC; @@ -249,7 +250,8 @@ extern MemRegion SWRAM_ARM7; extern u32 KeyInput; extern u16 RCnt; -extern SPIHost* SPI; +extern class SPU* SPU; +extern class SPIHost* SPI; extern class RTC* RTC; const u32 ARM7WRAMSize = 0x10000; diff --git a/src/SPI.cpp b/src/SPI.cpp index 4b72f5c..a95cd1c 100644 --- a/src/SPI.cpp +++ b/src/SPI.cpp @@ -533,7 +533,11 @@ SPIHost::SPIHost() Devices[SPIDevice_FirmwareMem] = new FirmwareMem(this); Devices[SPIDevice_PowerMan] = new PowerMan(this); - Devices[SPIDevice_TSC] = nullptr; + + if (NDS::ConsoleType == 1) + Devices[SPIDevice_TSC] = new DSi_TSC(this); + else + Devices[SPIDevice_TSC] = new TSC(this); } SPIHost::~SPIHost() @@ -553,14 +557,6 @@ void SPIHost::Reset() { Cnt = 0; - if (Devices[SPIDevice_TSC]) - delete Devices[SPIDevice_TSC]; - - if (NDS::ConsoleType == 1) - Devices[SPIDevice_TSC] = new DSi_TSC(this); - else - Devices[SPIDevice_TSC] = new TSC(this); - for (int i = 0; i < SPIDevice_MAX; i++) { Devices[i]->Reset(); diff --git a/src/SPU.cpp b/src/SPU.cpp index bfe6622..89b7fb3 100644 --- a/src/SPU.cpp +++ b/src/SPU.cpp @@ -32,12 +32,10 @@ using Platform::LogLevel; // * capture addition modes, overflow bugs // * channel hold -namespace SPU -{ -const s8 ADPCMIndexTable[8] = {-1, -1, -1, -1, 2, 4, 6, 8}; +const s8 SPUChannel::ADPCMIndexTable[8] = {-1, -1, -1, -1, 2, 4, 6, 8}; -const u16 ADPCMTable[89] = +const u16 SPUChannel::ADPCMTable[89] = { 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x0010, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001C, 0x001F, @@ -53,7 +51,7 @@ const u16 ADPCMTable[89] = 0x7FFF }; -const s16 PSGTable[8][8] = +const s16 SPUChannel::PSGTable[8][8] = { {-0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF}, {-0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF}, @@ -65,76 +63,63 @@ const s16 PSGTable[8][8] = {-0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF} }; -// audio interpolation is an improvement upon the original hardware -// (which performs no interpolation) -int InterpType; -s16 InterpCos[0x100]; -s16 InterpCubic[0x100][4]; - -const u32 OutputBufferSize = 2*2048; -s16 OutputBackbuffer[2 * OutputBufferSize]; -u32 OutputBackbufferWritePosition; - -s16 OutputFrontBuffer[2 * OutputBufferSize]; -u32 OutputFrontBufferWritePosition; -u32 OutputFrontBufferReadPosition; - -Platform::Mutex* AudioLock; +s16 SPUChannel::InterpCos[0x100]; +s16 SPUChannel::InterpCubic[0x100][4]; +bool SPUChannel::InterpInited = false; -u16 Cnt; -u8 MasterVolume; -u16 Bias; -bool ApplyBias; -bool Degrade10Bit; -Channel* Channels[16]; -CaptureUnit* Capture[2]; - - -bool Init() +SPU::SPU() { - NDS::RegisterEventFunc(NDS::Event_SPU, 0, Mix); + NDS::RegisterEventFunc(NDS::Event_SPU, 0, MemberEventFunc(SPU, Mix)); for (int i = 0; i < 16; i++) - Channels[i] = new Channel(i); + Channels[i] = new SPUChannel(i); - Capture[0] = new CaptureUnit(0); - Capture[1] = new CaptureUnit(1); + Capture[0] = new SPUCaptureUnit(0); + Capture[1] = new SPUCaptureUnit(1); AudioLock = Platform::Mutex_Create(); - InterpType = 0; ApplyBias = true; Degrade10Bit = false; - // generate interpolation tables - // values are 1:1:14 fixed-point + memset(OutputFrontBuffer, 0, 2*OutputBufferSize*2); - float m_pi = std::acos(-1.0f); - for (int i = 0; i < 0x100; i++) + OutputBackbufferWritePosition = 0; + OutputFrontBufferReadPosition = 0; + OutputFrontBufferWritePosition = 0; + + if (!SPUChannel::InterpInited) { - float ratio = (i * m_pi) / 255.0f; - ratio = 1.0f - std::cos(ratio); + // generate interpolation tables + // values are 1:1:14 fixed-point - InterpCos[i] = (s16)(ratio * 0x2000); - } + float m_pi = std::acos(-1.0f); + for (int i = 0; i < 0x100; i++) + { + float ratio = (i * m_pi) / 255.0f; + ratio = 1.0f - std::cos(ratio); - for (int i = 0; i < 0x100; i++) - { - s32 i1 = i << 6; - s32 i2 = (i * i) >> 2; - s32 i3 = (i * i * i) >> 10; - - InterpCubic[i][0] = -i3 + 2*i2 - i1; - InterpCubic[i][1] = i3 - 2*i2 + 0x4000; - InterpCubic[i][2] = -i3 + i2 + i1; - InterpCubic[i][3] = i3 - i2; - } + SPUChannel::InterpCos[i] = (s16)(ratio * 0x2000); + } - return true; + for (int i = 0; i < 0x100; i++) + { + s32 i1 = i << 6; + s32 i2 = (i * i) >> 2; + s32 i3 = (i * i * i) >> 10; + + SPUChannel::InterpCubic[i][0] = -i3 + 2*i2 - i1; + SPUChannel::InterpCubic[i][1] = i3 - 2*i2 + 0x4000; + SPUChannel::InterpCubic[i][2] = -i3 + i2 + i1; + SPUChannel::InterpCubic[i][3] = i3 - i2; + } + + SPUChannel::InterpInited = true; + } } -void DeInit() +SPU::~SPU() { for (int i = 0; i < 16; i++) { @@ -153,7 +138,7 @@ void DeInit() NDS::UnregisterEventFunc(NDS::Event_SPU, 0); } -void Reset() +void SPU::Reset() { InitOutput(); @@ -170,7 +155,7 @@ void Reset() NDS::ScheduleEvent(NDS::Event_SPU, false, 1024, 0, 0); } -void Stop() +void SPU::Stop() { Platform::Mutex_Lock(AudioLock); memset(OutputFrontBuffer, 0, 2*OutputBufferSize*2); @@ -181,7 +166,7 @@ void Stop() Platform::Mutex_Unlock(AudioLock); } -void DoSavestate(Savestate* file) +void SPU::DoSavestate(Savestate* file) { file->Section("SPU."); @@ -197,43 +182,46 @@ void DoSavestate(Savestate* file) } -void SetPowerCnt(u32 val) +void SPU::SetPowerCnt(u32 val) { // TODO } -void SetInterpolation(int type) +void SPU::SetInterpolation(int type) { - InterpType = type; + for (int i = 0; i < 16; i++) + Channels[i]->InterpType = type; } -void SetBias(u16 bias) +void SPU::SetBias(u16 bias) { Bias = bias; } -void SetApplyBias(bool enable) +void SPU::SetApplyBias(bool enable) { ApplyBias = enable; } -void SetDegrade10Bit(bool enable) +void SPU::SetDegrade10Bit(bool enable) { Degrade10Bit = enable; } -Channel::Channel(u32 num) +SPUChannel::SPUChannel(u32 num) { Num = num; + + InterpType = 0; } -Channel::~Channel() +SPUChannel::~SPUChannel() { } -void Channel::Reset() +void SPUChannel::Reset() { if (NDS::ConsoleType == 1) BusRead32 = DSi::ARM7Read32; @@ -257,7 +245,7 @@ void Channel::Reset() FIFOLevel = 0; } -void Channel::DoSavestate(Savestate* file) +void SPUChannel::DoSavestate(Savestate* file) { file->Var32(&Cnt); file->Var32(&SrcAddr); @@ -289,7 +277,7 @@ void Channel::DoSavestate(Savestate* file) file->VarArray(FIFO, sizeof(FIFO)); } -void Channel::FIFO_BufferData() +void SPUChannel::FIFO_BufferData() { u32 totallen = LoopPos + Length; @@ -330,7 +318,7 @@ void Channel::FIFO_BufferData() } template -T Channel::FIFO_ReadData() +T SPUChannel::FIFO_ReadData() { T ret = *(T*)&((u8*)FIFO)[FIFOReadPos]; @@ -344,7 +332,7 @@ T Channel::FIFO_ReadData() return ret; } -void Channel::Start() +void SPUChannel::Start() { Timer = TimerReload; @@ -372,7 +360,7 @@ void Channel::Start() } } -void Channel::NextSample_PCM8() +void SPUChannel::NextSample_PCM8() { Pos++; if (Pos < 0) return; @@ -395,7 +383,7 @@ void Channel::NextSample_PCM8() CurSample = val << 8; } -void Channel::NextSample_PCM16() +void SPUChannel::NextSample_PCM16() { Pos++; if (Pos < 0) return; @@ -418,7 +406,7 @@ void Channel::NextSample_PCM16() CurSample = val; } -void Channel::NextSample_ADPCM() +void SPUChannel::NextSample_ADPCM() { Pos++; if (Pos < 8) @@ -493,13 +481,13 @@ void Channel::NextSample_ADPCM() CurSample = ADPCMVal; } -void Channel::NextSample_PSG() +void SPUChannel::NextSample_PSG() { Pos++; CurSample = PSGTable[(Cnt >> 24) & 0x7][Pos & 0x7]; } -void Channel::NextSample_Noise() +void SPUChannel::NextSample_Noise() { if (NoiseVal & 0x1) { @@ -514,7 +502,7 @@ void Channel::NextSample_Noise() } template -s32 Channel::Run() +s32 SPUChannel::Run() { if (!(Cnt & (1<<31))) return 0; @@ -586,23 +574,23 @@ s32 Channel::Run() return val; } -void Channel::PanOutput(s32 in, s32& left, s32& right) +void SPUChannel::PanOutput(s32 in, s32& left, s32& right) { left += ((s64)in * (128-Pan)) >> 10; right += ((s64)in * Pan) >> 10; } -CaptureUnit::CaptureUnit(u32 num) +SPUCaptureUnit::SPUCaptureUnit(u32 num) { Num = num; } -CaptureUnit::~CaptureUnit() +SPUCaptureUnit::~SPUCaptureUnit() { } -void CaptureUnit::Reset() +void SPUCaptureUnit::Reset() { if (NDS::ConsoleType == 1) BusWrite32 = DSi::ARM7Write32; @@ -623,7 +611,7 @@ void CaptureUnit::Reset() FIFOLevel = 0; } -void CaptureUnit::DoSavestate(Savestate* file) +void SPUCaptureUnit::DoSavestate(Savestate* file) { file->Var8(&Cnt); file->Var32(&DstAddr); @@ -640,7 +628,7 @@ void CaptureUnit::DoSavestate(Savestate* file) file->VarArray(FIFO, 4*4); } -void CaptureUnit::FIFO_FlushData() +void SPUCaptureUnit::FIFO_FlushData() { for (u32 i = 0; i < 4; i++) { @@ -660,7 +648,7 @@ void CaptureUnit::FIFO_FlushData() } template -void CaptureUnit::FIFO_WriteData(T val) +void SPUCaptureUnit::FIFO_WriteData(T val) { *(T*)&((u8*)FIFO)[FIFOWritePos] = val; @@ -672,7 +660,7 @@ void CaptureUnit::FIFO_WriteData(T val) FIFO_FlushData(); } -void CaptureUnit::Run(s32 sample) +void SPUCaptureUnit::Run(s32 sample) { Timer += 512; @@ -725,7 +713,7 @@ void CaptureUnit::Run(s32 sample) } -void Mix(u32 dummy) +void SPU::Mix(u32 dummy) { s32 left = 0, right = 0; s32 leftoutput = 0, rightoutput = 0; @@ -746,7 +734,7 @@ void Mix(u32 dummy) for (int i = 4; i < 16; i++) { - Channel* chan = Channels[i]; + SPUChannel* chan = Channels[i]; s32 channel = chan->DoRun(); chan->PanOutput(channel, left, right); @@ -871,7 +859,7 @@ void Mix(u32 dummy) NDS::ScheduleEvent(NDS::Event_SPU, true, 1024, 0, 0); } -void TransferOutput() +void SPU::TransferOutput() { Platform::Mutex_Lock(AudioLock); for (u32 i = 0; i < OutputBackbufferWritePosition; i += 2) @@ -889,10 +877,10 @@ void TransferOutput() } } OutputBackbufferWritePosition = 0; - Platform::Mutex_Unlock(AudioLock); + Platform::Mutex_Unlock(AudioLock);; } -void TrimOutput() +void SPU::TrimOutput() { Platform::Mutex_Lock(AudioLock); const int halflimit = (OutputBufferSize / 2); @@ -904,7 +892,7 @@ void TrimOutput() Platform::Mutex_Unlock(AudioLock); } -void DrainOutput() +void SPU::DrainOutput() { Platform::Mutex_Lock(AudioLock); OutputFrontBufferWritePosition = 0; @@ -912,7 +900,7 @@ void DrainOutput() Platform::Mutex_Unlock(AudioLock); } -void InitOutput() +void SPU::InitOutput() { Platform::Mutex_Lock(AudioLock); memset(OutputBackbuffer, 0, 2*OutputBufferSize*2); @@ -922,7 +910,7 @@ void InitOutput() Platform::Mutex_Unlock(AudioLock); } -int GetOutputSize() +int SPU::GetOutputSize() { Platform::Mutex_Lock(AudioLock); @@ -938,7 +926,7 @@ int GetOutputSize() return ret; } -void Sync(bool wait) +void SPU::Sync(bool wait) { // this function is currently not used anywhere // depending on the usage context the thread safety measures could be made @@ -968,7 +956,7 @@ void Sync(bool wait) } } -int ReadOutput(s16* data, int samples) +int SPU::ReadOutput(s16* data, int samples) { Platform::Mutex_Lock(AudioLock); if (OutputFrontBufferReadPosition == OutputFrontBufferWritePosition) @@ -997,11 +985,11 @@ int ReadOutput(s16* data, int samples) } -u8 Read8(u32 addr) +u8 SPU::Read8(u32 addr) { if (addr < 0x04000500) { - Channel* chan = Channels[(addr >> 4) & 0xF]; + SPUChannel* chan = Channels[(addr >> 4) & 0xF]; switch (addr & 0xF) { @@ -1027,11 +1015,11 @@ u8 Read8(u32 addr) return 0; } -u16 Read16(u32 addr) +u16 SPU::Read16(u32 addr) { if (addr < 0x04000500) { - Channel* chan = Channels[(addr >> 4) & 0xF]; + SPUChannel* chan = Channels[(addr >> 4) & 0xF]; switch (addr & 0xF) { @@ -1054,11 +1042,11 @@ u16 Read16(u32 addr) return 0; } -u32 Read32(u32 addr) +u32 SPU::Read32(u32 addr) { if (addr < 0x04000500) { - Channel* chan = Channels[(addr >> 4) & 0xF]; + SPUChannel* chan = Channels[(addr >> 4) & 0xF]; switch (addr & 0xF) { @@ -1083,11 +1071,11 @@ u32 Read32(u32 addr) return 0; } -void Write8(u32 addr, u8 val) +void SPU::Write8(u32 addr, u8 val) { if (addr < 0x04000500) { - Channel* chan = Channels[(addr >> 4) & 0xF]; + SPUChannel* chan = Channels[(addr >> 4) & 0xF]; switch (addr & 0xF) { @@ -1124,11 +1112,11 @@ void Write8(u32 addr, u8 val) Log(LogLevel::Warn, "unknown SPU write8 %08X %02X\n", addr, val); } -void Write16(u32 addr, u16 val) +void SPU::Write16(u32 addr, u16 val) { if (addr < 0x04000500) { - Channel* chan = Channels[(addr >> 4) & 0xF]; + SPUChannel* chan = Channels[(addr >> 4) & 0xF]; switch (addr & 0xF) { @@ -1173,11 +1161,11 @@ void Write16(u32 addr, u16 val) Log(LogLevel::Warn, "unknown SPU write16 %08X %04X\n", addr, val); } -void Write32(u32 addr, u32 val) +void SPU::Write32(u32 addr, u32 val) { if (addr < 0x04000500) { - Channel* chan = Channels[(addr >> 4) & 0xF]; + SPUChannel* chan = Channels[(addr >> 4) & 0xF]; switch (addr & 0xF) { @@ -1220,5 +1208,3 @@ void Write32(u32 addr, u32 val) } } } - -} diff --git a/src/SPU.h b/src/SPU.h index 12cba61..407a3f6 100644 --- a/src/SPU.h +++ b/src/SPU.h @@ -20,51 +20,30 @@ #define SPU_H #include "Savestate.h" +#include "Platform.h" -namespace SPU -{ - -bool Init(); -void DeInit(); -void Reset(); -void Stop(); - -void DoSavestate(Savestate* file); - -void SetPowerCnt(u32 val); - -// 0=none 1=linear 2=cosine 3=cubic -void SetInterpolation(int type); - -void SetBias(u16 bias); -void SetDegrade10Bit(bool enable); -void SetApplyBias(bool enable); - -void Mix(u32 dummy); - -void TrimOutput(); -void DrainOutput(); -void InitOutput(); -int GetOutputSize(); -void Sync(bool wait); -int ReadOutput(s16* data, int samples); -void TransferOutput(); +class SPU; -u8 Read8(u32 addr); -u16 Read16(u32 addr); -u32 Read32(u32 addr); -void Write8(u32 addr, u8 val); -void Write16(u32 addr, u16 val); -void Write32(u32 addr, u32 val); - -class Channel +class SPUChannel { public: - Channel(u32 num); - ~Channel(); + SPUChannel(u32 num); + ~SPUChannel(); void Reset(); void DoSavestate(Savestate* file); + static const s8 ADPCMIndexTable[8]; + static const u16 ADPCMTable[89]; + static const s16 PSGTable[8][8]; + + static s16 InterpCos[0x100]; + static s16 InterpCubic[0x100][4]; + static bool InterpInited; + + // audio interpolation is an improvement upon the original hardware + // (which performs no interpolation) + int InterpType; + u32 Num; u32 Cnt; @@ -164,11 +143,11 @@ private: u32 (*BusRead32)(u32 addr); }; -class CaptureUnit +class SPUCaptureUnit { public: - CaptureUnit(u32 num); - ~CaptureUnit(); + SPUCaptureUnit(u32 num); + ~SPUCaptureUnit(); void Reset(); void DoSavestate(Savestate* file); @@ -221,6 +200,61 @@ private: void (*BusWrite32)(u32 addr, u32 val); }; -} +class SPU +{ +public: + SPU(); + ~SPU(); + void Reset(); + void DoSavestate(Savestate* file); + + void Stop(); + + void SetPowerCnt(u32 val); + + // 0=none 1=linear 2=cosine 3=cubic + void SetInterpolation(int type); + + void SetBias(u16 bias); + void SetDegrade10Bit(bool enable); + void SetApplyBias(bool enable); + + void Mix(u32 dummy); + + void TrimOutput(); + void DrainOutput(); + void InitOutput(); + int GetOutputSize(); + void Sync(bool wait); + int ReadOutput(s16* data, int samples); + void TransferOutput(); + + u8 Read8(u32 addr); + u16 Read16(u32 addr); + u32 Read32(u32 addr); + void Write8(u32 addr, u8 val); + void Write16(u32 addr, u16 val); + void Write32(u32 addr, u32 val); + +private: + static const u32 OutputBufferSize = 2*2048; + s16 OutputBackbuffer[2 * OutputBufferSize]; + u32 OutputBackbufferWritePosition; + + s16 OutputFrontBuffer[2 * OutputBufferSize]; + u32 OutputFrontBufferWritePosition; + u32 OutputFrontBufferReadPosition; + + Platform::Mutex* AudioLock; + + u16 Cnt; + u8 MasterVolume; + u16 Bias; + bool ApplyBias; + bool Degrade10Bit; + + SPUChannel* Channels[16]; + SPUCaptureUnit* Capture[2]; +}; #endif // SPU_H diff --git a/src/frontend/qt_sdl/AudioInOut.cpp b/src/frontend/qt_sdl/AudioInOut.cpp index 120ff5f..7faac9f 100644 --- a/src/frontend/qt_sdl/AudioInOut.cpp +++ b/src/frontend/qt_sdl/AudioInOut.cpp @@ -22,6 +22,7 @@ #include "FrontendUtil.h" #include "Config.h" +#include "NDS.h" #include "SPU.h" #include "Platform.h" #include "Input.h" @@ -54,7 +55,7 @@ void AudioCallback(void* data, Uint8* stream, int len) int num_in; SDL_LockMutex(audioSyncLock); - num_in = SPU::ReadOutput(buf_in, len_in); + num_in = NDS::SPU->ReadOutput(buf_in, len_in); SDL_CondSignal(audioSync); SDL_UnlockMutex(audioSyncLock); @@ -352,7 +353,7 @@ void AudioSync() if (audioDevice) { SDL_LockMutex(audioSyncLock); - while (SPU::GetOutputSize() > 1024) + while (NDS::SPU->GetOutputSize() > 1024) { int ret = SDL_CondWaitTimeout(audioSync, audioSyncLock, 500); if (ret == SDL_MUTEX_TIMEDOUT) break; @@ -365,7 +366,7 @@ void UpdateSettings() { MicClose(); - SPU::SetInterpolation(Config::AudioInterp); + NDS::SPU->SetInterpolation(Config::AudioInterp); SetupMicInputData(); MicOpen(); diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index dcd52bd..700caea 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -342,7 +342,7 @@ void EmuThread::run() GPU::InitRenderer(videoRenderer); GPU::SetRenderSettings(videoRenderer, videoSettings); - SPU::SetInterpolation(Config::AudioInterp); + NDS::SPU->SetInterpolation(Config::AudioInterp); Input::Init(); @@ -2942,12 +2942,12 @@ void MainWindow::onPathSettingsFinished(int res) void MainWindow::onUpdateAudioSettings() { - SPU::SetInterpolation(Config::AudioInterp); + NDS::SPU->SetInterpolation(Config::AudioInterp); if (Config::AudioBitDepth == 0) - SPU::SetDegrade10Bit(NDS::ConsoleType == 0); + NDS::SPU->SetDegrade10Bit(NDS::ConsoleType == 0); else - SPU::SetDegrade10Bit(Config::AudioBitDepth == 1); + NDS::SPU->SetDegrade10Bit(Config::AudioBitDepth == 1); } void MainWindow::onAudioSettingsFinished(int res) -- cgit v1.2.3