latency fix

This commit is contained in:
tildearrow 2022-09-23 19:01:01 -05:00
parent 5e2cefff94
commit e6fc9e09d2
4 changed files with 140 additions and 138 deletions

View file

@ -358,14 +358,6 @@ void DivPlatformYM2608::acquire(short* bufL, short* bufR, size_t start, size_t l
} }
void DivPlatformYM2608::tick(bool sysTick) { void DivPlatformYM2608::tick(bool sysTick) {
// PSG
ay->tick(sysTick);
ay->flushWrites();
for (DivRegWrite& i: ay->getRegisterWrites()) {
immWrite(i.addr&15,i.val);
}
ay->getRegisterWrites().clear();
// FM // FM
for (int i=0; i<6; i++) { for (int i=0; i<6; i++) {
if (i==2 && extMode) continue; if (i==2 && extMode) continue;
@ -522,6 +514,44 @@ void DivPlatformYM2608::tick(bool sysTick) {
chan[i].keyOff=false; chan[i].keyOff=false;
} }
} }
for (int i=16; i<512; i++) {
if (pendingWrites[i]!=oldWrites[i]) {
immWrite(i,pendingWrites[i]&0xff);
oldWrites[i]=pendingWrites[i];
}
}
for (int i=0; i<6; i++) {
if (i==2 && extMode) continue;
if (chan[i].freqChanged) {
if (parent->song.linearPitch==2) {
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11);
} else {
int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,false,4,chan[i].pitch2);
int block=(chan[i].baseFreq&0xf800)>>11;
if (fNum<0) fNum=0;
if (fNum>2047) {
while (block<7) {
fNum>>=1;
block++;
}
if (fNum>2047) fNum=2047;
}
chan[i].freq=(block<<11)|fNum;
}
if (chan[i].freq>0x3fff) chan[i].freq=0x3fff;
immWrite(chanOffs[i]+ADDR_FREQH,chan[i].freq>>8);
immWrite(chanOffs[i]+ADDR_FREQ,chan[i].freq&0xff);
chan[i].freqChanged=false;
}
if (chan[i].keyOn || chan[i].opMaskChanged) {
immWrite(0x28,(chan[i].opMask<<4)|konOffs[i]);
chan[i].opMaskChanged=false;
chan[i].keyOn=false;
}
}
// RSS // RSS
for (int i=9; i<15; i++) { for (int i=9; i<15; i++) {
if (chan[i].furnacePCM) { if (chan[i].furnacePCM) {
@ -615,47 +645,18 @@ void DivPlatformYM2608::tick(bool sysTick) {
writeRSSOff=0; writeRSSOff=0;
} }
for (int i=16; i<512; i++) {
if (pendingWrites[i]!=oldWrites[i]) {
immWrite(i,pendingWrites[i]&0xff);
oldWrites[i]=pendingWrites[i];
}
}
for (int i=0; i<6; i++) {
if (i==2 && extMode) continue;
if (chan[i].freqChanged) {
if (parent->song.linearPitch==2) {
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11);
} else {
int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,false,4,chan[i].pitch2);
int block=(chan[i].baseFreq&0xf800)>>11;
if (fNum<0) fNum=0;
if (fNum>2047) {
while (block<7) {
fNum>>=1;
block++;
}
if (fNum>2047) fNum=2047;
}
chan[i].freq=(block<<11)|fNum;
}
if (chan[i].freq>0x3fff) chan[i].freq=0x3fff;
immWrite(chanOffs[i]+ADDR_FREQH,chan[i].freq>>8);
immWrite(chanOffs[i]+ADDR_FREQ,chan[i].freq&0xff);
chan[i].freqChanged=false;
}
if (chan[i].keyOn || chan[i].opMaskChanged) {
immWrite(0x28,(chan[i].opMask<<4)|konOffs[i]);
chan[i].opMaskChanged=false;
chan[i].keyOn=false;
}
}
if (writeRSSOn) { if (writeRSSOn) {
immWrite(0x10,writeRSSOn); immWrite(0x10,writeRSSOn);
writeRSSOn=0; writeRSSOn=0;
} }
// PSG
ay->tick(sysTick);
ay->flushWrites();
for (DivRegWrite& i: ay->getRegisterWrites()) {
immWrite(i.addr&15,i.val);
}
ay->getRegisterWrites().clear();
} }
int DivPlatformYM2608::dispatch(DivCommand c) { int DivPlatformYM2608::dispatch(DivCommand c) {

View file

@ -294,15 +294,7 @@ void DivPlatformYM2610::acquire(short* bufL, short* bufR, size_t start, size_t l
} }
} }
void DivPlatformYM2610::tick(bool sysTick) { void DivPlatformYM2610::tick(bool sysTick) {
// PSG
ay->tick(sysTick);
ay->flushWrites();
for (DivRegWrite& i: ay->getRegisterWrites()) {
immWrite(i.addr&15,i.val);
}
ay->getRegisterWrites().clear();
// FM // FM
for (int i=0; i<psgChanOffs; i++) { for (int i=0; i<psgChanOffs; i++) {
if (i==1 && extMode) continue; if (i==1 && extMode) continue;
@ -460,6 +452,43 @@ void DivPlatformYM2610::tick(bool sysTick) {
} }
} }
for (int i=16; i<512; i++) {
if (pendingWrites[i]!=oldWrites[i]) {
immWrite(i,pendingWrites[i]&0xff);
oldWrites[i]=pendingWrites[i];
}
}
for (int i=0; i<psgChanOffs; i++) {
if (i==1 && extMode) continue;
if (chan[i].freqChanged) {
if (parent->song.linearPitch==2) {
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11);
} else {
int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11);
int block=(chan[i].baseFreq&0xf800)>>11;
if (fNum<0) fNum=0;
if (fNum>2047) {
while (block<7) {
fNum>>=1;
block++;
}
if (fNum>2047) fNum=2047;
}
chan[i].freq=(block<<11)|fNum;
}
if (chan[i].freq>0x3fff) chan[i].freq=0x3fff;
immWrite(chanOffs[i]+ADDR_FREQH,chan[i].freq>>8);
immWrite(chanOffs[i]+ADDR_FREQ,chan[i].freq&0xff);
chan[i].freqChanged=false;
}
if (chan[i].keyOn || chan[i].opMaskChanged) {
immWrite(0x28,(chan[i].opMask<<4)|konOffs[i]);
chan[i].opMaskChanged=false;
chan[i].keyOn=false;
}
}
// ADPCM-A // ADPCM-A
for (int i=adpcmAChanOffs; i<adpcmBChanOffs; i++) { for (int i=adpcmAChanOffs; i<adpcmBChanOffs; i++) {
if (chan[i].furnacePCM) { if (chan[i].furnacePCM) {
@ -555,47 +584,18 @@ void DivPlatformYM2610::tick(bool sysTick) {
writeADPCMAOff=0; writeADPCMAOff=0;
} }
for (int i=16; i<512; i++) {
if (pendingWrites[i]!=oldWrites[i]) {
immWrite(i,pendingWrites[i]&0xff);
oldWrites[i]=pendingWrites[i];
}
}
for (int i=0; i<psgChanOffs; i++) {
if (i==1 && extMode) continue;
if (chan[i].freqChanged) {
if (parent->song.linearPitch==2) {
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11);
} else {
int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11);
int block=(chan[i].baseFreq&0xf800)>>11;
if (fNum<0) fNum=0;
if (fNum>2047) {
while (block<7) {
fNum>>=1;
block++;
}
if (fNum>2047) fNum=2047;
}
chan[i].freq=(block<<11)|fNum;
}
if (chan[i].freq>0x3fff) chan[i].freq=0x3fff;
immWrite(chanOffs[i]+ADDR_FREQH,chan[i].freq>>8);
immWrite(chanOffs[i]+ADDR_FREQ,chan[i].freq&0xff);
chan[i].freqChanged=false;
}
if (chan[i].keyOn || chan[i].opMaskChanged) {
immWrite(0x28,(chan[i].opMask<<4)|konOffs[i]);
chan[i].opMaskChanged=false;
chan[i].keyOn=false;
}
}
if (writeADPCMAOn) { if (writeADPCMAOn) {
immWrite(0x100,writeADPCMAOn); immWrite(0x100,writeADPCMAOn);
writeADPCMAOn=0; writeADPCMAOn=0;
} }
// PSG
ay->tick(sysTick);
ay->flushWrites();
for (DivRegWrite& i: ay->getRegisterWrites()) {
immWrite(i.addr&15,i.val);
}
ay->getRegisterWrites().clear();
} }
int DivPlatformYM2610::dispatch(DivCommand c) { int DivPlatformYM2610::dispatch(DivCommand c) {

View file

@ -358,14 +358,6 @@ void DivPlatformYM2610B::acquire(short* bufL, short* bufR, size_t start, size_t
} }
void DivPlatformYM2610B::tick(bool sysTick) { void DivPlatformYM2610B::tick(bool sysTick) {
// PSG
ay->tick(sysTick);
ay->flushWrites();
for (DivRegWrite& i: ay->getRegisterWrites()) {
immWrite(i.addr&15,i.val);
}
ay->getRegisterWrites().clear();
// FM // FM
for (int i=0; i<psgChanOffs; i++) { for (int i=0; i<psgChanOffs; i++) {
if (i==2 && extMode) continue; if (i==2 && extMode) continue;
@ -522,6 +514,44 @@ void DivPlatformYM2610B::tick(bool sysTick) {
chan[i].keyOff=false; chan[i].keyOff=false;
} }
} }
for (int i=16; i<512; i++) {
if (pendingWrites[i]!=oldWrites[i]) {
immWrite(i,pendingWrites[i]&0xff);
oldWrites[i]=pendingWrites[i];
}
}
for (int i=0; i<psgChanOffs; i++) {
if (i==2 && extMode) continue;
if (chan[i].freqChanged) {
if (parent->song.linearPitch==2) {
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11);
} else {
int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,false,4,chan[i].pitch2);
int block=(chan[i].baseFreq&0xf800)>>11;
if (fNum<0) fNum=0;
if (fNum>2047) {
while (block<7) {
fNum>>=1;
block++;
}
if (fNum>2047) fNum=2047;
}
chan[i].freq=(block<<11)|fNum;
}
if (chan[i].freq>0x3fff) chan[i].freq=0x3fff;
immWrite(chanOffs[i]+ADDR_FREQH,chan[i].freq>>8);
immWrite(chanOffs[i]+ADDR_FREQ,chan[i].freq&0xff);
chan[i].freqChanged=false;
}
if (chan[i].keyOn || chan[i].opMaskChanged) {
immWrite(0x28,(chan[i].opMask<<4)|konOffs[i]);
chan[i].opMaskChanged=false;
chan[i].keyOn=false;
}
}
// ADPCM-A // ADPCM-A
for (int i=adpcmAChanOffs; i<adpcmBChanOffs; i++) { for (int i=adpcmAChanOffs; i<adpcmBChanOffs; i++) {
if (chan[i].furnacePCM) { if (chan[i].furnacePCM) {
@ -617,47 +647,18 @@ void DivPlatformYM2610B::tick(bool sysTick) {
writeADPCMAOff=0; writeADPCMAOff=0;
} }
for (int i=16; i<512; i++) {
if (pendingWrites[i]!=oldWrites[i]) {
immWrite(i,pendingWrites[i]&0xff);
oldWrites[i]=pendingWrites[i];
}
}
for (int i=0; i<psgChanOffs; i++) {
if (i==2 && extMode) continue;
if (chan[i].freqChanged) {
if (parent->song.linearPitch==2) {
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11);
} else {
int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,false,4,chan[i].pitch2);
int block=(chan[i].baseFreq&0xf800)>>11;
if (fNum<0) fNum=0;
if (fNum>2047) {
while (block<7) {
fNum>>=1;
block++;
}
if (fNum>2047) fNum=2047;
}
chan[i].freq=(block<<11)|fNum;
}
if (chan[i].freq>0x3fff) chan[i].freq=0x3fff;
immWrite(chanOffs[i]+ADDR_FREQH,chan[i].freq>>8);
immWrite(chanOffs[i]+ADDR_FREQ,chan[i].freq&0xff);
chan[i].freqChanged=false;
}
if (chan[i].keyOn || chan[i].opMaskChanged) {
immWrite(0x28,(chan[i].opMask<<4)|konOffs[i]);
chan[i].opMaskChanged=false;
chan[i].keyOn=false;
}
}
if (writeADPCMAOn) { if (writeADPCMAOn) {
immWrite(0x100,writeADPCMAOn); immWrite(0x100,writeADPCMAOn);
writeADPCMAOn=0; writeADPCMAOn=0;
} }
// PSG
ay->tick(sysTick);
ay->flushWrites();
for (DivRegWrite& i: ay->getRegisterWrites()) {
immWrite(i.addr&15,i.val);
}
ay->getRegisterWrites().clear();
} }
int DivPlatformYM2610B::dispatch(DivCommand c) { int DivPlatformYM2610B::dispatch(DivCommand c) {

View file

@ -265,7 +265,7 @@ template<int ChanNum> class DivPlatformYM2610Base: public DivPlatformOPN {
chipClock=24167829/3; chipClock=24167829/3;
break; break;
} }
rate=fm->sample_rate(chipClock); rate=chipClock/16;
for (int i=0; i<ChanNum; i++) { for (int i=0; i<ChanNum; i++) {
oscBuf[i]->rate=rate; oscBuf[i]->rate=rate;
} }
@ -287,7 +287,7 @@ template<int ChanNum> class DivPlatformYM2610Base: public DivPlatformOPN {
iface.adpcmBMem=adpcmBMem; iface.adpcmBMem=adpcmBMem;
iface.sampleBank=0; iface.sampleBank=0;
fm=new ymfm::ym2610b(iface); fm=new ymfm::ym2610b(iface);
fm->set_fidelity(ymfm::OPN_FIDELITY_MIN); fm->set_fidelity(ymfm::OPN_FIDELITY_MAX);
setFlags(flags); setFlags(flags);
// YM2149, 2MHz // YM2149, 2MHz
ay=new DivPlatformAY8910(true,chipClock,32); ay=new DivPlatformAY8910(true,chipClock,32);