SNES: fix some clicking issues
This commit is contained in:
parent
ec22150fb5
commit
6179ef493c
|
@ -69,14 +69,16 @@ void DivPlatformSNES::acquire(short* bufL, short* bufR, size_t start, size_t len
|
||||||
short out[2];
|
short out[2];
|
||||||
short chOut[16];
|
short chOut[16];
|
||||||
for (size_t h=start; h<start+len; h++) {
|
for (size_t h=start; h<start+len; h++) {
|
||||||
// TODO: delay
|
if (--delay<=0) {
|
||||||
if (!writes.empty()) {
|
delay=0;
|
||||||
QueuedWrite w=writes.front();
|
if (!writes.empty()) {
|
||||||
dsp.write(w.addr,w.val);
|
QueuedWrite w=writes.front();
|
||||||
regPool[w.addr&0x7f]=w.val;
|
dsp.write(w.addr,w.val);
|
||||||
writes.pop();
|
regPool[w.addr&0x7f]=w.val;
|
||||||
|
writes.pop();
|
||||||
|
delay=(w.addr==0x5c)?8:1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dsp.set_output(out,1);
|
dsp.set_output(out,1);
|
||||||
dsp.run(32);
|
dsp.run(32);
|
||||||
dsp.get_voice_outputs(chOut);
|
dsp.get_voice_outputs(chOut);
|
||||||
|
@ -159,7 +161,7 @@ void DivPlatformSNES::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chan[i].std.vol.had || chan[i].std.panL.had || chan[i].std.panR.had || hasInverted) {
|
if (chan[i].std.vol.had || chan[i].std.panL.had || chan[i].std.panR.had || hasInverted) {
|
||||||
writeOutVol(i);
|
chan[i].shallWriteVol=true;
|
||||||
}
|
}
|
||||||
if (chan[i].std.ex2.had) {
|
if (chan[i].std.ex2.had) {
|
||||||
if (chan[i].std.ex2.val&0x80) {
|
if (chan[i].std.ex2.val&0x80) {
|
||||||
|
@ -182,7 +184,7 @@ void DivPlatformSNES::tick(bool sysTick) {
|
||||||
chan[i].state.gainMode=DivInstrumentSNES::GAIN_MODE_DIRECT;
|
chan[i].state.gainMode=DivInstrumentSNES::GAIN_MODE_DIRECT;
|
||||||
chan[i].state.gain=chan[i].std.ex2.val&127;
|
chan[i].state.gain=chan[i].std.ex2.val&127;
|
||||||
}
|
}
|
||||||
writeEnv(i);
|
chan[i].shallWriteEnv=true;
|
||||||
}
|
}
|
||||||
if (chan[i].setPos) {
|
if (chan[i].setPos) {
|
||||||
// force keyon
|
// force keyon
|
||||||
|
@ -196,6 +198,8 @@ void DivPlatformSNES::tick(bool sysTick) {
|
||||||
updateWave(i);
|
updateWave(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
for (int i=0; i<8; i++) {
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
DivSample* s=parent->getSample(chan[i].sample);
|
DivSample* s=parent->getSample(chan[i].sample);
|
||||||
double off=(s->centerRate>=1)?((double)s->centerRate/8363.0):1.0;
|
double off=(s->centerRate>=1)?((double)s->centerRate/8363.0):1.0;
|
||||||
|
@ -228,6 +232,7 @@ void DivPlatformSNES::tick(bool sysTick) {
|
||||||
sampleMem[tabAddr+2]=loop&0xff;
|
sampleMem[tabAddr+2]=loop&0xff;
|
||||||
sampleMem[tabAddr+3]=loop>>8;
|
sampleMem[tabAddr+3]=loop>>8;
|
||||||
kon|=(1<<i);
|
kon|=(1<<i);
|
||||||
|
koff|=(1<<i);
|
||||||
chan[i].keyOn=false;
|
chan[i].keyOn=false;
|
||||||
}
|
}
|
||||||
if (chan[i].keyOff) {
|
if (chan[i].keyOff) {
|
||||||
|
@ -243,6 +248,9 @@ void DivPlatformSNES::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (koff!=0) {
|
||||||
|
rWrite(0x5c,koff);
|
||||||
|
}
|
||||||
if (writeControl) {
|
if (writeControl) {
|
||||||
unsigned char control=(noiseFreq&0x1f)|(echoOn?0:0x20);
|
unsigned char control=(noiseFreq&0x1f)|(echoOn?0:0x20);
|
||||||
rWrite(0x6c,control);
|
rWrite(0x6c,control);
|
||||||
|
@ -290,11 +298,24 @@ void DivPlatformSNES::tick(bool sysTick) {
|
||||||
rWrite(0x4d,echoBits);
|
rWrite(0x4d,echoBits);
|
||||||
writeEcho=false;
|
writeEcho=false;
|
||||||
}
|
}
|
||||||
|
for (int i=0; i<8; i++) {
|
||||||
|
if (chan[i].shallWriteEnv) {
|
||||||
|
writeEnv(i);
|
||||||
|
chan[i].shallWriteEnv=false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (koff!=0) {
|
||||||
|
rWrite(0x5c,0);
|
||||||
|
}
|
||||||
if (kon!=0) {
|
if (kon!=0) {
|
||||||
rWrite(0x4c,kon);
|
rWrite(0x4c,kon);
|
||||||
}
|
}
|
||||||
// always write KOFF as it's constantly polled
|
for (int i=0; i<8; i++) {
|
||||||
rWrite(0x5c,koff);
|
if (chan[i].shallWriteVol) {
|
||||||
|
writeOutVol(i);
|
||||||
|
chan[i].shallWriteVol=false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformSNES::dispatch(DivCommand c) {
|
int DivPlatformSNES::dispatch(DivCommand c) {
|
||||||
|
@ -324,7 +345,7 @@ int DivPlatformSNES::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
chan[c.chan].active=true;
|
chan[c.chan].active=true;
|
||||||
if (chan[c.chan].insChanged || chan[c.chan].state.sus) {
|
if (chan[c.chan].insChanged || chan[c.chan].state.sus) {
|
||||||
writeEnv(c.chan);
|
chan[c.chan].shallWriteEnv=true;
|
||||||
}
|
}
|
||||||
if (c.value!=DIV_NOTE_NULL) {
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
chan[c.chan].baseFreq=round(NOTE_FREQUENCY(c.value));
|
chan[c.chan].baseFreq=round(NOTE_FREQUENCY(c.value));
|
||||||
|
@ -341,7 +362,7 @@ int DivPlatformSNES::dispatch(DivCommand c) {
|
||||||
chan[c.chan].keyOff=true;
|
chan[c.chan].keyOff=true;
|
||||||
chan[c.chan].keyOn=false;
|
chan[c.chan].keyOn=false;
|
||||||
if (chan[c.chan].state.sus) {
|
if (chan[c.chan].state.sus) {
|
||||||
writeEnv(c.chan);
|
chan[c.chan].shallWriteEnv=true;
|
||||||
} else {
|
} else {
|
||||||
chan[c.chan].macroInit(NULL);
|
chan[c.chan].macroInit(NULL);
|
||||||
}
|
}
|
||||||
|
@ -351,7 +372,7 @@ int DivPlatformSNES::dispatch(DivCommand c) {
|
||||||
chan[c.chan].keyOff=true;
|
chan[c.chan].keyOff=true;
|
||||||
chan[c.chan].keyOn=false;
|
chan[c.chan].keyOn=false;
|
||||||
if (chan[c.chan].state.sus) {
|
if (chan[c.chan].state.sus) {
|
||||||
writeEnv(c.chan);
|
chan[c.chan].shallWriteEnv=true;
|
||||||
}
|
}
|
||||||
chan[c.chan].std.release();
|
chan[c.chan].std.release();
|
||||||
break;
|
break;
|
||||||
|
@ -369,7 +390,7 @@ int DivPlatformSNES::dispatch(DivCommand c) {
|
||||||
chan[c.chan].vol=c.value;
|
chan[c.chan].vol=c.value;
|
||||||
if (!chan[c.chan].std.vol.has) {
|
if (!chan[c.chan].std.vol.has) {
|
||||||
chan[c.chan].outVol=c.value;
|
chan[c.chan].outVol=c.value;
|
||||||
writeOutVol(c.chan);
|
chan[c.chan].shallWriteVol=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -379,7 +400,7 @@ int DivPlatformSNES::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_PANNING:
|
case DIV_CMD_PANNING:
|
||||||
chan[c.chan].panL=c.value>>1;
|
chan[c.chan].panL=c.value>>1;
|
||||||
chan[c.chan].panR=c.value2>>1;
|
chan[c.chan].panR=c.value2>>1;
|
||||||
writeOutVol(c.chan);
|
chan[c.chan].shallWriteVol=true;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PITCH:
|
case DIV_CMD_PITCH:
|
||||||
chan[c.chan].pitch=c.value;
|
chan[c.chan].pitch=c.value;
|
||||||
|
@ -441,7 +462,7 @@ int DivPlatformSNES::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_SNES_INVERT:
|
case DIV_CMD_SNES_INVERT:
|
||||||
chan[c.chan].invertL=(c.value>>4);
|
chan[c.chan].invertL=(c.value>>4);
|
||||||
chan[c.chan].invertR=c.chan&15;
|
chan[c.chan].invertR=c.chan&15;
|
||||||
writeOutVol(c.chan);
|
chan[c.chan].shallWriteVol=true;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_SNES_GAIN_MODE:
|
case DIV_CMD_SNES_GAIN_MODE:
|
||||||
if (c.value) {
|
if (c.value) {
|
||||||
|
@ -466,7 +487,7 @@ int DivPlatformSNES::dispatch(DivCommand c) {
|
||||||
} else {
|
} else {
|
||||||
chan[c.chan].state.useEnv=true;
|
chan[c.chan].state.useEnv=true;
|
||||||
}
|
}
|
||||||
writeEnv(c.chan);
|
chan[c.chan].shallWriteEnv=true;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_SNES_GAIN:
|
case DIV_CMD_SNES_GAIN:
|
||||||
if (chan[c.chan].state.gainMode==DivInstrumentSNES::GAIN_MODE_DIRECT) {
|
if (chan[c.chan].state.gainMode==DivInstrumentSNES::GAIN_MODE_DIRECT) {
|
||||||
|
@ -474,7 +495,7 @@ int DivPlatformSNES::dispatch(DivCommand c) {
|
||||||
} else {
|
} else {
|
||||||
chan[c.chan].state.gain=c.value&0x1f;
|
chan[c.chan].state.gain=c.value&0x1f;
|
||||||
}
|
}
|
||||||
if (!chan[c.chan].state.useEnv) writeEnv(c.chan);
|
if (!chan[c.chan].state.useEnv) chan[c.chan].shallWriteEnv=true;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_STD_NOISE_FREQ:
|
case DIV_CMD_STD_NOISE_FREQ:
|
||||||
noiseFreq=c.value&0x1f;
|
noiseFreq=c.value&0x1f;
|
||||||
|
@ -482,19 +503,19 @@ int DivPlatformSNES::dispatch(DivCommand c) {
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_FM_AR:
|
case DIV_CMD_FM_AR:
|
||||||
chan[c.chan].state.a=c.value&15;
|
chan[c.chan].state.a=c.value&15;
|
||||||
if (chan[c.chan].state.useEnv) writeEnv(c.chan);
|
if (chan[c.chan].state.useEnv) chan[c.chan].shallWriteEnv=true;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_FM_DR:
|
case DIV_CMD_FM_DR:
|
||||||
chan[c.chan].state.d=c.value&7;
|
chan[c.chan].state.d=c.value&7;
|
||||||
if (chan[c.chan].state.useEnv) writeEnv(c.chan);
|
if (chan[c.chan].state.useEnv) chan[c.chan].shallWriteEnv=true;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_FM_SL:
|
case DIV_CMD_FM_SL:
|
||||||
chan[c.chan].state.s=c.value&7;
|
chan[c.chan].state.s=c.value&7;
|
||||||
if (chan[c.chan].state.useEnv) writeEnv(c.chan);
|
if (chan[c.chan].state.useEnv) chan[c.chan].shallWriteEnv=true;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_FM_RR:
|
case DIV_CMD_FM_RR:
|
||||||
chan[c.chan].state.r=c.value&0x1f;
|
chan[c.chan].state.r=c.value&0x1f;
|
||||||
if (chan[c.chan].state.useEnv) writeEnv(c.chan);
|
if (chan[c.chan].state.useEnv) chan[c.chan].shallWriteEnv=true;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_SNES_ECHO:
|
case DIV_CMD_SNES_ECHO:
|
||||||
chan[c.chan].echo=c.value;
|
chan[c.chan].echo=c.value;
|
||||||
|
@ -605,7 +626,7 @@ void DivPlatformSNES::writeEnv(int ch) {
|
||||||
|
|
||||||
void DivPlatformSNES::muteChannel(int ch, bool mute) {
|
void DivPlatformSNES::muteChannel(int ch, bool mute) {
|
||||||
isMuted[ch]=mute;
|
isMuted[ch]=mute;
|
||||||
writeOutVol(ch);
|
chan[ch].shallWriteVol=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformSNES::forceIns() {
|
void DivPlatformSNES::forceIns() {
|
||||||
|
|
|
@ -33,7 +33,7 @@ class DivPlatformSNES: public DivDispatch {
|
||||||
int sample, wave, ins;
|
int sample, wave, ins;
|
||||||
int note;
|
int note;
|
||||||
int panL, panR;
|
int panL, panR;
|
||||||
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, useWave, setPos, noise, echo, pitchMod, invertL, invertR;
|
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, useWave, setPos, noise, echo, pitchMod, invertL, invertR, shallWriteVol, shallWriteEnv;
|
||||||
int vol, outVol;
|
int vol, outVol;
|
||||||
int wtLen;
|
int wtLen;
|
||||||
DivInstrumentSNES state;
|
DivInstrumentSNES state;
|
||||||
|
@ -68,6 +68,8 @@ class DivPlatformSNES: public DivDispatch {
|
||||||
pitchMod(false),
|
pitchMod(false),
|
||||||
invertL(false),
|
invertL(false),
|
||||||
invertR(false),
|
invertR(false),
|
||||||
|
shallWriteVol(false),
|
||||||
|
shallWriteEnv(false),
|
||||||
vol(127),
|
vol(127),
|
||||||
outVol(127),
|
outVol(127),
|
||||||
wtLen(16) {}
|
wtLen(16) {}
|
||||||
|
@ -77,6 +79,7 @@ class DivPlatformSNES: public DivDispatch {
|
||||||
bool isMuted[8];
|
bool isMuted[8];
|
||||||
int globalVolL, globalVolR;
|
int globalVolL, globalVolR;
|
||||||
unsigned char noiseFreq;
|
unsigned char noiseFreq;
|
||||||
|
signed char delay;
|
||||||
signed char echoVolL, echoVolR, echoFeedback;
|
signed char echoVolL, echoVolR, echoFeedback;
|
||||||
signed char echoFIR[8];
|
signed char echoFIR[8];
|
||||||
unsigned char echoDelay;
|
unsigned char echoDelay;
|
||||||
|
|
Loading…
Reference in New Issue