diff --git a/output/dll/octoshock.dll b/output/dll/octoshock.dll index 0c4d27c16d..5858ec05de 100644 Binary files a/output/dll/octoshock.dll and b/output/dll/octoshock.dll differ diff --git a/psx/octoshock/psx/spu.cpp b/psx/octoshock/psx/spu.cpp index 0c774e4c2f..8ef7c9abc7 100644 --- a/psx/octoshock/psx/spu.cpp +++ b/psx/octoshock/psx/spu.cpp @@ -82,11 +82,6 @@ static const int16 FIR_Table[256][4] = #include "spu_fir_table.inc" }; -static const uint32 NoiseFreqTable[64] = -{ - #include "spu_nft.inc" -}; - PS_SPU::PS_SPU() { last_rate = -1; @@ -94,8 +89,6 @@ PS_SPU::PS_SPU() IntermediateBufferPos = 0; memset(IntermediateBuffer, 0, sizeof(IntermediateBuffer)); - - for(int16 a = 32760; a >= 0; a++); } PS_SPU::~PS_SPU() @@ -147,6 +140,7 @@ void PS_SPU::Power(void) GlobalSweep[0].Power(); GlobalSweep[1].Power(); + NoiseDivider = 0; NoiseCounter = 0; LFSR = 0; @@ -356,8 +350,6 @@ void PS_SPU::RunDecoder(SPU_Voice *voice) //for(int z = 0; z < 4; z++) { - const uint16 CV = SPURAM[voice->CurAddr]; - if(SPUControl & 0x40) { unsigned test_addr = voice->CurAddr & 0x3FFFF; @@ -371,6 +363,8 @@ void PS_SPU::RunDecoder(SPU_Voice *voice) if((voice->CurAddr & 0x7) == 0) { + const uint16 CV = SPURAM[voice->CurAddr]; + voice->DecodeShift = CV & 0xF; voice->DecodeWeight = (CV >> 4) & 0xF; voice->DecodeFlags = (CV >> 8) & 0xFF; @@ -389,9 +383,15 @@ void PS_SPU::RunDecoder(SPU_Voice *voice) } } } + voice->CurAddr = (voice->CurAddr + 1) & 0x3FFFF; } - else + + // + // Don't else this block; we need to ALWAYS decode 4 samples per call to RunDecoder() if DecodeAvail < 11, or else sample playback + // at higher rates will fail horribly. + // { + const uint16 CV = SPURAM[voice->CurAddr]; const unsigned shift = voice->DecodeShift; const int32 weight_m1 = Weights[voice->DecodeWeight][0]; const int32 weight_m2 = Weights[voice->DecodeWeight][1]; @@ -414,8 +414,8 @@ void PS_SPU::RunDecoder(SPU_Voice *voice) } voice->DecodeWritePos = (voice->DecodeWritePos + 4) & 0x1F; voice->DecodeAvail += 4; + voice->CurAddr = (voice->CurAddr + 1) & 0x3FFFF; } - voice->CurAddr = (voice->CurAddr + 1) & 0x3FFFF; } } @@ -477,9 +477,7 @@ void PS_SPU::RunEnvelope(SPU_Voice *voice) //static INLINE void CalcVCDelta(const uint8 zs, uint8 speed, bool log_mode, bool decrement, bool inv_increment, int16 Current, int &increment, int &divinco) switch(ADSR->Phase) { - default: assert(0); - break; - + default: // Won't happen, but helps shut up gcc warnings. case ADSR_ATTACK: CalcVCDelta(0x7F, ADSR->AttackRate, ADSR->AttackExp, false, false, (int16)ADSR->EnvLevel, increment, divinco); uoflow_reset = 0x7FFF; @@ -553,6 +551,32 @@ INLINE uint16 PS_SPU::ReadSPURAM(uint32 addr) #include "spu_reverb.inc" +INLINE void PS_SPU::RunNoise(void) +{ + const unsigned rf = ((SPUControl >> 8) & 0x3F); + uint32 NoiseDividerInc = (2 << (rf >> 2)); + uint32 NoiseCounterInc = 4 + (rf & 0x3); + + if(rf >= 0x3C) + { + NoiseDividerInc = 0x8000; + NoiseCounterInc = 8; + } + + NoiseDivider += NoiseDividerInc; + if(NoiseDivider & 0x8000) + { + NoiseDivider = 0; + + NoiseCounter += NoiseCounterInc; + if(NoiseCounter & 0x8) + { + NoiseCounter &= 0x7; + LFSR = (LFSR << 1) | (((LFSR >> 15) ^ (LFSR >> 12) ^ (LFSR >> 11) ^ (LFSR >> 10) ^ 1) & 1); + } + } +} + int32 PS_SPU::UpdateFromCDC(int32 clocks) //pscpu_timestamp_t PS_SPU::Update(const pscpu_timestamp_t timestamp) { @@ -793,12 +817,7 @@ int32 PS_SPU::UpdateFromCDC(int32 clocks) CWA = (CWA + 1) & 0x1FF; - NoiseCounter += NoiseFreqTable[(SPUControl >> 8) & 0x3F]; - if(NoiseCounter >= 0x8000) - { - NoiseCounter -= 0x8000; - LFSR = (LFSR << 1) | (((LFSR >> 15) ^ (LFSR >> 12) ^ (LFSR >> 11) ^ (LFSR >> 10) ^ 1) & 1); - } + RunNoise(); clamp(&accum_l, -32768, 32767); clamp(&accum_r, -32768, 32767); diff --git a/psx/octoshock/psx/spu.h b/psx/octoshock/psx/spu.h index 813233b5ef..e31fe6fdf6 100644 --- a/psx/octoshock/psx/spu.h +++ b/psx/octoshock/psx/spu.h @@ -133,10 +133,12 @@ private: void RunReverb(int32 in_l, int32 in_r, int32 &out_l, int32 &out_r); + void RunNoise(void); bool GetCDAudio(int32 &l, int32 &r); SPU_Voice Voices[24]; + uint32 NoiseDivider; uint32 NoiseCounter; uint16 LFSR; diff --git a/psx/octoshock/psx/spu_nft.inc b/psx/octoshock/psx/spu_nft.inc deleted file mode 100644 index 95b8f49c11..0000000000 --- a/psx/octoshock/psx/spu_nft.inc +++ /dev/null @@ -1,64 +0,0 @@ -0x00000001, -0x00000001, -0x00000001, -0x00000001, -0x00000002, -0x00000002, -0x00000002, -0x00000002, -0x00000004, -0x00000005, -0x00000006, -0x00000007, -0x00000008, -0x0000000a, -0x0000000c, -0x0000000e, -0x00000010, -0x00000014, -0x00000018, -0x0000001c, -0x00000020, -0x00000028, -0x00000030, -0x00000038, -0x00000040, -0x00000050, -0x00000060, -0x00000070, -0x00000080, -0x000000a0, -0x000000c0, -0x000000e0, -0x00000100, -0x00000140, -0x00000180, -0x000001c0, -0x00000200, -0x00000280, -0x00000300, -0x00000380, -0x00000400, -0x00000500, -0x00000600, -0x00000700, -0x00000800, -0x00000a00, -0x00000c00, -0x00000e00, -0x00001000, -0x00001400, -0x00001800, -0x00001c00, -0x00002000, -0x00002800, -0x00003000, -0x00003800, -0x00004000, -0x00005000, -0x00006000, -0x00007000, -0x00008000, -0x00008000, -0x00008000, -0x00008000,