diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 12eb0eddb..d4e5e7346 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -2353,6 +2353,10 @@ double DivEngine::getSamplePreviewRate() { return sPreview.rate; } +double DivEngine::getCenterRate() { + return song.oldCenterRate?8363.0:8372.0; +} + String DivEngine::getConfigPath() { return configPath; } @@ -2897,6 +2901,7 @@ int DivEngine::addSample() { DivSample* sample=new DivSample; int sampleCount=(int)song.sample.size(); sample->name=fmt::sprintf(_("Sample %d"),sampleCount); + sample->centerRate=getCenterRate(); song.sample.push_back(sample); song.sampleLen=sampleCount+1; sPreview.sample=-1; diff --git a/src/engine/engine.h b/src/engine/engine.h index d947f7a92..4ace5c5c1 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -839,6 +839,9 @@ class DivEngine { // reset playback state void syncReset(); + // get C-4 rate for samples + double getCenterRate(); + // sample preview query bool isPreviewingSample(); int getSamplePreviewSample(); diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index a9df4e376..0c4022021 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -429,7 +429,7 @@ void DivPlatformAmiga::tick(bool sysTick) { if (s->centerRate<1) { off=1.0; } else { - off=8363.0/(double)s->centerRate; + off=parent->getCenterRate()/(double)s->centerRate; } } if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) { diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index bf99e4d42..6639296d1 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -515,7 +515,7 @@ void DivPlatformAY8910::tick(bool sysTick) { if (s->centerRate<1) { off=1.0; } else { - off=8363.0/(double)s->centerRate; + off=parent->getCenterRate()/(double)s->centerRate; } } chan[i].dac.rate=((double)rate*((sunsoft||clockSel)?8.0:16.0))/(double)(MAX(1,off*chan[i].freq)); diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index 87b3e9282..dcf7b30d8 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -341,7 +341,7 @@ void DivPlatformAY8930::tick(bool sysTick) { if (s->centerRate<1) { off=1.0; } else { - off=8363.0/(double)s->centerRate; + off=parent->getCenterRate()/(double)s->centerRate; } } chan[i].dac.rate=((double)chipClock*4.0)/(double)(MAX(1,off*chan[i].freq)); diff --git a/src/engine/platform/c140.cpp b/src/engine/platform/c140.cpp index 52493734e..99d6d6e6c 100644 --- a/src/engine/platform/c140.cpp +++ b/src/engine/platform/c140.cpp @@ -214,7 +214,7 @@ void DivPlatformC140::tick(bool sysTick) { if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) { DivSample* s=parent->getSample(chan[i].sample); unsigned char ctrl=0; - double off=(s->centerRate>=1)?((double)s->centerRate/8363.0):1.0; + double off=(s->centerRate>=1)?((double)s->centerRate/parent->getCenterRate()):1.0; chan[i].freq=(int)(off*parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,chipClock,CHIP_FREQBASE)); if (chan[i].freq<0) chan[i].freq=0; if (chan[i].freq>65535) chan[i].freq=65535; diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index 4ea8b6e62..44227732e 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -373,7 +373,7 @@ void DivPlatformC64::tick(bool sysTick) { if (s->centerRate<1) { off=1.0; } else { - off=(double)s->centerRate/8363.0; + off=(double)s->centerRate/parent->getCenterRate(); } } chan[i].pcmRate=off*parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,2,1); diff --git a/src/engine/platform/dave.cpp b/src/engine/platform/dave.cpp index 2c2cf3716..c61a51e70 100644 --- a/src/engine/platform/dave.cpp +++ b/src/engine/platform/dave.cpp @@ -239,7 +239,7 @@ void DivPlatformDave::tick(bool sysTick) { double off=1.0; if (chan[i].dacSample>=0 && chan[i].dacSamplesong.sampleLen) { DivSample* s=parent->getSample(chan[i].dacSample); - off=(double)s->centerRate/8363.0; + off=(double)s->centerRate/parent->getCenterRate(); } chan[i].dacRate=chan[i].freq*off; } else { diff --git a/src/engine/platform/es5506.cpp b/src/engine/platform/es5506.cpp index 25c98d0e2..9eafffc76 100644 --- a/src/engine/platform/es5506.cpp +++ b/src/engine/platform/es5506.cpp @@ -490,7 +490,7 @@ void DivPlatformES5506::tick(bool sysTick) { if (center<1) { off=1.0; } else { - off=(double)center/8363.0; + off=(double)center/parent->getCenterRate(); } if (ins->amiga.useNoteMap) { //chan[i].pcm.note=next; @@ -654,7 +654,7 @@ void DivPlatformES5506::tick(bool sysTick) { if (center<1) { off=1.0; } else { - off=(double)center/8363.0; + off=(double)center/parent->getCenterRate(); } chan[i].pcm.loopStart=(chan[i].pcm.start+(s->loopStart<<11))&0xfffff800; chan[i].pcm.loopEnd=(chan[i].pcm.start+((s->loopEnd)<<11))&0xffffff80; diff --git a/src/engine/platform/ga20.cpp b/src/engine/platform/ga20.cpp index 83928c334..499089d40 100644 --- a/src/engine/platform/ga20.cpp +++ b/src/engine/platform/ga20.cpp @@ -145,7 +145,7 @@ void DivPlatformGA20::tick(bool sysTick) { if (s->centerRate<1) { off=1.0; } else { - off=8363.0/s->centerRate; + off=parent->getCenterRate()/s->centerRate; } } DivSample* s=parent->getSample(chan[i].sample); diff --git a/src/engine/platform/gbadma.cpp b/src/engine/platform/gbadma.cpp index 07dd9f95a..c180cef1f 100644 --- a/src/engine/platform/gbadma.cpp +++ b/src/engine/platform/gbadma.cpp @@ -159,7 +159,7 @@ void DivPlatformGBADMA::tick(bool sysTick) { double off=1.0; if (!chan[i].useWave && chan[i].sample>=0 && chan[i].samplesong.sampleLen) { DivSample* s=parent->getSample(chan[i].sample); - off=(s->centerRate>=1)?(8363.0/(double)s->centerRate):1.0; + off=(s->centerRate>=1)?(parent->getCenterRate()/(double)s->centerRate):1.0; } chan[i].freq=off*parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER); diff --git a/src/engine/platform/gbaminmod.cpp b/src/engine/platform/gbaminmod.cpp index fd23b72c7..add60505e 100644 --- a/src/engine/platform/gbaminmod.cpp +++ b/src/engine/platform/gbaminmod.cpp @@ -295,7 +295,7 @@ void DivPlatformGBAMinMod::tick(bool sysTick) { } if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) { DivSample* s=parent->getSample(chan[i].sample); - double off=(s->centerRate>=1)?((double)s->centerRate/8363.0):1.0; + double off=(s->centerRate>=1)?((double)s->centerRate/parent->getCenterRate()):1.0; chan[i].freq=(int)(off*parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,chipClock,CHIP_FREQBASE)); if (chan[i].keyOn) { unsigned int start, end, loop; diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 4afbb0f57..e3455db01 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -865,7 +865,7 @@ void DivPlatformGenesis::tick(bool sysTick) { if (s->centerRate<1) { off=1.0; } else { - off=(double)s->centerRate/8363.0; + off=(double)s->centerRate/parent->getCenterRate(); } } chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,1,1); diff --git a/src/engine/platform/k007232.cpp b/src/engine/platform/k007232.cpp index a3a7e3360..6aaccc908 100644 --- a/src/engine/platform/k007232.cpp +++ b/src/engine/platform/k007232.cpp @@ -187,7 +187,7 @@ void DivPlatformK007232::tick(bool sysTick) { if (s->centerRate<1) { off=1.0; } else { - off=8363.0/s->centerRate; + off=parent->getCenterRate()/s->centerRate; } } DivSample* s=parent->getSample(chan[i].sample); diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp index 0bac35d66..1916270c3 100644 --- a/src/engine/platform/k053260.cpp +++ b/src/engine/platform/k053260.cpp @@ -142,7 +142,7 @@ void DivPlatformK053260::tick(bool sysTick) { if (s->centerRate<1) { off=1.0; } else { - off=8363.0/s->centerRate; + off=parent->getCenterRate()/s->centerRate; } } chan[i].freq=0x1000-(int)(off*parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER)); diff --git a/src/engine/platform/lynx.cpp b/src/engine/platform/lynx.cpp index 62745285b..e044ba5e6 100644 --- a/src/engine/platform/lynx.cpp +++ b/src/engine/platform/lynx.cpp @@ -257,7 +257,7 @@ void DivPlatformLynx::tick(bool sysTick) { if (s->centerRate<1) { off=1.0; } else { - off=(double)s->centerRate/8363.0; + off=(double)s->centerRate/parent->getCenterRate(); } } chan[i].sampleFreq=off*parent->calcFreq(chan[i].sampleBaseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,chipClock,CHIP_FREQBASE); diff --git a/src/engine/platform/mmc5.cpp b/src/engine/platform/mmc5.cpp index ce1532ca8..da024ecc0 100644 --- a/src/engine/platform/mmc5.cpp +++ b/src/engine/platform/mmc5.cpp @@ -161,7 +161,7 @@ void DivPlatformMMC5::tick(bool sysTick) { double off=1.0; if (dacSample>=0 && dacSamplesong.sampleLen) { DivSample* s=parent->getSample(dacSample); - off=(double)s->centerRate/8363.0; + off=(double)s->centerRate/parent->getCenterRate(); } dacRate=MIN(chan[2].freq*off,32000); if (dumpWrites) addWrite(0xffff0001,dacRate); diff --git a/src/engine/platform/nds.cpp b/src/engine/platform/nds.cpp index 3a2c89f65..2478989d0 100644 --- a/src/engine/platform/nds.cpp +++ b/src/engine/platform/nds.cpp @@ -160,7 +160,7 @@ void DivPlatformNDS::tick(bool sysTick) { case DIV_SAMPLE_DEPTH_16BIT: ctrl=0x20; break; default: break; } - double off=(s->centerRate>=1)?(8363.0/(double)s->centerRate):1.0; + double off=(s->centerRate>=1)?(parent->getCenterRate()/(double)s->centerRate):1.0; chan[i].freq=0x10000-(off*parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER)); if (chan[i].freq<0) chan[i].freq=0; if (chan[i].freq>65535) chan[i].freq=65535; diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index 37f7d0532..22c949f3a 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -391,7 +391,7 @@ void DivPlatformNES::tick(bool sysTick) { double off=1.0; if (dacSample>=0 && dacSamplesong.sampleLen) { DivSample* s=parent->getSample(dacSample); - off=(double)s->centerRate/8363.0; + off=(double)s->centerRate/parent->getCenterRate(); } dacRate=MIN(chan[4].freq*off,32000); if (chan[4].keyOn) { diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index f64a79399..6b0f3d4a9 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -1004,7 +1004,7 @@ void DivPlatformOPL::acquire(short** buf, size_t len) { double DivPlatformOPL::NOTE_ADPCMB(int note) { if (adpcmChan<0) return 0; if (chan[adpcmChan].sample>=0 && chan[adpcmChan].samplesong.sampleLen) { - double off=65535.0*(double)(parent->getSample(chan[adpcmChan].sample)->centerRate)/8363.0; + double off=65535.0*(double)(parent->getSample(chan[adpcmChan].sample)->centerRate)/parent->getCenterRate(); return parent->calcBaseFreq((double)chipClock/(compatYPitch?144:72),off,note,false); } return 0; @@ -1334,7 +1334,7 @@ void DivPlatformOPL::tick(bool sysTick) { } if (chan[adpcmChan].freqChanged || chan[adpcmChan].keyOn || chan[adpcmChan].keyOff) { if (chan[adpcmChan].sample>=0 && chan[adpcmChan].samplesong.sampleLen) { - double off=65535.0*(double)(parent->getSample(chan[adpcmChan].sample)->centerRate)/8363.0; + double off=65535.0*(double)(parent->getSample(chan[adpcmChan].sample)->centerRate)/parent->getCenterRate(); chan[adpcmChan].freq=parent->calcFreq(chan[adpcmChan].baseFreq,chan[adpcmChan].pitch,chan[adpcmChan].fixedArp?chan[adpcmChan].baseNoteOverride:chan[adpcmChan].arpOff,chan[adpcmChan].fixedArp,false,4,chan[adpcmChan].pitch2,(double)chipClock/(compatYPitch?144:72),off); } else { chan[adpcmChan].freq=0; @@ -1384,7 +1384,7 @@ void DivPlatformOPL::tick(bool sysTick) { if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) { DivSample* s=parent->getSample(chan[i].sample); unsigned char ctrl=0; - double off=(s->centerRate>=1)?((double)s->centerRate/8363.0):1.0; + double off=(s->centerRate>=1)?((double)s->centerRate/parent->getCenterRate()):1.0; chan[i].freq=(int)(off*parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,chipClock,(524288*768))); if (chan[i].freq<0x400) chan[i].freq=0x400; chan[i].freqH=0; diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index 11700ddaa..8bf09c83f 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -233,7 +233,7 @@ void DivPlatformPCE::tick(bool sysTick) { if (s->centerRate<1) { off=1.0; } else { - off=8363.0/(double)s->centerRate; + off=parent->getCenterRate()/(double)s->centerRate; } } chan[i].dacRate=((double)chipClock/2)/MAX(1,off*chan[i].freq); diff --git a/src/engine/platform/pcmdac.cpp b/src/engine/platform/pcmdac.cpp index dce985c7b..a9376ebd9 100644 --- a/src/engine/platform/pcmdac.cpp +++ b/src/engine/platform/pcmdac.cpp @@ -292,7 +292,7 @@ void DivPlatformPCMDAC::tick(bool sysTick) { double off=1.0; if (!chan[0].useWave && chan[0].sample>=0 && chan[0].samplesong.sampleLen) { DivSample* s=parent->getSample(chan[0].sample); - off=(s->centerRate>=1)?((double)s->centerRate/8363.0):1.0; + off=(s->centerRate>=1)?((double)s->centerRate/parent->getCenterRate()):1.0; } chan[0].freq=off*parent->calcFreq(chan[0].baseFreq,chan[0].pitch,chan[0].fixedArp?chan[0].baseNoteOverride:chan[0].arpOff,chan[0].fixedArp,false,2,chan[0].pitch2,chipClock,CHIP_FREQBASE); if (chan[0].freq>16777215) chan[0].freq=16777215; diff --git a/src/engine/platform/rf5c68.cpp b/src/engine/platform/rf5c68.cpp index be28576f1..a74a9ebce 100644 --- a/src/engine/platform/rf5c68.cpp +++ b/src/engine/platform/rf5c68.cpp @@ -135,7 +135,7 @@ void DivPlatformRF5C68::tick(bool sysTick) { unsigned char keyon=regPool[8]&~(1<getSample(chan[i].sample); - double off=(s->centerRate>=1)?((double)s->centerRate/8363.0):1.0; + double off=(s->centerRate>=1)?((double)s->centerRate/parent->getCenterRate()):1.0; chan[i].freq=(int)(off*parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,chipClock,CHIP_FREQBASE)); if (chan[i].freq>65535) chan[i].freq=65535; if (chan[i].keyOn) { diff --git a/src/engine/platform/segapcm.cpp b/src/engine/platform/segapcm.cpp index 21c5e219e..794fb4d50 100644 --- a/src/engine/platform/segapcm.cpp +++ b/src/engine/platform/segapcm.cpp @@ -119,7 +119,7 @@ void DivPlatformSegaPCM::tick(bool sysTick) { double off=1.0; if (chan[i].pcm.sample>=0 && chan[i].pcm.samplesong.sampleLen) { DivSample* s=parent->getSample(chan[i].pcm.sample); - off=(double)s->centerRate/8363.0; + off=(double)s->centerRate/parent->getCenterRate(); } chan[i].pcm.freq=MIN(255,((rate*0.5)+(off*parent->song.tuning*pow(2.0,double(chan[i].freq+512)/(128.0*12.0)))*255)/rate)+(oldSlides?chan[i].pitch2:0); rWrite(7+(i<<3),chan[i].pcm.freq); diff --git a/src/engine/platform/sid3.cpp b/src/engine/platform/sid3.cpp index bf0989038..4465b9794 100644 --- a/src/engine/platform/sid3.cpp +++ b/src/engine/platform/sid3.cpp @@ -716,7 +716,7 @@ void DivPlatformSID3::tick(bool sysTick) if (s->centerRate<1) { off=1.0; } else { - off=(double)s->centerRate/8363.0; + off=(double)s->centerRate/parent->getCenterRate(); } } chan[i].dacRate=chan[i].freq*(off / 32.0)*(double)chipClock/1000000.0; diff --git a/src/engine/platform/snes.cpp b/src/engine/platform/snes.cpp index e780cc414..754400d7e 100644 --- a/src/engine/platform/snes.cpp +++ b/src/engine/platform/snes.cpp @@ -208,7 +208,7 @@ void DivPlatformSNES::tick(bool sysTick) { // TODO: if wavetable length is higher than 32, we lose precision! if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) { DivSample* s=parent->getSample(chan[i].sample); - double off=(s->centerRate>=1)?((double)s->centerRate/8363.0):1.0; + double off=(s->centerRate>=1)?((double)s->centerRate/parent->getCenterRate()):1.0; if (chan[i].useWave) off=(double)chan[i].wtLen/32.0; chan[i].freq=(unsigned int)(off*parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,chipClock,CHIP_FREQBASE)); if (chan[i].freq>16383) chan[i].freq=16383; diff --git a/src/engine/platform/su.cpp b/src/engine/platform/su.cpp index 59f5292ff..07802f7a3 100644 --- a/src/engine/platform/su.cpp +++ b/src/engine/platform/su.cpp @@ -234,7 +234,7 @@ void DivPlatformSoundUnit::tick(bool sysTick) { if (sample->centerRate<1) { off=0.25; } else { - off=(double)sample->centerRate/(8363.0*4.0); + off=(double)sample->centerRate/(parent->getCenterRate()*4.0); } chan[i].freq=(double)chan[i].freq*off; } diff --git a/src/engine/platform/swan.cpp b/src/engine/platform/swan.cpp index ee0e02b31..6fb5afc3e 100644 --- a/src/engine/platform/swan.cpp +++ b/src/engine/platform/swan.cpp @@ -185,7 +185,7 @@ void DivPlatformSwan::tick(bool sysTick) { if (s->centerRate<1) { off=1.0; } else { - off=8363.0/(double)s->centerRate; + off=parent->getCenterRate()/(double)s->centerRate; } } dacRate=((double)chipClock/2)/MAX(1,off*chan[i].freq); diff --git a/src/engine/platform/vera.cpp b/src/engine/platform/vera.cpp index 1db64d90a..1845b6dd6 100644 --- a/src/engine/platform/vera.cpp +++ b/src/engine/platform/vera.cpp @@ -158,7 +158,7 @@ int DivPlatformVERA::calcNoteFreq(int ch, int note) { if (s->centerRate<1) { off=65536.0; } else { - off=65536.0*(s->centerRate/8363.0); + off=65536.0*(s->centerRate/parent->getCenterRate()); } } return (int)(parent->calcBaseFreq(chipClock,off,note,false)); @@ -230,10 +230,10 @@ void DivPlatformVERA::tick(bool sysTick) { DivSample* s=parent->getSample(chan[16].pcm.sample); lastCenterRate=s->centerRate; if (s->centerRate>=1) { - off=65536.0*(s->centerRate/8363.0); + off=65536.0*(s->centerRate/parent->getCenterRate()); } } else if (lastCenterRate>=1) { - off=65536.0*(lastCenterRate/8363.0); + off=65536.0*(lastCenterRate/parent->getCenterRate()); } chan[16].freq=parent->calcFreq(chan[16].baseFreq,chan[16].pitch,chan[16].fixedArp?chan[16].baseNoteOverride:chan[16].arpOff,chan[16].fixedArp,false,8,chan[16].pitch2,chipClock,off); if (chan[16].freq>128) chan[16].freq=128; diff --git a/src/engine/platform/vrc6.cpp b/src/engine/platform/vrc6.cpp index a23f179e8..d1c8372fa 100644 --- a/src/engine/platform/vrc6.cpp +++ b/src/engine/platform/vrc6.cpp @@ -208,7 +208,7 @@ void DivPlatformVRC6::tick(bool sysTick) { if (s->centerRate<1) { off=1.0; } else { - off=8363.0/(double)s->centerRate; + off=parent->getCenterRate()/(double)s->centerRate; } } chan[i].dacRate=((double)chipClock)/MAX(1,off*chan[i].freq); diff --git a/src/engine/platform/x1_010.cpp b/src/engine/platform/x1_010.cpp index 2cc26df61..a6c24f377 100644 --- a/src/engine/platform/x1_010.cpp +++ b/src/engine/platform/x1_010.cpp @@ -249,7 +249,7 @@ double DivPlatformX1_010::NoteX1_010(int ch, int note) { if (s->centerRate<1) { off=8192.0; } else { - off=8192.0*(s->centerRate/8363.0); + off=8192.0*(s->centerRate/parent->getCenterRate()); } } return parent->calcBaseFreq(chipClock,off,note,false); @@ -474,7 +474,7 @@ void DivPlatformX1_010::tick(bool sysTick) { if (s->centerRate<1) { off=8192.0; } else { - off=8192.0*(s->centerRate/8363.0); + off=8192.0*(s->centerRate/parent->getCenterRate()); } } } diff --git a/src/engine/platform/ym2608.cpp b/src/engine/platform/ym2608.cpp index f580b67fc..1380c0b50 100644 --- a/src/engine/platform/ym2608.cpp +++ b/src/engine/platform/ym2608.cpp @@ -289,7 +289,7 @@ double DivPlatformYM2608::NOTE_OPNB(int ch, int note) { double DivPlatformYM2608::NOTE_ADPCMB(int note) { if (chan[15+isCSM].sample>=0 && chan[15+isCSM].samplesong.sampleLen) { - double off=65535.0*(double)(parent->getSample(chan[15+isCSM].sample)->centerRate)/8363.0; + double off=65535.0*(double)(parent->getSample(chan[15+isCSM].sample)->centerRate)/parent->getCenterRate(); return parent->calcBaseFreq((double)chipClock/144,off,note,false); } return 0; @@ -982,7 +982,7 @@ void DivPlatformYM2608::tick(bool sysTick) { if (chan[(15+isCSM)].freqChanged || chan[(15+isCSM)].keyOn || chan[(15+isCSM)].keyOff) { if (chan[(15+isCSM)].furnacePCM) { if (chan[(15+isCSM)].sample>=0 && chan[(15+isCSM)].samplesong.sampleLen) { - double off=65535.0*(double)(parent->getSample(chan[(15+isCSM)].sample)->centerRate)/8363.0; + double off=65535.0*(double)(parent->getSample(chan[(15+isCSM)].sample)->centerRate)/parent->getCenterRate(); chan[(15+isCSM)].freq=parent->calcFreq(chan[(15+isCSM)].baseFreq,chan[(15+isCSM)].pitch,chan[(15+isCSM)].fixedArp?chan[(15+isCSM)].baseNoteOverride:chan[(15+isCSM)].arpOff,chan[(15+isCSM)].fixedArp,false,4,chan[(15+isCSM)].pitch2,(double)chipClock/144,off); } else { chan[(15+isCSM)].freq=0; diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index 13b077e35..025e75208 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -912,7 +912,7 @@ void DivPlatformYM2610::tick(bool sysTick) { if (chan[adpcmBChanOffs].freqChanged || chan[adpcmBChanOffs].keyOn || chan[adpcmBChanOffs].keyOff) { if (chan[adpcmBChanOffs].furnacePCM) { if (chan[adpcmBChanOffs].sample>=0 && chan[adpcmBChanOffs].samplesong.sampleLen) { - double off=65535.0*(double)(parent->getSample(chan[adpcmBChanOffs].sample)->centerRate)/8363.0; + double off=65535.0*(double)(parent->getSample(chan[adpcmBChanOffs].sample)->centerRate)/parent->getCenterRate(); chan[adpcmBChanOffs].freq=parent->calcFreq(chan[adpcmBChanOffs].baseFreq,chan[adpcmBChanOffs].pitch,chan[adpcmBChanOffs].fixedArp?chan[adpcmBChanOffs].baseNoteOverride:chan[adpcmBChanOffs].arpOff,chan[adpcmBChanOffs].fixedArp,false,4,chan[adpcmBChanOffs].pitch2,(double)chipClock/144,off); } else { chan[adpcmBChanOffs].freq=0; diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index 858cdf20b..55fbef1d5 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -980,7 +980,7 @@ void DivPlatformYM2610B::tick(bool sysTick) { if (chan[adpcmBChanOffs].freqChanged || chan[adpcmBChanOffs].keyOn || chan[adpcmBChanOffs].keyOff) { if (chan[adpcmBChanOffs].furnacePCM) { if (chan[adpcmBChanOffs].sample>=0 && chan[adpcmBChanOffs].samplesong.sampleLen) { - double off=65535.0*(double)(parent->getSample(chan[adpcmBChanOffs].sample)->centerRate)/8363.0; + double off=65535.0*(double)(parent->getSample(chan[adpcmBChanOffs].sample)->centerRate)/parent->getCenterRate(); chan[adpcmBChanOffs].freq=parent->calcFreq(chan[adpcmBChanOffs].baseFreq,chan[adpcmBChanOffs].pitch,chan[adpcmBChanOffs].fixedArp?chan[adpcmBChanOffs].baseNoteOverride:chan[adpcmBChanOffs].arpOff,chan[adpcmBChanOffs].fixedArp,false,4,chan[adpcmBChanOffs].pitch2,(double)chipClock/144,off); } else { chan[adpcmBChanOffs].freq=0; diff --git a/src/engine/platform/ym2610shared.h b/src/engine/platform/ym2610shared.h index 04200782c..2586aac20 100644 --- a/src/engine/platform/ym2610shared.h +++ b/src/engine/platform/ym2610shared.h @@ -101,7 +101,7 @@ class DivPlatformYM2610Base: public DivPlatformOPN { } double NOTE_ADPCMB(int note) { if (chan[adpcmBChanOffs].sample>=0 && chan[adpcmBChanOffs].samplesong.sampleLen) { - double off=65535.0*(double)(parent->getSample(chan[adpcmBChanOffs].sample)->centerRate)/8363.0; + double off=65535.0*(double)(parent->getSample(chan[adpcmBChanOffs].sample)->centerRate)/parent->getCenterRate(); return parent->calcBaseFreq((double)chipClock/144,off,note,false); } return 0; diff --git a/src/engine/platform/ymz280b.cpp b/src/engine/platform/ymz280b.cpp index 42b2a0f65..214a1e869 100644 --- a/src/engine/platform/ymz280b.cpp +++ b/src/engine/platform/ymz280b.cpp @@ -139,7 +139,7 @@ void DivPlatformYMZ280B::tick(bool sysTick) { case DIV_SAMPLE_DEPTH_16BIT: ctrl=0x60; break; default: ctrl=0; } - double off=(s->centerRate>=1)?((double)s->centerRate/8363.0):1.0; + double off=(s->centerRate>=1)?((double)s->centerRate/parent->getCenterRate()):1.0; chan[i].freq=(int)round(off*parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,chipClock,CHIP_FREQBASE)/256.0)-1; if (chan[i].freq<0) chan[i].freq=0; if (chan[i].freq>511) chan[i].freq=511; diff --git a/src/engine/platform/zxbeeperquadtone.cpp b/src/engine/platform/zxbeeperquadtone.cpp index 7401535d8..9c75df430 100644 --- a/src/engine/platform/zxbeeperquadtone.cpp +++ b/src/engine/platform/zxbeeperquadtone.cpp @@ -154,7 +154,7 @@ void DivPlatformZXBeeperQuadTone::tick(bool sysTick) { double off=CHIP_DIVIDER; if (curSample>=0 && curSamplesong.sampleLen) { DivSample* s=parent->getSample(curSample); - off=(s->centerRate>=1)?(CHIP_DIVIDER*(double)s->centerRate/8363.0):CHIP_DIVIDER; + off=(s->centerRate>=1)?(CHIP_DIVIDER*(double)s->centerRate/parent->getCenterRate()):CHIP_DIVIDER; } 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; diff --git a/src/engine/song.h b/src/engine/song.h index b557fd5df..d9cfe319f 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -352,6 +352,8 @@ struct DivSong { bool ceilVolumeScaling; bool oldAlwaysSetVolume; bool oldSampleOffset; + // TODO: this flag is not saved to the file yet. + bool oldCenterRate; std::vector ins; std::vector wave; @@ -481,7 +483,8 @@ struct DivSong { resetArpPhaseOnNewNote(false), ceilVolumeScaling(false), oldAlwaysSetVolume(false), - oldSampleOffset(false) { + oldSampleOffset(false), + oldCenterRate(true) { for (int i=0; igetCenterRate())/log(2.0))); int sampleNoteCoarse=60+(sampleNote>>7); int sampleNoteFine=(sampleNote&127)-64; @@ -662,7 +662,7 @@ void FurnaceGUI::drawSampleEdit() { if (coarseChanged) { MARK_MODIFIED sampleNote=((sampleNoteCoarse-60)<<7)+sampleNoteFine; - targetRate=8363.0*pow(2.0,(double)sampleNote/(128.0*12.0)); + targetRate=e->getCenterRate()*pow(2.0,(double)sampleNote/(128.0*12.0)); if (targetRate<100) targetRate=100; if (targetRate>384000) targetRate=384000; @@ -685,7 +685,7 @@ void FurnaceGUI::drawSampleEdit() { sampleNote=((sampleNoteCoarse-60)<<7)+sampleNoteFine; - targetRate=round(8363.0*pow(2.0,(double)sampleNote/(128.0*12.0))); + targetRate=round(e->getCenterRate()*pow(2.0,(double)sampleNote/(128.0*12.0))); if (targetRate==prevSampleRate) { if (prevFine==sampleNoteFine) {