#include "stdafx.h"
#define _IN_REVERB
#ifdef _IN_SPU
int * sRVBPlay[2];
int * sRVBEnd[2];
int * sRVBStart[2];
INLINE void StartREVERB(int ch)
{
int core=ch/24;
if((s_chan[ch].bReverbL || s_chan[ch].bReverbR) && (spuCtrl2[core]&0x80)) {
if(iUseReverb==1) s_chan[ch].bRVBActive=1;
}
else s_chan[ch].bRVBActive=0; }
INLINE void InitREVERB(void)
{
if(iUseReverb==1)
{
memset(sRVBStart[0],0,NSSIZE*2*4);
memset(sRVBStart[1],0,NSSIZE*2*4);
}
}
INLINE void StoreREVERB(int ch,int ns)
{
int core=ch/24;
if(iUseReverb==0) return;
else
if(iUseReverb==1) {
const int iRxl=(s_chan[ch].sval*s_chan[ch].iLeftVolume*s_chan[ch].bReverbL)/0x4000;
const int iRxr=(s_chan[ch].sval*s_chan[ch].iRightVolume*s_chan[ch].bReverbR)/0x4000;
ns<<=1;
*(sRVBStart[core]+ns) +=iRxl; *(sRVBStart[core]+ns+1)+=iRxr;
}
}
INLINE int g_buffer(int iOff,int core) {
short * p=(short *)spuMem;
iOff=(iOff)+rvb[core].CurrAddr;
while(iOff>rvb[core].EndAddr) iOff=rvb[core].StartAddr+(iOff-(rvb[core].EndAddr+1));
while(iOff<rvb[core].StartAddr) iOff=rvb[core].EndAddr-(rvb[core].StartAddr-iOff);
return (int)*(p+iOff);
}
INLINE void s_buffer(int iOff,int iVal,int core) {
short * p=(short *)spuMem;
iOff=(iOff)+rvb[core].CurrAddr;
while(iOff>rvb[core].EndAddr) iOff=rvb[core].StartAddr+(iOff-(rvb[core].EndAddr+1));
while(iOff<rvb[core].StartAddr) iOff=rvb[core].EndAddr-(rvb[core].StartAddr-iOff);
if(iVal<-32768L) iVal=-32768L;if(iVal>32767L) iVal=32767L;
*(p+iOff)=(short)iVal;
}
INLINE void s_buffer1(int iOff,int iVal,int core) {
short * p=(short *)spuMem;
iOff=(iOff)+rvb[core].CurrAddr+1;
while(iOff>rvb[core].EndAddr) iOff=rvb[core].StartAddr+(iOff-(rvb[core].EndAddr+1));
while(iOff<rvb[core].StartAddr) iOff=rvb[core].EndAddr-(rvb[core].StartAddr-iOff);
if(iVal<-32768L) iVal=-32768L;if(iVal>32767L) iVal=32767L;
*(p+iOff)=(short)iVal;
}
INLINE int MixREVERBLeft(int ns,int core)
{
if(iUseReverb==1)
{
if(!rvb[core].StartAddr || !rvb[core].EndAddr ||
rvb[core].StartAddr>=rvb[core].EndAddr) {
rvb[core].iLastRVBLeft=rvb[core].iLastRVBRight=rvb[core].iRVBLeft=rvb[core].iRVBRight=0;
return 0;
}
rvb[core].iCnt++;
if(rvb[core].iCnt&1) {
if((spuCtrl2[core]&0x80)) {
int ACC0,ACC1,FB_A0,FB_A1,FB_B0,FB_B1;
const int INPUT_SAMPLE_L=*(sRVBStart[core]+(ns<<1));
const int INPUT_SAMPLE_R=*(sRVBStart[core]+(ns<<1)+1);
const int IIR_INPUT_A0 = (g_buffer(rvb[core].IIR_SRC_A0,core) * rvb[core].IIR_COEF)/32768L + (INPUT_SAMPLE_L * rvb[core].IN_COEF_L)/32768L;
const int IIR_INPUT_A1 = (g_buffer(rvb[core].IIR_SRC_A1,core) * rvb[core].IIR_COEF)/32768L + (INPUT_SAMPLE_R * rvb[core].IN_COEF_R)/32768L;
const int IIR_INPUT_B0 = (g_buffer(rvb[core].IIR_SRC_B0,core) * rvb[core].IIR_COEF)/32768L + (INPUT_SAMPLE_L * rvb[core].IN_COEF_L)/32768L;
const int IIR_INPUT_B1 = (g_buffer(rvb[core].IIR_SRC_B1,core) * rvb[core].IIR_COEF)/32768L + (INPUT_SAMPLE_R * rvb[core].IN_COEF_R)/32768L;
const int IIR_A0 = (IIR_INPUT_A0 * rvb[core].IIR_ALPHA)/32768L + (g_buffer(rvb[core].IIR_DEST_A0,core) * (32768L - rvb[core].IIR_ALPHA))/32768L;
const int IIR_A1 = (IIR_INPUT_A1 * rvb[core].IIR_ALPHA)/32768L + (g_buffer(rvb[core].IIR_DEST_A1,core) * (32768L - rvb[core].IIR_ALPHA))/32768L;
const int IIR_B0 = (IIR_INPUT_B0 * rvb[core].IIR_ALPHA)/32768L + (g_buffer(rvb[core].IIR_DEST_B0,core) * (32768L - rvb[core].IIR_ALPHA))/32768L;
const int IIR_B1 = (IIR_INPUT_B1 * rvb[core].IIR_ALPHA)/32768L + (g_buffer(rvb[core].IIR_DEST_B1,core) * (32768L - rvb[core].IIR_ALPHA))/32768L;
s_buffer1(rvb[core].IIR_DEST_A0, IIR_A0,core);
s_buffer1(rvb[core].IIR_DEST_A1, IIR_A1,core);
s_buffer1(rvb[core].IIR_DEST_B0, IIR_B0,core);
s_buffer1(rvb[core].IIR_DEST_B1, IIR_B1,core);
ACC0 = (g_buffer(rvb[core].ACC_SRC_A0,core) * rvb[core].ACC_COEF_A)/32768L +
(g_buffer(rvb[core].ACC_SRC_B0,core) * rvb[core].ACC_COEF_B)/32768L +
(g_buffer(rvb[core].ACC_SRC_C0,core) * rvb[core].ACC_COEF_C)/32768L +
(g_buffer(rvb[core].ACC_SRC_D0,core) * rvb[core].ACC_COEF_D)/32768L;
ACC1 = (g_buffer(rvb[core].ACC_SRC_A1,core) * rvb[core].ACC_COEF_A)/32768L +
(g_buffer(rvb[core].ACC_SRC_B1,core) * rvb[core].ACC_COEF_B)/32768L +
(g_buffer(rvb[core].ACC_SRC_C1,core) * rvb[core].ACC_COEF_C)/32768L +
(g_buffer(rvb[core].ACC_SRC_D1,core) * rvb[core].ACC_COEF_D)/32768L;
FB_A0 = g_buffer(rvb[core].MIX_DEST_A0 - rvb[core].FB_SRC_A,core);
FB_A1 = g_buffer(rvb[core].MIX_DEST_A1 - rvb[core].FB_SRC_A,core);
FB_B0 = g_buffer(rvb[core].MIX_DEST_B0 - rvb[core].FB_SRC_B,core);
FB_B1 = g_buffer(rvb[core].MIX_DEST_B1 - rvb[core].FB_SRC_B,core);
s_buffer(rvb[core].MIX_DEST_A0, ACC0 - (FB_A0 * rvb[core].FB_ALPHA)/32768L,core);
s_buffer(rvb[core].MIX_DEST_A1, ACC1 - (FB_A1 * rvb[core].FB_ALPHA)/32768L,core);
s_buffer(rvb[core].MIX_DEST_B0, (rvb[core].FB_ALPHA * ACC0)/32768L - (FB_A0 * (int)(rvb[core].FB_ALPHA^0xFFFF8000))/32768L - (FB_B0 * rvb[core].FB_X)/32768L,core);
s_buffer(rvb[core].MIX_DEST_B1, (rvb[core].FB_ALPHA * ACC1)/32768L - (FB_A1 * (int)(rvb[core].FB_ALPHA^0xFFFF8000))/32768L - (FB_B1 * rvb[core].FB_X)/32768L,core);
rvb[core].iLastRVBLeft = rvb[core].iRVBLeft;
rvb[core].iLastRVBRight = rvb[core].iRVBRight;
rvb[core].iRVBLeft = (g_buffer(rvb[core].MIX_DEST_A0,core)+g_buffer(rvb[core].MIX_DEST_B0,core))/3;
rvb[core].iRVBRight = (g_buffer(rvb[core].MIX_DEST_A1,core)+g_buffer(rvb[core].MIX_DEST_B1,core))/3;
rvb[core].iRVBLeft = (rvb[core].iRVBLeft * rvb[core].VolLeft) / 0x4000;
rvb[core].iRVBRight = (rvb[core].iRVBRight * rvb[core].VolRight) / 0x4000;
rvb[core].CurrAddr++;
if(rvb[core].CurrAddr>rvb[core].EndAddr) rvb[core].CurrAddr=rvb[core].StartAddr;
return rvb[core].iLastRVBLeft+(rvb[core].iRVBLeft-rvb[core].iLastRVBLeft)/2;
}
else {
rvb[core].iLastRVBLeft=rvb[core].iLastRVBRight=rvb[core].iRVBLeft=rvb[core].iRVBRight=0;
}
rvb[core].CurrAddr++;
if(rvb[core].CurrAddr>rvb[core].EndAddr) rvb[core].CurrAddr=rvb[core].StartAddr;
}
return rvb[core].iLastRVBLeft;
}
return 0;
}
INLINE int MixREVERBRight(int core)
{
if(iUseReverb==1) {
int i=rvb[core].iLastRVBRight+(rvb[core].iRVBRight-rvb[core].iLastRVBRight)/2;
rvb[core].iLastRVBRight=rvb[core].iRVBRight;
return i; }
return 0;
}
#endif