SPU2-X: Revert Neill's x4 buffer indexers -- Fixes feedback. Update savestate version to fix prev savestates.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2089 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-10-27 14:08:25 +00:00
parent b0b928d4f4
commit 1cc740a9c0
4 changed files with 49 additions and 41 deletions

View File

@ -889,5 +889,15 @@ buffer[MIX_DEST_A1] = ACC1 - FB_A1 * FB_ALPHA;
buffer[MIX_DEST_B0] = (FB_ALPHA * ACC0) - FB_A0 * (FB_ALPHA^0x8000) - FB_B0 * FB_X;
buffer[MIX_DEST_B1] = (FB_ALPHA * ACC1) - FB_A1 * (FB_ALPHA^0x8000) - FB_B1 * FB_X;
Air notes:
The above is effectivly the same as:
buffer[MIX_DEST_B0] = (ACC0 * FB_ALPHA) + (FB_A0 * (1.0-FB_ALPHA)) - FB_B0 * FB_X;
buffer[MIX_DEST_B1] = (ACC1 * FB_ALPHA) + (FB_A1 * (1.0-FB_ALPHA)) - FB_B1 * FB_X;
Which reduces to:
buffer[MIX_DEST_B0] = ACC0 + ((FB_A0-ACC0) * FB_ALPHA) - FB_B0 * FB_X;
buffer[MIX_DEST_B1] = ACC1 + ((FB_A1-ACC1) * FB_ALPHA) - FB_B1 * FB_X;
-----------------------------------------------------------------------------
*/

View File

@ -28,12 +28,11 @@ __forceinline s32 V_Core::RevbGetIndexer( s32 offset )
{
u32 pos = ReverbX + offset; //*4);
// Need to use modulus here, because games can and will drop the buffer size
// without notice, and it leads to offsets several times past the end of the buffer.
// Fast and simple single step wrapping, made possible by the preparation of the
// effects buffer addresses.
if( pos > EffectsEndA )
{
//pos = EffectsStartA + ((ReverbX + offset) % (u32)EffectsBufferSize);
pos -= EffectsEndA+1;
pos += EffectsStartA;
}
@ -96,10 +95,10 @@ StereoOut32 V_Core::DoReverb( const StereoOut32& Input )
const u32 dest_b0 = RevbGetIndexer( RevBuffers.IIR_DEST_B0 );
const u32 dest_b1 = RevbGetIndexer( RevBuffers.IIR_DEST_B1 );
const u32 dest2_a0 = RevbGetIndexer( RevBuffers.IIR_DEST_A0 + 4 );
const u32 dest2_a1 = RevbGetIndexer( RevBuffers.IIR_DEST_A1 + 4 );
const u32 dest2_b0 = RevbGetIndexer( RevBuffers.IIR_DEST_B0 + 4 );
const u32 dest2_b1 = RevbGetIndexer( RevBuffers.IIR_DEST_B1 + 4 );
const u32 dest2_a0 = RevbGetIndexer( RevBuffers.IIR_DEST_A0 + 2 );
const u32 dest2_a1 = RevbGetIndexer( RevBuffers.IIR_DEST_A1 + 2 );
const u32 dest2_b0 = RevbGetIndexer( RevBuffers.IIR_DEST_B0 + 2 );
const u32 dest2_b1 = RevbGetIndexer( RevBuffers.IIR_DEST_B1 + 2 );
const u32 acc_src_a0 = RevbGetIndexer( RevBuffers.ACC_SRC_A0 );
const u32 acc_src_b0 = RevbGetIndexer( RevBuffers.ACC_SRC_B0 );
@ -141,15 +140,8 @@ StereoOut32 V_Core::DoReverb( const StereoOut32& Input )
const s32 IIR_INPUT_B0 = ((_spu2mem[src_b0] * Revb.IIR_COEF) + (INPUT_SAMPLE.Left * Revb.IN_COEF_L))>>16;
const s32 IIR_INPUT_B1 = ((_spu2mem[src_b1] * Revb.IIR_COEF) + (INPUT_SAMPLE.Right * Revb.IN_COEF_R))>>16;
/*const s32 IIR_A0 = (IIR_INPUT_A0 * Revb.IIR_ALPHA) + (_spu2mem[dest_a0] * (0xffff - Revb.IIR_ALPHA));
const s32 IIR_A1 = (IIR_INPUT_A1 * Revb.IIR_ALPHA) + (_spu2mem[dest_a1] * (0xffff - Revb.IIR_ALPHA));
const s32 IIR_B0 = (IIR_INPUT_B0 * Revb.IIR_ALPHA) + (_spu2mem[dest_b0] * (0xffff - Revb.IIR_ALPHA));
const s32 IIR_B1 = (IIR_INPUT_B1 * Revb.IIR_ALPHA) + (_spu2mem[dest_b1] * (0xffff - Revb.IIR_ALPHA));
_spu2mem[dest2_a0] = clamp_mix( IIR_A0 >> 16 );
_spu2mem[dest2_a1] = clamp_mix( IIR_A1 >> 16 );
_spu2mem[dest2_b0] = clamp_mix( IIR_B0 >> 16 );
_spu2mem[dest2_b1] = clamp_mix( IIR_B1 >> 16 );*/
// This section differs from Neill's doc as it uses single-mul interpolation instead
// of 0x8000-val inversion. (same result, faster)
const s32 IIR_A0 = IIR_INPUT_A0 + (((_spu2mem[dest_a0]-IIR_INPUT_A0) * Revb.IIR_ALPHA)>>16);
const s32 IIR_A1 = IIR_INPUT_A1 + (((_spu2mem[dest_a1]-IIR_INPUT_A1) * Revb.IIR_ALPHA)>>16);
const s32 IIR_B0 = IIR_INPUT_B0 + (((_spu2mem[dest_b0]-IIR_INPUT_B0) * Revb.IIR_ALPHA)>>16);
@ -164,37 +156,32 @@ StereoOut32 V_Core::DoReverb( const StereoOut32& Input )
((_spu2mem[acc_src_b0] * Revb.ACC_COEF_B)) +
((_spu2mem[acc_src_c0] * Revb.ACC_COEF_C)) +
((_spu2mem[acc_src_d0] * Revb.ACC_COEF_D))
) >> 16;
); // >> 16;
const s32 ACC1 = (
((_spu2mem[acc_src_a1] * Revb.ACC_COEF_A)) +
((_spu2mem[acc_src_b1] * Revb.ACC_COEF_B)) +
((_spu2mem[acc_src_c1] * Revb.ACC_COEF_C)) +
((_spu2mem[acc_src_d1] * Revb.ACC_COEF_D))
) >> 16;
); // >> 16;
// The following code differs from Neill's doc as it uses the more natural single-mul
// interpolative, instead of the funky ^0x8000 stuff. (better result, faster)
const s32 FB_A0 = (_spu2mem[fb_src_a0] * Revb.FB_ALPHA) >> 16;
const s32 FB_A1 = (_spu2mem[fb_src_a1] * Revb.FB_ALPHA) >> 16;
const s32 FB_A0 = _spu2mem[fb_src_a0] * Revb.FB_ALPHA;
const s32 FB_A1 = _spu2mem[fb_src_a1] * Revb.FB_ALPHA;
_spu2mem[mix_dest_a0] = clamp_mix( ACC0 - FB_A0 );
_spu2mem[mix_dest_a1] = clamp_mix( ACC1 - FB_A1 );
_spu2mem[mix_dest_a0] = clamp_mix( (ACC0 - FB_A0) >> 16 );
_spu2mem[mix_dest_a1] = clamp_mix( (ACC1 - FB_A1) >> 16 );
const s32 acc_fb_mix_a = ACC0 + (((_spu2mem[fb_src_a0] - ACC0) * Revb.FB_ALPHA)>>16);
const s32 acc_fb_mix_b = ACC1 + (((_spu2mem[fb_src_a1] - ACC1) * Revb.FB_ALPHA)>>16);
_spu2mem[mix_dest_b0] = clamp_mix( acc_fb_mix_a - ((_spu2mem[fb_src_b0] * Revb.FB_X) >> 16) );
_spu2mem[mix_dest_b1] = clamp_mix( acc_fb_mix_b - ((_spu2mem[fb_src_b1] * Revb.FB_X) >> 16) );
const s32 acc_fb_mix_a = ACC0 + ( (_spu2mem[fb_src_a0] - (ACC0>>16)) * Revb.FB_ALPHA );
const s32 acc_fb_mix_b = ACC1 + ( (_spu2mem[fb_src_a1] - (ACC1>>16)) * Revb.FB_ALPHA );
_spu2mem[mix_dest_b0] = clamp_mix( ( acc_fb_mix_a - (_spu2mem[fb_src_b0] * Revb.FB_X) ) >> 16 );
_spu2mem[mix_dest_b1] = clamp_mix( ( acc_fb_mix_b - (_spu2mem[fb_src_b1] * Revb.FB_X) ) >> 16 );
//const s32 fb_xor_a0 = _spu2mem[fb_src_a0] * ( Revb.FB_ALPHA ^ 0x8000 );
//const s32 fb_xor_a1 = _spu2mem[fb_src_a1] * ( Revb.FB_ALPHA ^ 0x8000 );
//_spu2mem[mix_dest_b0] = clamp_mix( (MulShr32(Revb.FB_ALPHA<<16, ACC0) - fb_xor_a0 - (_spu2mem[fb_src_b0] * Revb.FB_X)) >> 16 );
//_spu2mem[mix_dest_b1] = clamp_mix( (MulShr32(Revb.FB_ALPHA<<16, ACC1) - fb_xor_a1 - (_spu2mem[fb_src_b1] * Revb.FB_X)) >> 16 );
// Note: According Neill these should be divided by 3, but currently the
// output is way too quiet for that to fly.
upbuf[ubpos] = clamp_mix( StereoOut32(
(_spu2mem[mix_dest_a0] + _spu2mem[mix_dest_b0]) / 2, // left
(_spu2mem[mix_dest_a1] + _spu2mem[mix_dest_b1]) / 2 // right
(_spu2mem[mix_dest_a0] + _spu2mem[mix_dest_b0]), // left
(_spu2mem[mix_dest_a1] + _spu2mem[mix_dest_b1]) // right
) );
}
@ -205,8 +192,19 @@ StereoOut32 V_Core::DoReverb( const StereoOut32& Input )
retval.Left += (upbuf[(ubpos+x)&7].Left*downcoeffs[x]);
retval.Right += (upbuf[(ubpos+x)&7].Right*downcoeffs[x]);
}
retval.Left >>= (16-1); /* -1 To adjust for the null padding. */
retval.Right >>= (16-1);
// Notes:
// the first -1 is to adjust for the null padding in every other upbuf sample (which
// halves the overall volume).
// The second -1 divides by two, which is part of Neill's suggestion to divide by 3.
//
// According Neill the final result should be divided by 3, but currently the output
// is way too quiet for that to fly. In fact no division at all might be better.
// In any case the problem always seems to be that the reverb isn't resonating enough
// (indicating short buffers or bad coefficient math?), not that it isn't loud enough.
retval.Left >>= (16-1 + 1);
retval.Right >>= (16-1 + 1);
ubpos = (ubpos+1) & 7;

View File

@ -25,7 +25,7 @@ namespace Savestate
// versioning for saves.
// Increment this when changes to the savestate system are made.
static const u32 SAVE_VERSION = 0x0005;
static const u32 SAVE_VERSION = 0x0006;
static void wipe_the_cache()
{

View File

@ -161,18 +161,18 @@ void V_Core::Reset( int index )
s32 V_Core::EffectsBufferIndexer( s32 offset ) const
{
u32 pos = EffectsStartA + (offset*4);
u32 pos = EffectsStartA + offset;
// Need to use modulus here, because games can and will drop the buffer size
// without notice, and it leads to offsets several times past the end of the buffer.
if( pos > EffectsEndA )
{
pos = EffectsStartA + ((offset*4) % EffectsBufferSize);
pos = EffectsStartA + (offset % EffectsBufferSize);
}
else if( pos < EffectsStartA )
{
pos = EffectsEndA+1 - ((offset*4) % EffectsBufferSize );
pos = EffectsEndA+1 - (offset % EffectsBufferSize );
}
return pos;
}