mirror of https://github.com/PCSX2/pcsx2.git
commit
820462dbc0
|
@ -216,39 +216,39 @@ void DoFullDump()
|
|||
fprintf(dump, " - IN_COEF_L: %x\n", Cores[c].Revb.IN_COEF_R);
|
||||
fprintf(dump, " - IN_COEF_R: %x\n", Cores[c].Revb.IN_COEF_L);
|
||||
|
||||
fprintf(dump, " - FB_ALPHA: %x\n", Cores[c].Revb.FB_ALPHA);
|
||||
fprintf(dump, " - FB_X: %x\n", Cores[c].Revb.FB_X);
|
||||
fprintf(dump, " - FB_SRC_A: %x\n", Cores[c].Revb.FB_SRC_A);
|
||||
fprintf(dump, " - FB_SRC_B: %x\n", Cores[c].Revb.FB_SRC_B);
|
||||
fprintf(dump, " - APF1_VOL: %x\n", Cores[c].Revb.APF1_VOL);
|
||||
fprintf(dump, " - APF2_VOL: %x\n", Cores[c].Revb.APF2_VOL);
|
||||
fprintf(dump, " - APF1_SIZE: %x\n", Cores[c].Revb.APF1_SIZE);
|
||||
fprintf(dump, " - APF2_SIZE: %x\n", Cores[c].Revb.APF2_SIZE);
|
||||
|
||||
fprintf(dump, " - IIR_ALPHA: %x\n", Cores[c].Revb.IIR_ALPHA);
|
||||
fprintf(dump, " - IIR_COEF: %x\n", Cores[c].Revb.IIR_COEF);
|
||||
fprintf(dump, " - IIR_SRC_A0: %x\n", Cores[c].Revb.IIR_SRC_A0);
|
||||
fprintf(dump, " - IIR_SRC_A1: %x\n", Cores[c].Revb.IIR_SRC_A1);
|
||||
fprintf(dump, " - IIR_SRC_B1: %x\n", Cores[c].Revb.IIR_SRC_B0);
|
||||
fprintf(dump, " - IIR_SRC_B0: %x\n", Cores[c].Revb.IIR_SRC_B1);
|
||||
fprintf(dump, " - IIR_DEST_A0: %x\n", Cores[c].Revb.IIR_DEST_A0);
|
||||
fprintf(dump, " - IIR_DEST_A1: %x\n", Cores[c].Revb.IIR_DEST_A1);
|
||||
fprintf(dump, " - IIR_DEST_B0: %x\n", Cores[c].Revb.IIR_DEST_B0);
|
||||
fprintf(dump, " - IIR_DEST_B1: %x\n", Cores[c].Revb.IIR_DEST_B1);
|
||||
fprintf(dump, " - IIR_VOL: %x\n", Cores[c].Revb.IIR_VOL);
|
||||
fprintf(dump, " - WALL_VOL: %x\n", Cores[c].Revb.WALL_VOL);
|
||||
fprintf(dump, " - SAME_L_SRC: %x\n", Cores[c].Revb.SAME_L_SRC);
|
||||
fprintf(dump, " - SAME_R_SRC: %x\n", Cores[c].Revb.SAME_R_SRC);
|
||||
fprintf(dump, " - DIFF_L_SRC: %x\n", Cores[c].Revb.DIFF_L_SRC);
|
||||
fprintf(dump, " - DIFF_R_SRC: %x\n", Cores[c].Revb.DIFF_R_SRC);
|
||||
fprintf(dump, " - SAME_L_DST: %x\n", Cores[c].Revb.SAME_L_DST);
|
||||
fprintf(dump, " - SAME_R_DST: %x\n", Cores[c].Revb.SAME_R_DST);
|
||||
fprintf(dump, " - DIFF_L_DST: %x\n", Cores[c].Revb.DIFF_L_DST);
|
||||
fprintf(dump, " - DIFF_R_DST: %x\n", Cores[c].Revb.DIFF_R_DST);
|
||||
|
||||
fprintf(dump, " - ACC_COEF_A: %x\n", Cores[c].Revb.ACC_COEF_A);
|
||||
fprintf(dump, " - ACC_COEF_B: %x\n", Cores[c].Revb.ACC_COEF_B);
|
||||
fprintf(dump, " - ACC_COEF_C: %x\n", Cores[c].Revb.ACC_COEF_C);
|
||||
fprintf(dump, " - ACC_COEF_D: %x\n", Cores[c].Revb.ACC_COEF_D);
|
||||
fprintf(dump, " - ACC_SRC_A0: %x\n", Cores[c].Revb.ACC_SRC_A0);
|
||||
fprintf(dump, " - ACC_SRC_A1: %x\n", Cores[c].Revb.ACC_SRC_A1);
|
||||
fprintf(dump, " - ACC_SRC_B0: %x\n", Cores[c].Revb.ACC_SRC_B0);
|
||||
fprintf(dump, " - ACC_SRC_B1: %x\n", Cores[c].Revb.ACC_SRC_B1);
|
||||
fprintf(dump, " - ACC_SRC_C0: %x\n", Cores[c].Revb.ACC_SRC_C0);
|
||||
fprintf(dump, " - ACC_SRC_C1: %x\n", Cores[c].Revb.ACC_SRC_C1);
|
||||
fprintf(dump, " - ACC_SRC_D0: %x\n", Cores[c].Revb.ACC_SRC_D0);
|
||||
fprintf(dump, " - ACC_SRC_D1: %x\n", Cores[c].Revb.ACC_SRC_D1);
|
||||
fprintf(dump, " - COMB1_VOL: %x\n", Cores[c].Revb.COMB1_VOL);
|
||||
fprintf(dump, " - COMB2_VOL: %x\n", Cores[c].Revb.COMB2_VOL);
|
||||
fprintf(dump, " - COMB3_VOL: %x\n", Cores[c].Revb.COMB3_VOL);
|
||||
fprintf(dump, " - COMB4_VOL: %x\n", Cores[c].Revb.COMB4_VOL);
|
||||
fprintf(dump, " - COMB1_L_SRC: %x\n", Cores[c].Revb.COMB1_L_SRC);
|
||||
fprintf(dump, " - COMB1_R_SRC: %x\n", Cores[c].Revb.COMB1_R_SRC);
|
||||
fprintf(dump, " - COMB2_L_SRC: %x\n", Cores[c].Revb.COMB2_L_SRC);
|
||||
fprintf(dump, " - COMB2_R_SRC: %x\n", Cores[c].Revb.COMB2_R_SRC);
|
||||
fprintf(dump, " - COMB3_L_SRC: %x\n", Cores[c].Revb.COMB3_L_SRC);
|
||||
fprintf(dump, " - COMB3_R_SRC: %x\n", Cores[c].Revb.COMB3_R_SRC);
|
||||
fprintf(dump, " - COMB4_L_SRC: %x\n", Cores[c].Revb.COMB4_L_SRC);
|
||||
fprintf(dump, " - COMB4_R_SRC: %x\n", Cores[c].Revb.COMB4_R_SRC);
|
||||
|
||||
fprintf(dump, " - MIX_DEST_A0: %x\n", Cores[c].Revb.MIX_DEST_A0);
|
||||
fprintf(dump, " - MIX_DEST_A1: %x\n", Cores[c].Revb.MIX_DEST_A1);
|
||||
fprintf(dump, " - MIX_DEST_B0: %x\n", Cores[c].Revb.MIX_DEST_B0);
|
||||
fprintf(dump, " - MIX_DEST_B1: %x\n", Cores[c].Revb.MIX_DEST_B1);
|
||||
fprintf(dump, " - APF1_L_DST: %x\n", Cores[c].Revb.APF1_L_DST);
|
||||
fprintf(dump, " - APF1_R_DST: %x\n", Cores[c].Revb.APF1_R_DST);
|
||||
fprintf(dump, " - APF2_L_DST: %x\n", Cores[c].Revb.APF2_L_DST);
|
||||
fprintf(dump, " - APF2_R_DST: %x\n", Cores[c].Revb.APF2_R_DST);
|
||||
fprintf(dump, "#### END OF DUMP.\n\n");
|
||||
}
|
||||
fclose(dump);
|
||||
|
|
|
@ -675,6 +675,7 @@ StereoOut32 V_Core::Mix(const VoiceMixSet &inVoices, const StereoOut32 &Input, c
|
|||
|
||||
// ToDo:
|
||||
// Bad EndA causes memory corruption. Bad for us, unknown on PS2!
|
||||
// According to no$psx, effects always run but don't always write back, so the FxEnable check may be wrong
|
||||
if (!FxEnable || EffectsEndA >= 0x100000)
|
||||
return TD;
|
||||
|
||||
|
@ -886,194 +887,3 @@ __forceinline
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
PSX reverb hardware notes
|
||||
by Neill Corlett
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Yadda yadda disclaimer yadda probably not perfect yadda well it's okay anyway
|
||||
yadda yadda.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Basics
|
||||
------
|
||||
|
||||
- The reverb buffer is 22khz 16-bit mono PCM.
|
||||
- It starts at the reverb address given by 1DA2, extends to
|
||||
the end of sound RAM, and wraps back to the 1DA2 address.
|
||||
|
||||
Setting the address at 1DA2 resets the current reverb work address.
|
||||
|
||||
This work address ALWAYS increments every 1/22050 sec., regardless of
|
||||
whether reverb is enabled (bit 7 of 1DAA set).
|
||||
|
||||
And the contents of the reverb buffer ALWAYS play, scaled by the
|
||||
"reverberation depth left/right" volumes (1D84/1D86).
|
||||
(which, by the way, appear to be scaled so 3FFF=approx. 1.0, 4000=-1.0)
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Register names
|
||||
--------------
|
||||
|
||||
These are probably not their real names.
|
||||
These are probably not even correct names.
|
||||
We will use them anyway, because we can.
|
||||
|
||||
1DC0: FB_SRC_A (offset)
|
||||
1DC2: FB_SRC_B (offset)
|
||||
1DC4: IIR_ALPHA (coef.)
|
||||
1DC6: ACC_COEF_A (coef.)
|
||||
1DC8: ACC_COEF_B (coef.)
|
||||
1DCA: ACC_COEF_C (coef.)
|
||||
1DCC: ACC_COEF_D (coef.)
|
||||
1DCE: IIR_COEF (coef.)
|
||||
1DD0: FB_ALPHA (coef.)
|
||||
1DD2: FB_X (coef.)
|
||||
1DD4: IIR_DEST_A0 (offset)
|
||||
1DD6: IIR_DEST_A1 (offset)
|
||||
1DD8: ACC_SRC_A0 (offset)
|
||||
1DDA: ACC_SRC_A1 (offset)
|
||||
1DDC: ACC_SRC_B0 (offset)
|
||||
1DDE: ACC_SRC_B1 (offset)
|
||||
1DE0: IIR_SRC_A0 (offset)
|
||||
1DE2: IIR_SRC_A1 (offset)
|
||||
1DE4: IIR_DEST_B0 (offset)
|
||||
1DE6: IIR_DEST_B1 (offset)
|
||||
1DE8: ACC_SRC_C0 (offset)
|
||||
1DEA: ACC_SRC_C1 (offset)
|
||||
1DEC: ACC_SRC_D0 (offset)
|
||||
1DEE: ACC_SRC_D1 (offset)
|
||||
1DF0: IIR_SRC_B1 (offset)
|
||||
1DF2: IIR_SRC_B0 (offset)
|
||||
1DF4: MIX_DEST_A0 (offset)
|
||||
1DF6: MIX_DEST_A1 (offset)
|
||||
1DF8: MIX_DEST_B0 (offset)
|
||||
1DFA: MIX_DEST_B1 (offset)
|
||||
1DFC: IN_COEF_L (coef.)
|
||||
1DFE: IN_COEF_R (coef.)
|
||||
|
||||
The coefficients are signed fractional values.
|
||||
-32768 would be -1.0
|
||||
32768 would be 1.0 (if it were possible... the highest is of course 32767)
|
||||
|
||||
The offsets are (byte/8) offsets into the reverb buffer.
|
||||
i.e. you multiply them by 8, you get byte offsets.
|
||||
You can also think of them as (samples/4) offsets.
|
||||
They appear to be signed. They can be negative.
|
||||
None of the documented presets make them negative, though.
|
||||
|
||||
Yes, 1DF0 and 1DF2 appear to be backwards. Not a typo.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
What it does
|
||||
------------
|
||||
|
||||
We take all reverb sources:
|
||||
- regular channels that have the reverb bit on
|
||||
- cd and external sources, if their reverb bits are on
|
||||
and mix them into one stereo 44100hz signal.
|
||||
|
||||
Lowpass/downsample that to 22050hz. The PSX uses a proper bandlimiting
|
||||
algorithm here, but I haven't figured out the hysterically exact specifics.
|
||||
I use an 8-tap filter with these coefficients, which are nice but probably
|
||||
not the real ones:
|
||||
|
||||
0.037828187894
|
||||
0.157538631280
|
||||
0.321159685278
|
||||
0.449322115345
|
||||
0.449322115345
|
||||
0.321159685278
|
||||
0.157538631280
|
||||
0.037828187894
|
||||
|
||||
So we have two input samples (INPUT_SAMPLE_L, INPUT_SAMPLE_R) every 22050hz.
|
||||
|
||||
* IN MY EMULATION, I divide these by 2 to make it clip less.
|
||||
(and of course the L/R output coefficients are adjusted to compensate)
|
||||
The real thing appears to not do this.
|
||||
|
||||
At every 22050hz tick:
|
||||
- If the reverb bit is enabled (bit 7 of 1DAA), execute the reverb
|
||||
steady-state algorithm described below
|
||||
- AFTERWARDS, retrieve the "wet out" L and R samples from the reverb buffer
|
||||
(This part may not be exactly right and I guessed at the coefs. TODO: check later.)
|
||||
L is: 0.333 * (buffer[MIX_DEST_A0] + buffer[MIX_DEST_B0])
|
||||
R is: 0.333 * (buffer[MIX_DEST_A1] + buffer[MIX_DEST_B1])
|
||||
- Advance the current buffer position by 1 sample
|
||||
|
||||
The wet out L and R are then upsampled to 44100hz and played at the
|
||||
"reverberation depth left/right" (1D84/1D86) volume, independent of the main
|
||||
volume.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Reverb steady-state
|
||||
-------------------
|
||||
|
||||
The reverb steady-state algorithm is fairly clever, and of course by
|
||||
"clever" I mean "batshit insane".
|
||||
|
||||
buffer[x] is relative to the current buffer position, not the beginning of
|
||||
the buffer. Note that all buffer offsets must wrap around so they're
|
||||
contained within the reverb work area.
|
||||
|
||||
Clipping is performed at the end... maybe also sooner, but definitely at
|
||||
the end.
|
||||
|
||||
IIR_INPUT_A0 = buffer[IIR_SRC_A0] * IIR_COEF + INPUT_SAMPLE_L * IN_COEF_L;
|
||||
IIR_INPUT_A1 = buffer[IIR_SRC_A1] * IIR_COEF + INPUT_SAMPLE_R * IN_COEF_R;
|
||||
IIR_INPUT_B0 = buffer[IIR_SRC_B0] * IIR_COEF + INPUT_SAMPLE_L * IN_COEF_L;
|
||||
IIR_INPUT_B1 = buffer[IIR_SRC_B1] * IIR_COEF + INPUT_SAMPLE_R * IN_COEF_R;
|
||||
|
||||
IIR_A0 = IIR_INPUT_A0 * IIR_ALPHA + buffer[IIR_DEST_A0] * (1.0 - IIR_ALPHA);
|
||||
IIR_A1 = IIR_INPUT_A1 * IIR_ALPHA + buffer[IIR_DEST_A1] * (1.0 - IIR_ALPHA);
|
||||
IIR_B0 = IIR_INPUT_B0 * IIR_ALPHA + buffer[IIR_DEST_B0] * (1.0 - IIR_ALPHA);
|
||||
IIR_B1 = IIR_INPUT_B1 * IIR_ALPHA + buffer[IIR_DEST_B1] * (1.0 - IIR_ALPHA);
|
||||
|
||||
buffer[IIR_DEST_A0 + 1sample] = IIR_A0;
|
||||
buffer[IIR_DEST_A1 + 1sample] = IIR_A1;
|
||||
buffer[IIR_DEST_B0 + 1sample] = IIR_B0;
|
||||
buffer[IIR_DEST_B1 + 1sample] = IIR_B1;
|
||||
|
||||
ACC0 = buffer[ACC_SRC_A0] * ACC_COEF_A +
|
||||
buffer[ACC_SRC_B0] * ACC_COEF_B +
|
||||
buffer[ACC_SRC_C0] * ACC_COEF_C +
|
||||
buffer[ACC_SRC_D0] * ACC_COEF_D;
|
||||
ACC1 = buffer[ACC_SRC_A1] * ACC_COEF_A +
|
||||
buffer[ACC_SRC_B1] * ACC_COEF_B +
|
||||
buffer[ACC_SRC_C1] * ACC_COEF_C +
|
||||
buffer[ACC_SRC_D1] * ACC_COEF_D;
|
||||
|
||||
FB_A0 = buffer[MIX_DEST_A0 - FB_SRC_A];
|
||||
FB_A1 = buffer[MIX_DEST_A1 - FB_SRC_A];
|
||||
FB_B0 = buffer[MIX_DEST_B0 - FB_SRC_B];
|
||||
FB_B1 = buffer[MIX_DEST_B1 - FB_SRC_B];
|
||||
|
||||
buffer[MIX_DEST_A0] = ACC0 - FB_A0 * FB_ALPHA;
|
||||
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] = FB_A0 + ((ACC0-FB_A0) * FB_ALPHA) - FB_B0 * FB_X;
|
||||
buffer[MIX_DEST_B1] = FB_A1 + ((ACC1-FB_A1) * FB_ALPHA) - FB_B1 * FB_X;
|
||||
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
|
|
@ -93,29 +93,29 @@ void SPU2writeLog(const char *action, u32 rmem, u16 value)
|
|||
case REG_P_MVOLXR:
|
||||
RegLog(2, "MVOLXR", rmem, core, value);
|
||||
break;
|
||||
case R_IIR_ALPHA:
|
||||
RegLog(2, "IIR_ALPHA", rmem, core, value);
|
||||
case R_IIR_VOL:
|
||||
RegLog(2, "IIR_VOL", rmem, core, value);
|
||||
break;
|
||||
case R_ACC_COEF_A:
|
||||
RegLog(2, "ACC_COEF_A", rmem, core, value);
|
||||
case R_COMB1_VOL:
|
||||
RegLog(2, "COMB1_VOL", rmem, core, value);
|
||||
break;
|
||||
case R_ACC_COEF_B:
|
||||
RegLog(2, "ACC_COEF_B", rmem, core, value);
|
||||
case R_COMB2_VOL:
|
||||
RegLog(2, "COMB2_VOL", rmem, core, value);
|
||||
break;
|
||||
case R_ACC_COEF_C:
|
||||
RegLog(2, "ACC_COEF_C", rmem, core, value);
|
||||
case R_COMB3_VOL:
|
||||
RegLog(2, "COMB3_VOL", rmem, core, value);
|
||||
break;
|
||||
case R_ACC_COEF_D:
|
||||
RegLog(2, "ACC_COEF_D", rmem, core, value);
|
||||
case R_COMB4_VOL:
|
||||
RegLog(2, "COMB4_VOL", rmem, core, value);
|
||||
break;
|
||||
case R_IIR_COEF:
|
||||
RegLog(2, "IIR_COEF", rmem, core, value);
|
||||
case R_WALL_VOL:
|
||||
RegLog(2, "WALL_VOL", rmem, core, value);
|
||||
break;
|
||||
case R_FB_ALPHA:
|
||||
RegLog(2, "FB_ALPHA", rmem, core, value);
|
||||
case R_APF1_VOL:
|
||||
RegLog(2, "APF1_VOL", rmem, core, value);
|
||||
break;
|
||||
case R_FB_X:
|
||||
RegLog(2, "FB_X", rmem, core, value);
|
||||
case R_APF2_VOL:
|
||||
RegLog(2, "APF2_VOL", rmem, core, value);
|
||||
break;
|
||||
case R_IN_COEF_L:
|
||||
RegLog(2, "IN_COEF_L", rmem, core, value);
|
||||
|
@ -265,28 +265,28 @@ void SPU2writeLog(const char *action, u32 rmem, u16 value)
|
|||
RegLog(2, t "L", mem, core, value); \
|
||||
break;
|
||||
|
||||
LOG_REVB_REG(FB_SRC_A, "FB_SRC_A")
|
||||
LOG_REVB_REG(FB_SRC_B, "FB_SRC_B")
|
||||
LOG_REVB_REG(IIR_SRC_A0, "IIR_SRC_A0")
|
||||
LOG_REVB_REG(IIR_SRC_A1, "IIR_SRC_A1")
|
||||
LOG_REVB_REG(IIR_SRC_B1, "IIR_SRC_B1")
|
||||
LOG_REVB_REG(IIR_SRC_B0, "IIR_SRC_B0")
|
||||
LOG_REVB_REG(IIR_DEST_A0, "IIR_DEST_A0")
|
||||
LOG_REVB_REG(IIR_DEST_A1, "IIR_DEST_A1")
|
||||
LOG_REVB_REG(IIR_DEST_B0, "IIR_DEST_B0")
|
||||
LOG_REVB_REG(IIR_DEST_B1, "IIR_DEST_B1")
|
||||
LOG_REVB_REG(ACC_SRC_A0, "ACC_SRC_A0")
|
||||
LOG_REVB_REG(ACC_SRC_A1, "ACC_SRC_A1")
|
||||
LOG_REVB_REG(ACC_SRC_B0, "ACC_SRC_B0")
|
||||
LOG_REVB_REG(ACC_SRC_B1, "ACC_SRC_B1")
|
||||
LOG_REVB_REG(ACC_SRC_C0, "ACC_SRC_C0")
|
||||
LOG_REVB_REG(ACC_SRC_C1, "ACC_SRC_C1")
|
||||
LOG_REVB_REG(ACC_SRC_D0, "ACC_SRC_D0")
|
||||
LOG_REVB_REG(ACC_SRC_D1, "ACC_SRC_D1")
|
||||
LOG_REVB_REG(MIX_DEST_A0, "MIX_DEST_A0")
|
||||
LOG_REVB_REG(MIX_DEST_A1, "MIX_DEST_A1")
|
||||
LOG_REVB_REG(MIX_DEST_B0, "MIX_DEST_B0")
|
||||
LOG_REVB_REG(MIX_DEST_B1, "MIX_DEST_B1")
|
||||
LOG_REVB_REG(APF1_SIZE, "APF1_SIZE")
|
||||
LOG_REVB_REG(APF2_SIZE, "APF2_SIZE")
|
||||
LOG_REVB_REG(SAME_L_SRC, "SAME_L_SRC")
|
||||
LOG_REVB_REG(SAME_R_SRC, "SAME_R_SRC")
|
||||
LOG_REVB_REG(DIFF_L_SRC, "DIFF_L_SRC")
|
||||
LOG_REVB_REG(DIFF_R_SRC, "DIFF_R_SRC")
|
||||
LOG_REVB_REG(SAME_L_DST, "SAME_L_DST")
|
||||
LOG_REVB_REG(SAME_R_DST, "SAME_R_DST")
|
||||
LOG_REVB_REG(DIFF_L_DST, "DIFF_L_DST")
|
||||
LOG_REVB_REG(DIFF_R_DST, "DIFF_R_DST")
|
||||
LOG_REVB_REG(COMB1_L_SRC, "COMB1_L_SRC")
|
||||
LOG_REVB_REG(COMB1_R_SRC, "COMB1_R_SRC")
|
||||
LOG_REVB_REG(COMB2_L_SRC, "COMB2_L_SRC")
|
||||
LOG_REVB_REG(COMB2_R_SRC, "COMB2_R_SRC")
|
||||
LOG_REVB_REG(COMB3_L_SRC, "COMB3_L_SRC")
|
||||
LOG_REVB_REG(COMB3_R_SRC, "COMB3_R_SRC")
|
||||
LOG_REVB_REG(COMB4_L_SRC, "COMB4_L_SRC")
|
||||
LOG_REVB_REG(COMB4_R_SRC, "COMB4_R_SRC")
|
||||
LOG_REVB_REG(APF1_L_DST, "APF1_L_DST")
|
||||
LOG_REVB_REG(APF1_R_DST, "APF1_R_DST")
|
||||
LOG_REVB_REG(APF2_L_DST, "APF2_L_DST")
|
||||
LOG_REVB_REG(APF2_R_DST, "APF2_R_DST")
|
||||
|
||||
default:
|
||||
RegLog(2, "UNKNOWN", rmem, core, value);
|
||||
|
|
|
@ -99,28 +99,28 @@ u16 const *const regtable_original[0x401] =
|
|||
PCORE(0, ExtEffectsStartA) + 1,
|
||||
PCORE(0, ExtEffectsStartA),
|
||||
|
||||
PREVB_REG(0, FB_SRC_A),
|
||||
PREVB_REG(0, FB_SRC_B),
|
||||
PREVB_REG(0, IIR_DEST_A0),
|
||||
PREVB_REG(0, IIR_DEST_A1),
|
||||
PREVB_REG(0, ACC_SRC_A0),
|
||||
PREVB_REG(0, ACC_SRC_A1),
|
||||
PREVB_REG(0, ACC_SRC_B0),
|
||||
PREVB_REG(0, ACC_SRC_B1),
|
||||
PREVB_REG(0, IIR_SRC_A0),
|
||||
PREVB_REG(0, IIR_SRC_A1),
|
||||
PREVB_REG(0, IIR_DEST_B0),
|
||||
PREVB_REG(0, IIR_DEST_B1),
|
||||
PREVB_REG(0, ACC_SRC_C0),
|
||||
PREVB_REG(0, ACC_SRC_C1),
|
||||
PREVB_REG(0, ACC_SRC_D0),
|
||||
PREVB_REG(0, ACC_SRC_D1),
|
||||
PREVB_REG(0, IIR_SRC_B0),
|
||||
PREVB_REG(0, IIR_SRC_B1),
|
||||
PREVB_REG(0, MIX_DEST_A0),
|
||||
PREVB_REG(0, MIX_DEST_A1),
|
||||
PREVB_REG(0, MIX_DEST_B0),
|
||||
PREVB_REG(0, MIX_DEST_B1),
|
||||
PREVB_REG(0, APF1_SIZE),
|
||||
PREVB_REG(0, APF2_SIZE),
|
||||
PREVB_REG(0, SAME_L_DST),
|
||||
PREVB_REG(0, SAME_R_DST),
|
||||
PREVB_REG(0, COMB1_L_SRC),
|
||||
PREVB_REG(0, COMB1_R_SRC),
|
||||
PREVB_REG(0, COMB2_L_SRC),
|
||||
PREVB_REG(0, COMB2_R_SRC),
|
||||
PREVB_REG(0, SAME_L_SRC),
|
||||
PREVB_REG(0, SAME_R_SRC),
|
||||
PREVB_REG(0, DIFF_L_DST),
|
||||
PREVB_REG(0, DIFF_R_DST),
|
||||
PREVB_REG(0, COMB3_L_SRC),
|
||||
PREVB_REG(0, COMB3_R_SRC),
|
||||
PREVB_REG(0, COMB4_L_SRC),
|
||||
PREVB_REG(0, COMB4_R_SRC),
|
||||
PREVB_REG(0, DIFF_L_SRC),
|
||||
PREVB_REG(0, DIFF_R_SRC),
|
||||
PREVB_REG(0, APF1_L_DST),
|
||||
PREVB_REG(0, APF1_R_DST),
|
||||
PREVB_REG(0, APF2_L_DST),
|
||||
PREVB_REG(0, APF2_R_DST),
|
||||
|
||||
PCORE(0, ExtEffectsEndA) + 1,
|
||||
PCORE(0, ExtEffectsEndA),
|
||||
|
@ -202,28 +202,28 @@ u16 const *const regtable_original[0x401] =
|
|||
PCORE(1, ExtEffectsStartA) + 1,
|
||||
PCORE(1, ExtEffectsStartA),
|
||||
|
||||
PREVB_REG(1, FB_SRC_A),
|
||||
PREVB_REG(1, FB_SRC_B),
|
||||
PREVB_REG(1, IIR_DEST_A0),
|
||||
PREVB_REG(1, IIR_DEST_A1),
|
||||
PREVB_REG(1, ACC_SRC_A0),
|
||||
PREVB_REG(1, ACC_SRC_A1),
|
||||
PREVB_REG(1, ACC_SRC_B0),
|
||||
PREVB_REG(1, ACC_SRC_B1),
|
||||
PREVB_REG(1, IIR_SRC_A0),
|
||||
PREVB_REG(1, IIR_SRC_A1),
|
||||
PREVB_REG(1, IIR_DEST_B0),
|
||||
PREVB_REG(1, IIR_DEST_B1),
|
||||
PREVB_REG(1, ACC_SRC_C0),
|
||||
PREVB_REG(1, ACC_SRC_C1),
|
||||
PREVB_REG(1, ACC_SRC_D0),
|
||||
PREVB_REG(1, ACC_SRC_D1),
|
||||
PREVB_REG(1, IIR_SRC_B0),
|
||||
PREVB_REG(1, IIR_SRC_B1),
|
||||
PREVB_REG(1, MIX_DEST_A0),
|
||||
PREVB_REG(1, MIX_DEST_A1),
|
||||
PREVB_REG(1, MIX_DEST_B0),
|
||||
PREVB_REG(1, MIX_DEST_B1),
|
||||
PREVB_REG(1, APF1_SIZE),
|
||||
PREVB_REG(1, APF2_SIZE),
|
||||
PREVB_REG(1, SAME_L_DST),
|
||||
PREVB_REG(1, SAME_R_DST),
|
||||
PREVB_REG(1, COMB1_L_SRC),
|
||||
PREVB_REG(1, COMB1_R_SRC),
|
||||
PREVB_REG(1, COMB2_L_SRC),
|
||||
PREVB_REG(1, COMB2_R_SRC),
|
||||
PREVB_REG(1, SAME_L_SRC),
|
||||
PREVB_REG(1, SAME_R_SRC),
|
||||
PREVB_REG(1, DIFF_L_DST),
|
||||
PREVB_REG(1, DIFF_R_DST),
|
||||
PREVB_REG(1, COMB3_L_SRC),
|
||||
PREVB_REG(1, COMB3_R_SRC),
|
||||
PREVB_REG(1, COMB4_L_SRC),
|
||||
PREVB_REG(1, COMB4_R_SRC),
|
||||
PREVB_REG(1, DIFF_L_SRC),
|
||||
PREVB_REG(1, DIFF_R_SRC),
|
||||
PREVB_REG(1, APF1_L_DST),
|
||||
PREVB_REG(1, APF1_R_DST),
|
||||
PREVB_REG(1, APF2_L_DST),
|
||||
PREVB_REG(1, APF2_R_DST),
|
||||
|
||||
PCORE(1, ExtEffectsEndA) + 1,
|
||||
PCORE(1, ExtEffectsEndA),
|
||||
|
@ -248,14 +248,14 @@ u16 const *const regtable_original[0x401] =
|
|||
PCORE(0, InpVol.Right) + 1,
|
||||
PCORE(0, MasterVol.Left.Value) + 1,
|
||||
PCORE(0, MasterVol.Right.Value) + 1,
|
||||
PCORE(0, Revb.IIR_ALPHA),
|
||||
PCORE(0, Revb.ACC_COEF_A),
|
||||
PCORE(0, Revb.ACC_COEF_B),
|
||||
PCORE(0, Revb.ACC_COEF_C),
|
||||
PCORE(0, Revb.ACC_COEF_D),
|
||||
PCORE(0, Revb.IIR_COEF),
|
||||
PCORE(0, Revb.FB_ALPHA),
|
||||
PCORE(0, Revb.FB_X),
|
||||
PCORE(0, Revb.IIR_VOL),
|
||||
PCORE(0, Revb.COMB1_VOL),
|
||||
PCORE(0, Revb.COMB2_VOL),
|
||||
PCORE(0, Revb.COMB3_VOL),
|
||||
PCORE(0, Revb.COMB4_VOL),
|
||||
PCORE(0, Revb.WALL_VOL),
|
||||
PCORE(0, Revb.APF1_VOL),
|
||||
PCORE(0, Revb.APF2_VOL),
|
||||
PCORE(0, Revb.IN_COEF_L),
|
||||
PCORE(0, Revb.IN_COEF_R),
|
||||
|
||||
|
@ -269,14 +269,14 @@ u16 const *const regtable_original[0x401] =
|
|||
PCORE(1, InpVol.Right) + 1,
|
||||
PCORE(1, MasterVol.Left.Value) + 1,
|
||||
PCORE(1, MasterVol.Right.Value) + 1,
|
||||
PCORE(1, Revb.IIR_ALPHA),
|
||||
PCORE(1, Revb.ACC_COEF_A),
|
||||
PCORE(1, Revb.ACC_COEF_B),
|
||||
PCORE(1, Revb.ACC_COEF_C),
|
||||
PCORE(1, Revb.ACC_COEF_D),
|
||||
PCORE(1, Revb.IIR_COEF),
|
||||
PCORE(1, Revb.FB_ALPHA),
|
||||
PCORE(1, Revb.FB_X),
|
||||
PCORE(1, Revb.IIR_VOL),
|
||||
PCORE(1, Revb.COMB1_VOL),
|
||||
PCORE(1, Revb.COMB2_VOL),
|
||||
PCORE(1, Revb.COMB3_VOL),
|
||||
PCORE(1, Revb.COMB4_VOL),
|
||||
PCORE(1, Revb.WALL_VOL),
|
||||
PCORE(1, Revb.APF1_VOL),
|
||||
PCORE(1, Revb.APF2_VOL),
|
||||
PCORE(1, Revb.IN_COEF_L),
|
||||
PCORE(1, Revb.IN_COEF_R),
|
||||
|
||||
|
|
|
@ -16,13 +16,6 @@
|
|||
*/
|
||||
|
||||
#include "Global.h"
|
||||
#include "Lowpass.h"
|
||||
|
||||
// Low pass filters: Change these to 32 for a speedup (benchmarks needed to see if
|
||||
// the speed gain is worth the quality drop)
|
||||
|
||||
//static LowPassFilter64 lowpass_left( 11000, SampleRate );
|
||||
//static LowPassFilter64 lowpass_right( 11000, SampleRate );
|
||||
|
||||
__forceinline s32 V_Core::RevbGetIndexer(s32 offset)
|
||||
{
|
||||
|
@ -56,215 +49,85 @@ void V_Core::Reverb_AdvanceBuffer()
|
|||
|
||||
StereoOut32 V_Core::DoReverb(const StereoOut32 &Input)
|
||||
{
|
||||
#if 0
|
||||
static const s32 downcoeffs[8] =
|
||||
{
|
||||
1283, 5344, 10895, 15243,
|
||||
15243, 10895, 5344, 1283
|
||||
};
|
||||
#else
|
||||
// 2/3 of the above
|
||||
static const s32 downcoeffs[8] =
|
||||
{
|
||||
855, 3562, 7263, 10163,
|
||||
10163, 7263, 3562, 855};
|
||||
#endif
|
||||
if (EffectsBufferSize <= 0) {
|
||||
return StereoOut32::Empty;
|
||||
}
|
||||
|
||||
downbuf[dbpos] = Input;
|
||||
dbpos = (dbpos + 1) & 7;
|
||||
bool R = Cycles & 1;
|
||||
|
||||
// Reverb processing occurs at 24khz, so we skip processing every other sample,
|
||||
// and use the previous calculation for this core instead.
|
||||
// Calculate the read/write addresses we'll be needing for this session of reverb.
|
||||
|
||||
if ((Cycles & 1) == 0) {
|
||||
// Important: Factor silence into the upsampler here, otherwise the reverb engine
|
||||
// develops a nasty feedback loop.
|
||||
const u32 same_src = RevbGetIndexer(R ? RevBuffers.SAME_R_SRC : RevBuffers.SAME_L_SRC);
|
||||
const u32 same_dst = RevbGetIndexer(R ? RevBuffers.SAME_R_DST : RevBuffers.SAME_L_DST);
|
||||
const u32 same_prv = RevbGetIndexer(R ? RevBuffers.SAME_R_PRV : RevBuffers.SAME_L_PRV);
|
||||
|
||||
upbuf[ubpos] = StereoOut32::Empty;
|
||||
} else {
|
||||
if (EffectsBufferSize <= 0) {
|
||||
ubpos = (ubpos + 1) & 7;
|
||||
return StereoOut32::Empty;
|
||||
}
|
||||
const u32 diff_src = RevbGetIndexer(R ? RevBuffers.DIFF_L_SRC : RevBuffers.DIFF_R_SRC);
|
||||
const u32 diff_dst = RevbGetIndexer(R ? RevBuffers.DIFF_R_DST : RevBuffers.DIFF_L_DST);
|
||||
const u32 diff_prv = RevbGetIndexer(R ? RevBuffers.DIFF_R_PRV : RevBuffers.DIFF_L_PRV);
|
||||
|
||||
// Advance the current reverb buffer pointer, and cache the read/write addresses we'll be
|
||||
// needing for this session of reverb.
|
||||
const u32 comb1_src = RevbGetIndexer(R ? RevBuffers.COMB1_R_SRC : RevBuffers.COMB1_L_SRC);
|
||||
const u32 comb2_src = RevbGetIndexer(R ? RevBuffers.COMB2_R_SRC : RevBuffers.COMB2_L_SRC);
|
||||
const u32 comb3_src = RevbGetIndexer(R ? RevBuffers.COMB3_R_SRC : RevBuffers.COMB3_L_SRC);
|
||||
const u32 comb4_src = RevbGetIndexer(R ? RevBuffers.COMB4_R_SRC : RevBuffers.COMB4_L_SRC);
|
||||
|
||||
const u32 src_a0 = RevbGetIndexer(RevBuffers.IIR_SRC_A0);
|
||||
const u32 src_a1 = RevbGetIndexer(RevBuffers.IIR_SRC_A1);
|
||||
const u32 src_b0 = RevbGetIndexer(RevBuffers.IIR_SRC_B0);
|
||||
const u32 src_b1 = RevbGetIndexer(RevBuffers.IIR_SRC_B1);
|
||||
const u32 apf1_src = RevbGetIndexer(R ? RevBuffers.APF1_R_SRC : RevBuffers.APF1_L_SRC);
|
||||
const u32 apf1_dst = RevbGetIndexer(R ? RevBuffers.APF1_R_DST : RevBuffers.APF1_L_DST);
|
||||
const u32 apf2_src = RevbGetIndexer(R ? RevBuffers.APF2_R_SRC : RevBuffers.APF2_L_SRC);
|
||||
const u32 apf2_dst = RevbGetIndexer(R ? RevBuffers.APF2_R_DST : RevBuffers.APF2_L_DST);
|
||||
|
||||
const u32 dest_a0 = RevbGetIndexer(RevBuffers.IIR_DEST_A0);
|
||||
const u32 dest_a1 = RevbGetIndexer(RevBuffers.IIR_DEST_A1);
|
||||
const u32 dest_b0 = RevbGetIndexer(RevBuffers.IIR_DEST_B0);
|
||||
const u32 dest_b1 = RevbGetIndexer(RevBuffers.IIR_DEST_B1);
|
||||
// -----------------------------------------
|
||||
// Optimized IRQ Testing !
|
||||
// -----------------------------------------
|
||||
|
||||
const u32 dest2_a0 = RevbGetIndexer(RevBuffers.IIR_DEST_A0 + 1);
|
||||
const u32 dest2_a1 = RevbGetIndexer(RevBuffers.IIR_DEST_A1 + 1);
|
||||
const u32 dest2_b0 = RevbGetIndexer(RevBuffers.IIR_DEST_B0 + 1);
|
||||
const u32 dest2_b1 = RevbGetIndexer(RevBuffers.IIR_DEST_B1 + 1);
|
||||
// This test is enhanced by using the reverb effects area begin/end test as a
|
||||
// shortcut, since all buffer addresses are within that area. If the IRQA isn't
|
||||
// within that zone then the "bulk" of the test is skipped, so this should only
|
||||
// be a slowdown on a few evil games.
|
||||
|
||||
const u32 acc_src_a0 = RevbGetIndexer(RevBuffers.ACC_SRC_A0);
|
||||
const u32 acc_src_b0 = RevbGetIndexer(RevBuffers.ACC_SRC_B0);
|
||||
const u32 acc_src_c0 = RevbGetIndexer(RevBuffers.ACC_SRC_C0);
|
||||
const u32 acc_src_d0 = RevbGetIndexer(RevBuffers.ACC_SRC_D0);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (Cores[i].IRQEnable && ((Cores[i].IRQA >= EffectsStartA) && (Cores[i].IRQA <= EffectsEndA))) {
|
||||
if ((Cores[i].IRQA == same_src) || (Cores[i].IRQA == diff_src) ||
|
||||
(Cores[i].IRQA == same_dst) || (Cores[i].IRQA == diff_dst) ||
|
||||
(Cores[i].IRQA == same_prv) || (Cores[i].IRQA == diff_prv) ||
|
||||
|
||||
const u32 acc_src_a1 = RevbGetIndexer(RevBuffers.ACC_SRC_A1);
|
||||
const u32 acc_src_b1 = RevbGetIndexer(RevBuffers.ACC_SRC_B1);
|
||||
const u32 acc_src_c1 = RevbGetIndexer(RevBuffers.ACC_SRC_C1);
|
||||
const u32 acc_src_d1 = RevbGetIndexer(RevBuffers.ACC_SRC_D1);
|
||||
(Cores[i].IRQA == comb1_src) || (Cores[i].IRQA == comb2_src) ||
|
||||
(Cores[i].IRQA == comb3_src) || (Cores[i].IRQA == comb4_src) ||
|
||||
|
||||
const u32 fb_src_a0 = RevbGetIndexer(RevBuffers.FB_SRC_A0);
|
||||
const u32 fb_src_a1 = RevbGetIndexer(RevBuffers.FB_SRC_A1);
|
||||
const u32 fb_src_b0 = RevbGetIndexer(RevBuffers.FB_SRC_B0);
|
||||
const u32 fb_src_b1 = RevbGetIndexer(RevBuffers.FB_SRC_B1);
|
||||
|
||||
const u32 mix_dest_a0 = RevbGetIndexer(RevBuffers.MIX_DEST_A0);
|
||||
const u32 mix_dest_a1 = RevbGetIndexer(RevBuffers.MIX_DEST_A1);
|
||||
const u32 mix_dest_b0 = RevbGetIndexer(RevBuffers.MIX_DEST_B0);
|
||||
const u32 mix_dest_b1 = RevbGetIndexer(RevBuffers.MIX_DEST_B1);
|
||||
|
||||
// -----------------------------------------
|
||||
// Optimized IRQ Testing !
|
||||
// -----------------------------------------
|
||||
|
||||
// This test is enhanced by using the reverb effects area begin/end test as a
|
||||
// shortcut, since all buffer addresses are within that area. If the IRQA isn't
|
||||
// within that zone then the "bulk" of the test is skipped, so this should only
|
||||
// be a slowdown on a few evil games.
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (Cores[i].IRQEnable && ((Cores[i].IRQA >= EffectsStartA) && (Cores[i].IRQA <= EffectsEndA))) {
|
||||
if ((Cores[i].IRQA == src_a0) || (Cores[i].IRQA == src_a1) ||
|
||||
(Cores[i].IRQA == src_b0) || (Cores[i].IRQA == src_b1) ||
|
||||
|
||||
(Cores[i].IRQA == dest_a0) || (Cores[i].IRQA == dest_a1) ||
|
||||
(Cores[i].IRQA == dest_b0) || (Cores[i].IRQA == dest_b1) ||
|
||||
|
||||
(Cores[i].IRQA == dest2_a0) || (Cores[i].IRQA == dest2_a1) ||
|
||||
(Cores[i].IRQA == dest2_b0) || (Cores[i].IRQA == dest2_b1) ||
|
||||
|
||||
(Cores[i].IRQA == acc_src_a0) || (Cores[i].IRQA == acc_src_a1) ||
|
||||
(Cores[i].IRQA == acc_src_b0) || (Cores[i].IRQA == acc_src_b1) ||
|
||||
(Cores[i].IRQA == acc_src_c0) || (Cores[i].IRQA == acc_src_c1) ||
|
||||
(Cores[i].IRQA == acc_src_d0) || (Cores[i].IRQA == acc_src_d1) ||
|
||||
|
||||
(Cores[i].IRQA == fb_src_a0) || (Cores[i].IRQA == fb_src_a1) ||
|
||||
(Cores[i].IRQA == fb_src_b0) || (Cores[i].IRQA == fb_src_b1) ||
|
||||
|
||||
(Cores[i].IRQA == mix_dest_a0) || (Cores[i].IRQA == mix_dest_a1) ||
|
||||
(Cores[i].IRQA == mix_dest_b0) || (Cores[i].IRQA == mix_dest_b1)) {
|
||||
//printf("Core %d IRQ Called (Reverb). IRQA = %x\n",i,addr);
|
||||
SetIrqCall(i);
|
||||
}
|
||||
(Cores[i].IRQA == apf1_dst) || (Cores[i].IRQA == apf1_src) ||
|
||||
(Cores[i].IRQA == apf2_dst) || (Cores[i].IRQA == apf2_src)) {
|
||||
//printf("Core %d IRQ Called (Reverb). IRQA = %x\n",i,addr);
|
||||
SetIrqCall(i);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
// Begin Reverb Processing !
|
||||
// -----------------------------------------
|
||||
|
||||
StereoOut32 INPUT_SAMPLE;
|
||||
|
||||
for (int x = 0; x < 8; ++x) {
|
||||
INPUT_SAMPLE.Left += (downbuf[(dbpos + x) & 7].Left * downcoeffs[x]);
|
||||
INPUT_SAMPLE.Right += (downbuf[(dbpos + x) & 7].Right * downcoeffs[x]);
|
||||
}
|
||||
|
||||
INPUT_SAMPLE.Left >>= 16;
|
||||
INPUT_SAMPLE.Right >>= 16;
|
||||
|
||||
s32 input_L = INPUT_SAMPLE.Left * Revb.IN_COEF_L;
|
||||
s32 input_R = INPUT_SAMPLE.Right * Revb.IN_COEF_R;
|
||||
|
||||
const s32 IIR_INPUT_A0 = clamp_mix((((s32)_spu2mem[src_a0] * Revb.IIR_COEF) + input_L) >> 15);
|
||||
const s32 IIR_INPUT_A1 = clamp_mix((((s32)_spu2mem[src_a1] * Revb.IIR_COEF) + input_L) >> 15);
|
||||
const s32 IIR_INPUT_B0 = clamp_mix((((s32)_spu2mem[src_b0] * Revb.IIR_COEF) + input_R) >> 15);
|
||||
const s32 IIR_INPUT_B1 = clamp_mix((((s32)_spu2mem[src_b1] * Revb.IIR_COEF) + input_R) >> 15);
|
||||
|
||||
const s32 src_dest_a0 = _spu2mem[dest_a0];
|
||||
const s32 src_dest_a1 = _spu2mem[dest_a1];
|
||||
const s32 src_dest_b0 = _spu2mem[dest_b0];
|
||||
const s32 src_dest_b1 = _spu2mem[dest_b1];
|
||||
|
||||
// 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 = src_dest_a0 + (((IIR_INPUT_A0 - src_dest_a0) * Revb.IIR_ALPHA) >> 15);
|
||||
const s32 IIR_A1 = src_dest_a1 + (((IIR_INPUT_A1 - src_dest_a1) * Revb.IIR_ALPHA) >> 15);
|
||||
const s32 IIR_B0 = src_dest_b0 + (((IIR_INPUT_B0 - src_dest_b0) * Revb.IIR_ALPHA) >> 15);
|
||||
const s32 IIR_B1 = src_dest_b1 + (((IIR_INPUT_B1 - src_dest_b1) * Revb.IIR_ALPHA) >> 15);
|
||||
_spu2mem[dest2_a0] = clamp_mix(IIR_A0);
|
||||
_spu2mem[dest2_a1] = clamp_mix(IIR_A1);
|
||||
_spu2mem[dest2_b0] = clamp_mix(IIR_B0);
|
||||
_spu2mem[dest2_b1] = clamp_mix(IIR_B1);
|
||||
|
||||
const s32 ACC0 = clamp_mix(
|
||||
((_spu2mem[acc_src_a0] * Revb.ACC_COEF_A) >> 15) +
|
||||
((_spu2mem[acc_src_b0] * Revb.ACC_COEF_B) >> 15) +
|
||||
((_spu2mem[acc_src_c0] * Revb.ACC_COEF_C) >> 15) +
|
||||
((_spu2mem[acc_src_d0] * Revb.ACC_COEF_D) >> 15));
|
||||
|
||||
const s32 ACC1 = clamp_mix(
|
||||
((_spu2mem[acc_src_a1] * Revb.ACC_COEF_A) >> 15) +
|
||||
((_spu2mem[acc_src_b1] * Revb.ACC_COEF_B) >> 15) +
|
||||
((_spu2mem[acc_src_c1] * Revb.ACC_COEF_C) >> 15) +
|
||||
((_spu2mem[acc_src_d1] * Revb.ACC_COEF_D) >> 15));
|
||||
|
||||
// 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];
|
||||
const s32 FB_A1 = _spu2mem[fb_src_a1];
|
||||
const s32 FB_B0 = _spu2mem[fb_src_b0];
|
||||
const s32 FB_B1 = _spu2mem[fb_src_b1];
|
||||
|
||||
const s32 mix_a0 = clamp_mix(ACC0 - ((FB_A0 * Revb.FB_ALPHA) >> 15));
|
||||
const s32 mix_a1 = clamp_mix(ACC1 - ((FB_A1 * Revb.FB_ALPHA) >> 15));
|
||||
const s32 mix_b0 = clamp_mix(FB_A0 + (((ACC0 - FB_A0) * Revb.FB_ALPHA - FB_B0 * Revb.FB_X) >> 15));
|
||||
const s32 mix_b1 = clamp_mix(FB_A1 + (((ACC1 - FB_A1) * Revb.FB_ALPHA - FB_B1 * Revb.FB_X) >> 15));
|
||||
|
||||
_spu2mem[mix_dest_a0] = mix_a0;
|
||||
_spu2mem[mix_dest_a1] = mix_a1;
|
||||
_spu2mem[mix_dest_b0] = mix_b0;
|
||||
_spu2mem[mix_dest_b1] = mix_b1;
|
||||
|
||||
upbuf[ubpos] = clamp_mix(StereoOut32(
|
||||
mix_a0 + mix_b0, // left
|
||||
mix_a1 + mix_b1 // right
|
||||
));
|
||||
}
|
||||
|
||||
StereoOut32 retval;
|
||||
// Reverb algorithm pretty much directly ripped from http://drhell.web.fc2.com/ps1/
|
||||
// minus the 35 step FIR which just seems to break things.
|
||||
|
||||
//for( int x=0; x<8; ++x )
|
||||
//{
|
||||
// retval.Left += (upbuf[(ubpos+x)&7].Left*downcoeffs[x]);
|
||||
// retval.Right += (upbuf[(ubpos+x)&7].Right*downcoeffs[x]);
|
||||
//}
|
||||
s32 in, same, diff, apf1, apf2, out;
|
||||
|
||||
if ((Cycles & 1) == 0) {
|
||||
retval.Left = (upbuf[(ubpos + 5) & 7].Left + upbuf[(ubpos + 7) & 7].Left) >> 1;
|
||||
retval.Right = (upbuf[(ubpos + 5) & 7].Right + upbuf[(ubpos + 7) & 7].Right) >> 1;
|
||||
} else {
|
||||
retval.Left = upbuf[(ubpos + 6) & 7].Left;
|
||||
retval.Right = upbuf[(ubpos + 6) & 7].Right;
|
||||
#define MUL(x, y) ((x) * (y) >> 15)
|
||||
in = MUL(R ? Revb.IN_COEF_R : Revb.IN_COEF_L, R ? Input.Right : Input.Left);
|
||||
|
||||
same = MUL(Revb.IIR_VOL, in + MUL(Revb.WALL_VOL, _spu2mem[same_src]) - _spu2mem[same_prv]) + _spu2mem[same_prv];
|
||||
diff = MUL(Revb.IIR_VOL, in + MUL(Revb.WALL_VOL, _spu2mem[diff_src]) - _spu2mem[diff_prv]) + _spu2mem[diff_prv];
|
||||
|
||||
out = MUL(Revb.COMB1_VOL, _spu2mem[comb1_src]) + MUL(Revb.COMB2_VOL, _spu2mem[comb2_src]) + MUL(Revb.COMB3_VOL, _spu2mem[comb3_src]) + MUL(Revb.COMB4_VOL, _spu2mem[comb4_src]);
|
||||
|
||||
apf1 = out - MUL(Revb.APF1_VOL, _spu2mem[apf1_src]);
|
||||
out = _spu2mem[apf1_src] + MUL(Revb.APF1_VOL, apf1);
|
||||
apf2 = out - MUL(Revb.APF2_VOL, _spu2mem[apf2_src]);
|
||||
out = _spu2mem[apf2_src] + MUL(Revb.APF2_VOL, apf2);
|
||||
|
||||
// According to no$psx the effects always run but don't always write back, see check in V_Core::Mix
|
||||
if (FxEnable) {
|
||||
_spu2mem[same_dst] = clamp_mix(same);
|
||||
_spu2mem[diff_dst] = clamp_mix(diff);
|
||||
_spu2mem[apf1_dst] = clamp_mix(apf1);
|
||||
_spu2mem[apf2_dst] = clamp_mix(apf2);
|
||||
}
|
||||
|
||||
// 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.
|
||||
(R ? LastEffect.Right : LastEffect.Left) = -clamp_mix(out);
|
||||
|
||||
//retval.Left >>= (16-1 + 1);
|
||||
//retval.Right >>= (16-1 + 1);
|
||||
|
||||
ubpos = (ubpos + 1) & 7;
|
||||
|
||||
return retval;
|
||||
return LastEffect;
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "Mixer.h"
|
||||
#include "SndOut.h"
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SPU2 Memory Indexers
|
||||
|
@ -229,73 +230,78 @@ struct V_Reverb
|
|||
s16 IN_COEF_L;
|
||||
s16 IN_COEF_R;
|
||||
|
||||
u32 FB_SRC_A;
|
||||
u32 FB_SRC_B;
|
||||
u32 APF1_SIZE;
|
||||
u32 APF2_SIZE;
|
||||
|
||||
s16 FB_ALPHA;
|
||||
s16 FB_X;
|
||||
s16 APF1_VOL;
|
||||
s16 APF2_VOL;
|
||||
|
||||
u32 IIR_SRC_A0;
|
||||
u32 IIR_SRC_A1;
|
||||
u32 IIR_SRC_B1;
|
||||
u32 IIR_SRC_B0;
|
||||
u32 IIR_DEST_A0;
|
||||
u32 IIR_DEST_A1;
|
||||
u32 IIR_DEST_B0;
|
||||
u32 IIR_DEST_B1;
|
||||
u32 SAME_L_SRC;
|
||||
u32 SAME_R_SRC;
|
||||
u32 DIFF_L_SRC;
|
||||
u32 DIFF_R_SRC;
|
||||
u32 SAME_L_DST;
|
||||
u32 SAME_R_DST;
|
||||
u32 DIFF_L_DST;
|
||||
u32 DIFF_R_DST;
|
||||
|
||||
s16 IIR_ALPHA;
|
||||
s16 IIR_COEF;
|
||||
s16 IIR_VOL;
|
||||
s16 WALL_VOL;
|
||||
|
||||
u32 ACC_SRC_A0;
|
||||
u32 ACC_SRC_A1;
|
||||
u32 ACC_SRC_B0;
|
||||
u32 ACC_SRC_B1;
|
||||
u32 ACC_SRC_C0;
|
||||
u32 ACC_SRC_C1;
|
||||
u32 ACC_SRC_D0;
|
||||
u32 ACC_SRC_D1;
|
||||
u32 COMB1_L_SRC;
|
||||
u32 COMB1_R_SRC;
|
||||
u32 COMB2_L_SRC;
|
||||
u32 COMB2_R_SRC;
|
||||
u32 COMB3_L_SRC;
|
||||
u32 COMB3_R_SRC;
|
||||
u32 COMB4_L_SRC;
|
||||
u32 COMB4_R_SRC;
|
||||
|
||||
s16 ACC_COEF_A;
|
||||
s16 ACC_COEF_B;
|
||||
s16 ACC_COEF_C;
|
||||
s16 ACC_COEF_D;
|
||||
s16 COMB1_VOL;
|
||||
s16 COMB2_VOL;
|
||||
s16 COMB3_VOL;
|
||||
s16 COMB4_VOL;
|
||||
|
||||
u32 MIX_DEST_A0;
|
||||
u32 MIX_DEST_A1;
|
||||
u32 MIX_DEST_B0;
|
||||
u32 MIX_DEST_B1;
|
||||
u32 APF1_L_DST;
|
||||
u32 APF1_R_DST;
|
||||
u32 APF2_L_DST;
|
||||
u32 APF2_R_DST;
|
||||
};
|
||||
|
||||
struct V_ReverbBuffers
|
||||
{
|
||||
s32 FB_SRC_A0;
|
||||
s32 FB_SRC_B0;
|
||||
s32 FB_SRC_A1;
|
||||
s32 FB_SRC_B1;
|
||||
s32 SAME_L_SRC;
|
||||
s32 SAME_R_SRC;
|
||||
s32 DIFF_R_SRC;
|
||||
s32 DIFF_L_SRC;
|
||||
s32 SAME_L_DST;
|
||||
s32 SAME_R_DST;
|
||||
s32 DIFF_L_DST;
|
||||
s32 DIFF_R_DST;
|
||||
|
||||
s32 IIR_SRC_A0;
|
||||
s32 IIR_SRC_A1;
|
||||
s32 IIR_SRC_B0;
|
||||
s32 IIR_SRC_B1;
|
||||
s32 IIR_DEST_A0;
|
||||
s32 IIR_DEST_A1;
|
||||
s32 IIR_DEST_B0;
|
||||
s32 IIR_DEST_B1;
|
||||
s32 COMB1_L_SRC;
|
||||
s32 COMB1_R_SRC;
|
||||
s32 COMB2_L_SRC;
|
||||
s32 COMB2_R_SRC;
|
||||
s32 COMB3_L_SRC;
|
||||
s32 COMB3_R_SRC;
|
||||
s32 COMB4_L_SRC;
|
||||
s32 COMB4_R_SRC;
|
||||
|
||||
s32 ACC_SRC_A0;
|
||||
s32 ACC_SRC_A1;
|
||||
s32 ACC_SRC_B0;
|
||||
s32 ACC_SRC_B1;
|
||||
s32 ACC_SRC_C0;
|
||||
s32 ACC_SRC_C1;
|
||||
s32 ACC_SRC_D0;
|
||||
s32 ACC_SRC_D1;
|
||||
s32 APF1_L_DST;
|
||||
s32 APF1_R_DST;
|
||||
s32 APF2_L_DST;
|
||||
s32 APF2_R_DST;
|
||||
|
||||
s32 MIX_DEST_A0;
|
||||
s32 MIX_DEST_A1;
|
||||
s32 MIX_DEST_B0;
|
||||
s32 MIX_DEST_B1;
|
||||
s32 SAME_L_PRV;
|
||||
s32 SAME_R_PRV;
|
||||
s32 DIFF_L_PRV;
|
||||
s32 DIFF_R_PRV;
|
||||
|
||||
s32 APF1_L_SRC;
|
||||
s32 APF1_R_SRC;
|
||||
s32 APF2_L_SRC;
|
||||
s32 APF2_R_SRC;
|
||||
|
||||
bool NeedsUpdated;
|
||||
};
|
||||
|
@ -419,9 +425,7 @@ struct V_Core
|
|||
|
||||
V_CoreRegs Regs; // Registers
|
||||
|
||||
// Last samples to pass through the effects processor.
|
||||
// Used because the effects processor works at 24khz and just pulls
|
||||
// from this for the odd Ts.
|
||||
// Preserves the channel processed last cycle
|
||||
StereoOut32 LastEffect;
|
||||
|
||||
u8 CoreEnabled;
|
||||
|
@ -444,10 +448,6 @@ struct V_Core
|
|||
u16 psxSoundDataTransferControl;
|
||||
u16 psxSPUSTAT;
|
||||
|
||||
StereoOut32 downbuf[8];
|
||||
StereoOut32 upbuf[8];
|
||||
int dbpos, ubpos;
|
||||
|
||||
// HACK -- This is a temp buffer which is (or isn't?) used to circumvent some memory
|
||||
// corruption that originates elsewhere in the plugin. >_< The actual ADMA buffer
|
||||
// is an area mapped to SPU2 main memory.
|
||||
|
@ -471,8 +471,6 @@ struct V_Core
|
|||
void AnalyzeReverbPreset();
|
||||
|
||||
s32 EffectsBufferIndexer(s32 offset) const;
|
||||
void UpdateFeedbackBuffersA();
|
||||
void UpdateFeedbackBuffersB();
|
||||
|
||||
void WriteRegPS1(u32 mem, u16 value);
|
||||
u16 ReadRegPS1(u32 mem);
|
||||
|
|
|
@ -61,29 +61,29 @@
|
|||
|
||||
// .. repeated for each voice ..
|
||||
|
||||
#define REG_A_ESA 0x02E0 //Address: Top address of working area for effects processing
|
||||
#define R_FB_SRC_A 0x02E4 // Feedback Source A
|
||||
#define R_FB_SRC_B 0x02E8 // Feedback Source B
|
||||
#define R_IIR_DEST_A0 0x02EC
|
||||
#define R_IIR_DEST_A1 0x02F0
|
||||
#define R_ACC_SRC_A0 0x02F4
|
||||
#define R_ACC_SRC_A1 0x02F8
|
||||
#define R_ACC_SRC_B0 0x02FC
|
||||
#define R_ACC_SRC_B1 0x0300
|
||||
#define R_IIR_SRC_A0 0x0304
|
||||
#define R_IIR_SRC_A1 0x0308
|
||||
#define R_IIR_DEST_B0 0x030C
|
||||
#define R_IIR_DEST_B1 0x0310
|
||||
#define R_ACC_SRC_C0 0x0314
|
||||
#define R_ACC_SRC_C1 0x0318
|
||||
#define R_ACC_SRC_D0 0x031C
|
||||
#define R_ACC_SRC_D1 0x0320
|
||||
#define R_IIR_SRC_B0 0x0324 // Some sources have R_IIR_SRC_B0 and R_IIR_SRC_B1 swapped ><
|
||||
#define R_IIR_SRC_B1 0x0328 // Assume a typo in the docs and B0 is actually at 324, B1 at 328 in the HW.
|
||||
#define R_MIX_DEST_A0 0x032C
|
||||
#define R_MIX_DEST_A1 0x0330
|
||||
#define R_MIX_DEST_B0 0x0334
|
||||
#define R_MIX_DEST_B1 0x0338
|
||||
#define REG_A_ESA 0x02E0 //Address: Top address of working area for effects processing
|
||||
#define R_APF1_SIZE 0x02E4 // Feedback Source A
|
||||
#define R_APF2_SIZE 0x02E8 // Feedback Source B
|
||||
#define R_SAME_L_DST 0x02EC
|
||||
#define R_SAME_R_DST 0x02F0
|
||||
#define R_COMB1_L_SRC 0x02F4
|
||||
#define R_COMB1_R_SRC 0x02F8
|
||||
#define R_COMB2_L_SRC 0x02FC
|
||||
#define R_COMB2_R_SRC 0x0300
|
||||
#define R_SAME_L_SRC 0x0304
|
||||
#define R_SAME_R_SRC 0x0308
|
||||
#define R_DIFF_L_DST 0x030C
|
||||
#define R_DIFF_R_DST 0x0310
|
||||
#define R_COMB3_L_SRC 0x0314
|
||||
#define R_COMB3_R_SRC 0x0318
|
||||
#define R_COMB4_L_SRC 0x031C
|
||||
#define R_COMB4_R_SRC 0x0320
|
||||
#define R_DIFF_L_SRC 0x0324 // Some sources have R_DIFF_R_SRC and R_DIFF_L_SRC swapped ><
|
||||
#define R_DIFF_R_SRC 0x0328
|
||||
#define R_APF1_L_DST 0x032C
|
||||
#define R_APF1_R_DST 0x0330
|
||||
#define R_APF2_L_DST 0x0334
|
||||
#define R_APF2_R_DST 0x0338
|
||||
#define REG_A_EEA 0x033C // Address: End address of working area for effects processing (upper part of address only!)
|
||||
|
||||
#define REG_S_ENDX 0x0340 // End Point passed flag
|
||||
|
@ -110,14 +110,14 @@
|
|||
#define REG_P_MVOLXL 0x0770 // Current Master Volume Left
|
||||
#define REG_P_MVOLXR 0x0772 // Current Master Volume Right
|
||||
|
||||
#define R_IIR_ALPHA 0x0774 //IIR alpha (% used)
|
||||
#define R_ACC_COEF_A 0x0776
|
||||
#define R_ACC_COEF_B 0x0778
|
||||
#define R_ACC_COEF_C 0x077A
|
||||
#define R_ACC_COEF_D 0x077C
|
||||
#define R_IIR_COEF 0x077E
|
||||
#define R_FB_ALPHA 0x0780 //feedback alpha (% used)
|
||||
#define R_FB_X 0x0782 //feedback
|
||||
#define R_IIR_VOL 0x0774
|
||||
#define R_COMB1_VOL 0x0776
|
||||
#define R_COMB2_VOL 0x0778
|
||||
#define R_COMB3_VOL 0x077A
|
||||
#define R_COMB4_VOL 0x077C
|
||||
#define R_WALL_VOL 0x077E
|
||||
#define R_APF1_VOL 0x0780
|
||||
#define R_APF2_VOL 0x0782
|
||||
#define R_IN_COEF_L 0x0784
|
||||
#define R_IN_COEF_R 0x0786
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ static const u32 SAVE_ID = 0x1227521;
|
|||
|
||||
// versioning for saves.
|
||||
// Increment this when changes to the savestate system are made.
|
||||
static const u32 SAVE_VERSION = 0x000d;
|
||||
static const u32 SAVE_VERSION = 0x000e;
|
||||
|
||||
static void wipe_the_cache()
|
||||
{
|
||||
|
|
|
@ -195,29 +195,29 @@ void V_Core::AnalyzeReverbPreset()
|
|||
ConLog("----------------------------------------------------------\n");
|
||||
|
||||
ConLog(" IN_COEF_L, IN_COEF_R 0x%08x, 0x%08x\n", Revb.IN_COEF_L, Revb.IN_COEF_R);
|
||||
ConLog(" FB_SRC_A, FB_SRC_B 0x%08x, 0x%08x\n", Revb.FB_SRC_A, Revb.FB_SRC_B);
|
||||
ConLog(" FB_ALPHA, FB_X 0x%08x, 0x%08x\n", Revb.FB_ALPHA, Revb.FB_X);
|
||||
ConLog(" APF1_SIZE, APF2_SIZE 0x%08x, 0x%08x\n", Revb.APF1_SIZE, Revb.APF2_SIZE);
|
||||
ConLog(" APF1_VOL, APF2_VOL 0x%08x, 0x%08x\n", Revb.APF1_VOL, Revb.APF2_VOL);
|
||||
|
||||
ConLog(" ACC_COEF_A 0x%08x\n", Revb.ACC_COEF_A);
|
||||
ConLog(" ACC_COEF_B 0x%08x\n", Revb.ACC_COEF_B);
|
||||
ConLog(" ACC_COEF_C 0x%08x\n", Revb.ACC_COEF_C);
|
||||
ConLog(" ACC_COEF_D 0x%08x\n", Revb.ACC_COEF_D);
|
||||
ConLog(" COMB1_VOL 0x%08x\n", Revb.COMB1_VOL);
|
||||
ConLog(" COMB2_VOL 0x%08x\n", Revb.COMB2_VOL);
|
||||
ConLog(" COMB3_VOL 0x%08x\n", Revb.COMB3_VOL);
|
||||
ConLog(" COMB4_VOL 0x%08x\n", Revb.COMB4_VOL);
|
||||
|
||||
ConLog(" ACC_SRC_A0, ACC_SRC_A1 0x%08x, 0x%08x\n", Revb.ACC_SRC_A0, Revb.ACC_SRC_A1);
|
||||
ConLog(" ACC_SRC_B0, ACC_SRC_B1 0x%08x, 0x%08x\n", Revb.ACC_SRC_B0, Revb.ACC_SRC_B1);
|
||||
ConLog(" ACC_SRC_C0, ACC_SRC_C1 0x%08x, 0x%08x\n", Revb.ACC_SRC_C0, Revb.ACC_SRC_C1);
|
||||
ConLog(" ACC_SRC_D0, ACC_SRC_D1 0x%08x, 0x%08x\n", Revb.ACC_SRC_D0, Revb.ACC_SRC_D1);
|
||||
ConLog(" COMB1_L_SRC, COMB1_R_SRC 0x%08x, 0x%08x\n", Revb.COMB1_L_SRC, Revb.COMB1_R_SRC);
|
||||
ConLog(" COMB2_L_SRC, COMB2_R_SRC 0x%08x, 0x%08x\n", Revb.COMB2_L_SRC, Revb.COMB2_R_SRC);
|
||||
ConLog(" COMB3_L_SRC, COMB3_R_SRC 0x%08x, 0x%08x\n", Revb.COMB3_L_SRC, Revb.COMB3_R_SRC);
|
||||
ConLog(" COMB4_L_SRC, COMB4_R_SRC 0x%08x, 0x%08x\n", Revb.COMB4_L_SRC, Revb.COMB4_R_SRC);
|
||||
|
||||
ConLog(" IIR_SRC_A0, IIR_SRC_A1 0x%08x, 0x%08x\n", Revb.IIR_SRC_A0, Revb.IIR_SRC_A1);
|
||||
ConLog(" IIR_SRC_B0, IIR_SRC_B1 0x%08x, 0x%08x\n", Revb.IIR_SRC_B0, Revb.IIR_SRC_B1);
|
||||
ConLog(" IIR_DEST_A0, IIR_DEST_A1 0x%08x, 0x%08x\n", Revb.IIR_DEST_A0, Revb.IIR_DEST_A1);
|
||||
ConLog(" IIR_DEST_B0, IIR_DEST_B1 0x%08x, 0x%08x\n", Revb.IIR_DEST_B0, Revb.IIR_DEST_B1);
|
||||
ConLog(" IIR_ALPHA, IIR_COEF 0x%08x, 0x%08x\n", Revb.IIR_ALPHA, Revb.IIR_COEF);
|
||||
ConLog(" SAME_L_SRC, SAME_R_SRC 0x%08x, 0x%08x\n", Revb.SAME_L_SRC, Revb.SAME_R_SRC);
|
||||
ConLog(" DIFF_L_SRC, DIFF_R_SRC 0x%08x, 0x%08x\n", Revb.DIFF_L_SRC, Revb.DIFF_R_SRC);
|
||||
ConLog(" SAME_L_DST, SAME_R_DST 0x%08x, 0x%08x\n", Revb.SAME_L_DST, Revb.SAME_R_DST);
|
||||
ConLog(" DIFF_L_DST, DIFF_R_DST 0x%08x, 0x%08x\n", Revb.DIFF_L_DST, Revb.DIFF_R_DST);
|
||||
ConLog(" IIR_VOL, WALL_VOL 0x%08x, 0x%08x\n", Revb.IIR_VOL, Revb.WALL_VOL);
|
||||
|
||||
ConLog(" MIX_DEST_A0 0x%08x\n", Revb.MIX_DEST_A0);
|
||||
ConLog(" MIX_DEST_A1 0x%08x\n", Revb.MIX_DEST_A1);
|
||||
ConLog(" MIX_DEST_B0 0x%08x\n", Revb.MIX_DEST_B0);
|
||||
ConLog(" MIX_DEST_B1 0x%08x\n", Revb.MIX_DEST_B1);
|
||||
ConLog(" APF1_L_DST 0x%08x\n", Revb.APF1_L_DST);
|
||||
ConLog(" APF1_R_DST 0x%08x\n", Revb.APF1_R_DST);
|
||||
ConLog(" APF2_L_DST 0x%08x\n", Revb.APF2_L_DST);
|
||||
ConLog(" APF2_R_DST 0x%08x\n", Revb.APF2_R_DST);
|
||||
|
||||
ConLog(" EffectsBufferSize 0x%x\n", EffectsBufferSize);
|
||||
ConLog("----------------------------------------------------------\n");
|
||||
|
@ -242,18 +242,6 @@ s32 V_Core::EffectsBufferIndexer(s32 offset) const
|
|||
return pos;
|
||||
}
|
||||
|
||||
void V_Core::UpdateFeedbackBuffersA()
|
||||
{
|
||||
RevBuffers.FB_SRC_A0 = EffectsBufferIndexer(Revb.MIX_DEST_A0 - Revb.FB_SRC_A);
|
||||
RevBuffers.FB_SRC_A1 = EffectsBufferIndexer(Revb.MIX_DEST_A1 - Revb.FB_SRC_A);
|
||||
}
|
||||
|
||||
void V_Core::UpdateFeedbackBuffersB()
|
||||
{
|
||||
RevBuffers.FB_SRC_B0 = EffectsBufferIndexer(Revb.MIX_DEST_B0 - Revb.FB_SRC_B);
|
||||
RevBuffers.FB_SRC_B1 = EffectsBufferIndexer(Revb.MIX_DEST_B1 - Revb.FB_SRC_B);
|
||||
}
|
||||
|
||||
void V_Core::UpdateEffectsBufferSize()
|
||||
{
|
||||
const s32 newbufsize = EffectsEndA - EffectsStartA + 1;
|
||||
|
@ -281,32 +269,39 @@ void V_Core::UpdateEffectsBufferSize()
|
|||
AnalyzeReverbPreset();
|
||||
|
||||
// Rebuild buffer indexers.
|
||||
RevBuffers.ACC_SRC_A0 = EffectsBufferIndexer(Revb.ACC_SRC_A0);
|
||||
RevBuffers.ACC_SRC_A1 = EffectsBufferIndexer(Revb.ACC_SRC_A1);
|
||||
RevBuffers.ACC_SRC_B0 = EffectsBufferIndexer(Revb.ACC_SRC_B0);
|
||||
RevBuffers.ACC_SRC_B1 = EffectsBufferIndexer(Revb.ACC_SRC_B1);
|
||||
RevBuffers.ACC_SRC_C0 = EffectsBufferIndexer(Revb.ACC_SRC_C0);
|
||||
RevBuffers.ACC_SRC_C1 = EffectsBufferIndexer(Revb.ACC_SRC_C1);
|
||||
RevBuffers.ACC_SRC_D0 = EffectsBufferIndexer(Revb.ACC_SRC_D0);
|
||||
RevBuffers.ACC_SRC_D1 = EffectsBufferIndexer(Revb.ACC_SRC_D1);
|
||||
RevBuffers.COMB1_L_SRC = EffectsBufferIndexer(Revb.COMB1_L_SRC);
|
||||
RevBuffers.COMB1_R_SRC = EffectsBufferIndexer(Revb.COMB1_R_SRC);
|
||||
RevBuffers.COMB2_L_SRC = EffectsBufferIndexer(Revb.COMB2_L_SRC);
|
||||
RevBuffers.COMB2_R_SRC = EffectsBufferIndexer(Revb.COMB2_R_SRC);
|
||||
RevBuffers.COMB3_L_SRC = EffectsBufferIndexer(Revb.COMB3_L_SRC);
|
||||
RevBuffers.COMB3_R_SRC = EffectsBufferIndexer(Revb.COMB3_R_SRC);
|
||||
RevBuffers.COMB4_L_SRC = EffectsBufferIndexer(Revb.COMB4_L_SRC);
|
||||
RevBuffers.COMB4_R_SRC = EffectsBufferIndexer(Revb.COMB4_R_SRC);
|
||||
|
||||
UpdateFeedbackBuffersA();
|
||||
UpdateFeedbackBuffersB();
|
||||
RevBuffers.SAME_L_DST = EffectsBufferIndexer(Revb.SAME_L_DST);
|
||||
RevBuffers.SAME_R_DST = EffectsBufferIndexer(Revb.SAME_R_DST);
|
||||
RevBuffers.DIFF_L_DST = EffectsBufferIndexer(Revb.DIFF_L_DST);
|
||||
RevBuffers.DIFF_R_DST = EffectsBufferIndexer(Revb.DIFF_R_DST);
|
||||
|
||||
RevBuffers.IIR_DEST_A0 = EffectsBufferIndexer(Revb.IIR_DEST_A0);
|
||||
RevBuffers.IIR_DEST_A1 = EffectsBufferIndexer(Revb.IIR_DEST_A1);
|
||||
RevBuffers.IIR_DEST_B0 = EffectsBufferIndexer(Revb.IIR_DEST_B0);
|
||||
RevBuffers.IIR_DEST_B1 = EffectsBufferIndexer(Revb.IIR_DEST_B1);
|
||||
RevBuffers.SAME_L_SRC = EffectsBufferIndexer(Revb.SAME_L_SRC);
|
||||
RevBuffers.SAME_R_SRC = EffectsBufferIndexer(Revb.SAME_R_SRC);
|
||||
RevBuffers.DIFF_L_SRC = EffectsBufferIndexer(Revb.DIFF_L_SRC);
|
||||
RevBuffers.DIFF_R_SRC = EffectsBufferIndexer(Revb.DIFF_R_SRC);
|
||||
|
||||
RevBuffers.IIR_SRC_A0 = EffectsBufferIndexer(Revb.IIR_SRC_A0);
|
||||
RevBuffers.IIR_SRC_A1 = EffectsBufferIndexer(Revb.IIR_SRC_A1);
|
||||
RevBuffers.IIR_SRC_B0 = EffectsBufferIndexer(Revb.IIR_SRC_B0);
|
||||
RevBuffers.IIR_SRC_B1 = EffectsBufferIndexer(Revb.IIR_SRC_B1);
|
||||
RevBuffers.APF1_L_DST = EffectsBufferIndexer(Revb.APF1_L_DST);
|
||||
RevBuffers.APF1_R_DST = EffectsBufferIndexer(Revb.APF1_R_DST);
|
||||
RevBuffers.APF2_L_DST = EffectsBufferIndexer(Revb.APF2_L_DST);
|
||||
RevBuffers.APF2_R_DST = EffectsBufferIndexer(Revb.APF2_R_DST);
|
||||
|
||||
RevBuffers.MIX_DEST_A0 = EffectsBufferIndexer(Revb.MIX_DEST_A0);
|
||||
RevBuffers.MIX_DEST_A1 = EffectsBufferIndexer(Revb.MIX_DEST_A1);
|
||||
RevBuffers.MIX_DEST_B0 = EffectsBufferIndexer(Revb.MIX_DEST_B0);
|
||||
RevBuffers.MIX_DEST_B1 = EffectsBufferIndexer(Revb.MIX_DEST_B1);
|
||||
RevBuffers.SAME_L_PRV = EffectsBufferIndexer(Revb.SAME_L_DST - 1);
|
||||
RevBuffers.SAME_R_PRV = EffectsBufferIndexer(Revb.SAME_R_DST - 1);
|
||||
RevBuffers.DIFF_L_PRV = EffectsBufferIndexer(Revb.DIFF_L_DST - 1);
|
||||
RevBuffers.DIFF_R_PRV = EffectsBufferIndexer(Revb.DIFF_R_DST - 1);
|
||||
|
||||
RevBuffers.APF1_L_SRC = EffectsBufferIndexer(Revb.APF1_L_DST - Revb.APF1_SIZE);
|
||||
RevBuffers.APF1_R_SRC = EffectsBufferIndexer(Revb.APF1_R_DST - Revb.APF1_SIZE);
|
||||
RevBuffers.APF2_L_SRC = EffectsBufferIndexer(Revb.APF2_L_DST - Revb.APF2_SIZE);
|
||||
RevBuffers.APF2_R_SRC = EffectsBufferIndexer(Revb.APF2_R_DST - Revb.APF2_SIZE);
|
||||
}
|
||||
|
||||
void V_Voice::QueueStart()
|
||||
|
@ -719,94 +714,94 @@ void V_Core::WriteRegPS1(u32 mem, u16 value)
|
|||
break;
|
||||
|
||||
case 0x1DC0:
|
||||
Revb.FB_SRC_A = value * 4;
|
||||
Revb.APF1_SIZE = value * 4;
|
||||
break;
|
||||
case 0x1DC2:
|
||||
Revb.FB_SRC_B = value * 4;
|
||||
Revb.APF2_SIZE = value * 4;
|
||||
break;
|
||||
case 0x1DC4:
|
||||
Revb.IIR_ALPHA = value;
|
||||
Revb.IIR_VOL = value;
|
||||
break;
|
||||
case 0x1DC6:
|
||||
Revb.ACC_COEF_A = value;
|
||||
Revb.COMB1_VOL = value;
|
||||
break;
|
||||
case 0x1DC8:
|
||||
Revb.ACC_COEF_B = value;
|
||||
Revb.COMB2_VOL = value;
|
||||
break;
|
||||
case 0x1DCA:
|
||||
Revb.ACC_COEF_C = value;
|
||||
Revb.COMB3_VOL = value;
|
||||
break;
|
||||
case 0x1DCC:
|
||||
Revb.ACC_COEF_D = value;
|
||||
Revb.COMB4_VOL = value;
|
||||
break;
|
||||
case 0x1DCE:
|
||||
Revb.IIR_COEF = value;
|
||||
Revb.WALL_VOL = value;
|
||||
break;
|
||||
case 0x1DD0:
|
||||
Revb.FB_ALPHA = value;
|
||||
Revb.APF1_VOL = value;
|
||||
break;
|
||||
case 0x1DD2:
|
||||
Revb.FB_X = value;
|
||||
Revb.APF2_VOL = value;
|
||||
break;
|
||||
case 0x1DD4:
|
||||
Revb.IIR_DEST_A0 = value * 4;
|
||||
Revb.SAME_L_DST = value * 4;
|
||||
break;
|
||||
case 0x1DD6:
|
||||
Revb.IIR_DEST_A1 = value * 4;
|
||||
Revb.SAME_R_DST = value * 4;
|
||||
break;
|
||||
case 0x1DD8:
|
||||
Revb.ACC_SRC_A0 = value * 4;
|
||||
Revb.COMB1_L_SRC = value * 4;
|
||||
break;
|
||||
case 0x1DDA:
|
||||
Revb.ACC_SRC_A1 = value * 4;
|
||||
Revb.COMB1_R_SRC = value * 4;
|
||||
break;
|
||||
case 0x1DDC:
|
||||
Revb.ACC_SRC_B0 = value * 4;
|
||||
Revb.COMB2_L_SRC = value * 4;
|
||||
break;
|
||||
case 0x1DDE:
|
||||
Revb.ACC_SRC_B1 = value * 4;
|
||||
Revb.COMB2_R_SRC = value * 4;
|
||||
break;
|
||||
case 0x1DE0:
|
||||
Revb.IIR_SRC_A0 = value * 4;
|
||||
Revb.SAME_L_SRC = value * 4;
|
||||
break;
|
||||
case 0x1DE2:
|
||||
Revb.IIR_SRC_A1 = value * 4;
|
||||
Revb.SAME_R_SRC = value * 4;
|
||||
break;
|
||||
case 0x1DE4:
|
||||
Revb.IIR_DEST_B0 = value * 4;
|
||||
Revb.DIFF_L_DST = value * 4;
|
||||
break;
|
||||
case 0x1DE6:
|
||||
Revb.IIR_DEST_B1 = value * 4;
|
||||
Revb.DIFF_R_DST = value * 4;
|
||||
break;
|
||||
case 0x1DE8:
|
||||
Revb.ACC_SRC_C0 = value * 4;
|
||||
Revb.COMB3_L_SRC = value * 4;
|
||||
break;
|
||||
case 0x1DEA:
|
||||
Revb.ACC_SRC_C1 = value * 4;
|
||||
Revb.COMB3_R_SRC = value * 4;
|
||||
break;
|
||||
case 0x1DEC:
|
||||
Revb.ACC_SRC_D0 = value * 4;
|
||||
Revb.COMB4_L_SRC = value * 4;
|
||||
break;
|
||||
case 0x1DEE:
|
||||
Revb.ACC_SRC_D1 = value * 4;
|
||||
Revb.COMB4_R_SRC = value * 4;
|
||||
break;
|
||||
case 0x1DF0:
|
||||
Revb.IIR_SRC_B0 = value * 4;
|
||||
break; // IIR_SRC_B0 and IIR_SRC_B1 supposedly swapped on SPU2
|
||||
Revb.DIFF_L_SRC = value * 4;
|
||||
break; // DIFF_R_SRC and DIFF_L_SRC supposedly swapped on SPU2
|
||||
case 0x1DF2:
|
||||
Revb.IIR_SRC_B1 = value * 4;
|
||||
Revb.DIFF_R_SRC = value * 4;
|
||||
break; // but I don't believe it! (games in psxmode sound better unswapped)
|
||||
case 0x1DF4:
|
||||
Revb.MIX_DEST_A0 = value * 4;
|
||||
Revb.APF1_L_DST = value * 4;
|
||||
break;
|
||||
case 0x1DF6:
|
||||
Revb.MIX_DEST_A1 = value * 4;
|
||||
Revb.APF1_R_DST = value * 4;
|
||||
break;
|
||||
case 0x1DF8:
|
||||
Revb.MIX_DEST_B0 = value * 4;
|
||||
Revb.APF2_L_DST = value * 4;
|
||||
break;
|
||||
case 0x1DFA:
|
||||
Revb.MIX_DEST_B1 = value * 4;
|
||||
Revb.APF2_R_DST = value * 4;
|
||||
break;
|
||||
case 0x1DFC:
|
||||
Revb.IN_COEF_L = value;
|
||||
|
@ -1550,28 +1545,28 @@ static RegWriteHandler *const tbl_reg_writes[0x401] =
|
|||
|
||||
CoreParamsPair(0, REG_A_ESA),
|
||||
|
||||
ReverbPair(0, R_FB_SRC_A), // 0x02E4 // Feedback Source A
|
||||
ReverbPair(0, R_FB_SRC_B), // 0x02E8 // Feedback Source B
|
||||
ReverbPair(0, R_IIR_DEST_A0), // 0x02EC
|
||||
ReverbPair(0, R_IIR_DEST_A1), // 0x02F0
|
||||
ReverbPair(0, R_ACC_SRC_A0), // 0x02F4
|
||||
ReverbPair(0, R_ACC_SRC_A1), // 0x02F8
|
||||
ReverbPair(0, R_ACC_SRC_B0), // 0x02FC
|
||||
ReverbPair(0, R_ACC_SRC_B1), // 0x0300
|
||||
ReverbPair(0, R_IIR_SRC_A0), // 0x0304
|
||||
ReverbPair(0, R_IIR_SRC_A1), // 0x0308
|
||||
ReverbPair(0, R_IIR_DEST_B0), // 0x030C
|
||||
ReverbPair(0, R_IIR_DEST_B1), // 0x0310
|
||||
ReverbPair(0, R_ACC_SRC_C0), // 0x0314
|
||||
ReverbPair(0, R_ACC_SRC_C1), // 0x0318
|
||||
ReverbPair(0, R_ACC_SRC_D0), // 0x031C
|
||||
ReverbPair(0, R_ACC_SRC_D1), // 0x0320
|
||||
ReverbPair(0, R_IIR_SRC_B0), // 0x0324
|
||||
ReverbPair(0, R_IIR_SRC_B1), // 0x0328
|
||||
ReverbPair(0, R_MIX_DEST_A0), // 0x032C
|
||||
ReverbPair(0, R_MIX_DEST_A1), // 0x0330
|
||||
ReverbPair(0, R_MIX_DEST_B0), // 0x0334
|
||||
ReverbPair(0, R_MIX_DEST_B1), // 0x0338
|
||||
ReverbPair(0, R_APF1_SIZE), // 0x02E4 // Feedback Source A
|
||||
ReverbPair(0, R_APF2_SIZE), // 0x02E8 // Feedback Source B
|
||||
ReverbPair(0, R_SAME_L_DST), // 0x02EC
|
||||
ReverbPair(0, R_SAME_R_DST), // 0x02F0
|
||||
ReverbPair(0, R_COMB1_L_SRC), // 0x02F4
|
||||
ReverbPair(0, R_COMB1_R_SRC), // 0x02F8
|
||||
ReverbPair(0, R_COMB2_L_SRC), // 0x02FC
|
||||
ReverbPair(0, R_COMB2_R_SRC), // 0x0300
|
||||
ReverbPair(0, R_SAME_L_SRC), // 0x0304
|
||||
ReverbPair(0, R_SAME_R_SRC), // 0x0308
|
||||
ReverbPair(0, R_DIFF_L_DST), // 0x030C
|
||||
ReverbPair(0, R_DIFF_R_DST), // 0x0310
|
||||
ReverbPair(0, R_COMB3_L_SRC), // 0x0314
|
||||
ReverbPair(0, R_COMB3_R_SRC), // 0x0318
|
||||
ReverbPair(0, R_COMB4_L_SRC), // 0x031C
|
||||
ReverbPair(0, R_COMB4_R_SRC), // 0x0320
|
||||
ReverbPair(0, R_DIFF_L_SRC), // 0x0324
|
||||
ReverbPair(0, R_DIFF_R_SRC), // 0x0328
|
||||
ReverbPair(0, R_APF1_L_DST), // 0x032C
|
||||
ReverbPair(0, R_APF1_R_DST), // 0x0330
|
||||
ReverbPair(0, R_APF2_L_DST), // 0x0334
|
||||
ReverbPair(0, R_APF2_R_DST), // 0x0338
|
||||
|
||||
RegWrite_Core<0, REG_A_EEA>, RegWrite_Null,
|
||||
|
||||
|
@ -1640,28 +1635,28 @@ static RegWriteHandler *const tbl_reg_writes[0x401] =
|
|||
|
||||
CoreParamsPair(1, REG_A_ESA),
|
||||
|
||||
ReverbPair(1, R_FB_SRC_A), // 0x02E4 // Feedback Source A
|
||||
ReverbPair(1, R_FB_SRC_B), // 0x02E8 // Feedback Source B
|
||||
ReverbPair(1, R_IIR_DEST_A0), // 0x02EC
|
||||
ReverbPair(1, R_IIR_DEST_A1), // 0x02F0
|
||||
ReverbPair(1, R_ACC_SRC_A0), // 0x02F4
|
||||
ReverbPair(1, R_ACC_SRC_A1), // 0x02F8
|
||||
ReverbPair(1, R_ACC_SRC_B0), // 0x02FC
|
||||
ReverbPair(1, R_ACC_SRC_B1), // 0x0300
|
||||
ReverbPair(1, R_IIR_SRC_A0), // 0x0304
|
||||
ReverbPair(1, R_IIR_SRC_A1), // 0x0308
|
||||
ReverbPair(1, R_IIR_DEST_B0), // 0x030C
|
||||
ReverbPair(1, R_IIR_DEST_B1), // 0x0310
|
||||
ReverbPair(1, R_ACC_SRC_C0), // 0x0314
|
||||
ReverbPair(1, R_ACC_SRC_C1), // 0x0318
|
||||
ReverbPair(1, R_ACC_SRC_D0), // 0x031C
|
||||
ReverbPair(1, R_ACC_SRC_D1), // 0x0320
|
||||
ReverbPair(1, R_IIR_SRC_B0), // 0x0324
|
||||
ReverbPair(1, R_IIR_SRC_B1), // 0x0328
|
||||
ReverbPair(1, R_MIX_DEST_A0), // 0x032C
|
||||
ReverbPair(1, R_MIX_DEST_A1), // 0x0330
|
||||
ReverbPair(1, R_MIX_DEST_B0), // 0x0334
|
||||
ReverbPair(1, R_MIX_DEST_B1), // 0x0338
|
||||
ReverbPair(1, R_APF1_SIZE), // 0x02E4 // Feedback Source A
|
||||
ReverbPair(1, R_APF2_SIZE), // 0x02E8 // Feedback Source B
|
||||
ReverbPair(1, R_SAME_L_DST), // 0x02EC
|
||||
ReverbPair(1, R_SAME_R_DST), // 0x02F0
|
||||
ReverbPair(1, R_COMB1_L_SRC), // 0x02F4
|
||||
ReverbPair(1, R_COMB1_R_SRC), // 0x02F8
|
||||
ReverbPair(1, R_COMB2_L_SRC), // 0x02FC
|
||||
ReverbPair(1, R_COMB2_R_SRC), // 0x0300
|
||||
ReverbPair(1, R_SAME_L_SRC), // 0x0304
|
||||
ReverbPair(1, R_SAME_R_SRC), // 0x0308
|
||||
ReverbPair(1, R_DIFF_L_DST), // 0x030C
|
||||
ReverbPair(1, R_DIFF_R_DST), // 0x0310
|
||||
ReverbPair(1, R_COMB3_L_SRC), // 0x0314
|
||||
ReverbPair(1, R_COMB3_R_SRC), // 0x0318
|
||||
ReverbPair(1, R_COMB4_L_SRC), // 0x031C
|
||||
ReverbPair(1, R_COMB4_R_SRC), // 0x0320
|
||||
ReverbPair(1, R_DIFF_R_SRC), // 0x0324
|
||||
ReverbPair(1, R_DIFF_L_SRC), // 0x0328
|
||||
ReverbPair(1, R_APF1_L_DST), // 0x032C
|
||||
ReverbPair(1, R_APF1_R_DST), // 0x0330
|
||||
ReverbPair(1, R_APF2_L_DST), // 0x0334
|
||||
ReverbPair(1, R_APF2_R_DST), // 0x0338
|
||||
|
||||
RegWrite_Core<1, REG_A_EEA>, RegWrite_Null,
|
||||
|
||||
|
@ -1686,16 +1681,16 @@ static RegWriteHandler *const tbl_reg_writes[0x401] =
|
|||
RegWrite_CoreExt<0, REG_P_MVOLXL>, // 0x0770 // Current Master Volume Left
|
||||
RegWrite_CoreExt<0, REG_P_MVOLXR>, // 0x0772 // Current Master Volume Right
|
||||
|
||||
RegWrite_CoreExt<0, R_IIR_ALPHA>, // 0x0774 //IIR alpha (% used)
|
||||
RegWrite_CoreExt<0, R_ACC_COEF_A>, // 0x0776
|
||||
RegWrite_CoreExt<0, R_ACC_COEF_B>, // 0x0778
|
||||
RegWrite_CoreExt<0, R_ACC_COEF_C>, // 0x077A
|
||||
RegWrite_CoreExt<0, R_ACC_COEF_D>, // 0x077C
|
||||
RegWrite_CoreExt<0, R_IIR_COEF>, // 0x077E
|
||||
RegWrite_CoreExt<0, R_FB_ALPHA>, // 0x0780 //feedback alpha (% used)
|
||||
RegWrite_CoreExt<0, R_FB_X>, // 0x0782 //feedback
|
||||
RegWrite_CoreExt<0, R_IN_COEF_L>, // 0x0784
|
||||
RegWrite_CoreExt<0, R_IN_COEF_R>, // 0x0786
|
||||
RegWrite_CoreExt<0, R_IIR_VOL>, // 0x0774 //IIR alpha (% used)
|
||||
RegWrite_CoreExt<0, R_COMB1_VOL>, // 0x0776
|
||||
RegWrite_CoreExt<0, R_COMB2_VOL>, // 0x0778
|
||||
RegWrite_CoreExt<0, R_COMB3_VOL>, // 0x077A
|
||||
RegWrite_CoreExt<0, R_COMB4_VOL>, // 0x077C
|
||||
RegWrite_CoreExt<0, R_WALL_VOL>, // 0x077E
|
||||
RegWrite_CoreExt<0, R_APF1_VOL>, // 0x0780 //feedback alpha (% used)
|
||||
RegWrite_CoreExt<0, R_APF2_VOL>, // 0x0782 //feedback
|
||||
RegWrite_CoreExt<0, R_IN_COEF_L>, // 0x0784
|
||||
RegWrite_CoreExt<0, R_IN_COEF_R>, // 0x0786
|
||||
|
||||
// ------ -------
|
||||
|
||||
|
@ -1710,16 +1705,16 @@ static RegWriteHandler *const tbl_reg_writes[0x401] =
|
|||
RegWrite_CoreExt<1, REG_P_MVOLXL>, // 0x0770 // Current Master Volume Left
|
||||
RegWrite_CoreExt<1, REG_P_MVOLXR>, // 0x0772 // Current Master Volume Right
|
||||
|
||||
RegWrite_CoreExt<1, R_IIR_ALPHA>, // 0x0774 //IIR alpha (% used)
|
||||
RegWrite_CoreExt<1, R_ACC_COEF_A>, // 0x0776
|
||||
RegWrite_CoreExt<1, R_ACC_COEF_B>, // 0x0778
|
||||
RegWrite_CoreExt<1, R_ACC_COEF_C>, // 0x077A
|
||||
RegWrite_CoreExt<1, R_ACC_COEF_D>, // 0x077C
|
||||
RegWrite_CoreExt<1, R_IIR_COEF>, // 0x077E
|
||||
RegWrite_CoreExt<1, R_FB_ALPHA>, // 0x0780 //feedback alpha (% used)
|
||||
RegWrite_CoreExt<1, R_FB_X>, // 0x0782 //feedback
|
||||
RegWrite_CoreExt<1, R_IN_COEF_L>, // 0x0784
|
||||
RegWrite_CoreExt<1, R_IN_COEF_R>, // 0x0786
|
||||
RegWrite_CoreExt<1, R_IIR_VOL>, // 0x0774 //IIR alpha (% used)
|
||||
RegWrite_CoreExt<1, R_COMB1_VOL>, // 0x0776
|
||||
RegWrite_CoreExt<1, R_COMB2_VOL>, // 0x0778
|
||||
RegWrite_CoreExt<1, R_COMB3_VOL>, // 0x077A
|
||||
RegWrite_CoreExt<1, R_COMB4_VOL>, // 0x077C
|
||||
RegWrite_CoreExt<1, R_WALL_VOL>, // 0x077E
|
||||
RegWrite_CoreExt<1, R_APF1_VOL>, // 0x0780 //feedback alpha (% used)
|
||||
RegWrite_CoreExt<1, R_APF2_VOL>, // 0x0782 //feedback
|
||||
RegWrite_CoreExt<1, R_IN_COEF_L>, // 0x0784
|
||||
RegWrite_CoreExt<1, R_IN_COEF_R>, // 0x0786
|
||||
|
||||
REGRAW(0x7B0), REGRAW(0x7B2), REGRAW(0x7B4), REGRAW(0x7B6),
|
||||
REGRAW(0x7B8), REGRAW(0x7BA), REGRAW(0x7BC), REGRAW(0x7BE),
|
||||
|
|
Loading…
Reference in New Issue