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/Devel*
**/bin/PCSX2-linux.sh
_ReSharper.*
pcsx2.snapshot_*
svnrev.h
@ -63,6 +65,7 @@ oprofile_data/
# Visual Studio upgrades
/Backup*
/UpgradeLog*.htm
/.vscode*
/bin/**/*.dll
/bin/**/*.exp
@ -112,3 +115,4 @@ oprofile_data/
/pcsx2/windows/VCprojects/GSdx_opengl_debug_hw.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 SPU2reset();
void CALLBACK SPU2ps1reset();
void CALLBACK SPU2write(u32 mem, u16 value);
u16 CALLBACK SPU2read(u32 mem);
@ -432,6 +433,7 @@ typedef void(CALLBACK *_PADWriteEvent)(keyEvent &evt);
// SPU2
typedef s32(CALLBACK *_SPU2open)(void *pDsp);
typedef void(CALLBACK *_SPU2reset)();
typedef void (CALLBACK *_SPU2ps1reset)();
typedef void(CALLBACK *_SPU2write)(u32 mem, u16 value);
typedef u16(CALLBACK *_SPU2read)(u32 mem);
typedef void(CALLBACK *_SPU2readDMA4Mem)(u16 *pMem, int size);
@ -536,6 +538,7 @@ extern _PADWriteEvent PADWriteEvent;
#ifndef BUILTIN_SPU2_PLUGIN
extern _SPU2open SPU2open;
extern _SPU2reset SPU2reset;
extern _SPU2ps1reset SPU2ps1reset;
extern _SPU2write SPU2write;
extern _SPU2read SPU2read;

View File

@ -1473,24 +1473,24 @@ static __fi void cdvdWrite0F(u8 rt)
static __fi void cdvdWrite14(u8 rt)
{ // 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)
Console.Warning("*PCSX2*: go PS1 mode DISC SPEED = FAST");
else
Console.Warning("*PCSX2*: go PS1 mode DISC SPEED = %dX", rt);
//if (rt == 0xFE)
//Console.Warning("*PCSX2*: go PS1 mode DISC SPEED = FAST");
//else
//Console.Warning("*PCSX2*: go PS1 mode DISC SPEED = %dX", rt);
psxReset();
PSXCLK = 33868800;
setPsxSpeed();
//psxReset();
//PSXCLK = 33868800;
//setPsxSpeed();
// 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
// so.. something like this? :
//gsSetVideoMode(GS_VideoMode::NTSC);
//gsSetVideoMode(GS_VideoMode::DVD_NTSC);
psxHu32(0x1f801450) = 0x8;
psxHu32(0x1f801078) = 1;
psxRegs.cycle = cycle;
//psxHu32(0x1f801450) = 0x8;
//psxHu32(0x1f801078) = 1;
//psxRegs.cycle = cycle;
}
static __fi void fail_pol_cal()
@ -2175,9 +2175,9 @@ void cdvdWrite(u8 key, u8 rt)
case 0x0F:
cdvdWrite0F(rt);
break;
case 0x14:
cdvdWrite14(rt);
break;
//case 0x14:
// cdvdWrite14(rt);
// break;
case 0x16:
cdvdWrite16(rt);
break;

View File

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

View File

@ -177,15 +177,18 @@ void __fastcall _hwWrite32( u32 mem, u32 value )
return;
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?
//{
// u32 cycle = psxRegs.cycle;
// //pgifInit();
// psxHwReset();
// psxHu32(0x1f801450) = 0x8;
// psxHu32(0x1f801078) = 1;
// psxRegs.cycle = cycle;
//}
if (value & (1 << 19))
{
u32 cycle = psxRegs.cycle;
//pgifInit();
psxReset();
PSXCLK = 33868800;
SPU2ps1reset();
setPsxSpeed();
psxHu32(0x1f801450) = 0x8;
psxHu32(0x1f801078) = 1;
psxRegs.cycle = cycle;
}
if(!(value & 0x100))
psHu32(mem) &= ~0x100;
else

View File

@ -279,6 +279,7 @@ static void PAD_update( u32 padslot ) { }
_SPU2open SPU2open;
_SPU2write SPU2write;
_SPU2reset SPU2reset;
_SPU2ps1reset SPU2ps1reset;
_SPU2read SPU2read;
_SPU2readDMA4Mem SPU2readDMA4Mem;
@ -451,6 +452,7 @@ static const LegacyApi_ReqMethod s_MethMessReq_SPU2[] =
{
{ "SPU2open", (vMeth**)&SPU2open, NULL },
{ "SPU2reset", (vMeth**)&SPU2reset, SPU2_Reset },
{ "SPU2ps1reset", (vMeth**)&SPU2ps1reset, SPU2ps1reset},
{ "SPU2write", (vMeth**)&SPU2write, NULL },
{ "SPU2read", (vMeth**)&SPU2read, 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
//PGpuDataReg = 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();
} else if (addr == PGPU_STAT) {
PGpuStatReg = data; //Should all bits be writable?

View File

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

View File

@ -32,6 +32,7 @@
// PCSX2 expects ASNI, not unicode, so this MUST always be char...
static char libraryName[256];
int SampleRate = 48000;
static bool IsOpened = false;
static bool IsInitialized = false;
@ -279,14 +280,54 @@ CALLBACK SPU2writeDMA7Mem(u16 *pMem, u32 size)
Cores[1].DoDMAwrite(pMem, size);
}
EXPORT_C_(void)
EXPORT_C_(s32)
SPU2reset()
{
{
SampleRate = 48000;
if (SndBuffer::Test() != 0)
{
SndBuffer::Cleanup();
}
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.
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)
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)

View File

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

View File

@ -377,6 +377,7 @@ void SndBuffer::Init()
try {
const float latencyMS = SndOutLatencyMS * 16;
m_size = GetAlignedBufferSize((int)(latencyMS * SampleRate / 1000.0f));
printf("%d SampleRate: \n", SampleRate);
m_buffer = new StereoOut32[m_size];
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
// exactly. Trying to scale samplerates and maintain SPU2's Ts timing accuracy
// is too problematic. :)
static const int SampleRate = 48000;
extern int SampleRate;
extern int FindOutputModuleById(const wchar_t *omodid);

View File

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