OPL: more work and channel muting

This commit is contained in:
tildearrow 2022-03-14 02:47:04 -05:00
parent d2ad74206a
commit 714d189b57
2 changed files with 40 additions and 17 deletions

View File

@ -222,7 +222,7 @@ void DivPlatformOPL::acquire(short* bufL, short* bufR, size_t start, size_t len)
} }
void DivPlatformOPL::tick() { void DivPlatformOPL::tick() {
for (int i=0; i<20; i++) { for (int i=0; i<melodicChans; i++) {
chan[i].std.next(); chan[i].std.next();
/* /*
@ -361,7 +361,7 @@ void DivPlatformOPL::tick() {
if (oplType==3) { if (oplType==3) {
unsigned char opMask=chan[0].fourOp|(chan[2].fourOp<<1)|(chan[4].fourOp<<2)|(chan[6].fourOp<<3)|(chan[8].fourOp<<4)|(chan[10].fourOp<<5); unsigned char opMask=chan[0].fourOp|(chan[2].fourOp<<1)|(chan[4].fourOp<<2)|(chan[6].fourOp<<3)|(chan[8].fourOp<<4)|(chan[10].fourOp<<5);
immWrite(0x104,opMask); immWrite(0x104,opMask);
printf("updating opMask to %.2x\n",opMask); //printf("updating opMask to %.2x\n",opMask);
} }
} }
@ -372,7 +372,7 @@ void DivPlatformOPL::tick() {
} }
} }
for (int i=0; i<20; i++) { for (int i=0; i<melodicChans; i++) {
if (chan[i].freqChanged) { if (chan[i].freqChanged) {
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq)); chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq));
if (chan[i].freq>131071) chan[i].freq=131071; if (chan[i].freq>131071) chan[i].freq=131071;
@ -445,25 +445,42 @@ int DivPlatformOPL::toFreq(int freq) {
void DivPlatformOPL::muteChannel(int ch, bool mute) { void DivPlatformOPL::muteChannel(int ch, bool mute) {
isMuted[ch]=mute; isMuted[ch]=mute;
/* int ops=(slots[3][ch]!=255 && chan[ch].state.ops==4 && oplType==3)?4:2;
for (int j=0; j<4; j++) { chan[ch].fourOp=(ops==4);
unsigned short baseAddr=chanOffs[ch]|opOffs[j]; update4OpMask=true;
DivInstrumentFM::Operator& op=chan[ch].state.op[j]; for (int i=0; i<ops; i++) {
unsigned char slot=slots[i][ch];
if (slot==255) continue;
unsigned short baseAddr=slotMap[slot];
DivInstrumentFM::Operator& op=chan[ch].state.op[(ops==4)?orderedOpsL[i]:i];
if (isMuted[ch]) { if (isMuted[ch]) {
rWrite(baseAddr+ADDR_TL,127); rWrite(baseAddr+ADDR_KSL_TL,63|(op.ksl<<6));
} else { } else {
if (isOutput[chan[ch].state.alg][j]) { if (isOutputL[ops==4][chan[ch].state.alg][i]) {
rWrite(baseAddr+ADDR_TL,127-(((127-op.tl)*(chan[ch].outVol&0x7f))/127)); rWrite(baseAddr+ADDR_KSL_TL,(63-(((63-op.tl)*(chan[ch].outVol&0x3f))/63))|(op.ksl<<6));
} else { } else {
rWrite(baseAddr+ADDR_TL,op.tl); rWrite(baseAddr+ADDR_KSL_TL,op.tl|(op.ksl<<6));
} }
} }
} }
rWrite(chanOffs[ch]+ADDR_LRAF,(isMuted[ch]?0:(chan[ch].pan<<6))|(chan[ch].state.fms&7)|((chan[ch].state.ams&3)<<4));
*/ if (isMuted[ch]) {
rWrite(chanMap[ch]+ADDR_LR_FB_ALG,(chan[ch].state.alg&1)|(chan[ch].state.fb<<1));
if (ops==4) {
rWrite(chanMap[ch+1]+ADDR_LR_FB_ALG,((chan[ch].state.alg>>1)&1)|(chan[ch].state.fb<<1));
}
} else {
rWrite(chanMap[ch]+ADDR_LR_FB_ALG,(chan[ch].state.alg&1)|(chan[ch].state.fb<<1)|((chan[ch].pan&3)<<4));
if (ops==4) {
rWrite(chanMap[ch+1]+ADDR_LR_FB_ALG,((chan[ch].state.alg>>1)&1)|(chan[ch].state.fb<<1)|((chan[ch].pan&3)<<4));
}
}
} }
int DivPlatformOPL::dispatch(DivCommand c) { int DivPlatformOPL::dispatch(DivCommand c) {
// TODO: drums mode!
if (c.chan>=melodicChans) return 0;
switch (c.cmd) { switch (c.cmd) {
case DIV_CMD_NOTE_ON: { case DIV_CMD_NOTE_ON: {
DivInstrument* ins=parent->getIns(chan[c.chan].ins); DivInstrument* ins=parent->getIns(chan[c.chan].ins);
@ -714,7 +731,7 @@ int DivPlatformOPL::dispatch(DivCommand c) {
} }
void DivPlatformOPL::forceIns() { void DivPlatformOPL::forceIns() {
for (int i=0; i<18; i++) { for (int i=0; i<melodicChans; i++) {
int ops=(slots[3][i]!=255 && chan[i].state.ops==4 && oplType==3)?4:2; int ops=(slots[3][i]!=255 && chan[i].state.ops==4 && oplType==3)?4:2;
chan[i].fourOp=(ops==4); chan[i].fourOp=(ops==4);
for (int j=0; j<ops; j++) { for (int j=0; j<ops; j++) {
@ -784,7 +801,7 @@ void DivPlatformOPL::reset() {
if (dumpWrites) { if (dumpWrites) {
addWrite(0xffffffff,0); addWrite(0xffffffff,0);
} }
for (int i=0; i<20; i++) { for (int i=0; i<totalChans; i++) {
chan[i]=DivPlatformOPL::Channel(); chan[i]=DivPlatformOPL::Channel();
chan[i].vol=0x3f; chan[i].vol=0x3f;
chan[i].outVol=0x3f; chan[i].outVol=0x3f;
@ -824,7 +841,7 @@ bool DivPlatformOPL::keyOffAffectsPorta(int ch) {
} }
void DivPlatformOPL::notifyInsChange(int ins) { void DivPlatformOPL::notifyInsChange(int ins) {
for (int i=0; i<20; i++) { for (int i=0; i<totalChans; i++) {
if (chan[i].ins==ins) { if (chan[i].ins==ins) {
chan[i].insChanged=true; chan[i].insChanged=true;
} }
@ -858,6 +875,9 @@ void DivPlatformOPL::setOPLType(int type, bool drums) {
slots=drums?slotsDrums:slotsNonDrums; slots=drums?slotsDrums:slotsNonDrums;
chanMap=chanMapOPL2; chanMap=chanMapOPL2;
chipFreqBase=9440540*0.25; chipFreqBase=9440540*0.25;
chans=9;
melodicChans=drums?6:9;
totalChans=drums?11:9;
break; break;
case 3: case 3:
slotsNonDrums=slotsOPL3; slotsNonDrums=slotsOPL3;
@ -865,6 +885,9 @@ void DivPlatformOPL::setOPLType(int type, bool drums) {
slots=drums?slotsDrums:slotsNonDrums; slots=drums?slotsDrums:slotsNonDrums;
chanMap=chanMapOPL3; chanMap=chanMapOPL3;
chipFreqBase=9440540; chipFreqBase=9440540;
chans=18;
melodicChans=drums?15:18;
totalChans=drums?20:18;
break; break;
} }
oplType=type; oplType=type;

View File

@ -70,7 +70,7 @@ class DivPlatformOPL: public DivDispatch {
const unsigned char** slots; const unsigned char** slots;
const unsigned short* chanMap; const unsigned short* chanMap;
double chipFreqBase; double chipFreqBase;
int delay, oplType; int delay, oplType, chans, melodicChans, totalChans;
unsigned char lastBusy; unsigned char lastBusy;
unsigned char regPool[512]; unsigned char regPool[512];