SPU2: Set sample rate correctly for PS1 mode (#3532)

* Moved ps1 init. Added Sample Rate change for SPU that gets set but not applied
* SPU: misc fixes on SPU ps1 mode init
* Init the soundbuffer to apply sample rate. Actually set the correct sample rate for the ps1 though it still won't apply

Co-authored-by: Gauvain 'GovanifY' Roussel-Tarbouriech <gauvain@govanify.com>
Co-authored-by: kenshen112 <obarrtimothy@gmail.com>
This commit is contained in:
Timothy O'Barr 2020-09-20 17:04:40 -07:00 committed by GitHub
parent 551847411f
commit 73b02c204b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 92 additions and 28 deletions

4
.gitignore vendored
View File

@ -30,6 +30,8 @@
**/x64/Debug* **/x64/Debug*
**/x64/Devel* **/x64/Devel*
**/bin/PCSX2-linux.sh
_ReSharper.* _ReSharper.*
pcsx2.snapshot_* pcsx2.snapshot_*
svnrev.h svnrev.h
@ -63,6 +65,7 @@ oprofile_data/
# Visual Studio upgrades # Visual Studio upgrades
/Backup* /Backup*
/UpgradeLog*.htm /UpgradeLog*.htm
/.vscode*
/bin/**/*.dll /bin/**/*.dll
/bin/**/*.exp /bin/**/*.exp
@ -112,3 +115,4 @@ oprofile_data/
/pcsx2/windows/VCprojects/GSdx_opengl_debug_hw.txt /pcsx2/windows/VCprojects/GSdx_opengl_debug_hw.txt
/pcsx2/windows/VCprojects/GSdx_opengl_debug_sw.txt /pcsx2/windows/VCprojects/GSdx_opengl_debug_sw.txt
/out/build/x64-Debug (default)

View File

@ -263,6 +263,7 @@ void CALLBACK SPU2setSettingsDir(const char *dir);
void CALLBACK SPU2setLogDir(const char *dir); void CALLBACK SPU2setLogDir(const char *dir);
void CALLBACK SPU2reset(); void CALLBACK SPU2reset();
void CALLBACK SPU2ps1reset();
void CALLBACK SPU2write(u32 mem, u16 value); void CALLBACK SPU2write(u32 mem, u16 value);
u16 CALLBACK SPU2read(u32 mem); u16 CALLBACK SPU2read(u32 mem);
@ -432,6 +433,7 @@ typedef void(CALLBACK *_PADWriteEvent)(keyEvent &evt);
// SPU2 // SPU2
typedef s32(CALLBACK *_SPU2open)(void *pDsp); typedef s32(CALLBACK *_SPU2open)(void *pDsp);
typedef void(CALLBACK *_SPU2reset)(); typedef void(CALLBACK *_SPU2reset)();
typedef void (CALLBACK *_SPU2ps1reset)();
typedef void(CALLBACK *_SPU2write)(u32 mem, u16 value); typedef void(CALLBACK *_SPU2write)(u32 mem, u16 value);
typedef u16(CALLBACK *_SPU2read)(u32 mem); typedef u16(CALLBACK *_SPU2read)(u32 mem);
typedef void(CALLBACK *_SPU2readDMA4Mem)(u16 *pMem, int size); typedef void(CALLBACK *_SPU2readDMA4Mem)(u16 *pMem, int size);
@ -536,6 +538,7 @@ extern _PADWriteEvent PADWriteEvent;
#ifndef BUILTIN_SPU2_PLUGIN #ifndef BUILTIN_SPU2_PLUGIN
extern _SPU2open SPU2open; extern _SPU2open SPU2open;
extern _SPU2reset SPU2reset; extern _SPU2reset SPU2reset;
extern _SPU2ps1reset SPU2ps1reset;
extern _SPU2write SPU2write; extern _SPU2write SPU2write;
extern _SPU2read SPU2read; extern _SPU2read SPU2read;

View File

@ -1473,24 +1473,24 @@ static __fi void cdvdWrite0F(u8 rt)
static __fi void cdvdWrite14(u8 rt) static __fi void cdvdWrite14(u8 rt)
{ // PS1 MODE?? // This should be done in the SBUS_F240 bit 19 write in HwWrite.cpp { // PS1 MODE?? // This should be done in the SBUS_F240 bit 19 write in HwWrite.cpp
u32 cycle = psxRegs.cycle; //u32 cycle = psxRegs.cycle;
if (rt == 0xFE) //if (rt == 0xFE)
Console.Warning("*PCSX2*: go PS1 mode DISC SPEED = FAST"); //Console.Warning("*PCSX2*: go PS1 mode DISC SPEED = FAST");
else //else
Console.Warning("*PCSX2*: go PS1 mode DISC SPEED = %dX", rt); //Console.Warning("*PCSX2*: go PS1 mode DISC SPEED = %dX", rt);
psxReset(); //psxReset();
PSXCLK = 33868800; //PSXCLK = 33868800;
setPsxSpeed(); //setPsxSpeed();
// psxmode: todo: we should recalculate video timings for iop and ee. how to do that best? // psxmode: todo: we should recalculate video timings for iop and ee. how to do that best?
// unlike regular ps2 games, the video mode for ps1driver isn't going through the GS set mode syscall // unlike regular ps2 games, the video mode for ps1driver isn't going through the GS set mode syscall
// so.. something like this? : // so.. something like this? :
//gsSetVideoMode(GS_VideoMode::NTSC); //gsSetVideoMode(GS_VideoMode::NTSC);
//gsSetVideoMode(GS_VideoMode::DVD_NTSC); //gsSetVideoMode(GS_VideoMode::DVD_NTSC);
psxHu32(0x1f801450) = 0x8; //psxHu32(0x1f801450) = 0x8;
psxHu32(0x1f801078) = 1; //psxHu32(0x1f801078) = 1;
psxRegs.cycle = cycle; //psxRegs.cycle = cycle;
} }
static __fi void fail_pol_cal() static __fi void fail_pol_cal()
@ -2175,9 +2175,9 @@ void cdvdWrite(u8 key, u8 rt)
case 0x0F: case 0x0F:
cdvdWrite0F(rt); cdvdWrite0F(rt);
break; break;
case 0x14: //case 0x14:
cdvdWrite14(rt); // cdvdWrite14(rt);
break; // break;
case 0x16: case 0x16:
cdvdWrite16(rt); cdvdWrite16(rt);
break; break;

View File

@ -20,6 +20,7 @@
#include "newVif.h" #include "newVif.h"
#include "IPU/IPUdma.h" #include "IPU/IPUdma.h"
#include "Gif_Unit.h" #include "Gif_Unit.h"
#include "IopCommon.h"
using namespace R5900; using namespace R5900;
@ -63,6 +64,11 @@ void hwReset()
psHu32(DMAC_ENABLEW) = 0x1201; psHu32(DMAC_ENABLEW) = 0x1201;
psHu32(DMAC_ENABLER) = 0x1201; psHu32(DMAC_ENABLER) = 0x1201;
if ((psxHu32(HW_ICFG) & (1 << 3)))
{
SPU2ps1reset();
}
SPU2reset(); SPU2reset();
sifReset(); sifReset();

View File

@ -177,15 +177,18 @@ void __fastcall _hwWrite32( u32 mem, u32 value )
return; return;
mcase(SBUS_F240) : mcase(SBUS_F240) :
//if (value & (1 << 19)) // switch hardware into psx mode. Doesn't work for some reason, still needs this to be in cdvdWrite14? if (value & (1 << 19))
//{ {
// u32 cycle = psxRegs.cycle; u32 cycle = psxRegs.cycle;
// //pgifInit(); //pgifInit();
// psxHwReset(); psxReset();
// psxHu32(0x1f801450) = 0x8; PSXCLK = 33868800;
// psxHu32(0x1f801078) = 1; SPU2ps1reset();
// psxRegs.cycle = cycle; setPsxSpeed();
//} psxHu32(0x1f801450) = 0x8;
psxHu32(0x1f801078) = 1;
psxRegs.cycle = cycle;
}
if(!(value & 0x100)) if(!(value & 0x100))
psHu32(mem) &= ~0x100; psHu32(mem) &= ~0x100;
else else

View File

@ -279,6 +279,7 @@ static void PAD_update( u32 padslot ) { }
_SPU2open SPU2open; _SPU2open SPU2open;
_SPU2write SPU2write; _SPU2write SPU2write;
_SPU2reset SPU2reset; _SPU2reset SPU2reset;
_SPU2ps1reset SPU2ps1reset;
_SPU2read SPU2read; _SPU2read SPU2read;
_SPU2readDMA4Mem SPU2readDMA4Mem; _SPU2readDMA4Mem SPU2readDMA4Mem;
@ -451,6 +452,7 @@ static const LegacyApi_ReqMethod s_MethMessReq_SPU2[] =
{ {
{ "SPU2open", (vMeth**)&SPU2open, NULL }, { "SPU2open", (vMeth**)&SPU2open, NULL },
{ "SPU2reset", (vMeth**)&SPU2reset, SPU2_Reset }, { "SPU2reset", (vMeth**)&SPU2reset, SPU2_Reset },
{ "SPU2ps1reset", (vMeth**)&SPU2ps1reset, SPU2ps1reset},
{ "SPU2write", (vMeth**)&SPU2write, NULL }, { "SPU2write", (vMeth**)&SPU2write, NULL },
{ "SPU2read", (vMeth**)&SPU2read, NULL }, { "SPU2read", (vMeth**)&SPU2read, NULL },
{ "SPU2readDMA4Mem", (vMeth**)&SPU2readDMA4Mem, NULL }, { "SPU2readDMA4Mem", (vMeth**)&SPU2readDMA4Mem, NULL },

View File

@ -627,7 +627,7 @@ void PGIFw(int addr, u32 data)
} else if (addr == PGPU_DAT_FIFO) { //reverse write - mind the direction set by reg f380 } else if (addr == PGPU_DAT_FIFO) { //reverse write - mind the direction set by reg f380
//PGpuDataReg = data; //PGpuDataReg = data;
ringBufPut(&pgifDatRbC, &data); ringBufPut(&pgifDatRbC, &data);
// Console.WriteLn( "\n\r PGIF REVERSE !!! DATA write 0x%08X = 0x%08X IF_CTRL= %08X PGPU_STAT= %08X CmdCnt 0x%X \n\r", addr, data, getUpdPgifCtrlReg(), getUpdPgpuStatReg(), pgifCmdRbC.count); // Console.WriteLn( "\n\r PGIF REVERSE !!! DATA write 0x%08X = 0x%08X IF_CTRL= %08X PGPU_STAT= %08X CmdCnt 0x%X \n\r", addr, data, getUpdPgifCtrlReg(), getUpdPgpuStatReg(), pgifCmdRbC.count);
drainPgpuDmaNrToIop(); drainPgpuDmaNrToIop();
} else if (addr == PGPU_STAT) { } else if (addr == PGPU_STAT) {
PGpuStatReg = data; //Should all bits be writable? PGpuStatReg = data; //Should all bits be writable?

View File

@ -15,6 +15,7 @@
*/ */
void pgifInit(void); void pgifInit(void);
void pgifReset(void);
extern void psxGPUw(int, u32); extern void psxGPUw(int, u32);
extern u32 psxGPUr(int); extern u32 psxGPUr(int);

View File

@ -32,6 +32,7 @@
// PCSX2 expects ASNI, not unicode, so this MUST always be char... // PCSX2 expects ASNI, not unicode, so this MUST always be char...
static char libraryName[256]; static char libraryName[256];
int SampleRate = 48000;
static bool IsOpened = false; static bool IsOpened = false;
static bool IsInitialized = false; static bool IsInitialized = false;
@ -279,14 +280,54 @@ CALLBACK SPU2writeDMA7Mem(u16 *pMem, u32 size)
Cores[1].DoDMAwrite(pMem, size); Cores[1].DoDMAwrite(pMem, size);
} }
EXPORT_C_(void) EXPORT_C_(s32)
SPU2reset() SPU2reset()
{ {
SampleRate = 48000;
if (SndBuffer::Test() != 0)
{
SndBuffer::Cleanup();
}
memset(spu2regs, 0, 0x010000); memset(spu2regs, 0, 0x010000);
memset(_spu2mem, 0, 0x200000); memset(_spu2mem, 0, 0x200000);
memset(_spu2mem + 0x2800, 7, 0x10); // from BIOS reversal. Locks the voices so they don't run free. memset(_spu2mem + 0x2800, 7, 0x10); // from BIOS reversal. Locks the voices so they don't run free.
Cores[0].Init(0); Cores[0].Init(0);
Cores[1].Init(1); Cores[1].Init(1);
try {
SndBuffer::Init();
} catch (std::exception &ex) {
fprintf(stderr, "SPU2-X Error: Could not initialize device, or something.\nReason: %s", ex.what());
SPU2close();
return -1;
}
return 0;
}
EXPORT_C_(s32)
SPU2ps1reset()
{
SampleRate = 44100;
if (SndBuffer::Test() != 0)
{
SndBuffer::Cleanup();
}
printf("RESET PS1 \n");
memset(spu2regs, 0, 0x010000);
memset(_spu2mem, 0, 0x200000);
memset(_spu2mem + 0x2800, 7, 0x10); // from BIOS reversal. Locks the voices so they don't run free.
// Reset the cores to actually apply the sample rate. Beware, thar be dragons in here.
/*Cores[0].Init(0);
Cores[1].Init(1);*/
try {
SndBuffer::Init();
} catch (std::exception &ex) {
fprintf(stderr, "SPU2-X Error: Could not initialize device, or something.\nReason: %s", ex.what());
SPU2close();
return -1;
}
return 0;
} }
EXPORT_C_(s32) EXPORT_C_(s32)

View File

@ -35,9 +35,11 @@
EXPORT_C_(s32) EXPORT_C_(s32)
SPU2init(); SPU2init();
EXPORT_C_(void) EXPORT_C_(s32)
SPU2reset(); SPU2reset();
EXPORT_C_(s32) EXPORT_C_(s32)
SPU2ps1reset();
EXPORT_C_(s32)
SPU2open(void *pDsp); SPU2open(void *pDsp);
EXPORT_C_(void) EXPORT_C_(void)
SPU2close(); SPU2close();

View File

@ -377,6 +377,7 @@ void SndBuffer::Init()
try { try {
const float latencyMS = SndOutLatencyMS * 16; const float latencyMS = SndOutLatencyMS * 16;
m_size = GetAlignedBufferSize((int)(latencyMS * SampleRate / 1000.0f)); m_size = GetAlignedBufferSize((int)(latencyMS * SampleRate / 1000.0f));
printf("%d SampleRate: \n", SampleRate);
m_buffer = new StereoOut32[m_size]; m_buffer = new StereoOut32[m_size];
m_underrun_freeze = false; m_underrun_freeze = false;

View File

@ -32,7 +32,7 @@ static const int SndOutVolumeShift32 = 16 - SndOutVolumeShift; // shift up, not
// Samplerate of the SPU2. For accurate playback we need to match this // Samplerate of the SPU2. For accurate playback we need to match this
// exactly. Trying to scale samplerates and maintain SPU2's Ts timing accuracy // exactly. Trying to scale samplerates and maintain SPU2's Ts timing accuracy
// is too problematic. :) // is too problematic. :)
static const int SampleRate = 48000; extern int SampleRate;
extern int FindOutputModuleById(const wchar_t *omodid); extern int FindOutputModuleById(const wchar_t *omodid);

View File

@ -59,3 +59,4 @@ EXPORTS
SPU2replay = s2r_replay @30 SPU2replay = s2r_replay @30
SPU2reset @31 SPU2reset @31
SPU2ps1reset @32