// will be included from spu.c\r
#ifdef _IN_SPU\r
\r
-////////////////////////////////////////////////////////////////////////\r
-// globals\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-// REVERB info and timing vars...\r
-\r
-int * sRVBPlay = 0;\r
-int * sRVBEnd = 0;\r
-int * sRVBStart = 0;\r
-\r
////////////////////////////////////////////////////////////////////////\r
// START REVERB\r
////////////////////////////////////////////////////////////////////////\r
\r
INLINE void StartREVERB(int ch)\r
{\r
- if(s_chan[ch].bReverb && (spuCtrl&0x80)) // reverb possible?\r
+ if(spu.s_chan[ch].bReverb && (spu.spuCtrl&0x80)) // reverb possible?\r
{\r
- s_chan[ch].bRVBActive=!!iUseReverb;\r
+ spu.s_chan[ch].bRVBActive=!!spu_config.iUseReverb;\r
}\r
- else s_chan[ch].bRVBActive=0; // else -> no reverb\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// HELPER FOR NEILL'S REVERB: re-inits our reverb mixing buf\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-INLINE void InitREVERB(void)\r
-{\r
- memset(sRVBStart,0,NSSIZE*2*4);\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// STORE REVERB\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-INLINE void StoreREVERB(int ch,int ns,int l,int r)\r
-{\r
- ns<<=1;\r
-\r
- sRVBStart[ns] +=l; // -> we mix all active reverb channels into an extra buffer\r
- sRVBStart[ns+1]+=r;\r
+ else spu.s_chan[ch].bRVBActive=0; // else -> no reverb\r
}\r
\r
////////////////////////////////////////////////////////////////////////\r
\r
// get_buffer content helper: takes care about wraps\r
#define g_buffer(var) \\r
- ((int)(signed short)spuMem[rvb2ram_offs(curr_addr, space, rvb.n##var)])\r
+ ((int)(signed short)spu.spuMem[rvb2ram_offs(curr_addr, space, rvb->var)])\r
\r
// saturate iVal and store it as var\r
#define s_buffer(var, iVal) \\r
ssat32_to_16(iVal); \\r
- spuMem[rvb2ram_offs(curr_addr, space, rvb.n##var)] = iVal\r
+ spu.spuMem[rvb2ram_offs(curr_addr, space, rvb->var)] = iVal\r
\r
#define s_buffer1(var, iVal) \\r
ssat32_to_16(iVal); \\r
- spuMem[rvb2ram_offs(curr_addr, space, rvb.n##var + 1)] = iVal\r
+ spu.spuMem[rvb2ram_offs(curr_addr, space, rvb->var + 1)] = iVal\r
\r
////////////////////////////////////////////////////////////////////////\r
\r
// portions based on spu2-x from PCSX2\r
-static void MixREVERB(void)\r
+static void MixREVERB(int *SSumLR, int *RVB, int ns_to, int curr_addr)\r
{\r
- int l_old = rvb.iRVBLeft;\r
- int r_old = rvb.iRVBRight;\r
- int curr_addr = rvb.CurrAddr;\r
- int space = 0x40000 - rvb.StartAddr;\r
+ const REVERBInfo *rvb = spu.rvb;\r
+ int IIR_ALPHA = rvb->IIR_ALPHA;\r
+ int IIR_COEF = rvb->IIR_COEF;\r
+ int space = 0x40000 - rvb->StartAddr;\r
int l, r, ns;\r
\r
- for (ns = 0; ns < NSSIZE*2; )\r
+ for (ns = 0; ns < ns_to * 2; )\r
{\r
- int IIR_ALPHA = rvb.IIR_ALPHA;\r
int ACC0, ACC1, FB_A0, FB_A1, FB_B0, FB_B1;\r
int mix_dest_a0, mix_dest_a1, mix_dest_b0, mix_dest_b1;\r
\r
- int input_L = sRVBStart[ns] * rvb.IN_COEF_L;\r
- int input_R = sRVBStart[ns+1] * rvb.IN_COEF_R;\r
+ int input_L = RVB[ns] * rvb->IN_COEF_L;\r
+ int input_R = RVB[ns+1] * rvb->IN_COEF_R;\r
\r
- int IIR_INPUT_A0 = ((g_buffer(IIR_SRC_A0) * rvb.IIR_COEF) + input_L) >> 15;\r
- int IIR_INPUT_A1 = ((g_buffer(IIR_SRC_A1) * rvb.IIR_COEF) + input_R) >> 15;\r
- int IIR_INPUT_B0 = ((g_buffer(IIR_SRC_B0) * rvb.IIR_COEF) + input_L) >> 15;\r
- int IIR_INPUT_B1 = ((g_buffer(IIR_SRC_B1) * rvb.IIR_COEF) + input_R) >> 15;\r
+ int IIR_INPUT_A0 = ((g_buffer(IIR_SRC_A0) * IIR_COEF) + input_L) >> 15;\r
+ int IIR_INPUT_A1 = ((g_buffer(IIR_SRC_A1) * IIR_COEF) + input_R) >> 15;\r
+ int IIR_INPUT_B0 = ((g_buffer(IIR_SRC_B0) * IIR_COEF) + input_L) >> 15;\r
+ int IIR_INPUT_B1 = ((g_buffer(IIR_SRC_B1) * IIR_COEF) + input_R) >> 15;\r
\r
int iir_dest_a0 = g_buffer(IIR_DEST_A0);\r
int iir_dest_a1 = g_buffer(IIR_DEST_A1);\r
int IIR_B0 = iir_dest_b0 + ((IIR_INPUT_B0 - iir_dest_b0) * IIR_ALPHA >> 15);\r
int IIR_B1 = iir_dest_b1 + ((IIR_INPUT_B1 - iir_dest_b1) * IIR_ALPHA >> 15);\r
\r
+ preload(SSumLR + ns + 64*2/4 - 4);\r
+\r
s_buffer1(IIR_DEST_A0, IIR_A0);\r
s_buffer1(IIR_DEST_A1, IIR_A1);\r
s_buffer1(IIR_DEST_B0, IIR_B0);\r
s_buffer1(IIR_DEST_B1, IIR_B1);\r
\r
- ACC0 = (g_buffer(ACC_SRC_A0) * rvb.ACC_COEF_A +\r
- g_buffer(ACC_SRC_B0) * rvb.ACC_COEF_B +\r
- g_buffer(ACC_SRC_C0) * rvb.ACC_COEF_C +\r
- g_buffer(ACC_SRC_D0) * rvb.ACC_COEF_D) >> 15;\r
- ACC1 = (g_buffer(ACC_SRC_A1) * rvb.ACC_COEF_A +\r
- g_buffer(ACC_SRC_B1) * rvb.ACC_COEF_B +\r
- g_buffer(ACC_SRC_C1) * rvb.ACC_COEF_C +\r
- g_buffer(ACC_SRC_D1) * rvb.ACC_COEF_D) >> 15;\r
+ preload(RVB + ns + 64*2/4 - 4);\r
+\r
+ ACC0 = (g_buffer(ACC_SRC_A0) * rvb->ACC_COEF_A +\r
+ g_buffer(ACC_SRC_B0) * rvb->ACC_COEF_B +\r
+ g_buffer(ACC_SRC_C0) * rvb->ACC_COEF_C +\r
+ g_buffer(ACC_SRC_D0) * rvb->ACC_COEF_D) >> 15;\r
+ ACC1 = (g_buffer(ACC_SRC_A1) * rvb->ACC_COEF_A +\r
+ g_buffer(ACC_SRC_B1) * rvb->ACC_COEF_B +\r
+ g_buffer(ACC_SRC_C1) * rvb->ACC_COEF_C +\r
+ g_buffer(ACC_SRC_D1) * rvb->ACC_COEF_D) >> 15;\r
\r
FB_A0 = g_buffer(FB_SRC_A0);\r
FB_A1 = g_buffer(FB_SRC_A1);\r
FB_B0 = g_buffer(FB_SRC_B0);\r
FB_B1 = g_buffer(FB_SRC_B1);\r
\r
- mix_dest_a0 = ACC0 - ((FB_A0 * rvb.FB_ALPHA) >> 15);\r
- mix_dest_a1 = ACC1 - ((FB_A1 * rvb.FB_ALPHA) >> 15);\r
+ mix_dest_a0 = ACC0 - ((FB_A0 * rvb->FB_ALPHA) >> 15);\r
+ mix_dest_a1 = ACC1 - ((FB_A1 * rvb->FB_ALPHA) >> 15);\r
\r
- mix_dest_b0 = FB_A0 + (((ACC0 - FB_A0) * rvb.FB_ALPHA - FB_B0 * rvb.FB_X) >> 15);\r
- mix_dest_b1 = FB_A1 + (((ACC1 - FB_A1) * rvb.FB_ALPHA - FB_B1 * rvb.FB_X) >> 15);\r
+ mix_dest_b0 = FB_A0 + (((ACC0 - FB_A0) * rvb->FB_ALPHA - FB_B0 * rvb->FB_X) >> 15);\r
+ mix_dest_b1 = FB_A1 + (((ACC1 - FB_A1) * rvb->FB_ALPHA - FB_B1 * rvb->FB_X) >> 15);\r
\r
s_buffer(MIX_DEST_A0, mix_dest_a0);\r
s_buffer(MIX_DEST_A1, mix_dest_a1);\r
s_buffer(MIX_DEST_B0, mix_dest_b0);\r
s_buffer(MIX_DEST_B1, mix_dest_b1);\r
\r
- l = (mix_dest_a0 + mix_dest_b0) / 3;\r
- r = (mix_dest_a1 + mix_dest_b1) / 3;\r
+ l = (mix_dest_a0 + mix_dest_b0) / 2;\r
+ r = (mix_dest_a1 + mix_dest_b1) / 2;\r
\r
- l = (l * rvb.VolLeft) >> 14;\r
- r = (r * rvb.VolRight) >> 14;\r
+ l = (l * rvb->VolLeft) >> 15; // 15?\r
+ r = (r * rvb->VolRight) >> 15;\r
\r
- SSumLR[ns++] += (l + l_old) / 2;\r
- SSumLR[ns++] += (r + r_old) / 2;\r
SSumLR[ns++] += l;\r
SSumLR[ns++] += r;\r
-\r
- l_old = l;\r
- r_old = r;\r
+ SSumLR[ns++] += l;\r
+ SSumLR[ns++] += r;\r
\r
curr_addr++;\r
- if (curr_addr >= 0x40000) curr_addr = rvb.StartAddr;\r
+ if (curr_addr >= 0x40000) curr_addr = rvb->StartAddr;\r
}\r
+}\r
+\r
+static void MixREVERB_off(int *SSumLR, int ns_to, int curr_addr)\r
+{\r
+ const REVERBInfo *rvb = spu.rvb;\r
+ int space = 0x40000 - rvb->StartAddr;\r
+ int l, r, ns;\r
+\r
+ for (ns = 0; ns < ns_to * 2; )\r
+ {\r
+ preload(SSumLR + ns + 64*2/4 - 4);\r
+\r
+ l = (g_buffer(MIX_DEST_A0) + g_buffer(MIX_DEST_B0)) / 2;\r
+ r = (g_buffer(MIX_DEST_A1) + g_buffer(MIX_DEST_B1)) / 2;\r
+\r
+ l = (l * rvb->VolLeft) >> 15;\r
+ r = (r * rvb->VolRight) >> 15;\r
+\r
+ SSumLR[ns++] += l;\r
+ SSumLR[ns++] += r;\r
+ SSumLR[ns++] += l;\r
+ SSumLR[ns++] += r;\r
\r
- rvb.iRVBLeft = l;\r
- rvb.iRVBRight = r;\r
- rvb.CurrAddr = curr_addr;\r
+ curr_addr++;\r
+ if (curr_addr >= 0x40000) curr_addr = rvb->StartAddr;\r
+ }\r
}\r
\r
-static void prepare_offsets(void)\r
+static void REVERBPrep(void)\r
{\r
- int space = 0x40000 - rvb.StartAddr;\r
- int t;\r
- #define prep_offs(v) \\r
- t = rvb.v; \\r
+ REVERBInfo *rvb = spu.rvb;\r
+ int space, t;\r
+\r
+ t = spu.regArea[(H_SPUReverbAddr - 0xc00) >> 1];\r
+ if (t == 0xFFFF || t <= 0x200)\r
+ spu.rvb->StartAddr = spu.rvb->CurrAddr = 0;\r
+ else if (spu.rvb->StartAddr != (t << 2))\r
+ spu.rvb->StartAddr = spu.rvb->CurrAddr = t << 2;\r
+\r
+ space = 0x40000 - rvb->StartAddr;\r
+\r
+ #define prep_offs(v, r) \\r
+ t = spu.regArea[(0x1c0 + r) >> 1] * 4; \\r
while (t >= space) \\r
t -= space; \\r
- rvb.n##v = t\r
- #define prep_offs2(d, v1, v2) \\r
- t = rvb.v1 - rvb.v2; \\r
+ rvb->v = t\r
+ #define prep_offs2(d, r1, r2) \\r
+ t = spu.regArea[(0x1c0 + r1) >> 1] * 4; \\r
+ t -= spu.regArea[(0x1c0 + r2) >> 1] * 4; \\r
+ while (t < 0) \\r
+ t += space; \\r
while (t >= space) \\r
t -= space; \\r
- rvb.n##d = t\r
-\r
- prep_offs(IIR_SRC_A0);\r
- prep_offs(IIR_SRC_A1);\r
- prep_offs(IIR_SRC_B0);\r
- prep_offs(IIR_SRC_B1);\r
- prep_offs(IIR_DEST_A0);\r
- prep_offs(IIR_DEST_A1);\r
- prep_offs(IIR_DEST_B0);\r
- prep_offs(IIR_DEST_B1);\r
- prep_offs(ACC_SRC_A0);\r
- prep_offs(ACC_SRC_A1);\r
- prep_offs(ACC_SRC_B0);\r
- prep_offs(ACC_SRC_B1);\r
- prep_offs(ACC_SRC_C0);\r
- prep_offs(ACC_SRC_C1);\r
- prep_offs(ACC_SRC_D0);\r
- prep_offs(ACC_SRC_D1);\r
- prep_offs(MIX_DEST_A0);\r
- prep_offs(MIX_DEST_A1);\r
- prep_offs(MIX_DEST_B0);\r
- prep_offs(MIX_DEST_B1);\r
- prep_offs2(FB_SRC_A0, MIX_DEST_A0, FB_SRC_A);\r
- prep_offs2(FB_SRC_A1, MIX_DEST_A1, FB_SRC_A);\r
- prep_offs2(FB_SRC_B0, MIX_DEST_B0, FB_SRC_B);\r
- prep_offs2(FB_SRC_B1, MIX_DEST_B1, FB_SRC_B);\r
+ rvb->d = t\r
+\r
+ prep_offs(IIR_SRC_A0, 32);\r
+ prep_offs(IIR_SRC_A1, 34);\r
+ prep_offs(IIR_SRC_B0, 36);\r
+ prep_offs(IIR_SRC_B1, 38);\r
+ prep_offs(IIR_DEST_A0, 20);\r
+ prep_offs(IIR_DEST_A1, 22);\r
+ prep_offs(IIR_DEST_B0, 36);\r
+ prep_offs(IIR_DEST_B1, 38);\r
+ prep_offs(ACC_SRC_A0, 24);\r
+ prep_offs(ACC_SRC_A1, 26);\r
+ prep_offs(ACC_SRC_B0, 28);\r
+ prep_offs(ACC_SRC_B1, 30);\r
+ prep_offs(ACC_SRC_C0, 40);\r
+ prep_offs(ACC_SRC_C1, 42);\r
+ prep_offs(ACC_SRC_D0, 44);\r
+ prep_offs(ACC_SRC_D1, 46);\r
+ prep_offs(MIX_DEST_A0, 52);\r
+ prep_offs(MIX_DEST_A1, 54);\r
+ prep_offs(MIX_DEST_B0, 56);\r
+ prep_offs(MIX_DEST_B1, 58);\r
+ prep_offs2(FB_SRC_A0, 52, 0);\r
+ prep_offs2(FB_SRC_A1, 54, 0);\r
+ prep_offs2(FB_SRC_B0, 56, 2);\r
+ prep_offs2(FB_SRC_B1, 58, 2);\r
\r
#undef prep_offs\r
#undef prep_offs2\r
- rvb.dirty = 0;\r
+ rvb->dirty = 0;\r
}\r
\r
-INLINE void REVERBDo(void)\r
+INLINE void REVERBDo(int *SSumLR, int *RVB, int ns_to, int curr_addr)\r
{\r
- if (!rvb.StartAddr) // reverb is off\r
+ if (spu.spuCtrl & 0x80) // -> reverb on? oki\r
{\r
- rvb.iRVBLeft = rvb.iRVBRight = 0;\r
- return;\r
- }\r
-\r
- if (spuCtrl & 0x80) // -> reverb on? oki\r
- {\r
- if (rvb.dirty)\r
- prepare_offsets();\r
-\r
- MixREVERB();\r
+ MixREVERB(SSumLR, RVB, ns_to, curr_addr);\r
}\r
- else // -> reverb off\r
+ else if (spu.rvb->VolLeft || spu.rvb->VolRight)\r
{\r
- // supposedly runs anyway?\r
- rvb.CurrAddr += NSSIZE/2;\r
- while (rvb.CurrAddr >= 0x40000)\r
- rvb.CurrAddr -= 0x40000 - rvb.StartAddr;\r
+ MixREVERB_off(SSumLR, ns_to, curr_addr);\r
}\r
}\r
\r