Genesis: fully implement volume macro

This commit is contained in:
tildearrow 2022-01-26 18:03:08 -05:00
parent 143543e0b4
commit 1347d16da4
2 changed files with 29 additions and 7 deletions

View file

@ -88,6 +88,20 @@ void DivPlatformGenesis::tick() {
if (i==2 && extMode) continue; if (i==2 && extMode) continue;
chan[i].std.next(); chan[i].std.next();
// TODO
if (chan[i].std.hadVol) {
chan[i].outVol=(chan[i].vol*chan[i].std.vol)/127;
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
DivInstrumentFM::Operator& op=chan[i].state.op[j];
if (isOutput[chan[i].state.alg][j]) {
rWrite(baseAddr+ADDR_TL,127-(((127-op.tl)*(chan[i].outVol&0x7f))/127));
} else {
rWrite(baseAddr+ADDR_TL,op.tl);
}
}
}
if (chan[i].std.hadArp) { if (chan[i].std.hadArp) {
if (!chan[i].inPorta) { if (!chan[i].inPorta) {
if (chan[i].std.arpMode) { if (chan[i].std.arpMode) {
@ -151,7 +165,7 @@ void DivPlatformGenesis::tick() {
if (m.hadTl) { if (m.hadTl) {
op.tl=127-m.tl; op.tl=127-m.tl;
if (isOutput[chan[i].state.alg][j]) { if (isOutput[chan[i].state.alg][j]) {
rWrite(baseAddr+ADDR_TL,127-(((127-op.tl)*(chan[i].vol&0x7f))/127)); rWrite(baseAddr+ADDR_TL,127-(((127-op.tl)*(chan[i].outVol&0x7f))/127));
} else { } else {
rWrite(baseAddr+ADDR_TL,op.tl); rWrite(baseAddr+ADDR_TL,op.tl);
} }
@ -318,13 +332,18 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
if (chan[c.chan].insChanged) { if (chan[c.chan].insChanged) {
chan[c.chan].state=ins->fm; chan[c.chan].state=ins->fm;
} }
chan[c.chan].std.init(ins);
if (!chan[c.chan].std.willVol) {
chan[c.chan].outVol=chan[c.chan].vol;
}
for (int i=0; i<4; i++) { for (int i=0; i<4; i++) {
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i]; unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i]; DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
if (isOutput[chan[c.chan].state.alg][i]) { if (isOutput[chan[c.chan].state.alg][i]) {
if (!chan[c.chan].active || chan[c.chan].insChanged) { if (!chan[c.chan].active || chan[c.chan].insChanged) {
rWrite(baseAddr+ADDR_TL,127-(((127-op.tl)*(chan[c.chan].vol&0x7f))/127)); rWrite(baseAddr+ADDR_TL,127-(((127-op.tl)*(chan[c.chan].outVol&0x7f))/127));
} }
} else { } else {
if (chan[c.chan].insChanged) { if (chan[c.chan].insChanged) {
@ -353,7 +372,6 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
} }
chan[c.chan].keyOn=true; chan[c.chan].keyOn=true;
chan[c.chan].active=true; chan[c.chan].active=true;
chan[c.chan].std.init(ins);
break; break;
} }
case DIV_CMD_NOTE_OFF: case DIV_CMD_NOTE_OFF:
@ -366,11 +384,14 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
break; break;
case DIV_CMD_VOLUME: { case DIV_CMD_VOLUME: {
chan[c.chan].vol=c.value; chan[c.chan].vol=c.value;
if (!chan[c.chan].std.hasVol) {
chan[c.chan].outVol=c.value;
}
for (int i=0; i<4; i++) { for (int i=0; i<4; i++) {
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i]; unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i]; DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
if (isOutput[chan[c.chan].state.alg][i]) { if (isOutput[chan[c.chan].state.alg][i]) {
rWrite(baseAddr+ADDR_TL,127-(((127-op.tl)*(chan[c.chan].vol&0x7f))/127)); rWrite(baseAddr+ADDR_TL,127-(((127-op.tl)*(chan[c.chan].outVol&0x7f))/127));
} else { } else {
rWrite(baseAddr+ADDR_TL,op.tl); rWrite(baseAddr+ADDR_TL,op.tl);
} }
@ -473,7 +494,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]]; DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
op.tl=c.value2; op.tl=c.value2;
if (isOutput[chan[c.chan].state.alg][c.value]) { if (isOutput[chan[c.chan].state.alg][c.value]) {
rWrite(baseAddr+ADDR_TL,127-(((127-op.tl)*(chan[c.chan].vol&0x7f))/127)); rWrite(baseAddr+ADDR_TL,127-(((127-op.tl)*(chan[c.chan].outVol&0x7f))/127));
} else { } else {
rWrite(baseAddr+ADDR_TL,op.tl); rWrite(baseAddr+ADDR_TL,op.tl);
} }
@ -520,7 +541,7 @@ void DivPlatformGenesis::forceIns() {
unsigned short baseAddr=chanOffs[i]|opOffs[j]; unsigned short baseAddr=chanOffs[i]|opOffs[j];
DivInstrumentFM::Operator& op=chan[i].state.op[j]; DivInstrumentFM::Operator& op=chan[i].state.op[j];
if (isOutput[chan[i].state.alg][j]) { if (isOutput[chan[i].state.alg][j]) {
rWrite(baseAddr+ADDR_TL,127-(((127-op.tl)*(chan[i].vol&0x7f))/127)); rWrite(baseAddr+ADDR_TL,127-(((127-op.tl)*(chan[i].outVol&0x7f))/127));
} else { } else {
rWrite(baseAddr+ADDR_TL,op.tl); rWrite(baseAddr+ADDR_TL,op.tl);
} }
@ -555,6 +576,7 @@ void DivPlatformGenesis::reset() {
for (int i=0; i<10; i++) { for (int i=0; i<10; i++) {
chan[i]=DivPlatformGenesis::Channel(); chan[i]=DivPlatformGenesis::Channel();
chan[i].vol=0x7f; chan[i].vol=0x7f;
chan[i].outVol=0x7f;
} }
for (int i=0; i<512; i++) { for (int i=0; i<512; i++) {

View file

@ -15,7 +15,7 @@ class DivPlatformGenesis: public DivDispatch {
int freq, baseFreq, pitch, note; int freq, baseFreq, pitch, note;
unsigned char ins; unsigned char ins;
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, furnaceDac, inPorta; bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, furnaceDac, inPorta;
int vol; int vol, outVol;
unsigned char pan; unsigned char pan;
Channel(): Channel():
freqH(0), freqH(0),