mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-15 17:25:06 +00:00
OPL: more work and channel muting
This commit is contained in:
parent
d2ad74206a
commit
714d189b57
2 changed files with 40 additions and 17 deletions
|
@ -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;
|
||||||
|
|
|
@ -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];
|
||||||
|
|
Loading…
Reference in a new issue