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