mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-04 20:05:05 +00:00
SoundUnit: implement missing input line emulation
This commit is contained in:
parent
5534f55f7a
commit
f03123fd75
2 changed files with 69 additions and 4 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue