int mLAPF1_dAPF1, mRAPF1_dAPF1, mLAPF2_dAPF2, mRAPF2_dAPF2;\r
\r
int dirty; // registers changed\r
-\r
- // for filtering\r
- int SB[2][4*2];\r
} REVERBInfo;\r
\r
///////////////////////////////////////////////////////////\r
typedef union\r
{\r
int SB[28 + 4 + 4];\r
+ int SB_rvb[2][4*2]; // for reverb filtering\r
struct {\r
int sample[28];\r
union {\r
\r
unsigned short regArea[0x400];\r
\r
- sample_buf sb[MAXCHAN];\r
+ sample_buf sb[MAXCHAN+1]; // last entry is used for reverb filter\r
int interpolation;\r
\r
#if P_HAVE_PTHREAD || defined(WANT_THREAD_CODE)\r
sample_buf * sb_thread;\r
- sample_buf sb_thread_[MAXCHAN];\r
+ sample_buf sb_thread_[MAXCHAN+1];\r
#endif\r
} SPUInfo;\r
\r
unsigned int cycles)\r
{\r
SPUOSSFreeze_t * pFO = NULL;\r
+ sample_buf *sb_rvb = &spu.sb[MAXCHAN];\r
int i, j;\r
\r
if(!pF) return 0; // first check\r
\r
+#if P_HAVE_PTHREAD || defined(WANT_THREAD_CODE)\r
+ sb_rvb = &spu.sb_thread[MAXCHAN];\r
+#endif\r
if(ulFreezeMode) // info or save?\r
{//--------------------------------------------------//\r
int xa_left = 0, cdda_left = 0;\r
pFO->XALastVal = spu.XALastVal;\r
pFO->last_keyon_cycles = spu.last_keyon_cycles;\r
for (i = 0; i < 2; i++)\r
- memcpy(&pFO->rvb_sb[i], spu.rvb->SB[i], sizeof(pFO->rvb_sb[i]));\r
+ memcpy(&pFO->rvb_sb[i], sb_rvb->SB_rvb[i], sizeof(pFO->rvb_sb[i]));\r
\r
for(i=0;i<MAXCHAN;i++)\r
{\r
if (pFO && pF->ulFreezeSize >= sizeof(*pF) + sizeof(*pFO)) {\r
for (i = 0; i < 2; i++)\r
for (j = 0; j < 2; j++)\r
- memcpy(&spu.rvb->SB[i][j*4], pFO->rvb_sb[i], 4 * sizeof(spu.rvb->SB[i][0]));\r
+ memcpy(&sb_rvb->SB_rvb[i][j*4], pFO->rvb_sb[i], 4 * sizeof(sb_rvb->SB_rvb[i][0]));\r
}\r
\r
// repair some globals\r
\r
////////////////////////////////////////////////////////////////////////\r
\r
-static void reverb_interpolate(REVERBInfo *rvb, int curr_addr,\r
+static void reverb_interpolate(sample_buf *sb, int curr_addr,\r
int out0[2], int out1[2])\r
{\r
int spos = (curr_addr - 3) & 3;\r
int i;\r
\r
for (i = 0; i < 2; i++)\r
- rvb->SB[i][dpos] = rvb->SB[i][4 | dpos] = out0[i];\r
+ sb->SB_rvb[i][dpos] = sb->SB_rvb[i][4 | dpos] = out0[i];\r
\r
// mednafen uses some 20 coefs here, we just reuse gauss [0] and [128]\r
for (i = 0; i < 2; i++)\r
{\r
const int *s;\r
- s = &rvb->SB[i][spos];\r
+ s = &sb->SB_rvb[i][spos];\r
out0[i] = (s[0] * 0x12c7 + s[1] * 0x59b3 + s[2] * 0x1307) >> 15;\r
out1[i] = (s[0] * 0x019c + s[1] * 0x3def + s[2] * 0x3e4c + s[3] * 0x01a8) >> 15;\r
}\r
int do_filter)\r
{\r
unsigned short *spuMem = spu.spuMem;\r
- REVERBInfo *rvb = spu.rvb;\r
+ const REVERBInfo *rvb = spu.rvb;\r
+ sample_buf *sb = &spu.sb[MAXCHAN];\r
int space = 0x40000 - rvb->StartAddr;\r
int mlsame_m2o = rvb->mLSAME + space - 1;\r
int mrsame_m2o = rvb->mRSAME + space - 1;\r
int vWALL = rvb->vWALL;\r
int ns;\r
\r
+#if P_HAVE_PTHREAD || defined(WANT_THREAD_CODE)\r
+ sb = &spu.sb_thread[MAXCHAN];\r
+#endif\r
if (mlsame_m2o >= space) mlsame_m2o -= space;\r
if (mrsame_m2o >= space) mrsame_m2o -= space;\r
if (mldiff_m2o >= space) mldiff_m2o -= space;\r
out0[0] = out1[0] = (Lout >> 15) * rvb->VolLeft >> 15;\r
out0[1] = out1[1] = (Rout >> 15) * rvb->VolRight >> 15;\r
if (do_filter)\r
- reverb_interpolate(rvb, curr_addr, out0, out1);\r
+ reverb_interpolate(sb, curr_addr, out0, out1);\r
\r
SSumLR[ns++] += out0[0];\r
SSumLR[ns++] += out0[1];\r
{\r
if (spu.spuCtrl & 0x80) // -> reverb on? oki\r
{\r
- MixREVERB(SSumLR, RVB, ns_to, curr_addr, spu.interpolation > 1);\r
+ MixREVERB(SSumLR, RVB, ns_to, curr_addr, 0); //spu.interpolation > 1);\r
}\r
else if (spu.rvb->VolLeft || spu.rvb->VolRight)\r
{\r
static void thread_sync_caches(void)
{
if (f.stale_caches) {
- f.dsp_cache_inv_virt(spu.sb_thread, sizeof(spu.sb_thread[0]) * MAXCHAN);
+ f.dsp_cache_inv_virt(spu.sb_thread, sizeof(spu.sb_thread[0]) * (MAXCHAN+1));
f.dsp_cache_inv_virt(spu.spuMemC + 0x800, 0x800);
if (spu.rvb->StartAddr) {
int left = 0x40000 - spu.rvb->StartAddr;
struct region_mem *mem;
int ret;
+ spu.sb_thread = spu.sb_thread_;
if (f.handle == NULL) {
const char lib[] = "libc64.so.1";
int failed = 0;
struct region_mem {
unsigned char spu_ram[512 * 1024];
- sample_buf sb_thread[MAXCHAN];
+ sample_buf sb_thread[MAXCHAN+1];
// careful not to lose ARM writes by DSP overwriting
// with old data when it's writing out neighbor cachelines
- int _pad1[128/4 - ((sizeof(sample_buf) * MAXCHAN / 4) & (128/4 - 1))];
+ int _pad1[128/4 - ((sizeof(sample_buf) * (MAXCHAN+1) / 4) & (128/4 - 1))];
struct spu_in {
// these are not to be modified by DSP
SPUCHAN s_chan[24 + 1];
// nothing to do? Write out non-critical caches
if (dirty) {
syscalls.cache_wb(spu.spuMemC + 0x800, 0x800, 1);
- syscalls.cache_wb(spu.sb_thread, sizeof(spu.sb_thread[0]) * MAXCHAN, 1);
+ syscalls.cache_wb(spu.sb_thread, sizeof(spu.sb_thread_), 1);
if (had_rvb) {
left = 0x40000 - spu.rvb->StartAddr;
syscalls.cache_wb(spu.spuMem + spu.rvb->StartAddr, left * 2, 1);