FM: better pitch slide accuracy

so... it appears that pitch slides in Genesis system aren't truly linear
instead, they are "kind of linear". the frequency isn't linear, and when
it overflows the range of an octave, the high bit changes and the
frequency is shifted right
This commit is contained in:
tildearrow 2021-05-18 01:20:38 -05:00
parent b34321b556
commit b2908413fe
2 changed files with 25 additions and 2 deletions

View file

@ -133,6 +133,27 @@ void DivPlatformGenesis::tick() {
psg.tick();
}
int DivPlatformGenesis::octave(int freq) {
if (freq>=82432) {
return 128;
} else if (freq>=41216) {
return 64;
} else if (freq>=20608) {
return 32;
} else if (freq>=10304) {
return 16;
} else if (freq>=5152) {
return 8;
} else if (freq>=2576) {
return 4;
} else if (freq>=1288) {
return 2;
} else {
return 1;
}
return 1;
}
#define rWrite(a,v) pendingWrites[a]=v;
int DivPlatformGenesis::dispatch(DivCommand c) {
@ -242,13 +263,13 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
int destFreq=644.0f*pow(2.0f,((float)c.value2/12.0f));
bool return2=false;
if (destFreq>chan[c.chan].baseFreq) {
chan[c.chan].baseFreq=(chan[c.chan].baseFreq*(960+c.value))/960;
chan[c.chan].baseFreq=chan[c.chan].baseFreq+c.value*octave(chan[c.chan].baseFreq);
if (chan[c.chan].baseFreq>=destFreq) {
chan[c.chan].baseFreq=destFreq;
return2=true;
}
} else {
chan[c.chan].baseFreq=(chan[c.chan].baseFreq*(960-c.value))/960;
chan[c.chan].baseFreq=chan[c.chan].baseFreq-c.value*octave(chan[c.chan].baseFreq);
if (chan[c.chan].baseFreq<=destFreq) {
chan[c.chan].baseFreq=destFreq;
return2=true;

View file

@ -43,6 +43,8 @@ class DivPlatformGenesis: public DivDispatch {
short oldWrites[512];
short pendingWrites[512];
int octave(int freq);
public:
void acquire(int& l, int& r);