\r
int dirty; // registers changed\r
\r
- // normalized offsets\r
- int nIIR_DEST_A0, nIIR_DEST_A1, nIIR_DEST_B0, nIIR_DEST_B1,\r
- nACC_SRC_A0, nACC_SRC_A1, nACC_SRC_B0, nACC_SRC_B1, \r
- nIIR_SRC_A0, nIIR_SRC_A1, nIIR_SRC_B0, nIIR_SRC_B1,\r
- nACC_SRC_C0, nACC_SRC_C1, nACC_SRC_D0, nACC_SRC_D1,\r
- nMIX_DEST_A0, nMIX_DEST_A1, nMIX_DEST_B0, nMIX_DEST_B1;\r
// MIX_DEST_xx - FB_SRC_x\r
- int nFB_SRC_A0, nFB_SRC_A1, nFB_SRC_B0, nFB_SRC_B1;\r
+ int FB_SRC_A0, FB_SRC_A1, FB_SRC_B0, FB_SRC_B1;\r
} REVERBInfo;\r
\r
///////////////////////////////////////////////////////////\r
\r
if(!pF) return 0; // first check\r
\r
+ do_samples(cycles, 1);\r
+\r
if(ulFreezeMode) // info or save?\r
{//--------------------------------------------------//\r
if(ulFreezeMode==1) \r
\r
if(ulFreezeMode==2) return 1; // info mode? ok, bye\r
// save mode:\r
- do_samples(cycles, 1);\r
-\r
memcpy(pF->cSPURam,spu.spuMem,0x80000); // copy common infos\r
memcpy(pF->cSPUPort,spu.regArea,0x200);\r
\r
break;\r
//-------------------------------------------------//\r
case H_SPUReverbAddr:\r
- if(val==0xFFFF || val<=0x200)\r
- {spu.rvb->StartAddr=spu.rvb->CurrAddr=0;}\r
- else\r
- {\r
- const long iv=(unsigned long)val<<2;\r
- if(spu.rvb->StartAddr!=iv)\r
- {\r
- spu.rvb->StartAddr=(unsigned long)val<<2;\r
- spu.rvb->CurrAddr=spu.rvb->StartAddr;\r
- }\r
- }\r
goto rvbd;\r
//-------------------------------------------------//\r
case H_SPUirqAddr:\r
ReverbOn(16,24,val);\r
break;\r
//-------------------------------------------------//\r
- case H_Reverb+0 : spu.rvb->FB_SRC_A=val*4; goto rvbd;\r
- case H_Reverb+2 : spu.rvb->FB_SRC_B=val*4; goto rvbd;\r
- case H_Reverb+4 : spu.rvb->IIR_ALPHA=(short)val; goto rvbd;\r
- case H_Reverb+6 : spu.rvb->ACC_COEF_A=(short)val; goto rvbd;\r
- case H_Reverb+8 : spu.rvb->ACC_COEF_B=(short)val; goto rvbd;\r
- case H_Reverb+10 : spu.rvb->ACC_COEF_C=(short)val; goto rvbd;\r
- case H_Reverb+12 : spu.rvb->ACC_COEF_D=(short)val; goto rvbd;\r
- case H_Reverb+14 : spu.rvb->IIR_COEF=(short)val; goto rvbd;\r
- case H_Reverb+16 : spu.rvb->FB_ALPHA=(short)val; goto rvbd;\r
- case H_Reverb+18 : spu.rvb->FB_X=(short)val; goto rvbd;\r
- case H_Reverb+20 : spu.rvb->IIR_DEST_A0=val*4; goto rvbd;\r
- case H_Reverb+22 : spu.rvb->IIR_DEST_A1=val*4; goto rvbd;\r
- case H_Reverb+24 : spu.rvb->ACC_SRC_A0=val*4; goto rvbd;\r
- case H_Reverb+26 : spu.rvb->ACC_SRC_A1=val*4; goto rvbd;\r
- case H_Reverb+28 : spu.rvb->ACC_SRC_B0=val*4; goto rvbd;\r
- case H_Reverb+30 : spu.rvb->ACC_SRC_B1=val*4; goto rvbd;\r
- case H_Reverb+32 : spu.rvb->IIR_SRC_A0=val*4; goto rvbd;\r
- case H_Reverb+34 : spu.rvb->IIR_SRC_A1=val*4; goto rvbd;\r
- case H_Reverb+36 : spu.rvb->IIR_DEST_B0=val*4; goto rvbd;\r
- case H_Reverb+38 : spu.rvb->IIR_DEST_B1=val*4; goto rvbd;\r
- case H_Reverb+40 : spu.rvb->ACC_SRC_C0=val*4; goto rvbd;\r
- case H_Reverb+42 : spu.rvb->ACC_SRC_C1=val*4; goto rvbd;\r
- case H_Reverb+44 : spu.rvb->ACC_SRC_D0=val*4; goto rvbd;\r
- case H_Reverb+46 : spu.rvb->ACC_SRC_D1=val*4; goto rvbd;\r
- case H_Reverb+48 : spu.rvb->IIR_SRC_B1=val*4; goto rvbd;\r
- case H_Reverb+50 : spu.rvb->IIR_SRC_B0=val*4; goto rvbd;\r
- case H_Reverb+52 : spu.rvb->MIX_DEST_A0=val*4; goto rvbd;\r
- case H_Reverb+54 : spu.rvb->MIX_DEST_A1=val*4; goto rvbd;\r
- case H_Reverb+56 : spu.rvb->MIX_DEST_B0=val*4; goto rvbd;\r
- case H_Reverb+58 : spu.rvb->MIX_DEST_B1=val*4; goto rvbd;\r
- case H_Reverb+60 : spu.rvb->IN_COEF_L=(short)val; goto rvbd;\r
- case H_Reverb+62 : spu.rvb->IN_COEF_R=(short)val; goto rvbd;\r
+ case H_Reverb+0 : goto rvbd;\r
+ case H_Reverb+2 : goto rvbd;\r
+ case H_Reverb+4 : spu.rvb->IIR_ALPHA=(short)val; break;\r
+ case H_Reverb+6 : spu.rvb->ACC_COEF_A=(short)val; break;\r
+ case H_Reverb+8 : spu.rvb->ACC_COEF_B=(short)val; break;\r
+ case H_Reverb+10 : spu.rvb->ACC_COEF_C=(short)val; break;\r
+ case H_Reverb+12 : spu.rvb->ACC_COEF_D=(short)val; break;\r
+ case H_Reverb+14 : spu.rvb->IIR_COEF=(short)val; break;\r
+ case H_Reverb+16 : spu.rvb->FB_ALPHA=(short)val; break;\r
+ case H_Reverb+18 : spu.rvb->FB_X=(short)val; break;\r
+ case H_Reverb+20 : goto rvbd;\r
+ case H_Reverb+22 : goto rvbd;\r
+ case H_Reverb+24 : goto rvbd;\r
+ case H_Reverb+26 : goto rvbd;\r
+ case H_Reverb+28 : goto rvbd;\r
+ case H_Reverb+30 : goto rvbd;\r
+ case H_Reverb+32 : goto rvbd;\r
+ case H_Reverb+34 : goto rvbd;\r
+ case H_Reverb+36 : goto rvbd;\r
+ case H_Reverb+38 : goto rvbd;\r
+ case H_Reverb+40 : goto rvbd;\r
+ case H_Reverb+42 : goto rvbd;\r
+ case H_Reverb+44 : goto rvbd;\r
+ case H_Reverb+46 : goto rvbd;\r
+ case H_Reverb+48 : goto rvbd;\r
+ case H_Reverb+50 : goto rvbd;\r
+ case H_Reverb+52 : goto rvbd;\r
+ case H_Reverb+54 : goto rvbd;\r
+ case H_Reverb+56 : goto rvbd;\r
+ case H_Reverb+58 : goto rvbd;\r
+ case H_Reverb+60 : spu.rvb->IN_COEF_L=(short)val; break;\r
+ case H_Reverb+62 : spu.rvb->IN_COEF_R=(short)val; break;\r
}\r
return;\r
\r
\r
// get_buffer content helper: takes care about wraps\r
#define g_buffer(var) \\r
- ((int)(signed short)spu.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
- spu.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
- spu.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
static void REVERBPrep(void)\r
{\r
REVERBInfo *rvb = spu.rvb;\r
- int space = 0x40000 - rvb->StartAddr;\r
- int t;\r
- #define prep_offs(v) \\r
- t = rvb->v; \\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
}
if (spu.rvb->StartAddr) {
- if (do_rvb) {
- if (unlikely(spu.rvb->dirty))
- REVERBPrep();
-
+ if (do_rvb)
REVERBDo(spu.SSumLR, RVB, ns_to, spu.rvb->CurrAddr);
- }
spu.rvb->CurrAddr += ns_to / 2;
while (spu.rvb->CurrAddr >= 0x40000)
work->rvb_addr = 0;
if (spu.rvb->StartAddr) {
- if (spu_config.iUseReverb) {
- if (unlikely(spu.rvb->dirty))
- REVERBPrep();
+ if (spu_config.iUseReverb)
work->rvb_addr = spu.rvb->CurrAddr;
- }
spu.rvb->CurrAddr += ns_to / 2;
while (spu.rvb->CurrAddr >= 0x40000)
{
unsigned int mask;
unsigned int decode_dirty_ch = 0;
+ const SPUCHAN *s_chan;
int *SB, sinc, spos, sbpos;
int d, ch, ns_to;
- SPUCHAN *s_chan;
ns_to = work->ns_to;
struct work_item *work;
int done, used_space;
+ // rvb offsets will change, thread may be using them
+ force |= spu.rvb->dirty && spu.rvb->StartAddr;
+
done = thread_get_i_done() - worker->i_reaped;
used_space = worker->i_ready - worker->i_reaped;
//printf("done: %d use: %d dsp: %u/%u\n", done, used_space,
}
}
+ if (unlikely(spu.rvb->dirty))
+ REVERBPrep();
+
if (do_direct || worker == NULL || !spu_config.iUseThread) {
do_channels(ns_to);
do_samples_finish(spu.SSumLR, ns_to, silentch, spu.decode_pos);