aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ARMJIT_Memory.cpp4
-rw-r--r--src/NDS.cpp55
-rw-r--r--src/NDS.h4
-rw-r--r--src/SPI.cpp14
-rw-r--r--src/SPU.cpp206
-rw-r--r--src/SPU.h118
-rw-r--r--src/frontend/qt_sdl/AudioInOut.cpp7
-rw-r--r--src/frontend/qt_sdl/main.cpp8
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<typename T>
-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<u32 type>
-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<typename T>
-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)