Add fixed octave for block+fnum systems

This isn't implemented in SAA1099, despite also being block+fnum system, as there are no benefits from it
This commit is contained in:
Natt Akuma 2024-09-18 14:48:10 +07:00
parent 6a58797669
commit cf3d08ca5a
25 changed files with 194 additions and 97 deletions

View file

@ -292,7 +292,12 @@ void DivPlatformESFM::tick(bool sysTick) {
for (int i=0; i<18; i++) {
if (chan[i].freqChanged) {
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,octave(chan[i].baseFreq)*2,chan[i].pitch2,chipClock,CHIP_FREQBASE);
int mul=2;
int fixedBlock=parent->getIns(chan[i].ins)->fm.block;
if (parent->song.linearPitch!=2) {
mul=octave(chan[i].baseFreq,fixedBlock)*2;
}
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,mul,chan[i].pitch2,chipClock,CHIP_FREQBASE);
if (chan[i].freq<0) chan[i].freq=0;
if (chan[i].freq>131071) chan[i].freq=131071;
@ -315,10 +320,10 @@ void DivPlatformESFM::tick(bool sysTick) {
if(chan[i].opsState[o].hasOpPitch) {
pitch2=chan[i].opsState[o].pitch2+dt;
}
int opFreq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,arp,fixedArp,false,octave(chan[i].baseFreq)*2,pitch2,chipClock,CHIP_FREQBASE);
int opFreq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,arp,fixedArp,false,mul,pitch2,chipClock,CHIP_FREQBASE);
if (opFreq<0) opFreq=0;
if (opFreq>131071) opFreq=131071;
int freqt=toFreq(opFreq);
int freqt=toFreq(opFreq,fixedBlock);
chan[i].freqL[o]=freqt&0xff;
chan[i].freqH[o]=freqt>>8;
}
@ -366,16 +371,23 @@ void DivPlatformESFM::tick(bool sysTick) {
}
}
int DivPlatformESFM::octave(int freq) {
int DivPlatformESFM::octave(int freq, int fixedBlock) {
if (fixedBlock>0) {
return 1<<(fixedBlock-1);
}
if (freq>0x3ff) {
return 1<<(bsr32(freq)-10);
}
return 1;
}
int DivPlatformESFM::toFreq(int freq) {
int DivPlatformESFM::toFreq(int freq, int fixedBlock) {
int block=0;
if (freq>0x3ff) {
if (fixedBlock>0) {
block=fixedBlock-1;
freq>>=block;
if (freq>0x3ff) freq=0x3ff;
} else if (freq>0x3ff) {
block=bsr32(freq)-10;
freq>>=block;
}
@ -512,21 +524,27 @@ int DivPlatformESFM::dispatch(DivCommand c) {
int destFreq=NOTE_FREQUENCY(c.value2);
int newFreq;
bool return2=false;
int mul=1;
int fixedBlock=0;
if (parent->song.linearPitch!=2) {
fixedBlock=parent->getIns(chan[c.chan].ins)->fm.block;
mul=octave(chan[c.chan].baseFreq,fixedBlock);
}
if (destFreq>chan[c.chan].baseFreq) {
newFreq=chan[c.chan].baseFreq+c.value*((parent->song.linearPitch==2)?1:octave(chan[c.chan].baseFreq));
newFreq=chan[c.chan].baseFreq+c.value*mul;
if (newFreq>=destFreq) {
newFreq=destFreq;
return2=true;
}
} else {
newFreq=chan[c.chan].baseFreq-c.value*((parent->song.linearPitch==2)?1:octave(chan[c.chan].baseFreq));
newFreq=chan[c.chan].baseFreq-c.value*mul;
if (newFreq<=destFreq) {
newFreq=destFreq;
return2=true;
}
}
if (!chan[c.chan].portaPause && parent->song.linearPitch!=2) {
if (octave(chan[c.chan].baseFreq)!=octave(newFreq)) {
if (mul!=octave(newFreq,fixedBlock)) {
chan[c.chan].portaPause=true;
break;
}