YM2612: implement full linear pitch (part 2)
This commit is contained in:
parent
0cc2c06bbf
commit
f5dbc37902
|
@ -1023,7 +1023,7 @@ double DivEngine::calcBaseFreq(double clock, double divider, int note, bool peri
|
||||||
/* logV("f-num: %d block: %d",bf,block); */ \
|
/* logV("f-num: %d block: %d",bf,block); */ \
|
||||||
return bf|(block<<bits);
|
return bf|(block<<bits);
|
||||||
|
|
||||||
unsigned short DivEngine::calcBaseFreqFNumBlock(double clock, double divider, int note, int bits) {
|
int DivEngine::calcBaseFreqFNumBlock(double clock, double divider, int note, int bits) {
|
||||||
if (song.linearPitch==2) { // full linear
|
if (song.linearPitch==2) { // full linear
|
||||||
return (note<<7);
|
return (note<<7);
|
||||||
}
|
}
|
||||||
|
|
|
@ -481,7 +481,7 @@ class DivEngine {
|
||||||
double calcBaseFreq(double clock, double divider, int note, bool period);
|
double calcBaseFreq(double clock, double divider, int note, bool period);
|
||||||
|
|
||||||
// calculate base frequency in f-num/block format
|
// calculate base frequency in f-num/block format
|
||||||
unsigned short calcBaseFreqFNumBlock(double clock, double divider, int note, int bits);
|
int calcBaseFreqFNumBlock(double clock, double divider, int note, int bits);
|
||||||
|
|
||||||
// calculate frequency/period
|
// calculate frequency/period
|
||||||
int calcFreq(int base, int pitch, bool period=false, int octave=0, int pitch2=0, double clock=1.0, double divider=1.0, int blockBits=0);
|
int calcFreq(int base, int pitch, bool period=false, int octave=0, int pitch2=0, double clock=1.0, double divider=1.0, int blockBits=0);
|
||||||
|
|
|
@ -471,17 +471,21 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
||||||
for (int i=0; i<6; i++) {
|
for (int i=0; i<6; i++) {
|
||||||
if (i==2 && extMode) continue;
|
if (i==2 && extMode) continue;
|
||||||
if (chan[i].freqChanged) {
|
if (chan[i].freqChanged) {
|
||||||
int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11);
|
if (parent->song.linearPitch==2) {
|
||||||
int block=(chan[i].baseFreq&0xf800)>>11;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11);
|
||||||
if (fNum<0) fNum=0;
|
} else {
|
||||||
if (fNum>2047) {
|
int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11);
|
||||||
while (block<7) {
|
int block=(chan[i].baseFreq&0xf800)>>11;
|
||||||
fNum>>=1;
|
if (fNum<0) fNum=0;
|
||||||
block++;
|
if (fNum>2047) {
|
||||||
|
while (block<7) {
|
||||||
|
fNum>>=1;
|
||||||
|
block++;
|
||||||
|
}
|
||||||
|
if (fNum>2047) fNum=2047;
|
||||||
}
|
}
|
||||||
if (fNum>2047) fNum=2047;
|
chan[i].freq=(block<<11)|fNum;
|
||||||
}
|
}
|
||||||
chan[i].freq=(block<<11)|fNum;
|
|
||||||
if (chan[i].freq>0x3fff) chan[i].freq=0x3fff;
|
if (chan[i].freq>0x3fff) chan[i].freq=0x3fff;
|
||||||
immWrite(chanOffs[i]+ADDR_FREQH,chan[i].freq>>8);
|
immWrite(chanOffs[i]+ADDR_FREQH,chan[i].freq>>8);
|
||||||
immWrite(chanOffs[i]+ADDR_FREQ,chan[i].freq&0xff);
|
immWrite(chanOffs[i]+ADDR_FREQ,chan[i].freq&0xff);
|
||||||
|
@ -495,8 +499,7 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
||||||
off=(double)s->centerRate/8363.0;
|
off=(double)s->centerRate/8363.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: linear
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,4,chan[i].pitch2,1,1);
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,4,1,1)+chan[i].pitch2;
|
|
||||||
dacRate=chan[i].freq*off;
|
dacRate=chan[i].freq*off;
|
||||||
if (dacRate<1) dacRate=1;
|
if (dacRate<1) dacRate=1;
|
||||||
if (dumpWrites) addWrite(0xffff0001,dacRate);
|
if (dumpWrites) addWrite(0xffff0001,dacRate);
|
||||||
|
@ -703,6 +706,29 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_CMD_NOTE_PORTA: {
|
case DIV_CMD_NOTE_PORTA: {
|
||||||
|
if (parent->song.linearPitch==2) {
|
||||||
|
int destFreq=NOTE_FREQUENCY(c.value2);
|
||||||
|
bool return2=false;
|
||||||
|
if (destFreq>chan[c.chan].baseFreq) {
|
||||||
|
chan[c.chan].baseFreq+=c.value;
|
||||||
|
if (chan[c.chan].baseFreq>=destFreq) {
|
||||||
|
chan[c.chan].baseFreq=destFreq;
|
||||||
|
return2=true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
chan[c.chan].baseFreq-=c.value;
|
||||||
|
if (chan[c.chan].baseFreq<=destFreq) {
|
||||||
|
chan[c.chan].baseFreq=destFreq;
|
||||||
|
return2=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chan[c.chan].freqChanged=true;
|
||||||
|
if (return2) {
|
||||||
|
chan[c.chan].inPorta=false;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (c.chan==5 && chan[c.chan].furnaceDac && dacMode) {
|
if (c.chan==5 && chan[c.chan].furnaceDac && dacMode) {
|
||||||
int destFreq=parent->calcBaseFreq(1,1,c.value2,false);
|
int destFreq=parent->calcBaseFreq(1,1,c.value2,false);
|
||||||
bool return2=false;
|
bool return2=false;
|
||||||
|
|
|
@ -127,6 +127,29 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_CMD_NOTE_PORTA: {
|
case DIV_CMD_NOTE_PORTA: {
|
||||||
|
if (parent->song.linearPitch==2) {
|
||||||
|
int destFreq=NOTE_FREQUENCY(c.value2);
|
||||||
|
bool return2=false;
|
||||||
|
if (destFreq>opChan[ch].baseFreq) {
|
||||||
|
opChan[ch].baseFreq+=c.value;
|
||||||
|
if (opChan[ch].baseFreq>=destFreq) {
|
||||||
|
opChan[ch].baseFreq=destFreq;
|
||||||
|
return2=true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
opChan[ch].baseFreq-=c.value;
|
||||||
|
if (opChan[ch].baseFreq<=destFreq) {
|
||||||
|
opChan[ch].baseFreq=destFreq;
|
||||||
|
return2=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
opChan[ch].freqChanged=true;
|
||||||
|
if (return2) {
|
||||||
|
//opChan[ch].inPorta=false;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
int boundaryBottom=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,0,false);
|
int boundaryBottom=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,0,false);
|
||||||
int boundaryTop=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,12,false);
|
int boundaryTop=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,12,false);
|
||||||
int destFreq=NOTE_FNUM_BLOCK(c.value2,11);
|
int destFreq=NOTE_FNUM_BLOCK(c.value2,11);
|
||||||
|
@ -437,17 +460,21 @@ void DivPlatformGenesisExt::tick(bool sysTick) {
|
||||||
unsigned char writeMask=2;
|
unsigned char writeMask=2;
|
||||||
if (extMode) for (int i=0; i<4; i++) {
|
if (extMode) for (int i=0; i<4; i++) {
|
||||||
if (opChan[i].freqChanged) {
|
if (opChan[i].freqChanged) {
|
||||||
int fNum=parent->calcFreq(opChan[i].baseFreq&0x7ff,opChan[i].pitch,false,4,opChan[i].pitch2);
|
if (parent->song.linearPitch==2) {
|
||||||
int block=(opChan[i].baseFreq&0xf800)>>11;
|
opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,false,4,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11);
|
||||||
if (fNum<0) fNum=0;
|
} else {
|
||||||
if (fNum>2047) {
|
int fNum=parent->calcFreq(opChan[i].baseFreq&0x7ff,opChan[i].pitch,false,4,opChan[i].pitch2);
|
||||||
while (block<7) {
|
int block=(opChan[i].baseFreq&0xf800)>>11;
|
||||||
fNum>>=1;
|
if (fNum<0) fNum=0;
|
||||||
block++;
|
if (fNum>2047) {
|
||||||
|
while (block<7) {
|
||||||
|
fNum>>=1;
|
||||||
|
block++;
|
||||||
|
}
|
||||||
|
if (fNum>2047) fNum=2047;
|
||||||
}
|
}
|
||||||
if (fNum>2047) fNum=2047;
|
opChan[i].freq=(block<<11)|fNum;
|
||||||
}
|
}
|
||||||
opChan[i].freq=(block<<11)|fNum;
|
|
||||||
if (opChan[i].freq>0x3fff) opChan[i].freq=0x3fff;
|
if (opChan[i].freq>0x3fff) opChan[i].freq=0x3fff;
|
||||||
immWrite(opChanOffsH[i],opChan[i].freq>>8);
|
immWrite(opChanOffsH[i],opChan[i].freq>>8);
|
||||||
immWrite(opChanOffsL[i],opChan[i].freq&0xff);
|
immWrite(opChanOffsL[i],opChan[i].freq&0xff);
|
||||||
|
|
Loading…
Reference in a new issue