Smooth sound after loading state
Moved function-level static variables outside of functions and renamed them
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
92
src/sound.c
92
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) {
|
||||
|
||||
Reference in New Issue
Block a user