From e8130caa5211389c263ba8cec0a6ef9a89446d17 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 11 Jul 2023 17:21:51 -0500 Subject: [PATCH] C64: fix dSID multi-chip --- src/engine/platform/c64.cpp | 18 ++++++++++++++++++ src/engine/platform/c64.h | 1 + src/engine/platform/sound/c64_d/dsid.c | 19 +++++++++++-------- src/engine/platform/sound/c64_d/dsid.h | 2 ++ 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index b41a52d5..028bb94d 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -613,6 +613,24 @@ void DivPlatformC64::setFlags(const DivConfig& flags) { keyPriority=flags.getBool("keyPriority",true); testAD=((flags.getInt("testAttack",0)&15)<<4)|(flags.getInt("testDecay",0)&15); testSR=((flags.getInt("testSustain",0)&15)<<4)|(flags.getInt("testRelease",0)&15); + + // init fake filter table + // taken from dSID + double cutRatio=-2.0*3.14*(sidIs6581?(((double)oscBuf[0]->rate/44100.0)*(20000.0/256.0)):(12500.0/256.0))/(double)oscBuf[0]->rate; + + for (int i=0; i<2048; i++) { + double c=(double)i/8.0+0.2; + if (sidIs6581) { + if (c<24) { + c=2.0*sin(771.78/(double)oscBuf[0]->rate); + } else { + c=(44100.0/(double)oscBuf[0]->rate)-1.263*(44100.0/(double)oscBuf[0]->rate)*exp(c*cutRatio); + } + } else { + c=1-exp(c*cutRatio); + } + fakeCutTable[i]=c; + } } int DivPlatformC64::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) { diff --git a/src/engine/platform/c64.h b/src/engine/platform/c64.h index 26b39c80..44db167d 100644 --- a/src/engine/platform/c64.h +++ b/src/engine/platform/c64.h @@ -56,6 +56,7 @@ class DivPlatformC64: public DivDispatch { Channel chan[3]; DivDispatchOscBuffer* oscBuf[3]; bool isMuted[3]; + float fakeCutTable[2048]; struct QueuedWrite { unsigned char addr; unsigned char val; diff --git a/src/engine/platform/sound/c64_d/dsid.c b/src/engine/platform/sound/c64_d/dsid.c index d01dc7ad..2ff2dacf 100644 --- a/src/engine/platform/sound/c64_d/dsid.c +++ b/src/engine/platform/sound/c64_d/dsid.c @@ -115,11 +115,17 @@ void dSID_init(struct SID_chip* sid, double clockRate, double samplingRate, int double prd0 = sid->g.ckr > 9 ? sid->g.ckr : 9; sid->g.Aprd[0] = prd0; sid->g.Astp[0] = ceil(prd0 / 9); + + for (int i=0; i<3; i++) { + sid->fakeplp[i]=0; + sid->fakepbp[i]=0; + } } double dSID_render(struct SID_chip* sid) { double flin = 0, output = 0; double wfout = 0; + double step = 0; for (int chn = 0; chn < 3; chn++) { struct SIDVOICE *voic = &((struct SIDMEM *) (sid->M))->v[chn]; double pgt = (sid->SIDct->ch[chn].Ast & GAT); @@ -142,7 +148,6 @@ double dSID_render(struct SID_chip* sid) { if (sid->SIDct->ch[chn].rcnt >= 0x8000) sid->SIDct->ch[chn].rcnt -= 0x8000; - static double step; double prd; if (sid->SIDct->ch[chn].Ast & ATK) { @@ -291,8 +296,6 @@ double dSID_render(struct SID_chip* sid) { // mostly copypasted from below double fakeflin = chnout; double fakeflout = 0; - static double fakeplp[3] = {0}; - static double fakepbp[3] = {0}; double ctf = sid->g.ctf_table[((sid->M[0x15]&7)|(sid->M[0x16]<<3))&0x7ff]; double reso; if (sid->g.model == 8580) { @@ -300,15 +303,15 @@ double dSID_render(struct SID_chip* sid) { } else { reso = (sid->M[0x17] > 0x5F) ? 8.0 / (double) (sid->M[0x17] >> 4) : 1.41; } - double tmp = fakeflin + fakepbp[chn] * reso + fakeplp[chn]; + double tmp = fakeflin + sid->fakepbp[chn] * reso + sid->fakeplp[chn]; if (sid->M[0x18] & HP) fakeflout -= tmp; - tmp = fakepbp[chn] - tmp * ctf; - fakepbp[chn] = tmp; + tmp = sid->fakepbp[chn] - tmp * ctf; + sid->fakepbp[chn] = tmp; if (sid->M[0x18] & BP) fakeflout -= tmp; - tmp = fakeplp[chn] + tmp * ctf; - fakeplp[chn] = tmp; + tmp = sid->fakeplp[chn] + tmp * ctf; + sid->fakeplp[chn] = tmp; if (sid->M[0x18] & LP) fakeflout += tmp; diff --git a/src/engine/platform/sound/c64_d/dsid.h b/src/engine/platform/sound/c64_d/dsid.h index b02d1870..b17a51f5 100644 --- a/src/engine/platform/sound/c64_d/dsid.h +++ b/src/engine/platform/sound/c64_d/dsid.h @@ -81,6 +81,8 @@ struct SID_chip { uint8_t M[MemLen]; int16_t lastOut[3]; int mute_mask; + double fakeplp[3]; + double fakepbp[3]; }; double dSID_render(struct SID_chip* sid);