mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
b0b928d4f4
commit
1cc740a9c0
|
@ -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;
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue