WIP: adding fixed pitch mode; fix UB in ESFM driver

This commit is contained in:
Kagamiin~ 2023-10-15 19:46:07 -03:00
parent 84e0ec9dae
commit 4a0295fd1f
5 changed files with 88 additions and 28 deletions

View file

@ -245,6 +245,7 @@ bool DivInstrumentESFM::Operator::operator==(const DivInstrumentESFM::Operator&
_C(modIn) &&
_C(left) &&
_C(right) &&
_C(fixed) &&
_C(ct) &&
_C(dt)
);
@ -764,7 +765,7 @@ void DivInstrument::writeFeatureEF(SafeWriter* w) {
DivInstrumentESFM::Operator& op=esfm.op[i];
w->writeC(((op.delay&7)<<5)|((op.outLvl&7)<<2)|((op.right&1)<<1)|(op.left&1));
w->writeC(op.modIn&7);
w->writeC((op.fixed&1)<<3|(op.modIn&7));
w->writeC(op.ct);
w->writeC(op.dt);
}
@ -2644,6 +2645,7 @@ void DivInstrument::readFeatureEF(SafeReader& reader, short version) {
next=reader.readC();
op.modIn=next&7;
op.fixed=(next>>3)&1;
op.ct=reader.readC();
op.dt=reader.readC();

View file

@ -756,7 +756,7 @@ struct DivInstrumentSNES {
// ESFM operator structure:
// - DELAY, OUT, MOD, L, R, NOISE
// - Virtual: CT, DT, DTRAW
// - Virtual: CT, DT, FIXED
// - In FM struct: AM, DAM, AR, DR, MULT, RR, SL, TL
// - In FM struct: KSL, VIB, DVB, WS, SUS, KSR
// - Not in struct: FNUML, FNUMH, BLOCK
@ -770,7 +770,7 @@ struct DivInstrumentESFM {
// Only works on OP4, so putting it outside the Operator struct instead
unsigned char noise;
struct Operator {
unsigned char delay, outLvl, modIn, left, right;
unsigned char delay, outLvl, modIn, left, right, fixed;
signed char ct, dt;
bool operator==(const Operator& other);
@ -781,8 +781,9 @@ struct DivInstrumentESFM {
delay(0),
outLvl(0),
modIn(0),
left(true),
right(true),
left(1),
right(1),
fixed(0),
ct(0),
dt(0) {}
} op[4];

View file

@ -218,12 +218,17 @@ void DivPlatformESFM::tick(bool sysTick) {
DivInstrumentESFM::Operator& opE=chan[i].state.esfm.op[o];
int ct=(int)opE.ct;
int dt=(int)opE.dt;
int opFreq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride+ct:chan[i].arpOff+ct,chan[i].fixedArp,false,octave(chan[i].baseFreq)*2,chan[i].pitch2+dt,chipClock,CHIP_FREQBASE);
if (opFreq<0) opFreq=0;
if (opFreq>131071) opFreq=131071;
int freqt=toFreq(opFreq);
chan[i].freqL[o]=freqt&0xff;
chan[i].freqH[o]=freqt>>8;
if (opE.fixed) {
chan[i].freqL[o]=opE.dt;
chan[i].freqH[o]=opE.ct&0x1f;
} else {
int opFreq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride+ct:chan[i].arpOff+ct,chan[i].fixedArp,false,octave(chan[i].baseFreq)*2,chan[i].pitch2+dt,chipClock,CHIP_FREQBASE);
if (opFreq<0) opFreq=0;
if (opFreq>131071) opFreq=131071;
int freqt=toFreq(opFreq);
chan[i].freqL[o]=freqt&0xff;
chan[i].freqH[o]=freqt>>8;
}
immWrite(baseAddr+OFFSET_FREQL,chan[i].freqL[o]);
immWrite(baseAddr+OFFSET_FREQH_BLOCK_DELAY,chan[i].freqH[o]|(opE.delay<<5));
}
@ -558,7 +563,7 @@ int DivPlatformESFM::dispatch(DivCommand c) {
unsigned short baseAddr=c.chan*32 + o*8;
DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o];
op.rr=c.value2&15;
rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|op.rr);
rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf));
}
} else {
unsigned int o = c.value;
@ -566,7 +571,7 @@ int DivPlatformESFM::dispatch(DivCommand c) {
unsigned short baseAddr=c.chan*32 + o*8;
DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o];
op.rr=c.value2&15;
rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|op.rr);
rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf));
}
break;
}

View file

@ -40,6 +40,7 @@ class DivPlatformESFM: public DivDispatch {
SharedChannel<int>(0),
freqL{0, 0, 0, 0},
freqH{0, 0, 0, 0},
hardReset(false),
globalPan(3),
macroVolMul(64) {}
};