YM2612: early full linear pitch experiment
u n t e s t e d
This commit is contained in:
parent
c79e5e8081
commit
aad5d818f2
|
@ -995,46 +995,55 @@ double DivEngine::calcBaseFreq(double clock, double divider, int note, bool peri
|
||||||
base*(divider/clock);
|
base*(divider/clock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CONVERT_FNUM_BLOCK(bf,bits,note) \
|
||||||
|
double tuning=song.tuning; \
|
||||||
|
if (tuning<400.0) tuning=400.0; \
|
||||||
|
if (tuning>500.0) tuning=500.0; \
|
||||||
|
int boundaryBottom=tuning*pow(2.0,0.25)*(divider/clock); \
|
||||||
|
int boundaryTop=2.0*tuning*pow(2.0,0.25)*(divider/clock); \
|
||||||
|
int block=(note)/12; \
|
||||||
|
if (block<0) block=0; \
|
||||||
|
if (block>7) block=7; \
|
||||||
|
bf>>=block; \
|
||||||
|
if (bf<0) bf=0; \
|
||||||
|
/* octave boundaries */ \
|
||||||
|
while (bf>0 && bf<boundaryBottom && block>0) { \
|
||||||
|
bf<<=1; \
|
||||||
|
block--; \
|
||||||
|
} \
|
||||||
|
if (bf>boundaryTop) { \
|
||||||
|
while (block<7 && bf>boundaryTop) { \
|
||||||
|
bf>>=1; \
|
||||||
|
block++; \
|
||||||
|
} \
|
||||||
|
if (bf>((1<<bits)-1)) { \
|
||||||
|
bf=(1<<bits)-1; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
/* logV("f-num: %d block: %d",bf,block); */ \
|
||||||
|
return bf|(block<<bits);
|
||||||
|
|
||||||
unsigned short DivEngine::calcBaseFreqFNumBlock(double clock, double divider, int note, int bits) {
|
unsigned short 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);
|
||||||
}
|
}
|
||||||
double tuning=song.tuning;
|
|
||||||
if (tuning<400.0) tuning=400.0;
|
|
||||||
if (tuning>500.0) tuning=500.0;
|
|
||||||
int bf=calcBaseFreq(clock,divider,note,false);
|
int bf=calcBaseFreq(clock,divider,note,false);
|
||||||
int boundaryBottom=tuning*pow(2.0,0.25)*(divider/clock);
|
CONVERT_FNUM_BLOCK(bf,bits,note)
|
||||||
int boundaryTop=2.0*tuning*pow(2.0,0.25)*(divider/clock);
|
|
||||||
int block=note/12;
|
|
||||||
if (block<0) block=0;
|
|
||||||
if (block>7) block=7;
|
|
||||||
bf>>=block;
|
|
||||||
if (bf<0) bf=0;
|
|
||||||
// octave boundaries
|
|
||||||
while (bf>0 && bf<boundaryBottom && block>0) {
|
|
||||||
bf<<=1;
|
|
||||||
block--;
|
|
||||||
}
|
|
||||||
if (bf>boundaryTop) {
|
|
||||||
while (block<7 && bf>boundaryTop) {
|
|
||||||
bf>>=1;
|
|
||||||
block++;
|
|
||||||
}
|
|
||||||
if (bf>((1<<bits)-1)) {
|
|
||||||
bf=(1<<bits)-1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//logV("f-num: %d block: %d",bf,block);
|
|
||||||
return bf|(block<<bits);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivEngine::calcFreq(int base, int pitch, bool period, int octave, int pitch2, double clock, double divider) {
|
int DivEngine::calcFreq(int base, int pitch, bool period, int octave, int pitch2, double clock, double divider, int blockBits) {
|
||||||
if (song.linearPitch==2) {
|
if (song.linearPitch==2) {
|
||||||
// do frequency calculation here
|
// do frequency calculation here
|
||||||
double fbase=(period?(song.tuning*0.0625):song.tuning)*pow(2.0,(float)(base+pitch+384)/(128.0*12.0));
|
int nbase=base+pitch+pitch2;
|
||||||
return period?
|
double fbase=(period?(song.tuning*0.0625):song.tuning)*pow(2.0,(float)(nbase+384)/(128.0*12.0));
|
||||||
(clock/fbase)/divider:
|
int bf=period?
|
||||||
fbase*(divider/clock);
|
(clock/fbase)/divider:
|
||||||
|
fbase*(divider/clock);
|
||||||
|
if (blockBits>0) {
|
||||||
|
CONVERT_FNUM_BLOCK(bf,blockBits,nbase>>7)
|
||||||
|
} else {
|
||||||
|
return bf;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (song.linearPitch==1) {
|
if (song.linearPitch==1) {
|
||||||
// global pitch multiplier
|
// global pitch multiplier
|
||||||
|
|
|
@ -484,7 +484,7 @@ class DivEngine {
|
||||||
unsigned short calcBaseFreqFNumBlock(double clock, double divider, int note, int bits);
|
unsigned short 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 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);
|
||||||
|
|
||||||
// convert panning formats
|
// convert panning formats
|
||||||
int convertPanSplitToLinear(unsigned int val, unsigned char bits, int range);
|
int convertPanSplitToLinear(unsigned int val, unsigned char bits, int range);
|
||||||
|
|
|
@ -471,7 +471,7 @@ 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);
|
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;
|
int block=(chan[i].baseFreq&0xf800)>>11;
|
||||||
if (fNum<0) fNum=0;
|
if (fNum<0) fNum=0;
|
||||||
if (fNum>2047) {
|
if (fNum>2047) {
|
||||||
|
@ -495,7 +495,8 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
||||||
off=(double)s->centerRate/8363.0;
|
off=(double)s->centerRate/8363.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,4)+chan[i].pitch2;
|
// TODO: linear
|
||||||
|
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);
|
||||||
|
|
Loading…
Reference in New Issue