dev90 - linear pitch macro option
This commit is contained in:
parent
4a9855f090
commit
66f5b2117f
|
@ -29,6 +29,9 @@ furthermore, an `or reserved` indicates this field is always present, but is res
|
||||||
|
|
||||||
the format versions are:
|
the format versions are:
|
||||||
|
|
||||||
|
- 90: Furnace dev90
|
||||||
|
- 89: Furnace dev89
|
||||||
|
- 88: Furnace dev88
|
||||||
- 87: Furnace dev87
|
- 87: Furnace dev87
|
||||||
- 86: Furnace dev86
|
- 86: Furnace dev86
|
||||||
- 85: Furnace dev85
|
- 85: Furnace dev85
|
||||||
|
@ -280,7 +283,8 @@ size | description
|
||||||
1 | new Sega PCM (with macros and proper vol/pan) (>=84) or reserved
|
1 | new Sega PCM (with macros and proper vol/pan) (>=84) or reserved
|
||||||
1 | weird f-num/block-based chip pitch slides (>=85) or reserved
|
1 | weird f-num/block-based chip pitch slides (>=85) or reserved
|
||||||
1 | SN duty macro always resets phase (>=86) or reserved
|
1 | SN duty macro always resets phase (>=86) or reserved
|
||||||
20 | reserved
|
1 | pitch macro is linear (>=90) or reserved
|
||||||
|
19 | reserved
|
||||||
```
|
```
|
||||||
|
|
||||||
# instrument
|
# instrument
|
||||||
|
@ -669,6 +673,8 @@ size | description
|
||||||
1 | parameter 2
|
1 | parameter 2
|
||||||
1 | parameter 3
|
1 | parameter 3
|
||||||
1 | parameter 4
|
1 | parameter 4
|
||||||
|
--- | **extra C64 data** (>=89)
|
||||||
|
1 | don't test/gate before new note
|
||||||
```
|
```
|
||||||
|
|
||||||
# wavetable
|
# wavetable
|
||||||
|
|
|
@ -914,21 +914,28 @@ unsigned short DivEngine::calcBaseFreqFNumBlock(double clock, double divider, in
|
||||||
return bf|(block<<bits);
|
return bf|(block<<bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivEngine::calcFreq(int base, int pitch, bool period, int octave) {
|
int DivEngine::calcFreq(int base, int pitch, bool period, int octave, int pitch2) {
|
||||||
if (song.linearPitch) {
|
if (song.linearPitch) {
|
||||||
// global pitch multiplier
|
// global pitch multiplier
|
||||||
int whatTheFuck=(1024+(globalPitch<<6)-(globalPitch<0?globalPitch-6:0));
|
int whatTheFuck=(1024+(globalPitch<<6)-(globalPitch<0?globalPitch-6:0));
|
||||||
if (whatTheFuck<1) whatTheFuck=1; // avoids division by zero but please kill me
|
if (whatTheFuck<1) whatTheFuck=1; // avoids division by zero but please kill me
|
||||||
|
if (song.pitchMacroIsLinear) {
|
||||||
|
pitch+=pitch2;
|
||||||
|
}
|
||||||
pitch+=2048;
|
pitch+=2048;
|
||||||
if (pitch<0) pitch=0;
|
if (pitch<0) pitch=0;
|
||||||
if (pitch>4095) pitch=4095;
|
if (pitch>4095) pitch=4095;
|
||||||
return period?
|
int ret=period?
|
||||||
((base*(reversePitchTable[pitch]))/whatTheFuck):
|
((base*(reversePitchTable[pitch]))/whatTheFuck):
|
||||||
(((base*(pitchTable[pitch]))>>10)*whatTheFuck)/1024;
|
(((base*(pitchTable[pitch]))>>10)*whatTheFuck)/1024;
|
||||||
|
if (!song.pitchMacroIsLinear) {
|
||||||
|
ret+=period?(-pitch2):pitch2;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
return period?
|
return period?
|
||||||
base-pitch:
|
base-pitch-pitch2:
|
||||||
base+((pitch*octave)>>1);
|
base+((pitch*octave)>>1)+pitch2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivEngine::play() {
|
void DivEngine::play() {
|
||||||
|
|
|
@ -44,8 +44,8 @@
|
||||||
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
||||||
#define BUSY_END isBusy.unlock(); softLocked=false;
|
#define BUSY_END isBusy.unlock(); softLocked=false;
|
||||||
|
|
||||||
#define DIV_VERSION "dev89"
|
#define DIV_VERSION "dev90"
|
||||||
#define DIV_ENGINE_VERSION 89
|
#define DIV_ENGINE_VERSION 90
|
||||||
|
|
||||||
// for imports
|
// for imports
|
||||||
#define DIV_VERSION_MOD 0xff01
|
#define DIV_VERSION_MOD 0xff01
|
||||||
|
@ -468,7 +468,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 calcFreq(int base, int pitch, bool period=false, int octave=0, int pitch2=0);
|
||||||
|
|
||||||
// find song loop position
|
// find song loop position
|
||||||
void walkSong(int& loopOrder, int& loopRow, int& loopEnd);
|
void walkSong(int& loopOrder, int& loopRow, int& loopEnd);
|
||||||
|
|
|
@ -1011,6 +1011,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
if (ds.version<86) {
|
if (ds.version<86) {
|
||||||
ds.snDutyReset=true;
|
ds.snDutyReset=true;
|
||||||
}
|
}
|
||||||
|
if (ds.version<90) {
|
||||||
|
ds.pitchMacroIsLinear=false;
|
||||||
|
}
|
||||||
ds.isDMF=false;
|
ds.isDMF=false;
|
||||||
|
|
||||||
reader.readS(); // reserved
|
reader.readS(); // reserved
|
||||||
|
@ -1372,7 +1375,12 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
} else {
|
} else {
|
||||||
reader.readC();
|
reader.readC();
|
||||||
}
|
}
|
||||||
for (int i=0; i<20; i++) {
|
if (ds.version>=90) {
|
||||||
|
ds.pitchMacroIsLinear=reader.readC();
|
||||||
|
} else {
|
||||||
|
reader.readC();
|
||||||
|
}
|
||||||
|
for (int i=0; i<19; i++) {
|
||||||
reader.readC();
|
reader.readC();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2317,7 +2325,8 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
||||||
w->writeC(song.newSegaPCM);
|
w->writeC(song.newSegaPCM);
|
||||||
w->writeC(song.fbPortaPause);
|
w->writeC(song.fbPortaPause);
|
||||||
w->writeC(song.snDutyReset);
|
w->writeC(song.snDutyReset);
|
||||||
for (int i=0; i<20; i++) {
|
w->writeC(song.pitchMacroIsLinear);
|
||||||
|
for (int i=0; i<19; i++) {
|
||||||
w->writeC(0);
|
w->writeC(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -207,7 +207,7 @@ void DivPlatformAmiga::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
//DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_AMIGA);
|
//DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_AMIGA);
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val);
|
||||||
if (chan[i].freq>4095) chan[i].freq=4095;
|
if (chan[i].freq>4095) chan[i].freq=4095;
|
||||||
if (chan[i].freq<0) chan[i].freq=0;
|
if (chan[i].freq<0) chan[i].freq=0;
|
||||||
if (chan[i].keyOn) {
|
if (chan[i].keyOn) {
|
||||||
|
|
|
@ -239,7 +239,7 @@ void DivPlatformAY8910::tick(bool sysTick) {
|
||||||
if (!chan[i].std.ex3.will) chan[i].autoEnvNum=1;
|
if (!chan[i].std.ex3.will) chan[i].autoEnvNum=1;
|
||||||
}
|
}
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val);
|
||||||
if (chan[i].freq>4095) chan[i].freq=4095;
|
if (chan[i].freq>4095) chan[i].freq=4095;
|
||||||
if (chan[i].keyOn) {
|
if (chan[i].keyOn) {
|
||||||
//rWrite(16+i*5+1,((chan[i].duty&3)<<6)|(63-(ins->gb.soundLen&63)));
|
//rWrite(16+i*5+1,((chan[i].duty&3)<<6)|(63-(ins->gb.soundLen&63)));
|
||||||
|
|
|
@ -261,7 +261,7 @@ void DivPlatformAY8930::tick(bool sysTick) {
|
||||||
immWrite(0x1a,ayNoiseOr);
|
immWrite(0x1a,ayNoiseOr);
|
||||||
}
|
}
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val);
|
||||||
if (chan[i].freq>65535) chan[i].freq=65535;
|
if (chan[i].freq>65535) chan[i].freq=65535;
|
||||||
if (chan[i].keyOn) {
|
if (chan[i].keyOn) {
|
||||||
if (chan[i].insChanged) {
|
if (chan[i].insChanged) {
|
||||||
|
|
|
@ -205,7 +205,7 @@ void DivPlatformC64::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,8)+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,8,chan[i].std.pitch.val);
|
||||||
if (chan[i].freq>0xffff) chan[i].freq=0xffff;
|
if (chan[i].freq>0xffff) chan[i].freq=0xffff;
|
||||||
if (chan[i].keyOn) {
|
if (chan[i].keyOn) {
|
||||||
rWrite(i*7+5,(chan[i].attack<<4)|(chan[i].decay));
|
rWrite(i*7+5,(chan[i].attack<<4)|(chan[i].decay));
|
||||||
|
|
|
@ -177,7 +177,7 @@ void DivPlatformFDS::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false)+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,2,chan[i].std.pitch.val);
|
||||||
if (chan[i].freq>4095) chan[i].freq=4095;
|
if (chan[i].freq>4095) chan[i].freq=4095;
|
||||||
if (chan[i].freq<0) chan[i].freq=0;
|
if (chan[i].freq<0) chan[i].freq=0;
|
||||||
if (chan[i].keyOn) {
|
if (chan[i].keyOn) {
|
||||||
|
|
|
@ -227,7 +227,7 @@ void DivPlatformGB::tick(bool sysTick) {
|
||||||
if (ntPos>255) ntPos=255;
|
if (ntPos>255) ntPos=255;
|
||||||
chan[i].freq=noiseTable[ntPos];
|
chan[i].freq=noiseTable[ntPos];
|
||||||
} else {
|
} else {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val);
|
||||||
if (chan[i].freq>2047) chan[i].freq=2047;
|
if (chan[i].freq>2047) chan[i].freq=2047;
|
||||||
if (chan[i].freq<0) chan[i].freq=0;
|
if (chan[i].freq<0) chan[i].freq=0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -410,7 +410,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].std.pitch.val;
|
int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,false,4,chan[i].std.pitch.val);
|
||||||
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) {
|
||||||
|
|
|
@ -307,7 +307,7 @@ 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].std.pitch.val;
|
int fNum=parent->calcFreq(opChan[i].baseFreq&0x7ff,opChan[i].pitch,false,4,opChan[i].std.pitch.val);
|
||||||
int block=(opChan[i].baseFreq&0xf800)>>11;
|
int block=(opChan[i].baseFreq&0xf800)>>11;
|
||||||
if (fNum<0) fNum=0;
|
if (fNum<0) fNum=0;
|
||||||
if (fNum>2047) {
|
if (fNum>2047) {
|
||||||
|
|
|
@ -195,7 +195,7 @@ void DivPlatformLynx::tick(bool sysTick) {
|
||||||
WRITE_OTHER(i, ((chan[i].lfsr&0xf00)>>4));
|
WRITE_OTHER(i, ((chan[i].lfsr&0xf00)>>4));
|
||||||
chan[i].lfsr=-1;
|
chan[i].lfsr=-1;
|
||||||
}
|
}
|
||||||
chan[i].fd=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)+chan[i].std.pitch.val;
|
chan[i].fd=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val);
|
||||||
if (chan[i].std.duty.had) {
|
if (chan[i].std.duty.had) {
|
||||||
chan[i].duty=chan[i].std.duty.val;
|
chan[i].duty=chan[i].std.duty.val;
|
||||||
WRITE_FEEDBACK(i, chan[i].duty.feedback);
|
WRITE_FEEDBACK(i, chan[i].duty.feedback);
|
||||||
|
|
|
@ -133,7 +133,7 @@ void DivPlatformMMC5::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)-1+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val)-1;
|
||||||
if (chan[i].freq>2047) chan[i].freq=2047;
|
if (chan[i].freq>2047) chan[i].freq=2047;
|
||||||
if (chan[i].freq<0) chan[i].freq=0;
|
if (chan[i].freq<0) chan[i].freq=0;
|
||||||
if (chan[i].keyOn) {
|
if (chan[i].keyOn) {
|
||||||
|
|
|
@ -347,7 +347,7 @@ void DivPlatformN163::tick(bool sysTick) {
|
||||||
chan[i].waveUpdated=false;
|
chan[i].waveUpdated=false;
|
||||||
}
|
}
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
chan[i].freq=parent->calcFreq((((chan[i].baseFreq*chan[i].waveLen)*(chanMax+1))/16),chan[i].pitch,false,0)+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq((((chan[i].baseFreq*chan[i].waveLen)*(chanMax+1))/16),chan[i].pitch,false,0,chan[i].std.pitch.val);
|
||||||
if (chan[i].freq<0) chan[i].freq=0;
|
if (chan[i].freq<0) chan[i].freq=0;
|
||||||
if (chan[i].freq>0x3ffff) chan[i].freq=0x3ffff;
|
if (chan[i].freq>0x3ffff) chan[i].freq=0x3ffff;
|
||||||
if (chan[i].keyOn) {
|
if (chan[i].keyOn) {
|
||||||
|
|
|
@ -217,7 +217,7 @@ void DivPlatformNES::tick(bool sysTick) {
|
||||||
if (ntPos>252) ntPos=252;
|
if (ntPos>252) ntPos=252;
|
||||||
chan[i].freq=(parent->song.properNoiseLayout)?(15-(chan[i].baseFreq&15)):(noiseTable[ntPos]);
|
chan[i].freq=(parent->song.properNoiseLayout)?(15-(chan[i].baseFreq&15)):(noiseTable[ntPos]);
|
||||||
} else {
|
} else {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)-1+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val)-1;
|
||||||
if (chan[i].freq>2047) chan[i].freq=2047;
|
if (chan[i].freq>2047) chan[i].freq=2047;
|
||||||
if (chan[i].freq<0) chan[i].freq=0;
|
if (chan[i].freq<0) chan[i].freq=0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -417,7 +417,7 @@ void DivPlatformOPL::tick(bool sysTick) {
|
||||||
bool updateDrums=false;
|
bool updateDrums=false;
|
||||||
for (int i=0; i<totalChans; i++) {
|
for (int i=0; i<totalChans; i++) {
|
||||||
if (chan[i].freqChanged) {
|
if (chan[i].freqChanged) {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq));
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq),chan[i].std.pitch.val);
|
||||||
if (chan[i].freq>131071) chan[i].freq=131071;
|
if (chan[i].freq>131071) chan[i].freq=131071;
|
||||||
int freqt=toFreq(chan[i].freq)+chan[i].std.pitch.val;
|
int freqt=toFreq(chan[i].freq)+chan[i].std.pitch.val;
|
||||||
chan[i].freqH=freqt>>8;
|
chan[i].freqH=freqt>>8;
|
||||||
|
|
|
@ -261,7 +261,7 @@ void DivPlatformOPLL::tick(bool sysTick) {
|
||||||
|
|
||||||
for (int i=0; i<11; i++) {
|
for (int i=0; i<11; i++) {
|
||||||
if (chan[i].freqChanged) {
|
if (chan[i].freqChanged) {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq));
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq),chan[i].std.pitch.val);
|
||||||
if (chan[i].freq>262143) chan[i].freq=262143;
|
if (chan[i].freq>262143) chan[i].freq=262143;
|
||||||
int freqt=toFreq(chan[i].freq)+chan[i].std.pitch.val;
|
int freqt=toFreq(chan[i].freq)+chan[i].std.pitch.val;
|
||||||
chan[i].freqL=freqt&0xff;
|
chan[i].freqL=freqt&0xff;
|
||||||
|
|
|
@ -217,7 +217,7 @@ void DivPlatformPCE::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
//DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_PCE);
|
//DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_PCE);
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val);
|
||||||
if (chan[i].furnaceDac) {
|
if (chan[i].furnaceDac) {
|
||||||
double off=1.0;
|
double off=1.0;
|
||||||
if (chan[i].dacSample>=0 && chan[i].dacSample<parent->song.sampleLen) {
|
if (chan[i].dacSample>=0 && chan[i].dacSample<parent->song.sampleLen) {
|
||||||
|
|
|
@ -193,7 +193,7 @@ void DivPlatformPCSpeaker::tick(bool sysTick) {
|
||||||
chan[i].freqChanged=true;
|
chan[i].freqChanged=true;
|
||||||
}
|
}
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)-1+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val)-1;
|
||||||
if (chan[i].freq<0) chan[i].freq=0;
|
if (chan[i].freq<0) chan[i].freq=0;
|
||||||
if (chan[i].freq>65535) chan[i].freq=65535;
|
if (chan[i].freq>65535) chan[i].freq=65535;
|
||||||
if (chan[i].keyOn) {
|
if (chan[i].keyOn) {
|
||||||
|
|
|
@ -116,7 +116,7 @@ void DivPlatformPET::tick(bool sysTick) {
|
||||||
chan.freqChanged=true;
|
chan.freqChanged=true;
|
||||||
}
|
}
|
||||||
if (chan.freqChanged || chan.keyOn || chan.keyOff) {
|
if (chan.freqChanged || chan.keyOn || chan.keyOff) {
|
||||||
chan.freq=parent->calcFreq(chan.baseFreq,chan.pitch,true)+chan.std.pitch.val;
|
chan.freq=parent->calcFreq(chan.baseFreq,chan.pitch,true,0,chan.std.pitch.val);
|
||||||
if (chan.freq>257) chan.freq=257;
|
if (chan.freq>257) chan.freq=257;
|
||||||
if (chan.freq<2) chan.freq=2;
|
if (chan.freq<2) chan.freq=2;
|
||||||
rWrite(8,chan.freq-2);
|
rWrite(8,chan.freq-2);
|
||||||
|
|
|
@ -331,7 +331,7 @@ void DivPlatformQSound::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
//DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_AMIGA);
|
//DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_AMIGA);
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false)+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,2,chan[i].std.pitch.val);
|
||||||
if (chan[i].freq>0xffff) chan[i].freq=0xffff;
|
if (chan[i].freq>0xffff) chan[i].freq=0xffff;
|
||||||
if (chan[i].keyOn) {
|
if (chan[i].keyOn) {
|
||||||
rWrite(q1_reg_map[Q1V_BANK][i], qsound_bank);
|
rWrite(q1_reg_map[Q1V_BANK][i], qsound_bank);
|
||||||
|
|
|
@ -194,7 +194,7 @@ void DivPlatformSAA1099::tick(bool sysTick) {
|
||||||
rWrite(0x18+(i/3),saaEnv[i/3]);
|
rWrite(0x18+(i/3),saaEnv[i/3]);
|
||||||
}
|
}
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val);
|
||||||
if (chan[i].freq>65535) chan[i].freq=65535;
|
if (chan[i].freq>65535) chan[i].freq=65535;
|
||||||
if (chan[i].freq>=32768) {
|
if (chan[i].freq>=32768) {
|
||||||
chan[i].freqH=7;
|
chan[i].freqH=7;
|
||||||
|
|
|
@ -106,7 +106,7 @@ void DivPlatformSMS::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
for (int i=0; i<3; i++) {
|
for (int i=0; i<3; i++) {
|
||||||
if (chan[i].freqChanged) {
|
if (chan[i].freqChanged) {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val);
|
||||||
if (chan[i].freq>1023) chan[i].freq=1023;
|
if (chan[i].freq>1023) chan[i].freq=1023;
|
||||||
if (chan[i].freq<8) chan[i].freq=1;
|
if (chan[i].freq<8) chan[i].freq=1;
|
||||||
//if (chan[i].actualNote>0x5d) chan[i].freq=0x01;
|
//if (chan[i].actualNote>0x5d) chan[i].freq=0x01;
|
||||||
|
@ -121,7 +121,7 @@ void DivPlatformSMS::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chan[3].freqChanged || updateSNMode) {
|
if (chan[3].freqChanged || updateSNMode) {
|
||||||
chan[3].freq=parent->calcFreq(chan[3].baseFreq,chan[3].pitch,true)+chan[3].std.pitch.val;
|
chan[3].freq=parent->calcFreq(chan[3].baseFreq,chan[3].pitch,true,0,chan[3].std.pitch.val);
|
||||||
if (chan[3].freq>1023) chan[3].freq=1023;
|
if (chan[3].freq>1023) chan[3].freq=1023;
|
||||||
if (chan[3].actualNote>0x5d) chan[3].freq=0x01;
|
if (chan[3].actualNote>0x5d) chan[3].freq=0x01;
|
||||||
if (snNoiseMode&2) { // take period from channel 3
|
if (snNoiseMode&2) { // take period from channel 3
|
||||||
|
|
|
@ -168,7 +168,7 @@ void DivPlatformSoundUnit::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
//DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_SU);
|
//DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_SU);
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false)+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,2,chan[i].std.pitch.val);
|
||||||
chWrite(i,0x00,chan[i].freq&0xff);
|
chWrite(i,0x00,chan[i].freq&0xff);
|
||||||
chWrite(i,0x01,chan[i].freq>>8);
|
chWrite(i,0x01,chan[i].freq>>8);
|
||||||
if (chan[i].freq>65535) chan[i].freq=65535;
|
if (chan[i].freq>65535) chan[i].freq=65535;
|
||||||
|
|
|
@ -194,7 +194,7 @@ void DivPlatformSwan::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val);
|
||||||
if (i==1 && pcm && furnaceDac) {
|
if (i==1 && pcm && furnaceDac) {
|
||||||
double off=1.0;
|
double off=1.0;
|
||||||
if (dacSample>=0 && dacSample<parent->song.sampleLen) {
|
if (dacSample>=0 && dacSample<parent->song.sampleLen) {
|
||||||
|
|
|
@ -194,7 +194,7 @@ void DivPlatformVERA::tick(bool sysTick) {
|
||||||
chan[i].freqChanged=true;
|
chan[i].freqChanged=true;
|
||||||
}
|
}
|
||||||
if (chan[i].freqChanged) {
|
if (chan[i].freqChanged) {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,8)+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,8,chan[i].std.pitch.val);
|
||||||
if (chan[i].freq>65535) chan[i].freq=65535;
|
if (chan[i].freq>65535) chan[i].freq=65535;
|
||||||
rWrite(i,0,chan[i].freq&0xff);
|
rWrite(i,0,chan[i].freq&0xff);
|
||||||
rWrite(i,1,(chan[i].freq>>8)&0xff);
|
rWrite(i,1,(chan[i].freq>>8)&0xff);
|
||||||
|
|
|
@ -123,7 +123,7 @@ void DivPlatformVIC20::tick(bool sysTick) {
|
||||||
chan[i].freqChanged=true;
|
chan[i].freqChanged=true;
|
||||||
}
|
}
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val);
|
||||||
if (i<3) {
|
if (i<3) {
|
||||||
chan[i].freq>>=(2-i);
|
chan[i].freq>>=(2-i);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -183,9 +183,9 @@ void DivPlatformVRC6::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
if (i==2) { // sawtooth
|
if (i==2) { // sawtooth
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)-1+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val)-1;
|
||||||
} else { // pulse
|
} else { // pulse
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)-1+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val)-1;
|
||||||
if (chan[i].furnaceDac) {
|
if (chan[i].furnaceDac) {
|
||||||
double off=1.0;
|
double off=1.0;
|
||||||
if (chan[i].dacSample>=0 && chan[i].dacSample<parent->song.sampleLen) {
|
if (chan[i].dacSample>=0 && chan[i].dacSample<parent->song.sampleLen) {
|
||||||
|
|
|
@ -476,7 +476,7 @@ void DivPlatformX1_010::tick(bool sysTick) {
|
||||||
chan[i].envChanged=false;
|
chan[i].envChanged=false;
|
||||||
}
|
}
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false)+chan[i].std.pitch.val;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,2,chan[i].std.pitch.val);
|
||||||
if (chan[i].pcm) {
|
if (chan[i].pcm) {
|
||||||
if (chan[i].freq<1) chan[i].freq=1;
|
if (chan[i].freq<1) chan[i].freq=1;
|
||||||
if (chan[i].freq>255) chan[i].freq=255;
|
if (chan[i].freq>255) chan[i].freq=255;
|
||||||
|
|
|
@ -572,7 +572,7 @@ void DivPlatformYM2610::tick(bool sysTick) {
|
||||||
for (int i=0; i<4; i++) {
|
for (int i=0; i<4; i++) {
|
||||||
if (i==1 && extMode) continue;
|
if (i==1 && extMode) continue;
|
||||||
if (chan[i].freqChanged) {
|
if (chan[i].freqChanged) {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq));
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq),chan[i].std.pitch.val);
|
||||||
if (chan[i].freq>262143) chan[i].freq=262143;
|
if (chan[i].freq>262143) chan[i].freq=262143;
|
||||||
int freqt=toFreq(chan[i].freq)+chan[i].std.pitch.val;
|
int freqt=toFreq(chan[i].freq)+chan[i].std.pitch.val;
|
||||||
immWrite(chanOffs[i]+ADDR_FREQH,freqt>>8);
|
immWrite(chanOffs[i]+ADDR_FREQH,freqt>>8);
|
||||||
|
|
|
@ -635,7 +635,7 @@ void DivPlatformYM2610B::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) {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq));
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq),chan[i].std.pitch.val);
|
||||||
if (chan[i].freq>262143) chan[i].freq=262143;
|
if (chan[i].freq>262143) chan[i].freq=262143;
|
||||||
int freqt=toFreq(chan[i].freq)+chan[i].std.pitch.val;
|
int freqt=toFreq(chan[i].freq)+chan[i].std.pitch.val;
|
||||||
immWrite(chanOffs[i]+ADDR_FREQH,freqt>>8);
|
immWrite(chanOffs[i]+ADDR_FREQH,freqt>>8);
|
||||||
|
|
|
@ -336,6 +336,7 @@ struct DivSong {
|
||||||
bool newSegaPCM;
|
bool newSegaPCM;
|
||||||
bool fbPortaPause;
|
bool fbPortaPause;
|
||||||
bool snDutyReset;
|
bool snDutyReset;
|
||||||
|
bool pitchMacroIsLinear;
|
||||||
|
|
||||||
DivOrders orders;
|
DivOrders orders;
|
||||||
std::vector<DivInstrument*> ins;
|
std::vector<DivInstrument*> ins;
|
||||||
|
@ -441,7 +442,8 @@ struct DivSong {
|
||||||
e1e2AlsoTakePriority(false),
|
e1e2AlsoTakePriority(false),
|
||||||
newSegaPCM(true),
|
newSegaPCM(true),
|
||||||
fbPortaPause(false),
|
fbPortaPause(false),
|
||||||
snDutyReset(false) {
|
snDutyReset(false),
|
||||||
|
pitchMacroIsLinear(true) {
|
||||||
for (int i=0; i<32; i++) {
|
for (int i=0; i<32; i++) {
|
||||||
system[i]=DIV_SYSTEM_NULL;
|
system[i]=DIV_SYSTEM_NULL;
|
||||||
systemVol[i]=64;
|
systemVol[i]=64;
|
||||||
|
|
|
@ -121,6 +121,10 @@ void FurnaceGUI::drawCompatFlags() {
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::SetTooltip("when enabled, duty macro will always reset phase, even if its value hasn't changed.");
|
ImGui::SetTooltip("when enabled, duty macro will always reset phase, even if its value hasn't changed.");
|
||||||
}
|
}
|
||||||
|
ImGui::Checkbox("Pitch macro is linear",&e->song.pitchMacroIsLinear);
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::SetTooltip("when enabled, the pitch macro of an instrument is in linear space.");
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::Text("Loop modality:");
|
ImGui::Text("Loop modality:");
|
||||||
if (ImGui::RadioButton("Reset channels",e->song.loopModality==0)) {
|
if (ImGui::RadioButton("Reset channels",e->song.loopModality==0)) {
|
||||||
|
|
Loading…
Reference in a new issue