SoundUnit: implement missing input line emulation

This commit is contained in:
tildearrow 2022-08-06 16:22:57 -05:00
parent 5534f55f7a
commit f03123fd75
2 changed files with 69 additions and 4 deletions

View file

@ -5,9 +5,22 @@
#define minval(a,b) (((a)<(b))?(a):(b)) #define minval(a,b) (((a)<(b))?(a):(b))
#define maxval(a,b) (((a)>(b))?(a):(b)) #define maxval(a,b) (((a)>(b))?(a):(b))
#define FILVOL chan[4].special1C
#define ILCTRL chan[4].special1D
#define ILSIZE chan[5].special1C
#define FIL1 chan[5].special1D
#define IL1 chan[6].special1C
#define IL2 chan[6].special1D
#define IL0 chan[7].special1C
#define MVOL chan[7].special1D
void SoundUnit::NextSample(short* l, short* r) { void SoundUnit::NextSample(short* l, short* r) {
// run channels
for (int i=0; i<8; i++) { for (int i=0; i<8; i++) {
if (chan[i].vol==0 && !chan[i].flags.swvol) {fns[i]=0; continue;} if (chan[i].vol==0 && !chan[i].flags.swvol) {
fns[i]=0;
continue;
}
if (chan[i].flags.pcm) { if (chan[i].flags.pcm) {
ns[i]=pcm[chan[i].pcmpos]; ns[i]=pcm[chan[i].pcmpos];
} else switch (chan[i].flags.shape) { } else switch (chan[i].flags.shape) {
@ -48,7 +61,6 @@ void SoundUnit::NextSample(short* l, short* r) {
pcmdec[i]-=32768; pcmdec[i]-=32768;
if (chan[i].pcmpos<chan[i].pcmbnd) { if (chan[i].pcmpos<chan[i].pcmbnd) {
chan[i].pcmpos++; chan[i].pcmpos++;
chan[i].wc++;
if (chan[i].pcmpos==chan[i].pcmbnd) { if (chan[i].pcmpos==chan[i].pcmbnd) {
if (chan[i].flags.pcmloop) { if (chan[i].flags.pcmloop) {
chan[i].pcmpos=chan[i].pcmrst; chan[i].pcmpos=chan[i].pcmrst;
@ -221,9 +233,52 @@ void SoundUnit::NextSample(short* l, short* r) {
nsR[i]=0; nsR[i]=0;
} }
} }
// mix
tnsL=(nsL[0]+nsL[1]+nsL[2]+nsL[3]+nsL[4]+nsL[5]+nsL[6]+nsL[7])>>2; tnsL=(nsL[0]+nsL[1]+nsL[2]+nsL[3]+nsL[4]+nsL[5]+nsL[6]+nsL[7])>>2;
tnsR=(nsR[0]+nsR[1]+nsR[2]+nsR[3]+nsR[4]+nsR[5]+nsR[6]+nsR[7])>>2; tnsR=(nsR[0]+nsR[1]+nsR[2]+nsR[3]+nsR[4]+nsR[5]+nsR[6]+nsR[7])>>2;
// write input lines to sample memory
if (ILSIZE&64) {
if (++ilBufPeriod>=((1+(FIL1>>4))<<2)) {
ilBufPeriod=0;
unsigned short ilLowerBound=pcmSize-((1+(ILSIZE&63))<<7);
if (ilBufPos<ilLowerBound) ilBufPos=ilLowerBound;
switch (ILCTRL&3) {
case 0:
ilFeedback0=ilFeedback1=pcm[ilBufPos];
pcm[ilBufPos]=IL0+((pcm[ilBufPos]*(FIL1&15))>>4);
if (++ilBufPos>=pcmSize) ilBufPos=ilLowerBound;
break;
case 1:
ilFeedback0=ilFeedback1=pcm[ilBufPos];
pcm[ilBufPos]=IL1+((pcm[ilBufPos]*(FIL1&15))>>4);
if (++ilBufPos>=pcmSize) ilBufPos=ilLowerBound;
break;
case 2:
ilFeedback0=ilFeedback1=pcm[ilBufPos];
pcm[ilBufPos]=IL2+((pcm[ilBufPos]*(FIL1&15))>>4);
if (++ilBufPos>=pcmSize) ilBufPos=ilLowerBound;
break;
case 3:
ilFeedback0=pcm[ilBufPos];
pcm[ilBufPos]=IL1+((pcm[ilBufPos]*(FIL1&15))>>4);
if (++ilBufPos>=pcmSize) ilBufPos=ilLowerBound;
ilFeedback1=pcm[ilBufPos];
pcm[ilBufPos]=IL2+((pcm[ilBufPos]*(FIL1&15))>>4);
if (++ilBufPos>=pcmSize) ilBufPos=ilLowerBound;
break;
}
}
if (ILSIZE&128) {
tnsL+=ilFeedback1*(signed char)FILVOL;
tnsR+=ilFeedback0*(signed char)FILVOL;
} else {
tnsL+=ilFeedback0*(signed char)FILVOL;
tnsR+=ilFeedback1*(signed char)FILVOL;
}
}
*l=minval(32767,maxval(-32767,tnsL)); *l=minval(32767,maxval(-32767,tnsL));
*r=minval(32767,maxval(-32767,tnsR)); *r=minval(32767,maxval(-32767,tnsR));
} }
@ -272,6 +327,10 @@ void SoundUnit::Reset() {
} }
tnsL=0; tnsL=0;
tnsR=0; tnsR=0;
ilBufPos=0;
ilBufPeriod=0;
ilFeedback0=0;
ilFeedback1=0;
memset(chan,0,sizeof(SUChannel)*8); memset(chan,0,sizeof(SUChannel)*8);
} }

View file

@ -20,6 +20,10 @@ class SoundUnit {
int nshigh[8]; int nshigh[8];
int nsband[8]; int nsband[8];
int tnsL, tnsR; int tnsL, tnsR;
unsigned char ilBufPeriod;
unsigned short ilBufPos;
signed char ilFeedback0;
signed char ilFeedback1;
unsigned short oldfreq[8]; unsigned short oldfreq[8];
unsigned short oldflags[8]; unsigned short oldflags[8];
unsigned int pcmSize; unsigned int pcmSize;
@ -80,11 +84,13 @@ class SoundUnit {
unsigned char dir: 1; unsigned char dir: 1;
unsigned char bound; unsigned char bound;
} swcut; } swcut;
unsigned short wc; unsigned char special1C;
unsigned char special1D;
unsigned short restimer; unsigned short restimer;
} chan[8]; } chan[8];
signed char pcm[65536]; signed char pcm[65536];
bool muted[8]; bool muted[8];
void SetIL0(unsigned char addr);
void Write(unsigned char addr, unsigned char data); void Write(unsigned char addr, unsigned char data);
void NextSample(short* l, short* r); void NextSample(short* l, short* r);
inline int GetSample(int ch) { inline int GetSample(int ch) {