From f03123fd75a0543efc5d6af3c9709eeea342748f Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 6 Aug 2022 16:22:57 -0500 Subject: [PATCH] SoundUnit: implement missing input line emulation --- src/engine/platform/sound/su.cpp | 65 ++++++++++++++++++++++++++++++-- src/engine/platform/sound/su.h | 8 +++- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/engine/platform/sound/su.cpp b/src/engine/platform/sound/su.cpp index 0dd6dcdc..a2fd7653 100644 --- a/src/engine/platform/sound/su.cpp +++ b/src/engine/platform/sound/su.cpp @@ -5,9 +5,22 @@ #define minval(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) { + // run channels 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) { ns[i]=pcm[chan[i].pcmpos]; } else switch (chan[i].flags.shape) { @@ -48,7 +61,6 @@ void SoundUnit::NextSample(short* l, short* r) { pcmdec[i]-=32768; if (chan[i].pcmpos>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>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)); *r=minval(32767,maxval(-32767,tnsR)); } @@ -272,6 +327,10 @@ void SoundUnit::Reset() { } tnsL=0; tnsR=0; + ilBufPos=0; + ilBufPeriod=0; + ilFeedback0=0; + ilFeedback1=0; memset(chan,0,sizeof(SUChannel)*8); } diff --git a/src/engine/platform/sound/su.h b/src/engine/platform/sound/su.h index 3b125f03..0ee84348 100644 --- a/src/engine/platform/sound/su.h +++ b/src/engine/platform/sound/su.h @@ -20,6 +20,10 @@ class SoundUnit { int nshigh[8]; int nsband[8]; int tnsL, tnsR; + unsigned char ilBufPeriod; + unsigned short ilBufPos; + signed char ilFeedback0; + signed char ilFeedback1; unsigned short oldfreq[8]; unsigned short oldflags[8]; unsigned int pcmSize; @@ -80,11 +84,13 @@ class SoundUnit { unsigned char dir: 1; unsigned char bound; } swcut; - unsigned short wc; + unsigned char special1C; + unsigned char special1D; unsigned short restimer; } chan[8]; signed char pcm[65536]; bool muted[8]; + void SetIL0(unsigned char addr); void Write(unsigned char addr, unsigned char data); void NextSample(short* l, short* r); inline int GetSample(int ch) {