Merge branch 'master' of https://github.com/tildearrow/furnace into es5506_alt
* 'master' of https://github.com/tildearrow/furnace: implement channel swapping implement relative pitch macro mode prepare for relative pitch macro # Conflicts: # src/gui/insEdit.cpp
This commit is contained in:
commit
cdb3a51766
86 changed files with 842 additions and 370 deletions
|
|
@ -198,6 +198,12 @@ void DivPlatformAmiga::tick(bool sysTick) {
|
|||
chan[i].ws.tick();
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].std.phaseReset.had) {
|
||||
|
|
@ -207,7 +213,7 @@ void DivPlatformAmiga::tick(bool sysTick) {
|
|||
}
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
//DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_AMIGA);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].pitch2);
|
||||
if (chan[i].freq>4095) chan[i].freq=4095;
|
||||
if (chan[i].freq<0) chan[i].freq=0;
|
||||
if (chan[i].keyOn) {
|
||||
|
|
@ -266,7 +272,7 @@ int DivPlatformAmiga::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (chan[c.chan].useWave) {
|
||||
chan[c.chan].ws.init(ins,chan[c.chan].audLen<<1,255,chan[c.chan].insChanged);
|
||||
}
|
||||
|
|
@ -277,7 +283,7 @@ int DivPlatformAmiga::dispatch(DivCommand c) {
|
|||
chan[c.chan].sample=-1;
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -364,7 +370,7 @@ int DivPlatformAmiga::dispatch(DivCommand c) {
|
|||
}
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
class DivPlatformAmiga: public DivDispatch {
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch;
|
||||
int freq, baseFreq, pitch, pitch2;
|
||||
unsigned int audLoc;
|
||||
unsigned short audLen;
|
||||
unsigned int audPos;
|
||||
|
|
@ -41,10 +41,15 @@ class DivPlatformAmiga: public DivDispatch {
|
|||
signed char vol, outVol;
|
||||
DivMacroInt std;
|
||||
DivWaveSynth ws;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
audLoc(0),
|
||||
audLen(0),
|
||||
audPos(0),
|
||||
|
|
|
|||
|
|
@ -275,6 +275,12 @@ void DivPlatformArcade::tick(bool sysTick) {
|
|||
}
|
||||
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
|
||||
|
|
@ -420,7 +426,7 @@ void DivPlatformArcade::tick(bool sysTick) {
|
|||
|
||||
for (int i=0; i<8; i++) {
|
||||
if (chan[i].freqChanged) {
|
||||
chan[i].freq=chan[i].baseFreq+(chan[i].pitch>>1)-64+chan[i].std.pitch.val;
|
||||
chan[i].freq=chan[i].baseFreq+(chan[i].pitch>>1)-64+chan[i].pitch2;
|
||||
if (chan[i].freq<0) chan[i].freq=0;
|
||||
if (chan[i].freq>=(95<<6)) chan[i].freq=(95<<6)-1;
|
||||
immWrite(i+0x28,hScale(chan[i].freq>>6));
|
||||
|
|
@ -452,7 +458,7 @@ int DivPlatformArcade::dispatch(DivCommand c) {
|
|||
chan[c.chan].state=ins->fm;
|
||||
}
|
||||
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,18 +36,23 @@ class DivPlatformArcade: public DivDispatch {
|
|||
DivInstrumentFM state;
|
||||
DivMacroInt std;
|
||||
unsigned char freqH, freqL;
|
||||
int freq, baseFreq, pitch, note;
|
||||
int freq, baseFreq, pitch, pitch2, note;
|
||||
int ins;
|
||||
signed char konCycles;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, portaPause, furnacePCM, hardReset;
|
||||
int vol, outVol;
|
||||
unsigned char chVolL, chVolR;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freqH(0),
|
||||
freqL(0),
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
note(0),
|
||||
ins(-1),
|
||||
active(false),
|
||||
|
|
|
|||
|
|
@ -216,6 +216,12 @@ void DivPlatformAY8910::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].std.phaseReset.had) {
|
||||
|
|
@ -239,7 +245,7 @@ void DivPlatformAY8910::tick(bool sysTick) {
|
|||
if (!chan[i].std.ex3.will) chan[i].autoEnvNum=1;
|
||||
}
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].pitch2);
|
||||
if (chan[i].freq>4095) chan[i].freq=4095;
|
||||
if (chan[i].keyOn) {
|
||||
//rWrite(16+i*5+1,((chan[i].duty&3)<<6)|(63-(ins->gb.soundLen&63)));
|
||||
|
|
@ -302,7 +308,7 @@ int DivPlatformAY8910::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (isMuted[c.chan]) {
|
||||
rWrite(0x08+c.chan,0);
|
||||
} else if (intellivision && (chan[c.chan].psgMode&4)) {
|
||||
|
|
@ -315,7 +321,7 @@ int DivPlatformAY8910::dispatch(DivCommand c) {
|
|||
case DIV_CMD_NOTE_OFF:
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -457,7 +463,7 @@ int DivPlatformAY8910::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_AY));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AY));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class DivPlatformAY8910: public DivDispatch {
|
|||
inline unsigned char regRemap(unsigned char reg) { return intellivision?AY8914RegRemap[reg&0x0f]:reg&0x0f; }
|
||||
struct Channel {
|
||||
unsigned char freqH, freqL;
|
||||
int freq, baseFreq, note, pitch;
|
||||
int freq, baseFreq, note, pitch, pitch2;
|
||||
int ins;
|
||||
unsigned char psgMode, autoEnvNum, autoEnvDen;
|
||||
signed char konCycles;
|
||||
|
|
@ -40,7 +40,11 @@ class DivPlatformAY8910: public DivDispatch {
|
|||
int vol, outVol;
|
||||
unsigned char pan;
|
||||
DivMacroInt std;
|
||||
Channel(): freqH(0), freqL(0), freq(0), baseFreq(0), note(0), pitch(0), ins(-1), psgMode(1), autoEnvNum(0), autoEnvDen(0), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), inPorta(false), vol(0), outVol(15), pan(3) {}
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel(): freqH(0), freqL(0), freq(0), baseFreq(0), note(0), pitch(0), pitch2(0), ins(-1), psgMode(1), autoEnvNum(0), autoEnvDen(0), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), inPorta(false), vol(0), outVol(15), pan(3) {}
|
||||
};
|
||||
Channel chan[3];
|
||||
bool isMuted[3];
|
||||
|
|
|
|||
|
|
@ -227,6 +227,12 @@ void DivPlatformAY8930::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].std.phaseReset.had) {
|
||||
|
|
@ -261,7 +267,7 @@ void DivPlatformAY8930::tick(bool sysTick) {
|
|||
immWrite(0x1a,ayNoiseOr);
|
||||
}
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].pitch2);
|
||||
if (chan[i].freq>65535) chan[i].freq=65535;
|
||||
if (chan[i].keyOn) {
|
||||
if (chan[i].insChanged) {
|
||||
|
|
@ -326,7 +332,7 @@ int DivPlatformAY8930::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (isMuted[c.chan]) {
|
||||
rWrite(0x08+c.chan,0);
|
||||
} else {
|
||||
|
|
@ -337,7 +343,7 @@ int DivPlatformAY8930::dispatch(DivCommand c) {
|
|||
case DIV_CMD_NOTE_OFF:
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -482,7 +488,7 @@ int DivPlatformAY8930::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_AY8930));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AY8930));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class DivPlatformAY8930: public DivDispatch {
|
|||
protected:
|
||||
struct Channel {
|
||||
unsigned char freqH, freqL;
|
||||
int freq, baseFreq, note, pitch;
|
||||
int freq, baseFreq, note, pitch, pitch2;
|
||||
int ins;
|
||||
unsigned char psgMode, autoEnvNum, autoEnvDen, duty;
|
||||
signed char konCycles;
|
||||
|
|
@ -36,7 +36,11 @@ class DivPlatformAY8930: public DivDispatch {
|
|||
int vol, outVol;
|
||||
unsigned char pan;
|
||||
DivMacroInt std;
|
||||
Channel(): freqH(0), freqL(0), freq(0), baseFreq(0), note(0), pitch(0), ins(-1), psgMode(1), autoEnvNum(0), autoEnvDen(0), duty(4), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), inPorta(false), vol(0), outVol(31), pan(3) {}
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel(): freqH(0), freqL(0), freq(0), baseFreq(0), note(0), pitch(0), pitch2(0), ins(-1), psgMode(1), autoEnvNum(0), autoEnvDen(0), duty(4), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), inPorta(false), vol(0), outVol(31), pan(3) {}
|
||||
};
|
||||
Channel chan[3];
|
||||
bool isMuted[3];
|
||||
|
|
|
|||
|
|
@ -111,6 +111,12 @@ void DivPlatformBubSysWSG::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].active) {
|
||||
|
|
@ -120,7 +126,7 @@ void DivPlatformBubSysWSG::tick(bool sysTick) {
|
|||
}
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
//DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_SCC);
|
||||
chan[i].freq=0x1000-parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)+chan[i].std.pitch.val;
|
||||
chan[i].freq=0x1000-parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)+chan[i].pitch2;
|
||||
if (chan[i].freq<0) chan[i].freq=0;
|
||||
if (chan[i].freq>4095) chan[i].freq=4095;
|
||||
k005289->load(i,chan[i].freq);
|
||||
|
|
@ -151,7 +157,7 @@ int DivPlatformBubSysWSG::dispatch(DivCommand c) {
|
|||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
rWrite(2+c.chan,(chan[c.chan].wave<<5)|chan[c.chan].vol);
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (chan[c.chan].wave<0) {
|
||||
chan[c.chan].wave=0;
|
||||
chan[c.chan].ws.changeWave1(chan[c.chan].wave);
|
||||
|
|
@ -163,7 +169,7 @@ int DivPlatformBubSysWSG::dispatch(DivCommand c) {
|
|||
case DIV_CMD_NOTE_OFF:
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -228,7 +234,7 @@ int DivPlatformBubSysWSG::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_SCC));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SCC));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -28,16 +28,21 @@
|
|||
|
||||
class DivPlatformBubSysWSG: public DivDispatch {
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch, note, ins;
|
||||
int freq, baseFreq, pitch, pitch2, note, ins;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta;
|
||||
signed char vol, outVol, wave;
|
||||
signed char waveROM[32] = {0}; // 4 bit PROM per channel on bubble system
|
||||
DivMacroInt std;
|
||||
DivWaveSynth ws;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
note(0),
|
||||
ins(-1),
|
||||
active(false),
|
||||
|
|
|
|||
|
|
@ -183,6 +183,12 @@ void DivPlatformC64::tick(bool sysTick) {
|
|||
rWrite(i*7+4,(chan[i].wave<<4)|(chan[i].test<<3)|(chan[i].ring<<2)|(chan[i].sync<<1)|(int)(chan[i].active));
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].std.ex1.had) {
|
||||
|
|
@ -205,7 +211,7 @@ void DivPlatformC64::tick(bool sysTick) {
|
|||
}
|
||||
|
||||
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].pitch2);
|
||||
if (chan[i].freq>0xffff) chan[i].freq=0xffff;
|
||||
if (chan[i].keyOn) {
|
||||
rWrite(i*7+5,(chan[i].attack<<4)|(chan[i].decay));
|
||||
|
|
@ -264,14 +270,14 @@ int DivPlatformC64::dispatch(DivCommand c) {
|
|||
if (chan[c.chan].insChanged) {
|
||||
chan[c.chan].insChanged=false;
|
||||
}
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_NOTE_OFF:
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].keyOn=false;
|
||||
//chan[c.chan].std.init(NULL);
|
||||
//chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
chan[c.chan].active=false;
|
||||
|
|
@ -352,7 +358,7 @@ int DivPlatformC64::dispatch(DivCommand c) {
|
|||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta || !chan[c.chan].inPorta) {
|
||||
chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_C64));
|
||||
chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_C64));
|
||||
chan[c.chan].keyOn=true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,17 +26,22 @@
|
|||
|
||||
class DivPlatformC64: public DivDispatch {
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch, prevFreq, testWhen, note, ins;
|
||||
int freq, baseFreq, pitch, pitch2, prevFreq, testWhen, note, ins;
|
||||
unsigned char sweep, wave, attack, decay, sustain, release;
|
||||
short duty;
|
||||
bool active, insChanged, freqChanged, sweepChanged, keyOn, keyOff, inPorta, filter;
|
||||
bool resetMask, resetFilter, resetDuty, ring, sync, test;
|
||||
signed char vol, outVol;
|
||||
DivMacroInt std;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
prevFreq(65535),
|
||||
testWhen(0),
|
||||
note(0),
|
||||
|
|
|
|||
|
|
@ -270,6 +270,12 @@ void DivPlatformES5506::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAL(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
// phase reset macro
|
||||
|
|
@ -300,9 +306,9 @@ void DivPlatformES5506::tick(bool sysTick) {
|
|||
}
|
||||
break;
|
||||
case 2: { // delta
|
||||
signed int next_k1=MAX(0,MIN(65535,chan[i].filter.k1+chan[i].std.ex1.val));
|
||||
if (chan[i].filter.k1!=next_k1) {
|
||||
chan[i].filter.k1=next_k1;
|
||||
signed int next_k1=CLAMP_VAL(chan[i].k1Offs+chan[i].std.ex1.val,-65535,65535);
|
||||
if (chan[i].k1Offs!=next_k1) {
|
||||
chan[i].k1Offs=next_k1;
|
||||
chan[i].filterChanged.k1=1;
|
||||
}
|
||||
break;
|
||||
|
|
@ -326,9 +332,9 @@ void DivPlatformES5506::tick(bool sysTick) {
|
|||
}
|
||||
break;
|
||||
case 2: { // delta
|
||||
signed int next_k2=MAX(0,MIN(65535,chan[i].filter.k2+chan[i].std.ex2.val));
|
||||
if (chan[i].filter.k2!=next_k2) {
|
||||
chan[i].filter.k2=next_k2;
|
||||
signed int next_k2=CLAMP_VAL(chan[i].k2Offs+chan[i].std.ex2.val,-65535,65535);
|
||||
if (chan[i].k2Offs!=next_k2) {
|
||||
chan[i].k2Offs=next_k2;
|
||||
chan[i].filterChanged.k2=1;
|
||||
}
|
||||
break;
|
||||
|
|
@ -399,15 +405,15 @@ void DivPlatformES5506::tick(bool sysTick) {
|
|||
pageWriteMask(0x00|i,0x5f,0x00,(chan[i].filter.mode<<8),0x0300);
|
||||
}
|
||||
if (chan[i].filterChanged.k2) {
|
||||
if (chan[i].std.ex2.mode==0) { // Relative
|
||||
pageWrite(0x00|i,0x07,MAX(0,MIN(65535,chan[i].filter.k2+chan[i].k2Offs)));
|
||||
if (chan[i].std.ex2.mode!=1) { // Relative
|
||||
pageWrite(0x00|i,0x07,CLAMP_VAL(chan[i].filter.k2+chan[i].k2Offs,0,65535));
|
||||
} else {
|
||||
pageWrite(0x00|i,0x07,chan[i].filter.k2);
|
||||
}
|
||||
}
|
||||
if (chan[i].filterChanged.k1) {
|
||||
if (chan[i].std.ex1.mode==0) { // Relative
|
||||
pageWrite(0x00|i,0x09,MAX(0,MIN(65535,chan[i].filter.k1+chan[i].k1Offs)));
|
||||
if (chan[i].std.ex1.mode!=1) { // Relative
|
||||
pageWrite(0x00|i,0x09,CLAMP_VAL(chan[i].filter.k1+chan[i].k1Offs,0,65535));
|
||||
} else {
|
||||
pageWrite(0x00|i,0x09,chan[i].filter.k1);
|
||||
}
|
||||
|
|
@ -456,13 +462,13 @@ void DivPlatformES5506::tick(bool sysTick) {
|
|||
pageWrite(0x00|i,0x08,(((unsigned char)chan[i].envelope.k2Ramp)<<8)|(chan[i].envelope.k2Slow?1:0));
|
||||
// initialize filter
|
||||
pageWriteMask(0x00|i,0x5f,0x00,(chan[i].pcm.bank<<14)|(chan[i].filter.mode<<8),0xc300);
|
||||
if ((chan[i].std.ex2.mode==0) && (chan[i].std.ex2.had)) {
|
||||
pageWrite(0x00|i,0x07,MAX(0,MIN(65535,chan[i].filter.k2+chan[i].k2Offs)));
|
||||
if ((chan[i].std.ex2.mode!=1) && (chan[i].std.ex2.had)) {
|
||||
pageWrite(0x00|i,0x07,CLAMP_VAL(chan[i].filter.k2+chan[i].k2Offs,0,65535));
|
||||
} else {
|
||||
pageWrite(0x00|i,0x07,chan[i].filter.k2);
|
||||
}
|
||||
if ((chan[i].std.ex1.mode==0) && (chan[i].std.ex1.had)) {
|
||||
pageWrite(0x00|i,0x09,MAX(0,MIN(65535,chan[i].filter.k1+chan[i].k1Offs)));
|
||||
if ((chan[i].std.ex1.mode!=1) && (chan[i].std.ex1.had)) {
|
||||
pageWrite(0x00|i,0x09,CLAMP_VAL(chan[i].filter.k1+chan[i].k1Offs,0,65535));
|
||||
} else {
|
||||
pageWrite(0x00|i,0x09,chan[i].filter.k1);
|
||||
}
|
||||
|
|
@ -506,38 +512,35 @@ int DivPlatformES5506::dispatch(DivCommand c) {
|
|||
switch (c.cmd) {
|
||||
case DIV_CMD_NOTE_ON: {
|
||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins);
|
||||
if (chan[c.chan].insChanged) {
|
||||
chan[c.chan].sample=ins->amiga.useNoteMap?ins->amiga.noteMap[c.value].ind:ins->amiga.initSample;
|
||||
double off=1.0;
|
||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||
chan[c.chan].pcm.index=chan[c.chan].sample;
|
||||
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
if (s->centerRate<1) {
|
||||
off=1.0;
|
||||
} else {
|
||||
off=ins->amiga.useNoteMap?((double)ins->amiga.noteMap[c.value].freq/((double)s->centerRate*pow(2.0,((double)c.value-48.0)/12.0))):((double)s->centerRate/8363.0);
|
||||
}
|
||||
const unsigned int start=s->offES5506<<10;
|
||||
const unsigned int length=s->samples-1;
|
||||
const unsigned int end=start+(length<<11);
|
||||
chan[c.chan].pcm.loopMode=s->isLoopable()?s->loopMode:DIV_SAMPLE_LOOPMODE_ONESHOT;
|
||||
chan[c.chan].pcm.freqOffs=off;
|
||||
chan[c.chan].pcm.reversed=ins->amiga.reversed;
|
||||
chan[c.chan].pcm.bank=(s->offES5506>>22)&3;
|
||||
chan[c.chan].pcm.start=start;
|
||||
chan[c.chan].pcm.end=end;
|
||||
chan[c.chan].pcm.length=length;
|
||||
chan[c.chan].pcm.loopStart=(start+(s->loopStart<<11))&0xfffff800;
|
||||
chan[c.chan].pcm.loopEnd=(start+((s->loopEnd-1)<<11))&0xffffff80;
|
||||
chan[c.chan].filter=ins->es5506.filter;
|
||||
chan[c.chan].envelope=ins->es5506.envelope;
|
||||
chan[c.chan].sample=ins->amiga.useNoteMap?ins->amiga.noteMap[c.value].ind:ins->amiga.initSample;
|
||||
double off=1.0;
|
||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||
chan[c.chan].pcm.index=chan[c.chan].sample;
|
||||
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
if (s->centerRate<1) {
|
||||
off=1.0;
|
||||
} else {
|
||||
chan[c.chan].sample=-1;
|
||||
chan[c.chan].pcm.index=-1;
|
||||
chan[c.chan].filter=DivInstrumentES5506::Filter();
|
||||
chan[c.chan].envelope=DivInstrumentES5506::Envelope();
|
||||
off=(ins->amiga.useNoteMap?((double)ins->amiga.noteMap[c.value].freq/((double)s->centerRate*pow(2.0,((double)c.value-48.0)/12.0))):1.0)*((double)s->centerRate/8363.0);
|
||||
}
|
||||
chan[c.chan].insChanged=false;
|
||||
const unsigned int start=s->offES5506<<10;
|
||||
const unsigned int length=s->samples-1;
|
||||
const unsigned int end=start+(length<<11);
|
||||
chan[c.chan].pcm.loopMode=s->isLoopable()?s->loopMode:DIV_SAMPLE_LOOPMODE_ONESHOT;
|
||||
chan[c.chan].pcm.freqOffs=off;
|
||||
chan[c.chan].pcm.reversed=ins->amiga.reversed;
|
||||
chan[c.chan].pcm.bank=(s->offES5506>>22)&3;
|
||||
chan[c.chan].pcm.start=start;
|
||||
chan[c.chan].pcm.end=end;
|
||||
chan[c.chan].pcm.length=length;
|
||||
chan[c.chan].pcm.loopStart=(start+(s->loopStart<<11))&0xfffff800;
|
||||
chan[c.chan].pcm.loopEnd=(start+((s->loopEnd-1)<<11))&0xffffff80;
|
||||
chan[c.chan].filter=ins->es5506.filter;
|
||||
chan[c.chan].envelope=ins->es5506.envelope;
|
||||
} else {
|
||||
chan[c.chan].sample=-1;
|
||||
chan[c.chan].pcm.index=-1;
|
||||
chan[c.chan].filter=DivInstrumentES5506::Filter();
|
||||
chan[c.chan].envelope=DivInstrumentES5506::Envelope();
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].baseFreq=NOTE_ES5506(c.chan,c.value);
|
||||
|
|
@ -556,7 +559,7 @@ int DivPlatformES5506::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_NOTE_OFF:
|
||||
|
|
@ -565,7 +568,7 @@ int DivPlatformES5506::dispatch(DivCommand c) {
|
|||
chan[c.chan].sample=-1;
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -694,7 +697,7 @@ int DivPlatformES5506::dispatch(DivCommand c) {
|
|||
}
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
@ -763,6 +766,7 @@ void DivPlatformES5506::reset() {
|
|||
|
||||
pageWriteMask(0x00,0x60,0x0b,chanMax);
|
||||
pageWriteMask(0x00,0x60,0x0b,0x1f);
|
||||
// set serial output to I2S-ish, 16 bit
|
||||
pageWriteMask(0x20,0x60,0x0a,0x01);
|
||||
pageWriteMask(0x20,0x60,0x0b,0x11);
|
||||
pageWriteMask(0x20,0x60,0x0c,0x20);
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf {
|
|||
loopEnd(0),
|
||||
loopMode(DIV_SAMPLE_LOOPMODE_ONESHOT) {}
|
||||
} pcm;
|
||||
int freq, baseFreq, pitch, note, ins, sample, wave;
|
||||
int freq, baseFreq, pitch, pitch2, note, ins, sample, wave;
|
||||
bool active, insChanged, freqChanged, volChanged, keyOn, keyOff, inPorta, useWave, isReverseLoop;
|
||||
|
||||
struct FilterChanged { // Filter changed flags
|
||||
|
|
@ -96,10 +96,21 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf {
|
|||
DivInstrumentES5506::Filter filter;
|
||||
DivInstrumentES5506::Envelope envelope;
|
||||
DivMacroInt std;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
if (std.ex1.mode==2) {
|
||||
k1Offs=0;
|
||||
}
|
||||
if (std.ex1.mode==2) {
|
||||
k2Offs=0;
|
||||
}
|
||||
}
|
||||
Channel():
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
note(0),
|
||||
ins(-1),
|
||||
sample(-1),
|
||||
|
|
@ -111,6 +122,8 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf {
|
|||
keyOn(false),
|
||||
keyOff(false),
|
||||
inPorta(false),
|
||||
useWave(false),
|
||||
isReverseLoop(false),
|
||||
k1Offs(0),
|
||||
k2Offs(0),
|
||||
vol(0xff),
|
||||
|
|
|
|||
|
|
@ -146,6 +146,12 @@ void DivPlatformFDS::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].active) {
|
||||
|
|
@ -177,7 +183,7 @@ void DivPlatformFDS::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,2,chan[i].std.pitch.val);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,2,chan[i].pitch2);
|
||||
if (chan[i].freq>4095) chan[i].freq=4095;
|
||||
if (chan[i].freq<0) chan[i].freq=0;
|
||||
if (chan[i].keyOn) {
|
||||
|
|
@ -241,7 +247,7 @@ int DivPlatformFDS::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (chan[c.chan].wave<0) {
|
||||
chan[c.chan].wave=0;
|
||||
ws.changeWave1(chan[c.chan].wave);
|
||||
|
|
@ -254,7 +260,7 @@ int DivPlatformFDS::dispatch(DivCommand c) {
|
|||
case DIV_CMD_NOTE_OFF:
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -358,7 +364,7 @@ int DivPlatformFDS::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_FDS));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_FDS));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -26,16 +26,21 @@
|
|||
|
||||
class DivPlatformFDS: public DivDispatch {
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch, prevFreq, note, modFreq, ins;
|
||||
int freq, baseFreq, pitch, pitch2, prevFreq, note, modFreq, ins;
|
||||
unsigned char duty, sweep, modDepth, modPos;
|
||||
bool active, insChanged, freqChanged, sweepChanged, keyOn, keyOff, inPorta, modOn;
|
||||
signed char vol, outVol, wave;
|
||||
signed char modTable[32];
|
||||
DivMacroInt std;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
prevFreq(65535),
|
||||
note(0),
|
||||
modFreq(0),
|
||||
|
|
|
|||
|
|
@ -198,6 +198,12 @@ void DivPlatformGB::tick(bool sysTick) {
|
|||
rWrite(0x25,procMute());
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].std.phaseReset.had) {
|
||||
|
|
@ -227,7 +233,7 @@ void DivPlatformGB::tick(bool sysTick) {
|
|||
if (ntPos>255) ntPos=255;
|
||||
chan[i].freq=noiseTable[ntPos];
|
||||
} else {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].pitch2);
|
||||
if (chan[i].freq>2047) chan[i].freq=2047;
|
||||
if (chan[i].freq<0) chan[i].freq=0;
|
||||
}
|
||||
|
|
@ -281,7 +287,7 @@ int DivPlatformGB::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (c.chan==2) {
|
||||
if (chan[c.chan].wave<0) {
|
||||
chan[c.chan].wave=0;
|
||||
|
|
@ -295,7 +301,7 @@ int DivPlatformGB::dispatch(DivCommand c) {
|
|||
case DIV_CMD_NOTE_OFF:
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -379,7 +385,7 @@ int DivPlatformGB::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_GB));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_GB));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -27,15 +27,20 @@
|
|||
|
||||
class DivPlatformGB: public DivDispatch {
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch, note, ins;
|
||||
int freq, baseFreq, pitch, pitch2, note, ins;
|
||||
unsigned char duty, sweep;
|
||||
bool active, insChanged, freqChanged, sweepChanged, keyOn, keyOff, inPorta;
|
||||
signed char vol, outVol, wave;
|
||||
DivMacroInt std;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
note(0),
|
||||
ins(-1),
|
||||
duty(0),
|
||||
|
|
|
|||
|
|
@ -282,6 +282,12 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
|||
}
|
||||
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
|
||||
|
|
@ -412,7 +418,7 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
|||
for (int i=0; i<6; i++) {
|
||||
if (i==2 && extMode) continue;
|
||||
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].pitch2);
|
||||
int block=(chan[i].baseFreq&0xf800)>>11;
|
||||
if (fNum<0) fNum=0;
|
||||
if (fNum>2047) {
|
||||
|
|
@ -436,7 +442,7 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
|||
off=(double)s->centerRate/8363.0;
|
||||
}
|
||||
}
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,4)+chan[i].std.pitch.val;
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,4)+chan[i].pitch2;
|
||||
dacRate=chan[i].freq*off;
|
||||
if (dacRate<1) dacRate=1;
|
||||
if (dumpWrites) addWrite(0xffff0001,dacRate);
|
||||
|
|
@ -526,7 +532,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
|||
chan[c.chan].state=ins->fm;
|
||||
}
|
||||
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,17 +36,22 @@ class DivPlatformGenesis: public DivDispatch {
|
|||
DivInstrumentFM state;
|
||||
DivMacroInt std;
|
||||
unsigned char freqH, freqL;
|
||||
int freq, baseFreq, pitch, portaPauseFreq, note;
|
||||
int freq, baseFreq, pitch, pitch2, portaPauseFreq, note;
|
||||
int ins;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, furnaceDac, inPorta, hardReset;
|
||||
int vol, outVol;
|
||||
unsigned char pan;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freqH(0),
|
||||
freqL(0),
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
portaPauseFreq(0),
|
||||
note(0),
|
||||
ins(-1),
|
||||
|
|
|
|||
|
|
@ -307,7 +307,7 @@ void DivPlatformGenesisExt::tick(bool sysTick) {
|
|||
unsigned char writeMask=2;
|
||||
if (extMode) for (int i=0; i<4; i++) {
|
||||
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].pitch2);
|
||||
int block=(opChan[i].baseFreq&0xf800)>>11;
|
||||
if (fNum<0) fNum=0;
|
||||
if (fNum>2047) {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class DivPlatformGenesisExt: public DivPlatformGenesis {
|
|||
struct OpChannel {
|
||||
DivMacroInt std;
|
||||
unsigned char freqH, freqL;
|
||||
int freq, baseFreq, pitch, portaPauseFreq, ins;
|
||||
int freq, baseFreq, pitch, pitch2, portaPauseFreq, ins;
|
||||
signed char konCycles;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause;
|
||||
int vol;
|
||||
|
|
@ -36,6 +36,7 @@ class DivPlatformGenesisExt: public DivPlatformGenesis {
|
|||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
portaPauseFreq(0),
|
||||
ins(-1),
|
||||
active(false),
|
||||
|
|
|
|||
|
|
@ -186,6 +186,12 @@ void DivPlatformLynx::tick(bool sysTick) {
|
|||
}
|
||||
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
|
||||
|
|
@ -195,7 +201,7 @@ void DivPlatformLynx::tick(bool sysTick) {
|
|||
WRITE_OTHER(i, ((chan[i].lfsr&0xf00)>>4));
|
||||
chan[i].lfsr=-1;
|
||||
}
|
||||
chan[i].fd=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val);
|
||||
chan[i].fd=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].pitch2);
|
||||
if (chan[i].std.duty.had) {
|
||||
chan[i].duty=chan[i].std.duty.val;
|
||||
WRITE_FEEDBACK(i, chan[i].duty.feedback);
|
||||
|
|
@ -224,12 +230,12 @@ int DivPlatformLynx::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[c.chan].active=true;
|
||||
WRITE_VOLUME(c.chan,(isMuted[c.chan]?0:(chan[c.chan].vol&127)));
|
||||
chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_MIKEY));
|
||||
chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_MIKEY));
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF:
|
||||
chan[c.chan].active=false;
|
||||
WRITE_VOLUME(c.chan, 0);
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_LYNX_LFSR_LOAD:
|
||||
chan[c.chan].freqChanged=true;
|
||||
|
|
@ -241,7 +247,7 @@ int DivPlatformLynx::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_INSTRUMENT:
|
||||
chan[c.chan].ins=c.value;
|
||||
//chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_MIKEY));
|
||||
//chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_MIKEY));
|
||||
break;
|
||||
case DIV_CMD_VOLUME:
|
||||
if (chan[c.chan].vol!=c.value) {
|
||||
|
|
@ -297,7 +303,7 @@ int DivPlatformLynx::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_MIKEY));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_MIKEY));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -44,16 +44,21 @@ class DivPlatformLynx: public DivDispatch {
|
|||
DivMacroInt std;
|
||||
MikeyFreqDiv fd;
|
||||
MikeyDuty duty;
|
||||
int baseFreq, pitch, note, actualNote, lfsr, ins;
|
||||
int baseFreq, pitch, pitch2, note, actualNote, lfsr, ins;
|
||||
unsigned char pan;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta;
|
||||
signed char vol, outVol;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
std(),
|
||||
fd(0),
|
||||
duty(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
note(0),
|
||||
actualNote(0),
|
||||
lfsr(-1),
|
||||
|
|
|
|||
|
|
@ -125,6 +125,12 @@ void DivPlatformMMC5::tick(bool sysTick) {
|
|||
rWrite(0x5000+i*4,0x30|chan[i].outVol|((chan[i].duty&3)<<6));
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].std.phaseReset.had) {
|
||||
|
|
@ -134,7 +140,7 @@ void DivPlatformMMC5::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val)-1;
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].pitch2)-1;
|
||||
if (chan[i].freq>2047) chan[i].freq=2047;
|
||||
if (chan[i].freq<0) chan[i].freq=0;
|
||||
if (chan[i].keyOn) {
|
||||
|
|
@ -228,7 +234,7 @@ int DivPlatformMMC5::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
|
||||
chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
|
||||
rWrite(0x5000+c.chan*4,0x30|chan[c.chan].vol|((chan[c.chan].duty&3)<<6));
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF:
|
||||
|
|
@ -238,7 +244,7 @@ int DivPlatformMMC5::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -306,7 +312,7 @@ int DivPlatformMMC5::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -25,15 +25,20 @@
|
|||
|
||||
class DivPlatformMMC5: public DivDispatch {
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch, prevFreq, note, ins;
|
||||
int freq, baseFreq, pitch, pitch2, prevFreq, note, ins;
|
||||
unsigned char duty, sweep;
|
||||
bool active, insChanged, freqChanged, sweepChanged, keyOn, keyOff, inPorta, furnaceDac;
|
||||
signed char vol, outVol, wave;
|
||||
DivMacroInt std;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
prevFreq(65535),
|
||||
note(0),
|
||||
ins(-1),
|
||||
|
|
|
|||
|
|
@ -262,6 +262,12 @@ void DivPlatformN163::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].std.ex1.had) {
|
||||
|
|
@ -347,7 +353,7 @@ void DivPlatformN163::tick(bool sysTick) {
|
|||
chan[i].waveUpdated=false;
|
||||
}
|
||||
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].pitch2);
|
||||
if (chan[i].freq<0) chan[i].freq=0;
|
||||
if (chan[i].freq>0x3ffff) chan[i].freq=0x3ffff;
|
||||
if (chan[i].keyOn) {
|
||||
|
|
@ -398,7 +404,7 @@ int DivPlatformN163::dispatch(DivCommand c) {
|
|||
if (!isMuted[c.chan]) {
|
||||
chan[c.chan].volumeChanged=true;
|
||||
}
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
chan[c.chan].ws.init(ins,chan[c.chan].waveLen,15,chan[c.chan].insChanged);
|
||||
break;
|
||||
}
|
||||
|
|
@ -406,7 +412,7 @@ int DivPlatformN163::dispatch(DivCommand c) {
|
|||
chan[c.chan].active=false;
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].keyOn=false;
|
||||
//chan[c.chan].std.init(NULL);
|
||||
//chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
chan[c.chan].active=false;
|
||||
|
|
@ -546,7 +552,7 @@ int DivPlatformN163::dispatch(DivCommand c) {
|
|||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) {
|
||||
chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_N163));
|
||||
chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_N163));
|
||||
chan[c.chan].keyOn=true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
class DivPlatformN163: public DivDispatch {
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch, note;
|
||||
int freq, baseFreq, pitch, pitch2, note;
|
||||
short ins, wave, wavePos, waveLen;
|
||||
unsigned char waveMode;
|
||||
short loadWave, loadPos, loadLen;
|
||||
|
|
@ -37,10 +37,15 @@ class DivPlatformN163: public DivDispatch {
|
|||
signed char vol, outVol, resVol;
|
||||
DivMacroInt std;
|
||||
DivWaveSynth ws;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
note(0),
|
||||
ins(-1),
|
||||
wave(-1),
|
||||
|
|
|
|||
|
|
@ -197,6 +197,12 @@ void DivPlatformNES::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].sweepChanged) {
|
||||
|
|
@ -218,7 +224,7 @@ void DivPlatformNES::tick(bool sysTick) {
|
|||
if (ntPos>252) ntPos=252;
|
||||
chan[i].freq=(parent->song.properNoiseLayout)?(15-(chan[i].baseFreq&15)):(noiseTable[ntPos]);
|
||||
} else {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val)-1;
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].pitch2)-1;
|
||||
if (chan[i].freq>2047) chan[i].freq=2047;
|
||||
if (chan[i].freq<0) chan[i].freq=0;
|
||||
}
|
||||
|
|
@ -326,7 +332,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
|
||||
chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
|
||||
if (c.chan==2) {
|
||||
rWrite(0x4000+c.chan*4,0xff);
|
||||
} else {
|
||||
|
|
@ -340,7 +346,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -429,7 +435,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -25,15 +25,20 @@
|
|||
|
||||
class DivPlatformNES: public DivDispatch {
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch, prevFreq, note, ins;
|
||||
int freq, baseFreq, pitch, pitch2, prevFreq, note, ins;
|
||||
unsigned char duty, sweep;
|
||||
bool active, insChanged, freqChanged, sweepChanged, keyOn, keyOff, inPorta, furnaceDac;
|
||||
signed char vol, outVol, wave;
|
||||
DivMacroInt std;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
prevFreq(65535),
|
||||
note(0),
|
||||
ins(-1),
|
||||
|
|
|
|||
|
|
@ -274,6 +274,12 @@ void DivPlatformOPL::tick(bool sysTick) {
|
|||
}
|
||||
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
|
||||
|
|
@ -417,9 +423,9 @@ void DivPlatformOPL::tick(bool sysTick) {
|
|||
bool updateDrums=false;
|
||||
for (int i=0; i<totalChans; i++) {
|
||||
if (chan[i].freqChanged) {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq),chan[i].std.pitch.val);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq),chan[i].pitch2);
|
||||
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].pitch2;
|
||||
chan[i].freqH=freqt>>8;
|
||||
chan[i].freqL=freqt&0xff;
|
||||
immWrite(chanMap[i]+ADDR_FREQ,chan[i].freqL);
|
||||
|
|
@ -541,7 +547,7 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
chan[c.chan].state=ins->fm;
|
||||
}
|
||||
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
}
|
||||
|
|
@ -549,7 +555,7 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
|
||||
chan[c.chan].fourOp=(ops==4);
|
||||
if (chan[c.chan].fourOp) {
|
||||
chan[c.chan+1].std.init(NULL);
|
||||
chan[c.chan+1].macroInit(NULL);
|
||||
}
|
||||
update4OpMask=true;
|
||||
for (int i=0; i<ops; i++) {
|
||||
|
|
|
|||
|
|
@ -30,16 +30,21 @@ class DivPlatformOPL: public DivDispatch {
|
|||
DivInstrumentFM state;
|
||||
DivMacroInt std;
|
||||
unsigned char freqH, freqL;
|
||||
int freq, baseFreq, pitch, note, ins;
|
||||
int freq, baseFreq, pitch, pitch2, note, ins;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, furnaceDac, inPorta, fourOp;
|
||||
int vol, outVol;
|
||||
unsigned char pan;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freqH(0),
|
||||
freqL(0),
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
note(0),
|
||||
ins(-1),
|
||||
active(false),
|
||||
|
|
|
|||
|
|
@ -146,6 +146,12 @@ void DivPlatformOPLL::tick(bool sysTick) {
|
|||
}
|
||||
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
|
||||
|
|
@ -261,9 +267,9 @@ void DivPlatformOPLL::tick(bool sysTick) {
|
|||
|
||||
for (int i=0; i<11; i++) {
|
||||
if (chan[i].freqChanged) {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq),chan[i].std.pitch.val);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq),chan[i].pitch2);
|
||||
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].pitch2;
|
||||
chan[i].freqL=freqt&0xff;
|
||||
if (i>=6 && properDrums) {
|
||||
immWrite(0x10+drumSlot[i],freqt&0xff);
|
||||
|
|
@ -370,7 +376,7 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
|
|||
chan[c.chan].state=ins->fm;
|
||||
}
|
||||
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,16 +33,21 @@ class DivPlatformOPLL: public DivDispatch {
|
|||
DivInstrumentFM state;
|
||||
DivMacroInt std;
|
||||
unsigned char freqH, freqL;
|
||||
int freq, baseFreq, pitch, note, ins;
|
||||
int freq, baseFreq, pitch, pitch2, note, ins;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, furnaceDac, inPorta;
|
||||
int vol, outVol;
|
||||
unsigned char pan;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freqH(0),
|
||||
freqL(0),
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
note(0),
|
||||
ins(-1),
|
||||
active(false),
|
||||
|
|
|
|||
|
|
@ -208,6 +208,12 @@ void DivPlatformPCE::tick(bool sysTick) {
|
|||
chWrite(i,0x05,isMuted[i]?0:chan[i].pan);
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].active) {
|
||||
|
|
@ -217,7 +223,7 @@ void DivPlatformPCE::tick(bool sysTick) {
|
|||
}
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
//DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_PCE);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].pitch2);
|
||||
if (chan[i].furnaceDac) {
|
||||
double off=1.0;
|
||||
if (chan[i].dacSample>=0 && chan[i].dacSample<parent->song.sampleLen) {
|
||||
|
|
@ -279,7 +285,7 @@ int DivPlatformPCE::dispatch(DivCommand c) {
|
|||
chan[c.chan].note=c.value;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
//chan[c.chan].keyOn=true;
|
||||
chan[c.chan].furnaceDac=true;
|
||||
} else {
|
||||
|
|
@ -316,7 +322,7 @@ int DivPlatformPCE::dispatch(DivCommand c) {
|
|||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chWrite(c.chan,0x04,0x80|chan[c.chan].vol);
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (chan[c.chan].wave<0) {
|
||||
chan[c.chan].wave=0;
|
||||
chan[c.chan].ws.changeWave1(chan[c.chan].wave);
|
||||
|
|
@ -331,7 +337,7 @@ int DivPlatformPCE::dispatch(DivCommand c) {
|
|||
chan[c.chan].pcm=false;
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -429,7 +435,7 @@ int DivPlatformPCE::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_PCE));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_PCE));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
class DivPlatformPCE: public DivDispatch {
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch, note;
|
||||
int freq, baseFreq, pitch, pitch2, note;
|
||||
int dacPeriod, dacRate;
|
||||
unsigned int dacPos;
|
||||
int dacSample, ins;
|
||||
|
|
@ -37,10 +37,15 @@ class DivPlatformPCE: public DivDispatch {
|
|||
signed char vol, outVol, wave;
|
||||
DivMacroInt std;
|
||||
DivWaveSynth ws;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
note(0),
|
||||
dacPeriod(0),
|
||||
dacRate(0),
|
||||
|
|
|
|||
|
|
@ -190,10 +190,16 @@ void DivPlatformPCSpeaker::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val)-1;
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].pitch2)-1;
|
||||
if (chan[i].freq<0) chan[i].freq=0;
|
||||
if (chan[i].freq>65535) chan[i].freq=65535;
|
||||
if (chan[i].keyOn) {
|
||||
|
|
@ -220,12 +226,12 @@ int DivPlatformPCSpeaker::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_BEEPER));
|
||||
chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_BEEPER));
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF:
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -285,7 +291,7 @@ int DivPlatformPCSpeaker::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_BEEPER));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_BEEPER));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -25,15 +25,20 @@
|
|||
|
||||
class DivPlatformPCSpeaker: public DivDispatch {
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch, note, ins;
|
||||
int freq, baseFreq, pitch, pitch2, note, ins;
|
||||
unsigned char duty, sweep;
|
||||
bool active, insChanged, freqChanged, sweepChanged, keyOn, keyOff, inPorta, furnaceDac;
|
||||
signed char vol, outVol, wave;
|
||||
DivMacroInt std;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
note(0),
|
||||
ins(-1),
|
||||
duty(0),
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ void DivPlatformPET::tick(bool sysTick) {
|
|||
chan.freqChanged=true;
|
||||
}
|
||||
if (chan.freqChanged || chan.keyOn || chan.keyOff) {
|
||||
chan.freq=parent->calcFreq(chan.baseFreq,chan.pitch,true,0,chan.std.pitch.val);
|
||||
chan.freq=parent->calcFreq(chan.baseFreq,chan.pitch,true,0,chan.pitch2);
|
||||
if (chan.freq>257) chan.freq=257;
|
||||
if (chan.freq<2) chan.freq=2;
|
||||
rWrite(8,chan.freq-2);
|
||||
|
|
@ -146,13 +146,13 @@ int DivPlatformPET::dispatch(DivCommand c) {
|
|||
}
|
||||
chan.active=true;
|
||||
chan.keyOn=true;
|
||||
chan.std.init(ins);
|
||||
chan.macroInit(ins);
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_NOTE_OFF:
|
||||
chan.active=false;
|
||||
chan.keyOff=true;
|
||||
chan.std.init(NULL);
|
||||
chan.macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -213,7 +213,7 @@ int DivPlatformPET::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan.active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan.std.init(parent->getIns(chan.ins,DIV_INS_PET));
|
||||
if (parent->song.resetMacroOnPorta) chan.macroInit(parent->getIns(chan.ins,DIV_INS_PET));
|
||||
}
|
||||
chan.inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -25,17 +25,22 @@
|
|||
|
||||
class DivPlatformPET: public DivDispatch {
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch, note, ins;
|
||||
int freq, baseFreq, pitch, pitch2, note, ins;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta;
|
||||
int vol, outVol, wave;
|
||||
unsigned char sreg;
|
||||
int cnt;
|
||||
short out;
|
||||
DivMacroInt std;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
note(0),
|
||||
ins(-1),
|
||||
active(false),
|
||||
|
|
|
|||
|
|
@ -327,11 +327,17 @@ void DivPlatformQSound::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
//DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_AMIGA);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,2,chan[i].std.pitch.val);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,2,chan[i].pitch2);
|
||||
if (chan[i].freq>0xffff) chan[i].freq=0xffff;
|
||||
if (chan[i].keyOn) {
|
||||
rWrite(q1_reg_map[Q1V_BANK][i], qsound_bank);
|
||||
|
|
@ -386,14 +392,14 @@ int DivPlatformQSound::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_NOTE_OFF:
|
||||
chan[c.chan].sample=-1;
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -487,7 +493,7 @@ int DivPlatformQSound::dispatch(DivCommand c) {
|
|||
}
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
class DivPlatformQSound: public DivDispatch {
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch;
|
||||
int freq, baseFreq, pitch, pitch2;
|
||||
unsigned short audLen;
|
||||
unsigned int audPos;
|
||||
int sample, wave, ins;
|
||||
|
|
@ -36,10 +36,15 @@ class DivPlatformQSound: public DivDispatch {
|
|||
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, useWave;
|
||||
int vol, outVol;
|
||||
DivMacroInt std;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
audLen(0),
|
||||
audPos(0),
|
||||
sample(-1),
|
||||
|
|
|
|||
|
|
@ -187,6 +187,12 @@ void DivPlatformSAA1099::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].std.ex1.had) {
|
||||
|
|
@ -194,7 +200,7 @@ void DivPlatformSAA1099::tick(bool sysTick) {
|
|||
rWrite(0x18+(i/3),saaEnv[i/3]);
|
||||
}
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].pitch2);
|
||||
if (chan[i].freq>65535) chan[i].freq=65535;
|
||||
if (chan[i].freq>=32768) {
|
||||
chan[i].freqH=7;
|
||||
|
|
@ -257,7 +263,7 @@ int DivPlatformSAA1099::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (isMuted[c.chan]) {
|
||||
rWrite(c.chan,0);
|
||||
} else {
|
||||
|
|
@ -268,7 +274,7 @@ int DivPlatformSAA1099::dispatch(DivCommand c) {
|
|||
case DIV_CMD_NOTE_OFF:
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -356,7 +362,7 @@ int DivPlatformSAA1099::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_SAA1099));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SAA1099));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -35,14 +35,18 @@ class DivPlatformSAA1099: public DivDispatch {
|
|||
protected:
|
||||
struct Channel {
|
||||
unsigned char freqH, freqL;
|
||||
int freq, baseFreq, pitch, note, ins;
|
||||
int freq, baseFreq, pitch, pitch2, note, ins;
|
||||
unsigned char psgMode;
|
||||
signed char konCycles;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta;
|
||||
int vol, outVol;
|
||||
unsigned char pan;
|
||||
DivMacroInt std;
|
||||
Channel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), note(0), ins(-1), psgMode(1), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), inPorta(false), vol(0), outVol(15), pan(255) {}
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), pitch2(0), note(0), ins(-1), psgMode(1), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), inPorta(false), vol(0), outVol(15), pan(255) {}
|
||||
};
|
||||
Channel chan[6];
|
||||
bool isMuted[6];
|
||||
|
|
|
|||
|
|
@ -116,6 +116,12 @@ void DivPlatformSegaPCM::tick(bool sysTick) {
|
|||
}
|
||||
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
/*if (chan[i].keyOn || chan[i].keyOff) {
|
||||
|
|
@ -132,7 +138,7 @@ void DivPlatformSegaPCM::tick(bool sysTick) {
|
|||
DivSample* s=parent->getSample(chan[i].pcm.sample);
|
||||
off=(double)s->centerRate/8363.0;
|
||||
}
|
||||
chan[i].pcm.freq=MIN(255,(15625+(off*parent->song.tuning*pow(2.0,double(chan[i].freq+256)/(64.0*12.0)))*255)/31250)+chan[i].std.pitch.val;
|
||||
chan[i].pcm.freq=MIN(255,(15625+(off*parent->song.tuning*pow(2.0,double(chan[i].freq+256)/(64.0*12.0)))*255)/31250)+chan[i].pitch2;
|
||||
if (dumpWrites) {
|
||||
addWrite(0x10007+(i<<3),chan[i].pcm.freq);
|
||||
}
|
||||
|
|
@ -158,7 +164,7 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) {
|
|||
if (dumpWrites) {
|
||||
addWrite(0x10086+(c.chan<<3),3);
|
||||
}
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
}
|
||||
chan[c.chan].pcm.pos=0;
|
||||
|
|
@ -168,7 +174,7 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) {
|
|||
chan[c.chan].freqChanged=true;
|
||||
}
|
||||
chan[c.chan].furnacePCM=true;
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (dumpWrites) { // Sega PCM writes
|
||||
DivSample* s=parent->getSample(chan[c.chan].pcm.sample);
|
||||
addWrite(0x10086+(c.chan<<3),3+((s->offSegaPCM>>16)<<3));
|
||||
|
|
@ -185,7 +191,7 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].note=c.value;
|
||||
}
|
||||
|
|
@ -227,7 +233,7 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) {
|
|||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].keyOn=false;
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
chan[c.chan].keyOff=true;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class DivPlatformSegaPCM: public DivDispatch {
|
|||
struct Channel {
|
||||
DivMacroInt std;
|
||||
unsigned char freqH, freqL;
|
||||
int freq, baseFreq, pitch, note, ins;
|
||||
int freq, baseFreq, pitch, pitch2, note, ins;
|
||||
signed char konCycles;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, portaPause, furnacePCM;
|
||||
int vol, outVol;
|
||||
|
|
@ -42,7 +42,11 @@ class DivPlatformSegaPCM: public DivDispatch {
|
|||
unsigned char freq;
|
||||
PCMChannel(): sample(-1), pos(0), len(0), freq(0) {}
|
||||
} pcm;
|
||||
Channel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), note(0), ins(-1), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), inPorta(false), portaPause(false), furnacePCM(false), vol(0), outVol(0), chVolL(127), chVolR(127) {}
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), pitch2(0), note(0), ins(-1), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), inPorta(false), portaPause(false), furnacePCM(false), vol(0), outVol(0), chVolL(127), chVolR(127) {}
|
||||
};
|
||||
Channel chan[16];
|
||||
struct QueuedWrite {
|
||||
|
|
|
|||
|
|
@ -101,12 +101,18 @@ void DivPlatformSMS::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
}
|
||||
for (int i=0; i<3; i++) {
|
||||
if (chan[i].freqChanged) {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].pitch2);
|
||||
if (chan[i].freq>1023) chan[i].freq=1023;
|
||||
if (chan[i].freq<8) chan[i].freq=1;
|
||||
//if (chan[i].actualNote>0x5d) chan[i].freq=0x01;
|
||||
|
|
@ -121,7 +127,7 @@ void DivPlatformSMS::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (chan[3].freqChanged || updateSNMode) {
|
||||
chan[3].freq=parent->calcFreq(chan[3].baseFreq,chan[3].pitch,true,0,chan[3].std.pitch.val);
|
||||
chan[3].freq=parent->calcFreq(chan[3].baseFreq,chan[3].pitch,true,0,chan[3].pitch2);
|
||||
if (chan[3].freq>1023) chan[3].freq=1023;
|
||||
if (chan[3].actualNote>0x5d) chan[3].freq=0x01;
|
||||
if (snNoiseMode&2) { // take period from channel 3
|
||||
|
|
@ -177,12 +183,12 @@ int DivPlatformSMS::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[c.chan].active=true;
|
||||
rWrite(0x90|c.chan<<5|(isMuted[c.chan]?15:(15-(chan[c.chan].vol&15))));
|
||||
chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
|
||||
chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF:
|
||||
chan[c.chan].active=false;
|
||||
rWrite(0x9f|c.chan<<5);
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -190,7 +196,7 @@ int DivPlatformSMS::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_INSTRUMENT:
|
||||
chan[c.chan].ins=c.value;
|
||||
//chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
|
||||
//chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
|
||||
break;
|
||||
case DIV_CMD_VOLUME:
|
||||
if (chan[c.chan].vol!=c.value) {
|
||||
|
|
@ -246,7 +252,7 @@ int DivPlatformSMS::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -26,14 +26,19 @@
|
|||
|
||||
class DivPlatformSMS: public DivDispatch {
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch, note, actualNote, ins;
|
||||
int freq, baseFreq, pitch, pitch2, note, actualNote, ins;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta;
|
||||
signed char vol, outVol;
|
||||
DivMacroInt std;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
note(0),
|
||||
actualNote(0),
|
||||
ins(-1),
|
||||
|
|
|
|||
|
|
@ -456,7 +456,7 @@ void es5505_core::regs_w(u8 page, u8 address, u16 data, bool cpu_access)
|
|||
switch (address)
|
||||
{
|
||||
case 13: // ACT (Number of voices)
|
||||
m_active = clamp<u8>(bitfield(data, 0, 5), 7, 31);
|
||||
m_active = std::max<u8>(7, bitfield(data, 0, 5));
|
||||
break;
|
||||
case 14: // IRQV (Interrupting voice vector)
|
||||
// Read only
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ void es5506_core::tick()
|
|||
void es5506_core::tick_perf()
|
||||
{
|
||||
// output
|
||||
if (((!m_mode.lrclk_en) && (!m_mode.bclk_en) && (!m_mode.bclk_en)) && (m_w_st < m_w_end))
|
||||
if (((!m_mode.lrclk_en) && (!m_mode.bclk_en) && (!m_mode.wclk_en)) && (m_w_st < m_w_end))
|
||||
{
|
||||
const int output_bits = 20 - (m_w_end - m_w_st);
|
||||
if (output_bits < 20)
|
||||
|
|
@ -307,7 +307,7 @@ s32 es5506_core::voice_t::volume_calc(u16 volume, s32 in)
|
|||
{
|
||||
u8 exponent = bitfield(volume, 12, 4);
|
||||
u8 mantissa = bitfield(volume, 4, 8);
|
||||
return (in * s32(0x100 | mantissa)) >> (19 - exponent);
|
||||
return (in * s32(0x100 | mantissa)) >> (20 - exponent);
|
||||
}
|
||||
|
||||
void es5506_core::reset()
|
||||
|
|
@ -771,7 +771,7 @@ void es5506_core::regs_w(u8 page, u8 address, u32 data, bool cpu_access)
|
|||
v.m_k1ramp.ramp = bitfield(data, 8, 8);
|
||||
break;
|
||||
case 11: // ACT (Number of voices)
|
||||
m_active = std::min<u8>(4, bitfield(data, 0, 5));
|
||||
m_active = std::max<u8>(4, bitfield(data, 0, 5));
|
||||
break;
|
||||
case 12: // MODE (Global Mode)
|
||||
m_mode.lrclk_en = bitfield(data, 0);
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ namespace es550x
|
|||
// std::clamp is only for C++17 or later; I use my own code
|
||||
template<typename T> T clamp(T in, T min, T max)
|
||||
{
|
||||
return (in < max) ? max : ((in > min) ? min : in);
|
||||
return std::min(std::max(in, min), max);
|
||||
}
|
||||
|
||||
template<typename T, T InitWidth, u8 InitEdge = 0>
|
||||
|
|
|
|||
|
|
@ -151,6 +151,12 @@ void DivPlatformSoundUnit::tick(bool sysTick) {
|
|||
chWrite(i,0x03,chan[i].pan);
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].std.ex1.had) {
|
||||
|
|
@ -168,7 +174,7 @@ void DivPlatformSoundUnit::tick(bool sysTick) {
|
|||
}
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
//DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_SU);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,2,chan[i].std.pitch.val);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,2,chan[i].pitch2);
|
||||
chWrite(i,0x00,chan[i].freq&0xff);
|
||||
chWrite(i,0x01,chan[i].freq>>8);
|
||||
if (chan[i].freq>65535) chan[i].freq=65535;
|
||||
|
|
@ -198,14 +204,14 @@ int DivPlatformSoundUnit::dispatch(DivCommand c) {
|
|||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chWrite(c.chan,0x02,chan[c.chan].vol);
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
chan[c.chan].insChanged=false;
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_NOTE_OFF:
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -275,7 +281,7 @@ int DivPlatformSoundUnit::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_SU));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SU));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
class DivPlatformSoundUnit: public DivDispatch {
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch, note;
|
||||
int freq, baseFreq, pitch, pitch2, note;
|
||||
int ins, cutoff, res, control;
|
||||
signed char pan;
|
||||
unsigned char duty;
|
||||
|
|
@ -35,10 +35,15 @@ class DivPlatformSoundUnit: public DivDispatch {
|
|||
bool pcmLoop, timerSync, freqSweep, volSweep, cutSweep;
|
||||
signed char vol, outVol, wave;
|
||||
DivMacroInt std;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
note(0),
|
||||
ins(-1),
|
||||
cutoff(65535),
|
||||
|
|
|
|||
|
|
@ -185,6 +185,12 @@ void DivPlatformSwan::tick(bool sysTick) {
|
|||
calcAndWriteOutVol(i,chan[i].std.vol.will?chan[i].std.vol.val:15);
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].active) {
|
||||
|
|
@ -194,7 +200,7 @@ void DivPlatformSwan::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].pitch2);
|
||||
if (i==1 && pcm && furnaceDac) {
|
||||
double off=1.0;
|
||||
if (dacSample>=0 && dacSample<parent->song.sampleLen) {
|
||||
|
|
@ -271,7 +277,7 @@ int DivPlatformSwan::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[1].active=true;
|
||||
chan[1].keyOn=true;
|
||||
chan[1].std.init(ins);
|
||||
chan[1].macroInit(ins);
|
||||
furnaceDac=true;
|
||||
} else {
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
|
|
@ -303,7 +309,7 @@ int DivPlatformSwan::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (chan[c.chan].wave<0) {
|
||||
chan[c.chan].wave=0;
|
||||
chan[c.chan].ws.changeWave1(chan[c.chan].wave);
|
||||
|
|
@ -320,7 +326,7 @@ int DivPlatformSwan::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -417,7 +423,7 @@ int DivPlatformSwan::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_SWAN));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SWAN));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -28,16 +28,21 @@
|
|||
|
||||
class DivPlatformSwan: public DivDispatch {
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch, note, ins;
|
||||
int freq, baseFreq, pitch, pitch2, note, ins;
|
||||
unsigned char pan;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta;
|
||||
int vol, outVol, wave;
|
||||
DivMacroInt std;
|
||||
DivWaveSynth ws;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
note(0),
|
||||
ins(-1),
|
||||
pan(255),
|
||||
|
|
|
|||
|
|
@ -117,6 +117,12 @@ void DivPlatformTIA::tick(bool sysTick) {
|
|||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
|
|
@ -127,14 +133,14 @@ void DivPlatformTIA::tick(bool sysTick) {
|
|||
}
|
||||
chan[i].insChanged=false;
|
||||
}
|
||||
chan[i].freq=dealWithFreq(chan[i].shape,chan[i].baseFreq,chan[i].pitch)+chan[i].std.pitch.val;
|
||||
chan[i].freq=dealWithFreq(chan[i].shape,chan[i].baseFreq,chan[i].pitch)+chan[i].pitch2;
|
||||
if ((chan[i].shape==4 || chan[i].shape==5) && !(chan[i].baseFreq&0x80000000 && ((chan[i].baseFreq&0x7fffffff)<32))) {
|
||||
if (chan[i].baseFreq<39*256) {
|
||||
rWrite(0x15+i,6);
|
||||
chan[i].freq=dealWithFreq(6,chan[i].baseFreq,chan[i].pitch)+chan[i].std.pitch.val;
|
||||
chan[i].freq=dealWithFreq(6,chan[i].baseFreq,chan[i].pitch)+chan[i].pitch2;
|
||||
} else if (chan[i].baseFreq<59*256) {
|
||||
rWrite(0x15+i,12);
|
||||
chan[i].freq=dealWithFreq(12,chan[i].baseFreq,chan[i].pitch)+chan[i].std.pitch.val;
|
||||
chan[i].freq=dealWithFreq(12,chan[i].baseFreq,chan[i].pitch)+chan[i].pitch2;
|
||||
} else {
|
||||
rWrite(0x15+i,chan[i].shape);
|
||||
}
|
||||
|
|
@ -163,7 +169,7 @@ int DivPlatformTIA::dispatch(DivCommand c) {
|
|||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
rWrite(0x15+c.chan,chan[c.chan].shape);
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (isMuted[c.chan]) {
|
||||
rWrite(0x19+c.chan,0);
|
||||
} else {
|
||||
|
|
@ -174,7 +180,7 @@ int DivPlatformTIA::dispatch(DivCommand c) {
|
|||
case DIV_CMD_NOTE_OFF:
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -248,7 +254,7 @@ int DivPlatformTIA::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_TIA));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_TIA));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -27,13 +27,17 @@
|
|||
class DivPlatformTIA: public DivDispatch {
|
||||
protected:
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch, note, ins;
|
||||
int freq, baseFreq, pitch, pitch2, note, ins;
|
||||
unsigned char shape;
|
||||
signed char konCycles;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta;
|
||||
int vol, outVol;
|
||||
DivMacroInt std;
|
||||
Channel(): freq(0), baseFreq(0), pitch(0), note(0), ins(-1), shape(4), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), inPorta(false), vol(0), outVol(15) {}
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel(): freq(0), baseFreq(0), pitch(0), pitch2(0), note(0), ins(-1), shape(4), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), inPorta(false), vol(0), outVol(15) {}
|
||||
};
|
||||
Channel chan[2];
|
||||
bool isMuted[2];
|
||||
|
|
|
|||
|
|
@ -229,6 +229,12 @@ void DivPlatformTX81Z::tick(bool sysTick) {
|
|||
}
|
||||
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
|
||||
|
|
@ -391,7 +397,7 @@ void DivPlatformTX81Z::tick(bool sysTick) {
|
|||
|
||||
for (int i=0; i<8; i++) {
|
||||
if (chan[i].freqChanged) {
|
||||
chan[i].freq=chan[i].baseFreq+(chan[i].pitch>>1)-64+chan[i].std.pitch.val;
|
||||
chan[i].freq=chan[i].baseFreq+(chan[i].pitch>>1)-64+chan[i].pitch2;
|
||||
if (chan[i].freq<0) chan[i].freq=0;
|
||||
if (chan[i].freq>=(95<<6)) chan[i].freq=(95<<6)-1;
|
||||
immWrite(i+0x28,hScale(chan[i].freq>>6));
|
||||
|
|
@ -430,7 +436,7 @@ int DivPlatformTX81Z::dispatch(DivCommand c) {
|
|||
chan[c.chan].state=ins->fm;
|
||||
}
|
||||
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,17 +35,22 @@ class DivPlatformTX81Z: public DivDispatch {
|
|||
DivInstrumentFM state;
|
||||
DivMacroInt std;
|
||||
unsigned char freqH, freqL;
|
||||
int freq, baseFreq, pitch, note, ins;
|
||||
int freq, baseFreq, pitch, pitch2, note, ins;
|
||||
signed char konCycles;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, portaPause, furnacePCM, hardReset;
|
||||
int vol, outVol;
|
||||
unsigned char chVolL, chVolR;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freqH(0),
|
||||
freqL(0),
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
note(0),
|
||||
ins(-1),
|
||||
active(false),
|
||||
|
|
|
|||
|
|
@ -191,10 +191,16 @@ void DivPlatformVERA::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
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].pitch2);
|
||||
if (chan[i].freq>65535) chan[i].freq=65535;
|
||||
rWrite(i,0,chan[i].freq&0xff);
|
||||
rWrite(i,1,(chan[i].freq>>8)&0xff);
|
||||
|
|
@ -223,7 +229,7 @@ void DivPlatformVERA::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (chan[16].freqChanged) {
|
||||
chan[16].freq=parent->calcFreq(chan[16].baseFreq,chan[16].pitch,false,8)+chan[16].std.pitch.val;
|
||||
chan[16].freq=parent->calcFreq(chan[16].baseFreq,chan[16].pitch,false,8,chan[16].pitch2);
|
||||
if (chan[16].freq>128) chan[16].freq=128;
|
||||
rWritePCMRate(chan[16].freq&0xff);
|
||||
chan[16].freqChanged=false;
|
||||
|
|
@ -259,7 +265,7 @@ int DivPlatformVERA::dispatch(DivCommand c) {
|
|||
chan[c.chan].note=c.value;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_VERA));
|
||||
chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_VERA));
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF:
|
||||
chan[c.chan].active=false;
|
||||
|
|
@ -270,7 +276,7 @@ int DivPlatformVERA::dispatch(DivCommand c) {
|
|||
rWritePCMCtrl(0x80);
|
||||
rWritePCMRate(0);
|
||||
}
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -327,7 +333,7 @@ int DivPlatformVERA::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_VERA));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_VERA));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ struct VERA_PCM;
|
|||
class DivPlatformVERA: public DivDispatch {
|
||||
protected:
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch, note, ins;
|
||||
int freq, baseFreq, pitch, pitch2, note, ins;
|
||||
unsigned char pan;
|
||||
bool active, freqChanged, inPorta;
|
||||
int vol, outVol;
|
||||
|
|
@ -45,7 +45,12 @@ class DivPlatformVERA: public DivDispatch {
|
|||
bool depth16;
|
||||
PCMChannel(): sample(-1), pos(0), len(0), freq(0), depth16(false) {}
|
||||
} pcm;
|
||||
Channel(): freq(0), baseFreq(0), pitch(0), note(0), ins(-1), pan(0), active(false), freqChanged(false), inPorta(false), vol(0), outVol(0), accum(0), noiseval(0) {}
|
||||
// somebody please split this into multiple lines!
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel(): freq(0), baseFreq(0), pitch(0), pitch2(0), note(0), ins(-1), pan(0), active(false), freqChanged(false), inPorta(false), vol(0), outVol(0), accum(0), noiseval(0) {}
|
||||
};
|
||||
Channel chan[17];
|
||||
bool isMuted[17];
|
||||
|
|
|
|||
|
|
@ -120,10 +120,16 @@ void DivPlatformVIC20::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].pitch2);
|
||||
if (i<3) {
|
||||
chan[i].freq>>=(2-i);
|
||||
} else {
|
||||
|
|
@ -166,13 +172,13 @@ int DivPlatformVIC20::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_NOTE_OFF:
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -232,7 +238,7 @@ int DivPlatformVIC20::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_VIC));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_VIC));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -27,15 +27,20 @@
|
|||
|
||||
class DivPlatformVIC20: public DivDispatch {
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch, note, ins;
|
||||
int freq, baseFreq, pitch, pitch2, note, ins;
|
||||
unsigned char pan;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta;
|
||||
int vol, outVol, wave, waveWriteCycle;
|
||||
DivMacroInt std;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
note(0),
|
||||
ins(-1),
|
||||
pan(255),
|
||||
|
|
|
|||
|
|
@ -179,13 +179,19 @@ void DivPlatformVRC6::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
if (i==2) { // sawtooth
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val)-1;
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].pitch2)-1;
|
||||
} else { // pulse
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].std.pitch.val)-1;
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].pitch2)-1;
|
||||
if (chan[i].furnaceDac) {
|
||||
double off=1.0;
|
||||
if (chan[i].dacSample>=0 && chan[i].dacSample<parent->song.sampleLen) {
|
||||
|
|
@ -249,7 +255,7 @@ int DivPlatformVRC6::dispatch(DivCommand c) {
|
|||
chan[c.chan].note=c.value;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
//chan[c.chan].keyOn=true;
|
||||
chan[c.chan].furnaceDac=true;
|
||||
} else {
|
||||
|
|
@ -284,7 +290,7 @@ int DivPlatformVRC6::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_VRC6));
|
||||
chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_VRC6));
|
||||
if (!isMuted[c.chan]) {
|
||||
if (c.chan==2) { // sawtooth
|
||||
chWrite(c.chan,0,chan[c.chan].vol);
|
||||
|
|
@ -299,7 +305,7 @@ int DivPlatformVRC6::dispatch(DivCommand c) {
|
|||
chan[c.chan].pcm=false;
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -380,7 +386,7 @@ int DivPlatformVRC6::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_VRC6));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_VRC6));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
class DivPlatformVRC6: public DivDispatch {
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch, note;
|
||||
int freq, baseFreq, pitch, pitch2, note;
|
||||
int dacPeriod, dacRate, dacOut;
|
||||
unsigned int dacPos;
|
||||
int dacSample, ins;
|
||||
|
|
@ -36,10 +36,15 @@ class DivPlatformVRC6: public DivDispatch {
|
|||
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, pcm, furnaceDac;
|
||||
signed char vol, outVol;
|
||||
DivMacroInt std;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
note(0),
|
||||
dacPeriod(0),
|
||||
dacRate(0),
|
||||
|
|
|
|||
|
|
@ -383,6 +383,12 @@ void DivPlatformX1_010::tick(bool sysTick) {
|
|||
chan[i].envChanged=true;
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].std.ex1.had) {
|
||||
|
|
@ -476,7 +482,7 @@ void DivPlatformX1_010::tick(bool sysTick) {
|
|||
chan[i].envChanged=false;
|
||||
}
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,2,chan[i].std.pitch.val);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,2,chan[i].pitch2);
|
||||
if (chan[i].pcm) {
|
||||
if (chan[i].freq<1) chan[i].freq=1;
|
||||
if (chan[i].freq>255) chan[i].freq=255;
|
||||
|
|
@ -535,7 +541,7 @@ int DivPlatformX1_010::dispatch(DivCommand c) {
|
|||
if (skipRegisterWrites) break;
|
||||
if (chan[c.chan].furnacePCM) {
|
||||
chan[c.chan].pcm=true;
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
chan[c.chan].sample=ins->amiga.initSample;
|
||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
|
|
@ -548,7 +554,7 @@ int DivPlatformX1_010::dispatch(DivCommand c) {
|
|||
chan[c.chan].freqChanged=true;
|
||||
}
|
||||
} else {
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
if ((12*sampleBank+c.value%12)>=parent->song.sampleLen) {
|
||||
chWrite(c.chan,0,0); // reset
|
||||
|
|
@ -560,7 +566,7 @@ int DivPlatformX1_010::dispatch(DivCommand c) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
if ((12*sampleBank+c.value%12)>=parent->song.sampleLen) {
|
||||
chWrite(c.chan,0,0); // reset
|
||||
|
|
@ -585,7 +591,7 @@ int DivPlatformX1_010::dispatch(DivCommand c) {
|
|||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chan[c.chan].envChanged=true;
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (chan[c.chan].wave<0) {
|
||||
chan[c.chan].wave=0;
|
||||
chan[c.chan].ws.changeWave1(chan[c.chan].wave);
|
||||
|
|
@ -599,7 +605,7 @@ int DivPlatformX1_010::dispatch(DivCommand c) {
|
|||
chan[c.chan].pcm=false;
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
|
|
@ -703,7 +709,7 @@ int DivPlatformX1_010::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_X1_010));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_X1_010));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ class DivPlatformX1_010: public DivDispatch {
|
|||
slide(0),
|
||||
slidefrac(0) {}
|
||||
};
|
||||
int freq, baseFreq, pitch, note;
|
||||
int freq, baseFreq, pitch, pitch2, note;
|
||||
int wave, sample, ins;
|
||||
unsigned char pan, autoEnvNum, autoEnvDen;
|
||||
bool active, insChanged, envChanged, freqChanged, keyOn, keyOff, inPorta, furnacePCM, pcm;
|
||||
|
|
@ -89,7 +89,7 @@ class DivPlatformX1_010: public DivDispatch {
|
|||
DivMacroInt std;
|
||||
DivWaveSynth ws;
|
||||
void reset() {
|
||||
freq = baseFreq = pitch = note = 0;
|
||||
freq = baseFreq = pitch = pitch2 = note = 0;
|
||||
wave = sample = ins = -1;
|
||||
pan = 255;
|
||||
autoEnvNum = autoEnvDen = 0;
|
||||
|
|
@ -99,8 +99,12 @@ class DivPlatformX1_010: public DivDispatch {
|
|||
vol = outVol = lvol = rvol = 15;
|
||||
waveBank = 0;
|
||||
}
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freq(0), baseFreq(0), pitch(0), note(0),
|
||||
freq(0), baseFreq(0), pitch(0), pitch2(0), note(0),
|
||||
wave(-1), sample(-1), ins(-1),
|
||||
pan(255), autoEnvNum(0), autoEnvDen(0),
|
||||
active(false), insChanged(true), envChanged(true), freqChanged(false), keyOn(false), keyOff(false), inPorta(false), furnacePCM(false), pcm(false),
|
||||
|
|
|
|||
|
|
@ -414,6 +414,12 @@ void DivPlatformYM2610::tick(bool sysTick) {
|
|||
}
|
||||
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
|
||||
|
|
@ -572,9 +578,9 @@ void DivPlatformYM2610::tick(bool sysTick) {
|
|||
for (int i=0; i<4; i++) {
|
||||
if (i==1 && extMode) continue;
|
||||
if (chan[i].freqChanged) {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq),chan[i].std.pitch.val);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq),chan[i].pitch2);
|
||||
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].pitch2;
|
||||
immWrite(chanOffs[i]+ADDR_FREQH,freqt>>8);
|
||||
immWrite(chanOffs[i]+ADDR_FREQ,freqt&0xff);
|
||||
chan[i].freqChanged=false;
|
||||
|
|
@ -643,7 +649,7 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
|||
}
|
||||
if (skipRegisterWrites) break;
|
||||
if (chan[c.chan].furnacePCM) {
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
immWrite(0x1b,chan[c.chan].outVol);
|
||||
|
|
@ -675,7 +681,7 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
|||
}
|
||||
} else {
|
||||
chan[c.chan].sample=-1;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
if ((12*sampleBank+c.value%12)>=parent->song.sampleLen) {
|
||||
immWrite(0x10,0x01); // reset
|
||||
|
|
@ -719,7 +725,7 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
|||
break;
|
||||
}
|
||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_FM);
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (c.chan<4) {
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
|
|
@ -779,7 +785,7 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
|||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].keyOn=false;
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
if (c.chan>12) {
|
||||
|
|
@ -981,7 +987,7 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
|||
case DIV_CMD_PRE_PORTA:
|
||||
if (c.chan>3) {
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_FM));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_FM));
|
||||
}
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class DivPlatformYM2610: public DivDispatch {
|
|||
struct Channel {
|
||||
DivInstrumentFM state;
|
||||
unsigned char freqH, freqL;
|
||||
int freq, baseFreq, pitch, note, ins;
|
||||
int freq, baseFreq, pitch, pitch2, note, ins;
|
||||
unsigned char psgMode, autoEnvNum, autoEnvDen;
|
||||
signed char konCycles;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM, hardReset;
|
||||
|
|
@ -51,12 +51,17 @@ class DivPlatformYM2610: public DivDispatch {
|
|||
int sample;
|
||||
unsigned char pan;
|
||||
DivMacroInt std;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freqH(0),
|
||||
freqL(0),
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
note(0),
|
||||
ins(-1),
|
||||
psgMode(1),
|
||||
|
|
|
|||
|
|
@ -478,6 +478,12 @@ void DivPlatformYM2610B::tick(bool sysTick) {
|
|||
}
|
||||
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-2048,2048);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
|
||||
|
|
@ -635,9 +641,9 @@ void DivPlatformYM2610B::tick(bool sysTick) {
|
|||
for (int i=0; i<6; i++) {
|
||||
if (i==2 && extMode) continue;
|
||||
if (chan[i].freqChanged) {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq),chan[i].std.pitch.val);
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq),chan[i].pitch2);
|
||||
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].pitch2;
|
||||
immWrite(chanOffs[i]+ADDR_FREQH,freqt>>8);
|
||||
immWrite(chanOffs[i]+ADDR_FREQ,freqt&0xff);
|
||||
chan[i].freqChanged=false;
|
||||
|
|
@ -706,7 +712,7 @@ int DivPlatformYM2610B::dispatch(DivCommand c) {
|
|||
}
|
||||
if (skipRegisterWrites) break;
|
||||
if (chan[c.chan].furnacePCM) {
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
immWrite(0x1b,chan[c.chan].outVol);
|
||||
|
|
@ -738,7 +744,7 @@ int DivPlatformYM2610B::dispatch(DivCommand c) {
|
|||
}
|
||||
} else {
|
||||
chan[c.chan].sample=-1;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
if ((12*sampleBank+c.value%12)>=parent->song.sampleLen) {
|
||||
immWrite(0x10,0x01); // reset
|
||||
|
|
@ -782,7 +788,7 @@ int DivPlatformYM2610B::dispatch(DivCommand c) {
|
|||
break;
|
||||
}
|
||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_FM);
|
||||
chan[c.chan].std.init(ins);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (c.chan<6) {
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
|
|
@ -842,7 +848,7 @@ int DivPlatformYM2610B::dispatch(DivCommand c) {
|
|||
chan[c.chan].keyOff=true;
|
||||
chan[c.chan].keyOn=false;
|
||||
chan[c.chan].active=false;
|
||||
chan[c.chan].std.init(NULL);
|
||||
chan[c.chan].macroInit(NULL);
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
if (c.chan>14) {
|
||||
|
|
@ -1044,7 +1050,7 @@ int DivPlatformYM2610B::dispatch(DivCommand c) {
|
|||
case DIV_CMD_PRE_PORTA:
|
||||
if (c.chan>5) {
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].std.init(parent->getIns(chan[c.chan].ins,DIV_INS_FM));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_FM));
|
||||
}
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class DivPlatformYM2610B: public DivDispatch {
|
|||
struct Channel {
|
||||
DivInstrumentFM state;
|
||||
unsigned char freqH, freqL;
|
||||
int freq, baseFreq, pitch, note, ins;
|
||||
int freq, baseFreq, pitch, pitch2, note, ins;
|
||||
unsigned char psgMode, autoEnvNum, autoEnvDen;
|
||||
signed char konCycles;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM, hardReset;
|
||||
|
|
@ -43,12 +43,17 @@ class DivPlatformYM2610B: public DivDispatch {
|
|||
int sample;
|
||||
unsigned char pan;
|
||||
DivMacroInt std;
|
||||
void macroInit(DivInstrument* which) {
|
||||
std.init(which);
|
||||
pitch2=0;
|
||||
}
|
||||
Channel():
|
||||
freqH(0),
|
||||
freqL(0),
|
||||
freq(0),
|
||||
baseFreq(0),
|
||||
pitch(0),
|
||||
pitch2(0),
|
||||
note(0),
|
||||
ins(-1),
|
||||
psgMode(1),
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ void DivPlatformYM2610BExt::tick(bool sysTick) {
|
|||
unsigned char writeMask=2;
|
||||
if (extMode) for (int i=0; i<4; i++) {
|
||||
if (opChan[i].freqChanged) {
|
||||
opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch);
|
||||
opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,false,octave(opChan[i].baseFreq),opChan[i].pitch2);
|
||||
if (opChan[i].freq>262143) opChan[i].freq=262143;
|
||||
int freqt=toFreq(opChan[i].freq);
|
||||
opChan[i].freqH=freqt>>8;
|
||||
|
|
|
|||
|
|
@ -25,12 +25,12 @@ class DivPlatformYM2610BExt: public DivPlatformYM2610B {
|
|||
struct OpChannel {
|
||||
DivMacroInt std;
|
||||
unsigned char freqH, freqL;
|
||||
int freq, baseFreq, pitch, ins;
|
||||
int freq, baseFreq, pitch, pitch2, ins;
|
||||
signed char konCycles;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause;
|
||||
int vol;
|
||||
unsigned char pan;
|
||||
OpChannel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), ins(-1), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), vol(0), pan(3) {}
|
||||
OpChannel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), pitch2(0), ins(-1), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), vol(0), pan(3) {}
|
||||
};
|
||||
OpChannel opChan[4];
|
||||
bool isOpMuted[4];
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ void DivPlatformYM2610Ext::tick(bool sysTick) {
|
|||
unsigned char writeMask=2;
|
||||
if (extMode) for (int i=0; i<4; i++) {
|
||||
if (opChan[i].freqChanged) {
|
||||
opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch);
|
||||
opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,false,octave(opChan[i].baseFreq),opChan[i].pitch2);
|
||||
if (opChan[i].freq>262143) opChan[i].freq=262143;
|
||||
int freqt=toFreq(opChan[i].freq);
|
||||
opChan[i].freqH=freqt>>8;
|
||||
|
|
|
|||
|
|
@ -25,12 +25,12 @@ class DivPlatformYM2610Ext: public DivPlatformYM2610 {
|
|||
struct OpChannel {
|
||||
DivMacroInt std;
|
||||
unsigned char freqH, freqL;
|
||||
int freq, baseFreq, pitch, ins;
|
||||
int freq, baseFreq, pitch, pitch2, ins;
|
||||
signed char konCycles;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause;
|
||||
int vol;
|
||||
unsigned char pan;
|
||||
OpChannel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), ins(-1), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), vol(0), pan(3) {}
|
||||
OpChannel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), pitch2(0), ins(-1), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), vol(0), pan(3) {}
|
||||
};
|
||||
OpChannel opChan[4];
|
||||
bool isOpMuted[4];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue