diff --git a/src/filter.c b/src/filter.c index 6f1f73f..0627058 100644 --- a/src/filter.c +++ b/src/filter.c @@ -41,8 +41,9 @@ void SexyFilter2(int32 *in, int32 count) { } } +int64 sexyfilter_acc1 = 0, sexyfilter_acc2 = 0; + void SexyFilter(int32 *in, int32 *out, int32 count) { - static int64 acc1 = 0, acc2 = 0; int32 mul1, mul2, vmul; mul1 = (94 << 16) / FSettings.SndRate; @@ -56,12 +57,12 @@ void SexyFilter(int32 *in, int32 *out, int32 count) { while (count) { int64 ino = (int64) * in * vmul; - acc1 += ((ino - acc1) * mul1) >> 16; - acc2 += ((ino - acc1 - acc2) * mul2) >> 16; + sexyfilter_acc1 += ((ino - sexyfilter_acc1) * mul1) >> 16; + sexyfilter_acc2 += ((ino - sexyfilter_acc1 - sexyfilter_acc2) * mul2) >> 16; /* printf("%d ",*in); */ *in = 0; { - int32 t = (acc1 - ino + acc2) >> 16; + int32 t = (sexyfilter_acc1 - ino + sexyfilter_acc2) >> 16; /* if(t>32767 || t<-32768) printf("Flow: %d\n",t); */ if (t > 32767) t = 32767; if (t < -32768) t = -32768; diff --git a/src/filter.h b/src/filter.h index ca31e7e..f913508 100644 --- a/src/filter.h +++ b/src/filter.h @@ -5,4 +5,6 @@ int32 NeoFilterSound(int32 *in, int32 *out, uint32 inlen, int32 *leftover); void MakeFilters(int32 rate); void SexyFilter(int32 *in, int32 *out, int32 count); +extern int64 sexyfilter_acc1, sexyfilter_acc2; + #endif diff --git a/src/sound.c b/src/sound.c index ec16307..3d84251 100644 --- a/src/sound.c +++ b/src/sound.c @@ -706,11 +706,11 @@ static void RDoTriangle(void) { ChannelBC[2] = SOUNDTS; } -static void RDoTriangleNoisePCMLQ(void) { - static uint32 tcout = 0; - static int32 triacc = 0; - static int32 noiseacc = 0; +uint32 lq_tcout = 0; +int32 lq_triacc = 0; +int32 lq_noiseacc = 0; +static void RDoTriangleNoisePCMLQ(void) { int32 V; int32 start, end; int32 freq[2]; @@ -752,77 +752,77 @@ static void RDoTriangleNoisePCMLQ(void) { nshift = 13; - totalout = wlookup2[tcout + noiseout + RawDALatch]; + totalout = wlookup2[lq_tcout + noiseout + RawDALatch]; if (inie[0] && inie[1]) { for (V = start; V < end; V++) { Wave[V >> 4] += totalout; - triacc -= inie[0]; - noiseacc -= inie[1]; + lq_triacc -= inie[0]; + lq_noiseacc -= inie[1]; - if (triacc <= 0) { + if (lq_triacc <= 0) { rea: - triacc += freq[0]; /* t; */ + lq_triacc += freq[0]; /* t; */ tristep = (tristep + 1) & 0x1F; - if (triacc <= 0) goto rea; - tcout = (tristep & 0xF); - if (!(tristep & 0x10)) tcout ^= 0xF; - tcout = tcout * 3; - totalout = wlookup2[tcout + noiseout + RawDALatch]; + if (lq_triacc <= 0) goto rea; + lq_tcout = (tristep & 0xF); + if (!(tristep & 0x10)) lq_tcout ^= 0xF; + lq_tcout = lq_tcout * 3; + totalout = wlookup2[lq_tcout + noiseout + RawDALatch]; } - if (noiseacc <= 0) { + if (lq_noiseacc <= 0) { rea2: /* used to added <<(16+2) when the noise table * values were half. */ if (PAL) - noiseacc += PALNoiseFreqTable[PSG[0xE] & 0xF] << (16 + 1); + lq_noiseacc += PALNoiseFreqTable[PSG[0xE] & 0xF] << (16 + 1); else - noiseacc += NTSCNoiseFreqTable[PSG[0xE] & 0xF] << (16 + 1); + lq_noiseacc += NTSCNoiseFreqTable[PSG[0xE] & 0xF] << (16 + 1); nreg = (nreg << 1) + (((nreg >> nshift) ^ (nreg >> 14)) & 1); nreg &= 0x7fff; noiseout = amptab[(nreg >> 0xe) & 1]; - if (noiseacc <= 0) goto rea2; - totalout = wlookup2[tcout + noiseout + RawDALatch]; + if (lq_noiseacc <= 0) goto rea2; + totalout = wlookup2[lq_tcout + noiseout + RawDALatch]; } /* noiseacc<=0 */ } /* for(V=... */ } else if (inie[0]) { for (V = start; V < end; V++) { Wave[V >> 4] += totalout; - triacc -= inie[0]; + lq_triacc -= inie[0]; - if (triacc <= 0) { + if (lq_triacc <= 0) { area: - triacc += freq[0]; /* t; */ + lq_triacc += freq[0]; /* t; */ tristep = (tristep + 1) & 0x1F; - if (triacc <= 0) goto area; - tcout = (tristep & 0xF); - if (!(tristep & 0x10)) tcout ^= 0xF; - tcout = tcout * 3; - totalout = wlookup2[tcout + noiseout + RawDALatch]; + if (lq_triacc <= 0) goto area; + lq_tcout = (tristep & 0xF); + if (!(tristep & 0x10)) lq_tcout ^= 0xF; + lq_tcout = lq_tcout * 3; + totalout = wlookup2[lq_tcout + noiseout + RawDALatch]; } } } else if (inie[1]) { for (V = start; V < end; V++) { Wave[V >> 4] += totalout; - noiseacc -= inie[1]; - if (noiseacc <= 0) { + lq_noiseacc -= inie[1]; + if (lq_noiseacc <= 0) { area2: /* used to be added <<(16+2) when the noise table * values were half. */ if (PAL) - noiseacc += PALNoiseFreqTable[PSG[0xE] & 0xF] << (16 + 1); + lq_noiseacc += PALNoiseFreqTable[PSG[0xE] & 0xF] << (16 + 1); else - noiseacc += NTSCNoiseFreqTable[PSG[0xE] & 0xF] << (16 + 1); + lq_noiseacc += NTSCNoiseFreqTable[PSG[0xE] & 0xF] << (16 + 1); nreg = (nreg << 1) + (((nreg >> nshift) ^ (nreg >> 14)) & 1); nreg &= 0x7fff; noiseout = amptab[(nreg >> 0xe) & 1]; - if (noiseacc <= 0) goto area2; - totalout = wlookup2[tcout + noiseout + RawDALatch]; + if (lq_noiseacc <= 0) goto area2; + totalout = wlookup2[lq_tcout + noiseout + RawDALatch]; } /* noiseacc<=0 */ } } else { @@ -1162,7 +1162,31 @@ SFORMAT FCEUSND_STATEINFO[] = { { &DMCAddressLatch, 1, "5ADL" }, { &DMCFormat, 1, "5FMT" }, { &RawDALatch, 1, "RWDA" }, - { 0 } + + //these are important for smooth sound after loading state + { &sqacc[0], sizeof(sqacc[0]) | FCEUSTATE_RLSB, "SAC1" }, + { &sqacc[1], sizeof(sqacc[1]) | FCEUSTATE_RLSB, "SAC2" }, + { &RectDutyCount, sizeof(RectDutyCount) | FCEUSTATE_RLSB, "RCTD"}, + { &tristep, sizeof(tristep) | FCEUSTATE_RLSB, "TRIS"}, + { &lq_triacc, sizeof(lq_triacc) | FCEUSTATE_RLSB, "TACC" }, + { &lq_noiseacc, sizeof(lq_noiseacc) | FCEUSTATE_RLSB, "NACC" }, + + //not sure about these, but save/load them anyway + { &ChannelBC[0], sizeof(ChannelBC[1]) | FCEUSTATE_RLSB, "CBC1" }, + { &ChannelBC[1], sizeof(ChannelBC[1]) | FCEUSTATE_RLSB, "CBC2" }, + { &ChannelBC[2], sizeof(ChannelBC[2]) | FCEUSTATE_RLSB, "CBC3" }, + { &ChannelBC[3], sizeof(ChannelBC[3]) | FCEUSTATE_RLSB, "CBC4" }, + { &ChannelBC[4], sizeof(ChannelBC[4]) | FCEUSTATE_RLSB, "CBC5" }, + { &sound_timestamp, sizeof(sound_timestamp) | FCEUSTATE_RLSB, "SNTS" }, + { &soundtsoffs, sizeof(soundtsoffs) | FCEUSTATE_RLSB, "TSOF"}, + { &wlcount[0], sizeof(wlcount[0]) | FCEUSTATE_RLSB, "WLC1" }, + { &wlcount[1], sizeof(wlcount[1]) | FCEUSTATE_RLSB, "WLC2" }, + { &wlcount[2], sizeof(wlcount[2]) | FCEUSTATE_RLSB, "WLC3" }, + { &wlcount[3], sizeof(wlcount[3]) | FCEUSTATE_RLSB, "WLC4" }, + { &sexyfilter_acc1, sizeof(sexyfilter_acc1) | FCEUSTATE_RLSB, "FAC1" }, + { &sexyfilter_acc2, sizeof(sexyfilter_acc2) | FCEUSTATE_RLSB, "FAC2" }, + { &lq_tcout, sizeof(lq_tcout) | FCEUSTATE_RLSB, "TCOU"}, +{ 0 } }; void FCEUSND_SaveState(void) {