mirror of https://github.com/PCSX2/pcsx2.git
SPU2-X: Reverb compatibility improvements (fixes Ys6).
* EEA / ESA writes are ignored when Effects are enabled. * When effects are disabled, reverb does not process IRQs or produce sound. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3326 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
7dbbaf1c04
commit
af40a22ee8
|
@ -34,13 +34,10 @@ namespace soundtouch
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
// This will be brought in later anyways, but if we bring it in now, it'll avoid
|
// This will be brought in later anyways, but if we bring it in now, it'll avoid
|
||||||
// warnings about redefining __LINUX__.
|
// warnings about redefining __LINUX__.
|
||||||
|
|
|
@ -667,23 +667,33 @@ StereoOut32 V_Core::Mix( const VoiceMixSet& inVoices, const StereoOut32& Input,
|
||||||
TD.Left += Ext.Left & DryGate.ExtL;
|
TD.Left += Ext.Left & DryGate.ExtL;
|
||||||
TD.Right += Ext.Right & DryGate.ExtR;
|
TD.Right += Ext.Right & DryGate.ExtR;
|
||||||
|
|
||||||
|
// User-level Effects disabling. Nice speedup but breaks games that depend on
|
||||||
|
// reverb IRQs (very few -- if you find one name it here!).
|
||||||
if( EffectsDisabled ) return TD;
|
if( EffectsDisabled ) return TD;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Reverberation Effects Processing
|
// Reverberation Effects Processing
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// The FxEnable bit is, like many other things in the SPU2, only a partial systems
|
// SPU2 has an FxEnable bit which seems to disable all reverb processing *and*
|
||||||
// toogle. It disables the *inputs* to the reverb, such that the reverb is fed silence,
|
// output, but does *not* disable the advancing buffers. IRQs are not triggered
|
||||||
// but it does not actually disable reverb effects processing. In practical terms
|
// and reverb is rendered silent.
|
||||||
// this means that when a game turns off reverb, an existing reverb effect should trail
|
//
|
||||||
// off naturally, instead of being chopped off dead silent.
|
// Technically we should advance the buffers even when fx are disabled. However
|
||||||
|
// there are two things that make this very unlikely to matter:
|
||||||
|
//
|
||||||
|
// 1. Any SPU2 app wanting to avoid noise or pops needs to clear the reverb buffers
|
||||||
|
// when adjusting settings anyway; so the read/write positions in the reverb
|
||||||
|
// buffer after FxEnabled is set back to 1 doesn't really matter.
|
||||||
|
//
|
||||||
|
// 2. Writes to ESA (and possibly EEA) reset the buffer pointers to 0.
|
||||||
|
//
|
||||||
|
// On the other hand, updating the buffer is cheap and easy, so might as well. ;)
|
||||||
|
|
||||||
Reverb_AdvanceBuffer();
|
Reverb_AdvanceBuffer();
|
||||||
|
if (!FxEnable) return TD;
|
||||||
|
|
||||||
StereoOut32 TW;
|
StereoOut32 TW;
|
||||||
|
|
||||||
if( FxEnable )
|
|
||||||
{
|
|
||||||
// Mix Input, Voice, and External data:
|
// Mix Input, Voice, and External data:
|
||||||
|
|
||||||
TW.Left = Input.Left & WetGate.InpL;
|
TW.Left = Input.Left & WetGate.InpL;
|
||||||
|
@ -693,7 +703,6 @@ StereoOut32 V_Core::Mix( const VoiceMixSet& inVoices, const StereoOut32& Input,
|
||||||
TW.Right += Voices.Wet.Right & WetGate.SndR;
|
TW.Right += Voices.Wet.Right & WetGate.SndR;
|
||||||
TW.Left += Ext.Left & WetGate.ExtL;
|
TW.Left += Ext.Left & WetGate.ExtL;
|
||||||
TW.Right += Ext.Right & WetGate.ExtR;
|
TW.Right += Ext.Right & WetGate.ExtR;
|
||||||
}
|
|
||||||
|
|
||||||
WaveDump::WriteCore( Index, CoreSrc_PreReverb, TW );
|
WaveDump::WriteCore( Index, CoreSrc_PreReverb, TW );
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
#include "Global.h"
|
#include "Global.h"
|
||||||
#include "soundtouch/SoundTouch.h"
|
#include "soundtouch/SoundTouch.h"
|
||||||
|
|
||||||
|
|
||||||
static soundtouch::SoundTouch* pSoundTouch = NULL;
|
static soundtouch::SoundTouch* pSoundTouch = NULL;
|
||||||
static int ts_stats_stretchblocks = 0;
|
static int ts_stats_stretchblocks = 0;
|
||||||
static int ts_stats_normalblocks = 0;
|
static int ts_stats_normalblocks = 0;
|
||||||
|
|
|
@ -930,10 +930,12 @@ static void __fastcall RegWrite_Core( u16 value )
|
||||||
|
|
||||||
case REG_C_ATTR:
|
case REG_C_ATTR:
|
||||||
{
|
{
|
||||||
|
bool fxenable = thiscore.FxEnable;
|
||||||
bool irqe = thiscore.IRQEnable;
|
bool irqe = thiscore.IRQEnable;
|
||||||
int bit0 = thiscore.AttrBit0;
|
int bit0 = thiscore.AttrBit0;
|
||||||
u8 oldDmaMode = thiscore.DmaMode;
|
u8 oldDmaMode = thiscore.DmaMode;
|
||||||
|
|
||||||
|
|
||||||
if( ((value>>15)&1) && (!thiscore.CoreEnabled) && (thiscore.InitDelay==0) ) // on init/reset
|
if( ((value>>15)&1) && (!thiscore.CoreEnabled) && (thiscore.InitDelay==0) ) // on init/reset
|
||||||
{
|
{
|
||||||
// When we have exact cycle update info from the Pcsx2 IOP unit, then use
|
// When we have exact cycle update info from the Pcsx2 IOP unit, then use
|
||||||
|
@ -960,10 +962,13 @@ static void __fastcall RegWrite_Core( u16 value )
|
||||||
thiscore.FxEnable =(value>> 7) & 0x01; //1 bit
|
thiscore.FxEnable =(value>> 7) & 0x01; //1 bit
|
||||||
thiscore.NoiseClk =(value>> 8) & 0x3f; //6 bits
|
thiscore.NoiseClk =(value>> 8) & 0x3f; //6 bits
|
||||||
//thiscore.Mute =(value>>14) & 0x01; //1 bit
|
//thiscore.Mute =(value>>14) & 0x01; //1 bit
|
||||||
thiscore.Mute=0;
|
thiscore.Mute =0;
|
||||||
thiscore.CoreEnabled=(value>>15) & 0x01; //1 bit
|
thiscore.CoreEnabled=(value>>15) & 0x01; //1 bit
|
||||||
thiscore.Regs.ATTR =value&0x7fff;
|
thiscore.Regs.ATTR =value&0x7fff;
|
||||||
|
|
||||||
|
if (!fxenable && thiscore.FxEnable)
|
||||||
|
thiscore.RevBuffers.NeedsUpdated = true;
|
||||||
|
|
||||||
if(oldDmaMode != thiscore.DmaMode)
|
if(oldDmaMode != thiscore.DmaMode)
|
||||||
{
|
{
|
||||||
// FIXME... maybe: if this mode was cleared in the middle of a DMA, should we interrupt it?
|
// FIXME... maybe: if this mode was cleared in the middle of a DMA, should we interrupt it?
|
||||||
|
@ -1111,31 +1116,36 @@ static void __fastcall RegWrite_Core( u16 value )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Reverb Start and End Address Writes!
|
// Reverb Start and End Address Writes!
|
||||||
|
// * These regs are only writable when Effects are *DISABLED* (FxEnable is false).
|
||||||
|
// Writes while enabled should be ignored.
|
||||||
// * Yes, these are backwards from all the volumes -- the hiword comes FIRST (wtf!)
|
// * Yes, these are backwards from all the volumes -- the hiword comes FIRST (wtf!)
|
||||||
// * End position is a hiword only! Loword is always ffff.
|
// * End position is a hiword only! Loword is always ffff.
|
||||||
// * The Reverb buffer position resets on writes to StartA. It probably resets
|
// * The Reverb buffer position resets on writes to StartA. It probably resets
|
||||||
// on writes to End too. Docs don't say, but they're for PSX, which couldn't
|
// on writes to End too. Docs don't say, but they're for PSX, which couldn't
|
||||||
// change the end address anyway.
|
// change the end address anyway.
|
||||||
|
//
|
||||||
case REG_A_ESA:
|
case REG_A_ESA:
|
||||||
//if (thiscore.FxEnable){printf("!! ESA\n"); return;}
|
if (!thiscore.FxEnable)
|
||||||
|
{
|
||||||
SetHiWord( thiscore.EffectsStartA, value );
|
SetHiWord( thiscore.EffectsStartA, value );
|
||||||
thiscore.RevBuffers.NeedsUpdated = true;
|
|
||||||
thiscore.ReverbX = 0;
|
thiscore.ReverbX = 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (REG_A_ESA + 2):
|
case (REG_A_ESA + 2):
|
||||||
//if (thiscore.FxEnable){printf("!! ESA\n"); return;}
|
if (!thiscore.FxEnable)
|
||||||
|
{
|
||||||
SetLoWord( thiscore.EffectsStartA, value );
|
SetLoWord( thiscore.EffectsStartA, value );
|
||||||
thiscore.RevBuffers.NeedsUpdated = true;
|
|
||||||
thiscore.ReverbX = 0;
|
thiscore.ReverbX = 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REG_A_EEA:
|
case REG_A_EEA:
|
||||||
//if (thiscore.FxEnable){printf("!! EEA\n"); return;}
|
if (!thiscore.FxEnable)
|
||||||
|
{
|
||||||
thiscore.EffectsEndA = ((u32)value<<16) | 0xFFFF;
|
thiscore.EffectsEndA = ((u32)value<<16) | 0xFFFF;
|
||||||
thiscore.RevBuffers.NeedsUpdated = true;
|
|
||||||
thiscore.ReverbX = 0;
|
thiscore.ReverbX = 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REG_S_ADMAS:
|
case REG_S_ADMAS:
|
||||||
|
|
Loading…
Reference in New Issue