mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-22 20:45:11 +00:00
QuadTone: Fix PCM playback and add no hiss flag
This commit is contained in:
parent
731b7a1bd6
commit
1200e76469
3 changed files with 53 additions and 29 deletions
|
@ -30,13 +30,14 @@ const char** DivPlatformZXBeeperQuadTone::getRegisterSheet() {
|
|||
}
|
||||
|
||||
void DivPlatformZXBeeperQuadTone::acquire(short** buf, size_t len) {
|
||||
bool o=false;
|
||||
for (size_t h=0; h<len; h++) {
|
||||
if (curSample>=0 && curSample<parent->song.sampleLen && !isMuted[4]) {
|
||||
bool sampleActive=false;
|
||||
if (curSample>=0 && curSample<parent->song.sampleLen) {
|
||||
sampleActive=!isMuted[4];
|
||||
while (curSamplePeriod>=chan[4].freq) {
|
||||
DivSample* s=parent->getSample(curSample);
|
||||
if (s->samples>0) {
|
||||
if (!isMuted[4]) o=(s->data8[curSamplePos++]>0);
|
||||
chan[4].out=(s->data8[curSamplePos++]>0);
|
||||
if (curSamplePos>=s->samples) curSample=-1;
|
||||
// (theoretical) 32KiB limit
|
||||
if (curSamplePos>=32768*8) curSample=-1;
|
||||
|
@ -46,46 +47,49 @@ void DivPlatformZXBeeperQuadTone::acquire(short** buf, size_t len) {
|
|||
curSamplePeriod-=chan[4].freq;
|
||||
}
|
||||
curSamplePeriod+=40;
|
||||
}
|
||||
if (sampleActive) {
|
||||
buf[0][h]=chan[4].out?32767:0;
|
||||
if ((outputClock&3)==0) {
|
||||
oscBuf[0]->data[oscBuf[0]->needle++]=0;
|
||||
oscBuf[1]->data[oscBuf[1]->needle++]=0;
|
||||
oscBuf[2]->data[oscBuf[2]->needle++]=0;
|
||||
oscBuf[3]->data[oscBuf[3]->needle++]=0;
|
||||
oscBuf[4]->data[oscBuf[4]->needle++]=o?32767:0;
|
||||
oscBuf[4]->data[oscBuf[4]->needle++]=buf[0][h];
|
||||
}
|
||||
} else {
|
||||
int ch=outputClock/2;
|
||||
int b=ch*4;
|
||||
bool o=false;
|
||||
if ((outputClock&1)==0) {
|
||||
short oscOut;
|
||||
chan[ch].sPosition+=(regPool[1+b]<<8)|regPool[0+b];
|
||||
chan[ch].out=regPool[3+b]+((((chan[ch].sPosition>>8)&0xff)<regPool[2+b])?1:0);
|
||||
if (isMuted[ch]) chan[ch].out=0;
|
||||
if ((chan[ch].out&0x18)==0x18) {
|
||||
oscOut=32767;
|
||||
} else if ((chan[ch].out&0x18)==0) {
|
||||
oscOut=0;
|
||||
} else {
|
||||
oscOut=16383;
|
||||
}
|
||||
oscBuf[ch]->data[oscBuf[ch]->needle++]=oscOut;
|
||||
}
|
||||
if ((outputClock&3)==0) {
|
||||
oscBuf[4]->data[oscBuf[4]->needle++]=0;
|
||||
}
|
||||
o=chan[ch].out&0x10;
|
||||
oscBuf[ch]->data[oscBuf[ch]->needle++]=o?32767:0;
|
||||
chan[ch].out<<=1;
|
||||
|
||||
// if muted, ztill run sample
|
||||
if (curSample>=0 && curSample<parent->song.sampleLen && isMuted[4]) {
|
||||
while (curSamplePeriod>=chan[4].freq) {
|
||||
DivSample* s=parent->getSample(curSample);
|
||||
if (s->samples>0) {
|
||||
if (curSamplePos>=s->samples) curSample=-1;
|
||||
// (theoretical) 32KiB limit
|
||||
if (curSamplePos>=32768*8) curSample=-1;
|
||||
} else {
|
||||
curSample=-1;
|
||||
}
|
||||
curSamplePeriod-=chan[4].freq;
|
||||
if (!isMuted[ch]) o=chan[ch].out&0x10;
|
||||
if (noHiss) {
|
||||
deHisser[outputClock]=o;
|
||||
buf[0][h]=-1;
|
||||
for (int i=0; i<8; i++) {
|
||||
buf[0][h]+=deHisser[i]?4096:0;
|
||||
}
|
||||
curSamplePeriod+=40;
|
||||
} else {
|
||||
buf[0][h]=o?32767:0;
|
||||
}
|
||||
chan[ch].out<<=1;
|
||||
}
|
||||
outputClock=(outputClock+1)&7;
|
||||
buf[0][h]=o?32767:0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,6 +161,7 @@ void DivPlatformZXBeeperQuadTone::tick(bool sysTick) {
|
|||
chan[4].freq=parent->calcFreq(chan[4].baseFreq,chan[4].pitch,chan[4].fixedArp?chan[4].baseNoteOverride:chan[4].arpOff,chan[4].fixedArp,true,2,chan[4].pitch2,chipClock,off);
|
||||
if (chan[4].freq>258) chan[4].freq=258;
|
||||
if (chan[4].freq<3) chan[4].freq=3;
|
||||
rWrite(16,(chan[4].freq-2)&255);
|
||||
chan[4].freq*=13;
|
||||
}
|
||||
if (chan[4].keyOn) chan[4].keyOn=false;
|
||||
|
@ -340,11 +345,12 @@ unsigned char* DivPlatformZXBeeperQuadTone::getRegisterPool() {
|
|||
}
|
||||
|
||||
int DivPlatformZXBeeperQuadTone::getRegisterPoolSize() {
|
||||
return 16;
|
||||
return 17;
|
||||
}
|
||||
|
||||
void DivPlatformZXBeeperQuadTone::reset() {
|
||||
memset(regPool,0,16);
|
||||
memset(regPool,0,17);
|
||||
memset(deHisser,0,8);
|
||||
for (int i=0; i<5; i++) {
|
||||
chan[i]=DivPlatformZXBeeperQuadTone::Channel();
|
||||
chan[i].std.setEngine(parent);
|
||||
|
@ -353,7 +359,6 @@ void DivPlatformZXBeeperQuadTone::reset() {
|
|||
cycles=0;
|
||||
curChan=0;
|
||||
sOffTimer=0;
|
||||
ulaOut=0;
|
||||
curSample=-1;
|
||||
curSamplePos=0;
|
||||
curSamplePeriod=0;
|
||||
|
@ -381,7 +386,8 @@ void DivPlatformZXBeeperQuadTone::setFlags(const DivConfig& flags) {
|
|||
}
|
||||
CHECK_CUSTOM_CLOCK;
|
||||
rate=chipClock/40;
|
||||
for (int i=0; i<4; i++) {
|
||||
noHiss=flags.getBool("noHiss",false);
|
||||
for (int i=0; i<5; i++) {
|
||||
oscBuf[i]->rate=rate/4;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,12 +36,13 @@ class DivPlatformZXBeeperQuadTone: public DivDispatch {
|
|||
Channel chan[5];
|
||||
DivDispatchOscBuffer* oscBuf[5];
|
||||
bool isMuted[5];
|
||||
unsigned char ulaOut;
|
||||
bool noHiss;
|
||||
bool deHisser[8];
|
||||
|
||||
int cycles, curChan, sOffTimer, delay, curSample, curSamplePeriod;
|
||||
unsigned int curSamplePos;
|
||||
unsigned int outputClock;
|
||||
unsigned char regPool[16];
|
||||
unsigned char regPool[17];
|
||||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
public:
|
||||
|
|
|
@ -2270,6 +2270,23 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl
|
|||
}
|
||||
break;
|
||||
}
|
||||
case DIV_SYSTEM_SFX_BEEPER_QUADTONE: {
|
||||
bool sysPal=flags.getInt("clockSel",0);
|
||||
bool noHiss=flags.getBool("noHiss",false);
|
||||
if (ImGui::Checkbox("PAL",&sysPal)) {
|
||||
altered=true;
|
||||
}
|
||||
if (ImGui::Checkbox("Disable hissing",&noHiss)) {
|
||||
altered=true;
|
||||
}
|
||||
if (altered) {
|
||||
e->lockSave([&]() {
|
||||
flags.set("clockSel",(int)sysPal);
|
||||
flags.set("noHiss",noHiss);
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DIV_SYSTEM_SWAN:
|
||||
case DIV_SYSTEM_BUBSYS_WSG:
|
||||
case DIV_SYSTEM_PET:
|
||||
|
|
Loading…
Reference in a new issue