total extinction of legacy sample mode, part 3
remove all the code which handles legacy sample mode next up is a conversion strategy
This commit is contained in:
parent
aa8054754c
commit
183526cdbd
21 changed files with 706 additions and 870 deletions
|
|
@ -598,7 +598,7 @@ void DivPlatformAY8910::tick(bool sysTick) {
|
|||
}
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER);
|
||||
if (chan[i].dac.furnaceDAC) {
|
||||
if (chan[i].curPSGMode.val&8) {
|
||||
double off=1.0;
|
||||
if (chan[i].dac.sample>=0 && chan[i].dac.sample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(chan[i].dac.sample);
|
||||
|
|
@ -677,54 +677,49 @@ int DivPlatformAY8910::dispatch(DivCommand c) {
|
|||
switch (c.cmd) {
|
||||
case DIV_CMD_NOTE_ON: {
|
||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AY);
|
||||
if (!parent->song.disableSampleMacro && (ins->type==DIV_INS_AMIGA || ins->amiga.useSample)) {
|
||||
if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) {
|
||||
chan[c.chan].nextPSGMode.val|=8;
|
||||
} else if (chan[c.chan].dac.furnaceDAC) {
|
||||
} else {
|
||||
chan[c.chan].nextPSGMode.val&=~8;
|
||||
}
|
||||
if (chan[c.chan].nextPSGMode.val&8) {
|
||||
if (skipRegisterWrites) break;
|
||||
if (!parent->song.disableSampleMacro && (ins->type==DIV_INS_AMIGA || ins->amiga.useSample)) {
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].dac.sample=ins->amiga.getSample(c.value);
|
||||
chan[c.chan].sampleNote=c.value;
|
||||
c.value=ins->amiga.getFreq(c.value);
|
||||
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
|
||||
} else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].dac.sample=ins->amiga.getSample(chan[c.chan].sampleNote);
|
||||
c.value=ins->amiga.getFreq(chan[c.chan].sampleNote);
|
||||
}
|
||||
if (chan[c.chan].dac.sample<0 || chan[c.chan].dac.sample>=parent->song.sampleLen) {
|
||||
chan[c.chan].dac.sample=-1;
|
||||
//if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0);
|
||||
break;
|
||||
} else {
|
||||
if (dumpWrites) {
|
||||
rWrite(0x08+c.chan,0);
|
||||
//addWrite(0xffff0000+(c.chan<<8),chan[c.chan].dac.sample);
|
||||
}
|
||||
}
|
||||
if (chan[c.chan].dac.setPos) {
|
||||
chan[c.chan].dac.setPos=false;
|
||||
} else {
|
||||
chan[c.chan].dac.pos=0;
|
||||
}
|
||||
chan[c.chan].dac.period=0;
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
|
||||
chan[c.chan].freqChanged=true;
|
||||
chan[c.chan].note=c.value;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
}
|
||||
//chan[c.chan].keyOn=true;
|
||||
chan[c.chan].dac.furnaceDAC=true;
|
||||
} else {
|
||||
assert(false && "LEGACY SAMPLE MODE!!!");
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].dac.sample=ins->amiga.getSample(c.value);
|
||||
chan[c.chan].sampleNote=c.value;
|
||||
c.value=ins->amiga.getFreq(c.value);
|
||||
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
|
||||
} else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].dac.sample=ins->amiga.getSample(chan[c.chan].sampleNote);
|
||||
c.value=ins->amiga.getFreq(chan[c.chan].sampleNote);
|
||||
}
|
||||
if (chan[c.chan].dac.sample<0 || chan[c.chan].dac.sample>=parent->song.sampleLen) {
|
||||
chan[c.chan].dac.sample=-1;
|
||||
//if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0);
|
||||
break;
|
||||
} else {
|
||||
if (dumpWrites) {
|
||||
rWrite(0x08+c.chan,0);
|
||||
//addWrite(0xffff0000+(c.chan<<8),chan[c.chan].dac.sample);
|
||||
}
|
||||
}
|
||||
if (chan[c.chan].dac.setPos) {
|
||||
chan[c.chan].dac.setPos=false;
|
||||
} else {
|
||||
chan[c.chan].dac.pos=0;
|
||||
}
|
||||
chan[c.chan].dac.period=0;
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
|
||||
chan[c.chan].freqChanged=true;
|
||||
chan[c.chan].note=c.value;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
}
|
||||
//chan[c.chan].keyOn=true;
|
||||
chan[c.chan].curPSGMode.val&=~8;
|
||||
chan[c.chan].curPSGMode.val|=chan[c.chan].nextPSGMode.val&8;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -402,7 +402,7 @@ void DivPlatformAY8930::tick(bool sysTick) {
|
|||
}
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER);
|
||||
if (chan[i].dac.furnaceDAC) {
|
||||
if (chan[i].curPSGMode.val&8) {
|
||||
double off=1.0;
|
||||
if (chan[i].dac.sample>=0 && chan[i].dac.sample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(chan[i].dac.sample);
|
||||
|
|
@ -507,52 +507,47 @@ int DivPlatformAY8930::dispatch(DivCommand c) {
|
|||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AY8930);
|
||||
if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) {
|
||||
chan[c.chan].nextPSGMode.val|=8;
|
||||
} else if (chan[c.chan].dac.furnaceDAC) {
|
||||
} else {
|
||||
chan[c.chan].nextPSGMode.val&=~8;
|
||||
}
|
||||
if (chan[c.chan].nextPSGMode.val&8) {
|
||||
if (skipRegisterWrites) break;
|
||||
if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) {
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].dac.sample=ins->amiga.getSample(c.value);
|
||||
chan[c.chan].sampleNote=c.value;
|
||||
c.value=ins->amiga.getFreq(c.value);
|
||||
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
|
||||
} else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].dac.sample=ins->amiga.getSample(chan[c.chan].sampleNote);
|
||||
c.value=ins->amiga.getFreq(chan[c.chan].sampleNote);
|
||||
}
|
||||
if (chan[c.chan].dac.sample<0 || chan[c.chan].dac.sample>=parent->song.sampleLen) {
|
||||
chan[c.chan].dac.sample=-1;
|
||||
if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0);
|
||||
break;
|
||||
} else {
|
||||
if (dumpWrites) {
|
||||
rWrite(0x08+c.chan,0);
|
||||
addWrite(0xffff0000+(c.chan<<8),chan[c.chan].dac.sample);
|
||||
}
|
||||
}
|
||||
if (chan[c.chan].dac.setPos) {
|
||||
chan[c.chan].dac.setPos=false;
|
||||
} else {
|
||||
chan[c.chan].dac.pos=0;
|
||||
}
|
||||
chan[c.chan].dac.period=0;
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
|
||||
chan[c.chan].freqChanged=true;
|
||||
chan[c.chan].note=c.value;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
}
|
||||
//chan[c.chan].keyOn=true;
|
||||
chan[c.chan].dac.furnaceDAC=true;
|
||||
} else {
|
||||
assert(false && "LEGACY SAMPLE MODE!!!");
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].dac.sample=ins->amiga.getSample(c.value);
|
||||
chan[c.chan].sampleNote=c.value;
|
||||
c.value=ins->amiga.getFreq(c.value);
|
||||
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
|
||||
} else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].dac.sample=ins->amiga.getSample(chan[c.chan].sampleNote);
|
||||
c.value=ins->amiga.getFreq(chan[c.chan].sampleNote);
|
||||
}
|
||||
if (chan[c.chan].dac.sample<0 || chan[c.chan].dac.sample>=parent->song.sampleLen) {
|
||||
chan[c.chan].dac.sample=-1;
|
||||
if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0);
|
||||
break;
|
||||
} else {
|
||||
if (dumpWrites) {
|
||||
rWrite(0x08+c.chan,0);
|
||||
addWrite(0xffff0000+(c.chan<<8),chan[c.chan].dac.sample);
|
||||
}
|
||||
}
|
||||
if (chan[c.chan].dac.setPos) {
|
||||
chan[c.chan].dac.setPos=false;
|
||||
} else {
|
||||
chan[c.chan].dac.pos=0;
|
||||
}
|
||||
chan[c.chan].dac.period=0;
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
|
||||
chan[c.chan].freqChanged=true;
|
||||
chan[c.chan].note=c.value;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
}
|
||||
//chan[c.chan].keyOn=true;
|
||||
chan[c.chan].curPSGMode.val&=~8;
|
||||
chan[c.chan].curPSGMode.val|=chan[c.chan].nextPSGMode.val&8;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -681,7 +681,7 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
|||
|
||||
if (chan[i].std.vol.had) {
|
||||
int inVol=chan[i].std.vol.val;
|
||||
if (chan[i].furnaceDac && inVol>0) {
|
||||
if (inVol>0) {
|
||||
inVol+=63;
|
||||
}
|
||||
chan[i].outVol=VOL_SCALE_LOG_BROKEN(chan[i].vol,MIN(127,inVol),127);
|
||||
|
|
@ -700,7 +700,7 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
|
||||
if (i>=5 && chan[i].furnaceDac && chan[i].dacMode) {
|
||||
if (i>=5 && chan[i].dacMode) {
|
||||
if (NEW_ARP_STRAT) {
|
||||
chan[i].handleArp();
|
||||
} else if (chan[i].std.arp.had) {
|
||||
|
|
@ -720,7 +720,7 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
|
||||
if (i>=5 && chan[i].furnaceDac) {
|
||||
if (i>=5 && chan[i].dacMode) {
|
||||
if (chan[i].std.panL.had) {
|
||||
chan[5].pan&=1;
|
||||
chan[5].pan|=chan[i].std.panL.val?2:0;
|
||||
|
|
@ -752,7 +752,7 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
|||
}
|
||||
|
||||
if (i>=5 && chan[i].std.phaseReset.had) {
|
||||
if (chan[i].std.phaseReset.val==1 && chan[i].furnaceDac) {
|
||||
if (chan[i].std.phaseReset.val==1 && chan[i].dacMode) {
|
||||
chan[i].dacPos=0;
|
||||
}
|
||||
}
|
||||
|
|
@ -915,7 +915,7 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
|||
immWrite(chanOffs[i]+ADDR_FREQ,chan[i].freq&0xff);
|
||||
hardResetElapsed+=2;
|
||||
}
|
||||
if (chan[i].furnaceDac && chan[i].dacMode) {
|
||||
if (chan[i].dacMode) {
|
||||
double off=1.0;
|
||||
if (chan[i].dacSample>=0 && chan[i].dacSample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(chan[i].dacSample);
|
||||
|
|
@ -1051,15 +1051,11 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
|||
if (ins->type==DIV_INS_AMIGA) {
|
||||
chan[c.chan].dacMode=1;
|
||||
rWrite(0x2b,1<<7);
|
||||
} else if (chan[c.chan].furnaceDac) {
|
||||
} else {
|
||||
chan[c.chan].dacMode=0;
|
||||
rWrite(0x2b,0<<7);
|
||||
chan[c.chan].sampleNote=DIV_NOTE_NULL;
|
||||
chan[c.chan].sampleNoteDelta=0;
|
||||
} else if (!chan[c.chan].dacMode) {
|
||||
rWrite(0x2b,0<<7);
|
||||
chan[c.chan].sampleNote=DIV_NOTE_NULL;
|
||||
chan[c.chan].sampleNoteDelta=0;
|
||||
}
|
||||
}
|
||||
if (c.chan>=5 && chan[c.chan].dacMode) {
|
||||
|
|
@ -1097,7 +1093,6 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
|||
chan[c.chan].note=c.value;
|
||||
chan[c.chan].freqChanged=true;
|
||||
}
|
||||
chan[c.chan].furnaceDac=true;
|
||||
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
|
|
@ -1251,7 +1246,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
if (c.chan>=5 && chan[c.chan].furnaceDac && chan[c.chan].dacMode) {
|
||||
if (c.chan>=5 && chan[c.chan].dacMode) {
|
||||
int destFreq=parent->calcBaseFreq(1,1,c.value2+chan[c.chan].sampleNoteDelta,false);
|
||||
bool return2=false;
|
||||
if (destFreq>chan[c.chan].baseFreq) {
|
||||
|
|
@ -1298,7 +1293,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
|||
case DIV_CMD_LEGATO: {
|
||||
if (c.chan==csmChan) {
|
||||
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
|
||||
} else if (c.chan>=5 && chan[c.chan].furnaceDac && chan[c.chan].dacMode) {
|
||||
} else if (c.chan>=5 && chan[c.chan].dacMode) {
|
||||
chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value+chan[c.chan].sampleNoteDelta,false);
|
||||
} else {
|
||||
if (chan[c.chan].insChanged) {
|
||||
|
|
|
|||
|
|
@ -171,15 +171,13 @@ void DivPlatformMMC5::tick(bool sysTick) {
|
|||
// PCM
|
||||
if (chan[2].freqChanged) {
|
||||
chan[2].freq=parent->calcFreq(chan[2].baseFreq,chan[2].pitch,chan[2].fixedArp?chan[2].baseNoteOverride:chan[2].arpOff,chan[2].fixedArp,false,0,chan[2].pitch2,1,1);
|
||||
if (chan[2].furnaceDac) {
|
||||
double off=1.0;
|
||||
if (dacSample>=0 && dacSample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(dacSample);
|
||||
off=(double)s->centerRate/parent->getCenterRate();
|
||||
}
|
||||
dacRate=MIN(chan[2].freq*off,32000);
|
||||
if (dumpWrites) addWrite(0xffff0001,dacRate);
|
||||
double off=1.0;
|
||||
if (dacSample>=0 && dacSample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(dacSample);
|
||||
off=(double)s->centerRate/parent->getCenterRate();
|
||||
}
|
||||
dacRate=MIN(chan[2].freq*off,32000);
|
||||
if (dumpWrites) addWrite(0xffff0001,dacRate);
|
||||
chan[2].freqChanged=false;
|
||||
}
|
||||
}
|
||||
|
|
@ -189,40 +187,35 @@ int DivPlatformMMC5::dispatch(DivCommand c) {
|
|||
case DIV_CMD_NOTE_ON:
|
||||
if (c.chan==2) { // PCM
|
||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_STD);
|
||||
if (ins->type==DIV_INS_AMIGA) {
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
dacSample=ins->amiga.getSample(c.value);
|
||||
chan[c.chan].sampleNote=c.value;
|
||||
c.value=ins->amiga.getFreq(c.value);
|
||||
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
|
||||
} else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) {
|
||||
dacSample=ins->amiga.getSample(chan[c.chan].sampleNote);
|
||||
c.value=ins->amiga.getFreq(chan[c.chan].sampleNote);
|
||||
}
|
||||
if (dacSample<0 || dacSample>=parent->song.sampleLen) {
|
||||
dacSample=-1;
|
||||
if (dumpWrites) addWrite(0xffff0002,0);
|
||||
break;
|
||||
} else {
|
||||
if (dumpWrites) addWrite(0xffff0000,dacSample);
|
||||
}
|
||||
if (chan[c.chan].setPos) {
|
||||
chan[c.chan].setPos=false;
|
||||
} else {
|
||||
dacPos=0;
|
||||
}
|
||||
dacPeriod=0;
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value,false);
|
||||
chan[c.chan].freqChanged=true;
|
||||
chan[c.chan].note=c.value;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chan[c.chan].furnaceDac=true;
|
||||
} else {
|
||||
assert(false && "LEGACY SAMPLE MODE!!!");
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
dacSample=ins->amiga.getSample(c.value);
|
||||
chan[c.chan].sampleNote=c.value;
|
||||
c.value=ins->amiga.getFreq(c.value);
|
||||
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
|
||||
} else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) {
|
||||
dacSample=ins->amiga.getSample(chan[c.chan].sampleNote);
|
||||
c.value=ins->amiga.getFreq(chan[c.chan].sampleNote);
|
||||
}
|
||||
if (dacSample<0 || dacSample>=parent->song.sampleLen) {
|
||||
dacSample=-1;
|
||||
if (dumpWrites) addWrite(0xffff0002,0);
|
||||
break;
|
||||
} else {
|
||||
if (dumpWrites) addWrite(0xffff0000,dacSample);
|
||||
}
|
||||
if (chan[c.chan].setPos) {
|
||||
chan[c.chan].setPos=false;
|
||||
} else {
|
||||
dacPos=0;
|
||||
}
|
||||
dacPeriod=0;
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value,false);
|
||||
chan[c.chan].freqChanged=true;
|
||||
chan[c.chan].note=c.value;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
break;
|
||||
} else {
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
|
|
|
|||
|
|
@ -162,29 +162,20 @@ int DivPlatformMSM6258::dispatch(DivCommand c) {
|
|||
switch (c.cmd) {
|
||||
case DIV_CMD_NOTE_ON: {
|
||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_FM);
|
||||
if (ins->type==DIV_INS_MSM6258 || ins->type==DIV_INS_AMIGA) {
|
||||
chan[c.chan].furnacePCM=true;
|
||||
} else {
|
||||
chan[c.chan].furnacePCM=false;
|
||||
}
|
||||
if (skipRegisterWrites) break;
|
||||
if (chan[c.chan].furnacePCM) {
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) sample=ins->amiga.getSample(c.value);
|
||||
samplePos=0;
|
||||
if (sample>=0 && sample<parent->song.sampleLen) {
|
||||
//DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].note=c.value;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
} else {
|
||||
break;
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) sample=ins->amiga.getSample(c.value);
|
||||
samplePos=0;
|
||||
if (sample>=0 && sample<parent->song.sampleLen) {
|
||||
//DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].note=c.value;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,12 +27,10 @@
|
|||
class DivPlatformMSM6258: public DivDispatch {
|
||||
protected:
|
||||
struct Channel: public SharedChannel<int> {
|
||||
bool furnacePCM;
|
||||
int sample;
|
||||
unsigned char pan;
|
||||
Channel():
|
||||
SharedChannel<int>(8),
|
||||
furnacePCM(false),
|
||||
sample(-1),
|
||||
pan(3) {}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -161,31 +161,22 @@ int DivPlatformMSM6295::dispatch(DivCommand c) {
|
|||
switch (c.cmd) {
|
||||
case DIV_CMD_NOTE_ON: {
|
||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_FM);
|
||||
if (ins->type==DIV_INS_MSM6295 || ins->type==DIV_INS_AMIGA) {
|
||||
chan[c.chan].furnacePCM=true;
|
||||
} else {
|
||||
chan[c.chan].furnacePCM=false;
|
||||
}
|
||||
if (skipRegisterWrites) break;
|
||||
if (chan[c.chan].furnacePCM) {
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value);
|
||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||
//DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].note=c.value;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
rWriteDelay(0,(8<<c.chan),180); // turn off
|
||||
setPhrase(c.chan);
|
||||
rWrite(0,(16<<c.chan)|(8-chan[c.chan].outVol)); // turn on
|
||||
} else {
|
||||
break;
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value);
|
||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||
//DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].note=c.value;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
rWriteDelay(0,(8<<c.chan),180); // turn off
|
||||
setPhrase(c.chan);
|
||||
rWrite(0,(16<<c.chan)|(8-chan[c.chan].outVol)); // turn on
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,11 +27,9 @@
|
|||
class DivPlatformMSM6295: public DivDispatch, public vgsound_emu_mem_intf {
|
||||
protected:
|
||||
struct Channel: public SharedChannel<int> {
|
||||
bool furnacePCM;
|
||||
int sample;
|
||||
Channel():
|
||||
SharedChannel<int>(8),
|
||||
furnacePCM(false),
|
||||
sample(-1) {}
|
||||
};
|
||||
Channel chan[4];
|
||||
|
|
|
|||
|
|
@ -419,79 +419,78 @@ void DivPlatformNES::tick(bool sysTick) {
|
|||
// PCM
|
||||
if (chan[4].freqChanged || chan[4].keyOn) {
|
||||
chan[4].freq=parent->calcFreq(chan[4].baseFreq,chan[4].pitch,chan[4].fixedArp?chan[4].baseNoteOverride:chan[4].arpOff,chan[4].fixedArp,false);
|
||||
if (chan[4].furnaceDac) {
|
||||
double off=1.0;
|
||||
if (dacSample>=0 && dacSample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(dacSample);
|
||||
off=(double)s->centerRate/parent->getCenterRate();
|
||||
}
|
||||
dacRate=MIN(chan[4].freq*off,32000);
|
||||
if (chan[4].keyOn) {
|
||||
if (dpcmMode && !skipRegisterWrites && dacSample>=0 && dacSample<parent->song.sampleLen) {
|
||||
unsigned int dpcmAddr=sampleOffDPCM[dacSample]+(dacPos>>3);
|
||||
int dpcmLen=(parent->getSample(dacSample)->lengthDPCM-(dacPos>>3))>>4;
|
||||
if (dpcmLen<0) dpcmLen=0;
|
||||
if (dpcmLen>255) dpcmLen=255;
|
||||
goingToLoop=parent->getSample(dacSample)->isLoopable();
|
||||
// write DPCM
|
||||
rWrite(0x4015,15);
|
||||
if (nextDPCMFreq>=0) {
|
||||
rWrite(0x4010,nextDPCMFreq|(goingToLoop?0x40:0));
|
||||
nextDPCMFreq=-1;
|
||||
} else {
|
||||
rWrite(0x4010,calcDPCMRate(dacRate)|(goingToLoop?0x40:0));
|
||||
}
|
||||
if (nextDPCMDelta>=0) {
|
||||
rWrite(0x4011,nextDPCMDelta);
|
||||
nextDPCMDelta=-1;
|
||||
}
|
||||
rWrite(0x4012,(dpcmAddr>>6)&0xff);
|
||||
rWrite(0x4013,dpcmLen&0xff);
|
||||
rWrite(0x4015,31);
|
||||
if (dpcmBank!=(dpcmAddr>>14)) {
|
||||
dpcmBank=dpcmAddr>>14;
|
||||
logV("switching bank to %d",dpcmBank);
|
||||
if (dumpWrites) addWrite(0xffff0004,dpcmBank);
|
||||
}
|
||||
|
||||
// sample custom loop point...
|
||||
DivSample* lsamp=parent->getSample(dacSample);
|
||||
|
||||
// how it works:
|
||||
// when the initial sample info is written (see above) and playback is launched,
|
||||
// the parameters (start point in memory and length) are locked until sample end
|
||||
// is reached.
|
||||
|
||||
// thus, if we write new data after just several APU clock cycles, it will be used only when
|
||||
// sample finishes one full loop.
|
||||
|
||||
// thus we can write sample's loop point as "start address" and sample's looped part length
|
||||
// as "full sample length".
|
||||
|
||||
// APU will play full sample once and then repeatedly cycle through the looped part.
|
||||
|
||||
// sources:
|
||||
// https://www.nesdev.org/wiki/APU_DMC
|
||||
// https://www.youtube.com/watch?v=vB4P8x2Am6Y
|
||||
|
||||
if (lsamp->loopEnd>lsamp->loopStart && goingToLoop) {
|
||||
int loopStartAddr=sampleOffDPCM[dacSample]+(lsamp->loopStart>>3);
|
||||
int loopLen=(lsamp->loopEnd-lsamp->loopStart)>>3;
|
||||
|
||||
rWrite(0x4012,(loopStartAddr>>6)&0xff);
|
||||
rWrite(0x4013,(loopLen>>4)&0xff);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
double off=1.0;
|
||||
if (dacSample>=0 && dacSample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(dacSample);
|
||||
off=(double)s->centerRate/parent->getCenterRate();
|
||||
}
|
||||
dacRate=MIN(chan[4].freq*off,32000);
|
||||
if (chan[4].keyOn) {
|
||||
if (dpcmMode && !skipRegisterWrites && dacSample>=0 && dacSample<parent->song.sampleLen) {
|
||||
unsigned int dpcmAddr=sampleOffDPCM[dacSample]+(dacPos>>3);
|
||||
int dpcmLen=(parent->getSample(dacSample)->lengthDPCM-(dacPos>>3))>>4;
|
||||
if (dpcmLen<0) dpcmLen=0;
|
||||
if (dpcmLen>255) dpcmLen=255;
|
||||
goingToLoop=parent->getSample(dacSample)->isLoopable();
|
||||
// write DPCM
|
||||
rWrite(0x4015,15);
|
||||
if (nextDPCMFreq>=0) {
|
||||
rWrite(0x4010,nextDPCMFreq|(goingToLoop?0x40:0));
|
||||
nextDPCMFreq=-1;
|
||||
} else {
|
||||
rWrite(0x4010,calcDPCMRate(dacRate)|(goingToLoop?0x40:0));
|
||||
}
|
||||
if (nextDPCMDelta>=0) {
|
||||
rWrite(0x4011,nextDPCMDelta);
|
||||
nextDPCMDelta=-1;
|
||||
}
|
||||
rWrite(0x4012,(dpcmAddr>>6)&0xff);
|
||||
rWrite(0x4013,dpcmLen&0xff);
|
||||
rWrite(0x4015,31);
|
||||
if (dpcmBank!=(dpcmAddr>>14)) {
|
||||
dpcmBank=dpcmAddr>>14;
|
||||
logV("switching bank to %d",dpcmBank);
|
||||
if (dumpWrites) addWrite(0xffff0004,dpcmBank);
|
||||
}
|
||||
|
||||
// sample custom loop point...
|
||||
DivSample* lsamp=parent->getSample(dacSample);
|
||||
|
||||
// how it works:
|
||||
// when the initial sample info is written (see above) and playback is launched,
|
||||
// the parameters (start point in memory and length) are locked until sample end
|
||||
// is reached.
|
||||
|
||||
// thus, if we write new data after just several APU clock cycles, it will be used only when
|
||||
// sample finishes one full loop.
|
||||
|
||||
// thus we can write sample's loop point as "start address" and sample's looped part length
|
||||
// as "full sample length".
|
||||
|
||||
// APU will play full sample once and then repeatedly cycle through the looped part.
|
||||
|
||||
// sources:
|
||||
// https://www.nesdev.org/wiki/APU_DMC
|
||||
// https://www.youtube.com/watch?v=vB4P8x2Am6Y
|
||||
|
||||
if (lsamp->loopEnd>lsamp->loopStart && goingToLoop) {
|
||||
int loopStartAddr=sampleOffDPCM[dacSample]+(lsamp->loopStart>>3);
|
||||
int loopLen=(lsamp->loopEnd-lsamp->loopStart)>>3;
|
||||
|
||||
rWrite(0x4012,(loopStartAddr>>6)&0xff);
|
||||
rWrite(0x4013,(loopLen>>4)&0xff);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (nextDPCMFreq>=0) {
|
||||
rWrite(0x4010,nextDPCMFreq|(goingToLoop?0x40:0));
|
||||
nextDPCMFreq=-1;
|
||||
} else {
|
||||
rWrite(0x4010,calcDPCMRate(dacRate)|(goingToLoop?0x40:0));
|
||||
}
|
||||
if (dumpWrites && !dpcmMode) addWrite(0xffff0001,dacRate);
|
||||
}
|
||||
if (dumpWrites && !dpcmMode) addWrite(0xffff0001,dacRate);
|
||||
|
||||
if (chan[4].keyOn) chan[4].keyOn=false;
|
||||
chan[4].freqChanged=false;
|
||||
}
|
||||
|
|
@ -504,69 +503,64 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
|||
case DIV_CMD_NOTE_ON:
|
||||
if (c.chan==4) { // PCM
|
||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_NES);
|
||||
if (ins->type==DIV_INS_AMIGA || (ins->type==DIV_INS_NES && !parent->song.oldDPCM)) {
|
||||
if (ins->type==DIV_INS_NES) {
|
||||
if (!dpcmMode) {
|
||||
dpcmMode=true;
|
||||
if (dumpWrites) addWrite(0xffff0002,0);
|
||||
dacSample=-1;
|
||||
rWrite(0x4015,15);
|
||||
rWrite(0x4010,0);
|
||||
rWrite(0x4012,0);
|
||||
rWrite(0x4013,0);
|
||||
rWrite(0x4015,31);
|
||||
}
|
||||
|
||||
if (ins->amiga.useNoteMap) {
|
||||
nextDPCMFreq=ins->amiga.getDPCMFreq(c.value);
|
||||
if (nextDPCMFreq<0 || nextDPCMFreq>15) nextDPCMFreq=lastDPCMFreq;
|
||||
lastDPCMFreq=nextDPCMFreq;
|
||||
nextDPCMDelta=ins->amiga.getDPCMDelta(c.value);
|
||||
} else {
|
||||
if (c.value==DIV_NOTE_NULL) {
|
||||
nextDPCMFreq=lastDPCMFreq;
|
||||
} else {
|
||||
nextDPCMFreq=c.value&15;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
dacSample=(int)ins->amiga.getSample(c.value);
|
||||
if (ins->type==DIV_INS_AMIGA) {
|
||||
chan[c.chan].sampleNote=c.value;
|
||||
c.value=ins->amiga.getFreq(c.value);
|
||||
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
|
||||
}
|
||||
} else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) {
|
||||
dacSample=(int)ins->amiga.getSample(chan[c.chan].sampleNote);
|
||||
if (ins->type==DIV_INS_AMIGA) {
|
||||
c.value=ins->amiga.getFreq(chan[c.chan].sampleNote);
|
||||
}
|
||||
}
|
||||
if (dacSample<0 || dacSample>=parent->song.sampleLen) {
|
||||
if (ins->type==DIV_INS_NES) {
|
||||
if (!dpcmMode) {
|
||||
dpcmMode=true;
|
||||
if (dumpWrites) addWrite(0xffff0002,0);
|
||||
dacSample=-1;
|
||||
if (dumpWrites && !dpcmMode) addWrite(0xffff0002,0);
|
||||
break;
|
||||
rWrite(0x4015,15);
|
||||
rWrite(0x4010,0);
|
||||
rWrite(0x4012,0);
|
||||
rWrite(0x4013,0);
|
||||
rWrite(0x4015,31);
|
||||
}
|
||||
|
||||
if (ins->amiga.useNoteMap) {
|
||||
nextDPCMFreq=ins->amiga.getDPCMFreq(c.value);
|
||||
if (nextDPCMFreq<0 || nextDPCMFreq>15) nextDPCMFreq=lastDPCMFreq;
|
||||
lastDPCMFreq=nextDPCMFreq;
|
||||
nextDPCMDelta=ins->amiga.getDPCMDelta(c.value);
|
||||
} else {
|
||||
if (dumpWrites && !dpcmMode) addWrite(0xffff0000,dacSample);
|
||||
if (c.value==DIV_NOTE_NULL) {
|
||||
nextDPCMFreq=lastDPCMFreq;
|
||||
} else {
|
||||
nextDPCMFreq=c.value&15;
|
||||
}
|
||||
}
|
||||
if (chan[c.chan].setPos) {
|
||||
chan[c.chan].setPos=false;
|
||||
} else {
|
||||
dacPos=0;
|
||||
}
|
||||
dacPeriod=0;
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value,false);
|
||||
chan[c.chan].freqChanged=true;
|
||||
chan[c.chan].note=c.value;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chan[c.chan].furnaceDac=true;
|
||||
} else {
|
||||
assert(false && "LEGACY SAMPLE MODE!!!");
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
dacSample=(int)ins->amiga.getSample(c.value);
|
||||
if (ins->type==DIV_INS_AMIGA) {
|
||||
chan[c.chan].sampleNote=c.value;
|
||||
c.value=ins->amiga.getFreq(c.value);
|
||||
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
|
||||
}
|
||||
} else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) {
|
||||
dacSample=(int)ins->amiga.getSample(chan[c.chan].sampleNote);
|
||||
if (ins->type==DIV_INS_AMIGA) {
|
||||
c.value=ins->amiga.getFreq(chan[c.chan].sampleNote);
|
||||
}
|
||||
}
|
||||
if (dacSample<0 || dacSample>=parent->song.sampleLen) {
|
||||
dacSample=-1;
|
||||
if (dumpWrites && !dpcmMode) addWrite(0xffff0002,0);
|
||||
break;
|
||||
} else {
|
||||
if (dumpWrites && !dpcmMode) addWrite(0xffff0000,dacSample);
|
||||
}
|
||||
if (chan[c.chan].setPos) {
|
||||
chan[c.chan].setPos=false;
|
||||
} else {
|
||||
dacPos=0;
|
||||
}
|
||||
dacPeriod=0;
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value,false);
|
||||
chan[c.chan].freqChanged=true;
|
||||
chan[c.chan].note=c.value;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
break;
|
||||
} else if (c.chan==3) { // noise
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class DivPlatformNES: public DivDispatch {
|
|||
struct Channel: public SharedChannel<signed char> {
|
||||
int prevFreq;
|
||||
unsigned char duty, sweep, envMode, len;
|
||||
bool sweepChanged, furnaceDac, setPos;
|
||||
bool sweepChanged, setPos;
|
||||
Channel():
|
||||
SharedChannel<signed char>(15),
|
||||
prevFreq(65535),
|
||||
|
|
@ -39,7 +39,6 @@ class DivPlatformNES: public DivDispatch {
|
|||
envMode(3),
|
||||
len(0x1f),
|
||||
sweepChanged(false),
|
||||
furnaceDac(false),
|
||||
setPos(false) {}
|
||||
};
|
||||
Channel chan[5];
|
||||
|
|
|
|||
|
|
@ -1387,26 +1387,24 @@ void DivPlatformOPL::tick(bool sysTick) {
|
|||
|
||||
// ADPCM
|
||||
if (adpcmChan>=0) {
|
||||
if (chan[adpcmChan].furnacePCM) {
|
||||
chan[adpcmChan].std.next();
|
||||
chan[adpcmChan].std.next();
|
||||
|
||||
if (chan[adpcmChan].std.vol.had) {
|
||||
chan[adpcmChan].outVol=(chan[adpcmChan].vol*MIN(chan[adpcmChan].macroVolMul,chan[adpcmChan].std.vol.val))/chan[adpcmChan].macroVolMul;
|
||||
immWrite(18,(isMuted[adpcmChan]?0:chan[adpcmChan].outVol));
|
||||
}
|
||||
if (chan[adpcmChan].std.vol.had) {
|
||||
chan[adpcmChan].outVol=(chan[adpcmChan].vol*MIN(chan[adpcmChan].macroVolMul,chan[adpcmChan].std.vol.val))/chan[adpcmChan].macroVolMul;
|
||||
immWrite(18,(isMuted[adpcmChan]?0:chan[adpcmChan].outVol));
|
||||
}
|
||||
|
||||
if (NEW_ARP_STRAT) {
|
||||
chan[adpcmChan].handleArp();
|
||||
} else if (chan[adpcmChan].std.arp.had) {
|
||||
if (!chan[adpcmChan].inPorta) {
|
||||
chan[adpcmChan].baseFreq=NOTE_ADPCMB(parent->calcArp(chan[adpcmChan].note,chan[adpcmChan].std.arp.val));
|
||||
}
|
||||
chan[adpcmChan].freqChanged=true;
|
||||
if (NEW_ARP_STRAT) {
|
||||
chan[adpcmChan].handleArp();
|
||||
} else if (chan[adpcmChan].std.arp.had) {
|
||||
if (!chan[adpcmChan].inPorta) {
|
||||
chan[adpcmChan].baseFreq=NOTE_ADPCMB(parent->calcArp(chan[adpcmChan].note,chan[adpcmChan].std.arp.val));
|
||||
}
|
||||
if (chan[adpcmChan].std.phaseReset.had) {
|
||||
if ((chan[adpcmChan].std.phaseReset.val==1) && chan[adpcmChan].active) {
|
||||
chan[adpcmChan].keyOn=true;
|
||||
}
|
||||
chan[adpcmChan].freqChanged=true;
|
||||
}
|
||||
if (chan[adpcmChan].std.phaseReset.had) {
|
||||
if ((chan[adpcmChan].std.phaseReset.val==1) && chan[adpcmChan].active) {
|
||||
chan[adpcmChan].keyOn=true;
|
||||
}
|
||||
}
|
||||
if (chan[adpcmChan].freqChanged || chan[adpcmChan].keyOn || chan[adpcmChan].keyOff) {
|
||||
|
|
@ -1838,48 +1836,39 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
} else if (c.chan==adpcmChan) { // ADPCM
|
||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_FM);
|
||||
chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:255;
|
||||
if (ins->type==DIV_INS_AMIGA || ins->type==DIV_INS_ADPCMB) {
|
||||
chan[c.chan].furnacePCM=true;
|
||||
} else {
|
||||
chan[c.chan].furnacePCM=false;
|
||||
}
|
||||
if (skipRegisterWrites) break;
|
||||
if (chan[c.chan].furnacePCM) {
|
||||
chan[c.chan].macroInit(ins);
|
||||
chan[c.chan].fixedFreq=0;
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
immWrite(18,(isMuted[adpcmChan]?0:chan[adpcmChan].outVol));
|
||||
}
|
||||
chan[c.chan].macroInit(ins);
|
||||
chan[c.chan].fixedFreq=0;
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
immWrite(18,(isMuted[adpcmChan]?0:chan[adpcmChan].outVol));
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].sample=ins->amiga.getSample(c.value);
|
||||
c.value=ins->amiga.getFreq(c.value);
|
||||
}
|
||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
immWrite(8,0);
|
||||
immWrite(9,(sampleOffB[chan[c.chan].sample]>>2)&0xff);
|
||||
immWrite(10,(sampleOffB[chan[c.chan].sample]>>10)&0xff);
|
||||
int end=sampleOffB[chan[c.chan].sample]+s->lengthB-1;
|
||||
immWrite(11,(end>>2)&0xff);
|
||||
immWrite(12,(end>>10)&0xff);
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].sample=ins->amiga.getSample(c.value);
|
||||
c.value=ins->amiga.getFreq(c.value);
|
||||
}
|
||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
immWrite(8,0);
|
||||
immWrite(9,(sampleOffB[chan[c.chan].sample]>>2)&0xff);
|
||||
immWrite(10,(sampleOffB[chan[c.chan].sample]>>10)&0xff);
|
||||
int end=sampleOffB[chan[c.chan].sample]+s->lengthB-1;
|
||||
immWrite(11,(end>>2)&0xff);
|
||||
immWrite(12,(end>>10)&0xff);
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].note=c.value;
|
||||
chan[c.chan].baseFreq=NOTE_ADPCMB(chan[c.chan].note);
|
||||
chan[c.chan].freqChanged=true;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
} else {
|
||||
immWrite(7,0x01); // reset
|
||||
immWrite(9,0);
|
||||
immWrite(10,0);
|
||||
immWrite(11,0);
|
||||
immWrite(12,0);
|
||||
break;
|
||||
chan[c.chan].note=c.value;
|
||||
chan[c.chan].baseFreq=NOTE_ADPCMB(chan[c.chan].note);
|
||||
chan[c.chan].freqChanged=true;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
} else {
|
||||
assert(false && "LEGACY SAMPLE MODE!!!");
|
||||
immWrite(7,0x01); // reset
|
||||
immWrite(9,0);
|
||||
immWrite(10,0);
|
||||
immWrite(11,0);
|
||||
immWrite(12,0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -2060,9 +2049,6 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
break;
|
||||
}
|
||||
case DIV_CMD_PITCH: {
|
||||
if (c.chan==adpcmChan) {
|
||||
if (!chan[c.chan].furnacePCM) break;
|
||||
}
|
||||
chan[c.chan].pitch=c.value;
|
||||
chan[c.chan].freqChanged=true;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ class DivPlatformOPL: public DivDispatch {
|
|||
DivInstrumentFM state;
|
||||
unsigned int freqH, freqL;
|
||||
int sample, fixedFreq;
|
||||
bool furnacePCM, fourOp, hardReset, writeCtrl;
|
||||
bool fourOp, hardReset, writeCtrl;
|
||||
bool levelDirect, damp, pseudoReverb, lfoReset, ch;
|
||||
int lfo, vib, am, ar, d1r, d2r, dl, rc, rr;
|
||||
int pan;
|
||||
|
|
@ -70,7 +70,6 @@ class DivPlatformOPL: public DivDispatch {
|
|||
freqL(0),
|
||||
sample(-1),
|
||||
fixedFreq(0),
|
||||
furnacePCM(false),
|
||||
fourOp(false),
|
||||
hardReset(false),
|
||||
writeCtrl(false),
|
||||
|
|
|
|||
|
|
@ -34,14 +34,12 @@ class DivPlatformOPLL: public DivDispatch {
|
|||
DivInstrumentFM state;
|
||||
unsigned char freqH, freqL;
|
||||
int fixedFreq;
|
||||
bool furnaceDac;
|
||||
unsigned char pan;
|
||||
Channel():
|
||||
SharedChannel<int>(0),
|
||||
freqH(0),
|
||||
freqL(0),
|
||||
fixedFreq(0),
|
||||
furnaceDac(false),
|
||||
pan(3) {}
|
||||
};
|
||||
Channel chan[11];
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ void DivPlatformPCE::tick(bool sysTick) {
|
|||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].std.phaseReset.had && chan[i].std.phaseReset.val==1) {
|
||||
if (chan[i].furnaceDac && chan[i].pcm) {
|
||||
if (chan[i].pcm) {
|
||||
if (chan[i].active && chan[i].dacSample>=0 && chan[i].dacSample<parent->song.sampleLen) {
|
||||
if (chan[i].setPos) {
|
||||
chan[i].setPos=false;
|
||||
|
|
@ -249,7 +249,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,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER);
|
||||
if (chan[i].furnaceDac && chan[i].pcm) {
|
||||
if (chan[i].pcm) {
|
||||
double off=1.0;
|
||||
if (chan[i].dacSample>=0 && chan[i].dacSample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(chan[i].dacSample);
|
||||
|
|
@ -301,54 +301,48 @@ int DivPlatformPCE::dispatch(DivCommand c) {
|
|||
chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:31;
|
||||
if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) {
|
||||
chan[c.chan].pcm=true;
|
||||
} else if (chan[c.chan].furnaceDac) {
|
||||
} else {
|
||||
chan[c.chan].pcm=false;
|
||||
chan[c.chan].sampleNote=DIV_NOTE_NULL;
|
||||
chan[c.chan].sampleNoteDelta=0;
|
||||
if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0);
|
||||
}
|
||||
if (chan[c.chan].pcm) {
|
||||
if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) {
|
||||
chan[c.chan].furnaceDac=true;
|
||||
if (skipRegisterWrites) break;
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].dacSample=ins->amiga.getSample(c.value);
|
||||
chan[c.chan].sampleNote=c.value;
|
||||
c.value=ins->amiga.getFreq(c.value);
|
||||
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
|
||||
} else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].dacSample=ins->amiga.getSample(chan[c.chan].sampleNote);
|
||||
c.value=ins->amiga.getFreq(chan[c.chan].sampleNote);
|
||||
}
|
||||
if (chan[c.chan].dacSample<0 || chan[c.chan].dacSample>=parent->song.sampleLen) {
|
||||
chan[c.chan].dacSample=-1;
|
||||
if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0);
|
||||
break;
|
||||
} else {
|
||||
if (dumpWrites) {
|
||||
chWrite(c.chan,0x04,parent->song.disableSampleMacro?0xdf:(0xc0|chan[c.chan].vol));
|
||||
addWrite(0xffff0000+(c.chan<<8),chan[c.chan].dacSample);
|
||||
}
|
||||
}
|
||||
if (chan[c.chan].setPos) {
|
||||
chan[c.chan].setPos=false;
|
||||
} else {
|
||||
chan[c.chan].dacPos=0;
|
||||
}
|
||||
chan[c.chan].dacPeriod=0;
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
|
||||
chan[c.chan].freqChanged=true;
|
||||
chan[c.chan].note=c.value;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
}
|
||||
//chan[c.chan].keyOn=true;
|
||||
if (skipRegisterWrites) break;
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].dacSample=ins->amiga.getSample(c.value);
|
||||
chan[c.chan].sampleNote=c.value;
|
||||
c.value=ins->amiga.getFreq(c.value);
|
||||
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
|
||||
} else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].dacSample=ins->amiga.getSample(chan[c.chan].sampleNote);
|
||||
c.value=ins->amiga.getFreq(chan[c.chan].sampleNote);
|
||||
}
|
||||
if (chan[c.chan].dacSample<0 || chan[c.chan].dacSample>=parent->song.sampleLen) {
|
||||
chan[c.chan].dacSample=-1;
|
||||
if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0);
|
||||
break;
|
||||
} else {
|
||||
assert(false && "LEGACY SAMPLE MODE!!!");
|
||||
if (dumpWrites) {
|
||||
chWrite(c.chan,0x04,parent->song.disableSampleMacro?0xdf:(0xc0|chan[c.chan].vol));
|
||||
addWrite(0xffff0000+(c.chan<<8),chan[c.chan].dacSample);
|
||||
}
|
||||
}
|
||||
if (chan[c.chan].setPos) {
|
||||
chan[c.chan].setPos=false;
|
||||
} else {
|
||||
chan[c.chan].dacPos=0;
|
||||
}
|
||||
chan[c.chan].dacPeriod=0;
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
|
||||
chan[c.chan].freqChanged=true;
|
||||
chan[c.chan].note=c.value;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class DivPlatformPCE: public DivDispatch {
|
|||
unsigned int dacPos;
|
||||
int dacSample;
|
||||
unsigned char pan;
|
||||
bool noise, pcm, furnaceDac, deferredWaveUpdate, setPos;
|
||||
bool noise, pcm, deferredWaveUpdate, setPos;
|
||||
signed short wave;
|
||||
int macroVolMul, noiseSeek;
|
||||
DivWaveSynth ws;
|
||||
|
|
@ -48,7 +48,6 @@ class DivPlatformPCE: public DivDispatch {
|
|||
pan(255),
|
||||
noise(false),
|
||||
pcm(false),
|
||||
furnaceDac(false),
|
||||
deferredWaveUpdate(false),
|
||||
setPos(false),
|
||||
wave(-1),
|
||||
|
|
|
|||
|
|
@ -278,7 +278,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,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER);
|
||||
if (i==1 && pcm && furnaceDac) {
|
||||
if (i==1 && pcm) {
|
||||
double off=1.0;
|
||||
if (dacSample>=0 && dacSample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(dacSample);
|
||||
|
|
@ -355,7 +355,7 @@ int DivPlatformSwan::dispatch(DivCommand c) {
|
|||
if (c.chan==1) {
|
||||
if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) {
|
||||
pcm=true;
|
||||
} else if (furnaceDac) {
|
||||
} else {
|
||||
pcm=false;
|
||||
chan[c.chan].sampleNote=DIV_NOTE_NULL;
|
||||
chan[c.chan].sampleNoteDelta=0;
|
||||
|
|
@ -368,37 +368,32 @@ int DivPlatformSwan::dispatch(DivCommand c) {
|
|||
dacPos=0;
|
||||
}
|
||||
dacPeriod=0;
|
||||
if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) {
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
dacSample=ins->amiga.getSample(c.value);
|
||||
chan[c.chan].sampleNote=c.value;
|
||||
c.value=ins->amiga.getFreq(c.value);
|
||||
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
|
||||
} else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) {
|
||||
dacSample=ins->amiga.getSample(chan[c.chan].sampleNote);
|
||||
c.value=ins->amiga.getFreq(chan[c.chan].sampleNote);
|
||||
}
|
||||
if (dacSample<0 || dacSample>=parent->song.sampleLen) {
|
||||
dacSample=-1;
|
||||
if (dumpWrites) postWrite(0xffff0002,0);
|
||||
break;
|
||||
} else {
|
||||
if (dumpWrites) {
|
||||
postWrite(0xffff0000,dacSample);
|
||||
}
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[1].baseFreq=NOTE_PERIODIC(c.value);
|
||||
chan[1].freqChanged=true;
|
||||
chan[1].note=c.value;
|
||||
}
|
||||
chan[1].active=true;
|
||||
chan[1].keyOn=true;
|
||||
chan[1].macroInit(ins);
|
||||
furnaceDac=true;
|
||||
} else {
|
||||
assert(false && "LEGACY SAMPLE MODE!!!");
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
dacSample=ins->amiga.getSample(c.value);
|
||||
chan[c.chan].sampleNote=c.value;
|
||||
c.value=ins->amiga.getFreq(c.value);
|
||||
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
|
||||
} else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) {
|
||||
dacSample=ins->amiga.getSample(chan[c.chan].sampleNote);
|
||||
c.value=ins->amiga.getFreq(chan[c.chan].sampleNote);
|
||||
}
|
||||
if (dacSample<0 || dacSample>=parent->song.sampleLen) {
|
||||
dacSample=-1;
|
||||
if (dumpWrites) postWrite(0xffff0002,0);
|
||||
break;
|
||||
} else {
|
||||
if (dumpWrites) {
|
||||
postWrite(0xffff0000,dacSample);
|
||||
}
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[1].baseFreq=NOTE_PERIODIC(c.value);
|
||||
chan[1].freqChanged=true;
|
||||
chan[1].note=c.value;
|
||||
}
|
||||
chan[1].active=true;
|
||||
chan[1].keyOn=true;
|
||||
chan[1].macroInit(ins);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -652,7 +647,6 @@ void DivPlatformSwan::reset() {
|
|||
swan_sound_init(&ws, true);
|
||||
pcm=false;
|
||||
sweep=false;
|
||||
furnaceDac=false;
|
||||
setPos=false;
|
||||
noise=0;
|
||||
dacPeriod=0;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class DivPlatformSwan: public DivDispatch {
|
|||
bool isMuted[4];
|
||||
bool stereo;
|
||||
bool useMdfn;
|
||||
bool pcm, sweep, furnaceDac, setPos;
|
||||
bool pcm, sweep, setPos;
|
||||
unsigned char noise;
|
||||
int dacPeriod, dacRate;
|
||||
unsigned int dacPos;
|
||||
|
|
|
|||
|
|
@ -947,31 +947,29 @@ void DivPlatformYM2608::tick(bool sysTick) {
|
|||
|
||||
// RSS
|
||||
for (int i=(9+isCSM); i<(15+isCSM); i++) {
|
||||
if (chan[i].furnacePCM) {
|
||||
chan[i].std.next();
|
||||
if (chan[i].std.vol.had) {
|
||||
chan[i].outVol=(chan[i].vol*MIN(chan[i].macroVolMul,chan[i].std.vol.val))/chan[i].macroVolMul;
|
||||
}
|
||||
if (chan[i].std.duty.had) {
|
||||
if (globalRSSVolume!=(chan[i].std.duty.val&0x3f)) {
|
||||
globalRSSVolume=chan[i].std.duty.val&0x3f;
|
||||
immWrite(0x11,globalRSSVolume);
|
||||
hardResetElapsed++;
|
||||
}
|
||||
}
|
||||
if (chan[i].std.panL.had) {
|
||||
chan[i].pan=chan[i].std.panL.val&3;
|
||||
}
|
||||
if (chan[i].std.phaseReset.had) {
|
||||
if ((chan[i].std.phaseReset.val==1) && chan[i].active) {
|
||||
chan[i].keyOn=true;
|
||||
}
|
||||
}
|
||||
if (!isMuted[i] && (chan[i].std.vol.had || chan[i].std.panL.had)) {
|
||||
immWrite(0x18+(i-(9+isCSM)),isMuted[i]?0:((chan[i].pan<<6)|chan[i].outVol));
|
||||
chan[i].std.next();
|
||||
if (chan[i].std.vol.had) {
|
||||
chan[i].outVol=(chan[i].vol*MIN(chan[i].macroVolMul,chan[i].std.vol.val))/chan[i].macroVolMul;
|
||||
}
|
||||
if (chan[i].std.duty.had) {
|
||||
if (globalRSSVolume!=(chan[i].std.duty.val&0x3f)) {
|
||||
globalRSSVolume=chan[i].std.duty.val&0x3f;
|
||||
immWrite(0x11,globalRSSVolume);
|
||||
hardResetElapsed++;
|
||||
}
|
||||
}
|
||||
if (chan[i].std.panL.had) {
|
||||
chan[i].pan=chan[i].std.panL.val&3;
|
||||
}
|
||||
if (chan[i].std.phaseReset.had) {
|
||||
if ((chan[i].std.phaseReset.val==1) && chan[i].active) {
|
||||
chan[i].keyOn=true;
|
||||
}
|
||||
}
|
||||
if (!isMuted[i] && (chan[i].std.vol.had || chan[i].std.panL.had)) {
|
||||
immWrite(0x18+(i-(9+isCSM)),isMuted[i]?0:((chan[i].pan<<6)|chan[i].outVol));
|
||||
hardResetElapsed++;
|
||||
}
|
||||
if (chan[i].keyOff) {
|
||||
writeRSSOff|=(1<<(i-(9+isCSM)));
|
||||
chan[i].keyOff=false;
|
||||
|
|
@ -982,57 +980,54 @@ void DivPlatformYM2608::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
// ADPCM-B
|
||||
if (chan[(15+isCSM)].furnacePCM) {
|
||||
chan[(15+isCSM)].std.next();
|
||||
chan[(15+isCSM)].std.next();
|
||||
|
||||
if (chan[(15+isCSM)].std.vol.had) {
|
||||
chan[(15+isCSM)].outVol=(chan[(15+isCSM)].vol*MIN(chan[(15+isCSM)].macroVolMul,chan[(15+isCSM)].std.vol.val))/chan[(15+isCSM)].macroVolMul;
|
||||
immWrite(0x10b,chan[(15+isCSM)].outVol);
|
||||
hardResetElapsed++;
|
||||
}
|
||||
if (chan[(15+isCSM)].std.vol.had) {
|
||||
chan[(15+isCSM)].outVol=(chan[(15+isCSM)].vol*MIN(chan[(15+isCSM)].macroVolMul,chan[(15+isCSM)].std.vol.val))/chan[(15+isCSM)].macroVolMul;
|
||||
immWrite(0x10b,chan[(15+isCSM)].outVol);
|
||||
hardResetElapsed++;
|
||||
}
|
||||
|
||||
if (NEW_ARP_STRAT) {
|
||||
chan[(15+isCSM)].handleArp();
|
||||
} else if (chan[(15+isCSM)].std.arp.had) {
|
||||
if (!chan[(15+isCSM)].inPorta) {
|
||||
chan[(15+isCSM)].baseFreq=NOTE_ADPCMB(parent->calcArp(chan[(15+isCSM)].note,chan[(15+isCSM)].std.arp.val));
|
||||
}
|
||||
chan[(15+isCSM)].freqChanged=true;
|
||||
if (NEW_ARP_STRAT) {
|
||||
chan[(15+isCSM)].handleArp();
|
||||
} else if (chan[(15+isCSM)].std.arp.had) {
|
||||
if (!chan[(15+isCSM)].inPorta) {
|
||||
chan[(15+isCSM)].baseFreq=NOTE_ADPCMB(parent->calcArp(chan[(15+isCSM)].note,chan[(15+isCSM)].std.arp.val));
|
||||
}
|
||||
chan[(15+isCSM)].freqChanged=true;
|
||||
}
|
||||
|
||||
if (chan[(15+isCSM)].std.pitch.had) {
|
||||
if (chan[(15+isCSM)].std.pitch.mode) {
|
||||
chan[(15+isCSM)].pitch2+=chan[(15+isCSM)].std.pitch.val;
|
||||
CLAMP_VAR(chan[(15+isCSM)].pitch2,-65535,65535);
|
||||
} else {
|
||||
chan[(15+isCSM)].pitch2=chan[(15+isCSM)].std.pitch.val;
|
||||
}
|
||||
chan[(15+isCSM)].freqChanged=true;
|
||||
if (chan[(15+isCSM)].std.pitch.had) {
|
||||
if (chan[(15+isCSM)].std.pitch.mode) {
|
||||
chan[(15+isCSM)].pitch2+=chan[(15+isCSM)].std.pitch.val;
|
||||
CLAMP_VAR(chan[(15+isCSM)].pitch2,-65535,65535);
|
||||
} else {
|
||||
chan[(15+isCSM)].pitch2=chan[(15+isCSM)].std.pitch.val;
|
||||
}
|
||||
chan[(15+isCSM)].freqChanged=true;
|
||||
}
|
||||
|
||||
if (chan[(15+isCSM)].std.panL.had) {
|
||||
if (chan[(15+isCSM)].pan!=(chan[(15+isCSM)].std.panL.val&3)) {
|
||||
chan[(15+isCSM)].pan=chan[(15+isCSM)].std.panL.val&3;
|
||||
if (!isMuted[(15 + isCSM)]) {
|
||||
immWrite(0x101,(isMuted[(15 + isCSM)]?0:(chan[(15+isCSM)].pan<<6))|memConfig);
|
||||
hardResetElapsed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chan[(15+isCSM)].std.phaseReset.had) {
|
||||
if ((chan[(15+isCSM)].std.phaseReset.val==1) && chan[(15+isCSM)].active) {
|
||||
chan[(15+isCSM)].keyOn=true;
|
||||
if (chan[(15+isCSM)].std.panL.had) {
|
||||
if (chan[(15+isCSM)].pan!=(chan[(15+isCSM)].std.panL.val&3)) {
|
||||
chan[(15+isCSM)].pan=chan[(15+isCSM)].std.panL.val&3;
|
||||
if (!isMuted[(15 + isCSM)]) {
|
||||
immWrite(0x101,(isMuted[(15 + isCSM)]?0:(chan[(15+isCSM)].pan<<6))|memConfig);
|
||||
hardResetElapsed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chan[(15+isCSM)].std.phaseReset.had) {
|
||||
if ((chan[(15+isCSM)].std.phaseReset.val==1) && chan[(15+isCSM)].active) {
|
||||
chan[(15+isCSM)].keyOn=true;
|
||||
}
|
||||
}
|
||||
|
||||
if (chan[(15+isCSM)].freqChanged || chan[(15+isCSM)].keyOn || chan[(15+isCSM)].keyOff) {
|
||||
if (chan[(15+isCSM)].furnacePCM) {
|
||||
if (chan[(15+isCSM)].sample>=0 && chan[(15+isCSM)].sample<parent->song.sampleLen) {
|
||||
double off=65535.0*(double)(parent->getSample(chan[(15+isCSM)].sample)->centerRate)/parent->getCenterRate();
|
||||
chan[(15+isCSM)].freq=parent->calcFreq(chan[(15+isCSM)].baseFreq,chan[(15+isCSM)].pitch,chan[(15+isCSM)].fixedArp?chan[(15+isCSM)].baseNoteOverride:chan[(15+isCSM)].arpOff,chan[(15+isCSM)].fixedArp,false,4,chan[(15+isCSM)].pitch2,(double)chipClock/144,off);
|
||||
} else {
|
||||
chan[(15+isCSM)].freq=0;
|
||||
}
|
||||
if (chan[(15+isCSM)].sample>=0 && chan[(15+isCSM)].sample<parent->song.sampleLen) {
|
||||
double off=65535.0*(double)(parent->getSample(chan[(15+isCSM)].sample)->centerRate)/parent->getCenterRate();
|
||||
chan[(15+isCSM)].freq=parent->calcFreq(chan[(15+isCSM)].baseFreq,chan[(15+isCSM)].pitch,chan[(15+isCSM)].fixedArp?chan[(15+isCSM)].baseNoteOverride:chan[(15+isCSM)].arpOff,chan[(15+isCSM)].fixedArp,false,4,chan[(15+isCSM)].pitch2,(double)chipClock/144,off);
|
||||
} else {
|
||||
chan[(15+isCSM)].freq=0;
|
||||
}
|
||||
if (chan[adpcmBChanOffs].freq<0) chan[adpcmBChanOffs].freq=0;
|
||||
if (chan[adpcmBChanOffs].freq>65535) chan[adpcmBChanOffs].freq=65535;
|
||||
|
|
@ -1153,70 +1148,50 @@ int DivPlatformYM2608::dispatch(DivCommand c) {
|
|||
if (c.chan>(14+isCSM)) { // ADPCM-B
|
||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_FM);
|
||||
chan[c.chan].macroVolMul=(ins->type==DIV_INS_AMIGA)?64:255;
|
||||
if (ins->type==DIV_INS_AMIGA || ins->type==DIV_INS_ADPCMB) {
|
||||
chan[c.chan].furnacePCM=true;
|
||||
} else {
|
||||
chan[c.chan].furnacePCM=false;
|
||||
}
|
||||
if (skipRegisterWrites) break;
|
||||
if (chan[c.chan].furnacePCM) {
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
immWrite(0x10b,chan[c.chan].outVol);
|
||||
}
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
immWrite(0x10b,chan[c.chan].outVol);
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].sample=ins->amiga.getSample(c.value);
|
||||
chan[c.chan].sampleNote=c.value;
|
||||
c.value=ins->amiga.getFreq(c.value);
|
||||
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
|
||||
}
|
||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
immWrite(0x100,0x01); // reset
|
||||
immWrite(0x102,(sampleOffB[chan[c.chan].sample]>>5)&0xff);
|
||||
immWrite(0x103,(sampleOffB[chan[c.chan].sample]>>13)&0xff);
|
||||
int end=sampleOffB[chan[c.chan].sample]+s->lengthB-1;
|
||||
immWrite(0x104,(end>>5)&0xff);
|
||||
immWrite(0x105,(end>>13)&0xff);
|
||||
immWrite(0x101,(isMuted[c.chan]?0:(chan[c.chan].pan<<6))|memConfig);
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].sample=ins->amiga.getSample(c.value);
|
||||
chan[c.chan].sampleNote=c.value;
|
||||
c.value=ins->amiga.getFreq(c.value);
|
||||
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
|
||||
}
|
||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
immWrite(0x100,0x01); // reset
|
||||
immWrite(0x102,(sampleOffB[chan[c.chan].sample]>>5)&0xff);
|
||||
immWrite(0x103,(sampleOffB[chan[c.chan].sample]>>13)&0xff);
|
||||
int end=sampleOffB[chan[c.chan].sample]+s->lengthB-1;
|
||||
immWrite(0x104,(end>>5)&0xff);
|
||||
immWrite(0x105,(end>>13)&0xff);
|
||||
immWrite(0x101,(isMuted[c.chan]?0:(chan[c.chan].pan<<6))|memConfig);
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].note=c.value;
|
||||
chan[c.chan].baseFreq=NOTE_ADPCMB(chan[c.chan].note);
|
||||
chan[c.chan].freqChanged=true;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
} else {
|
||||
immWrite(0x100,0x01); // reset
|
||||
immWrite(0x102,0);
|
||||
immWrite(0x103,0);
|
||||
immWrite(0x104,0);
|
||||
immWrite(0x105,0);
|
||||
break;
|
||||
chan[c.chan].note=c.value;
|
||||
chan[c.chan].baseFreq=NOTE_ADPCMB(chan[c.chan].note);
|
||||
chan[c.chan].freqChanged=true;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
} else {
|
||||
assert(false && "LEGACY SAMPLE MODE!!!");
|
||||
immWrite(0x100,0x01); // reset
|
||||
immWrite(0x102,0);
|
||||
immWrite(0x103,0);
|
||||
immWrite(0x104,0);
|
||||
immWrite(0x105,0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (c.chan>(8+isCSM)) { // RSS
|
||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_FM);
|
||||
chan[c.chan].macroVolMul=(ins->type==DIV_INS_AMIGA)?64:31;
|
||||
if (ins->type==DIV_INS_AMIGA || ins->type==DIV_INS_ADPCMA) {
|
||||
chan[c.chan].furnacePCM=true;
|
||||
} else {
|
||||
chan[c.chan].furnacePCM=false;
|
||||
}
|
||||
if (skipRegisterWrites) break;
|
||||
if (chan[c.chan].furnacePCM) {
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
immWrite(0x18+(c.chan-(9+isCSM)),isMuted[c.chan]?0:((chan[c.chan].pan<<6)|chan[c.chan].outVol));
|
||||
}
|
||||
} else {
|
||||
chan[c.chan].macroInit(NULL);
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
immWrite(0x18+(c.chan-(9+isCSM)),isMuted[c.chan]?0:((chan[c.chan].pan<<6)|chan[c.chan].outVol));
|
||||
}
|
||||
|
|
@ -1337,7 +1312,6 @@ int DivPlatformYM2608::dispatch(DivCommand c) {
|
|||
break;
|
||||
}
|
||||
case DIV_CMD_PITCH: {
|
||||
if (c.chan==(15+isCSM) && !chan[c.chan].furnacePCM) break;
|
||||
chan[c.chan].pitch=c.value;
|
||||
chan[c.chan].freqChanged=true;
|
||||
break;
|
||||
|
|
@ -1396,7 +1370,6 @@ int DivPlatformYM2608::dispatch(DivCommand c) {
|
|||
if (c.chan==csmChan) {
|
||||
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
|
||||
}
|
||||
if (c.chan==(15+isCSM) && !chan[c.chan].furnacePCM) break;
|
||||
if (c.chan<=psgChanOffs) {
|
||||
if (chan[c.chan].insChanged) {
|
||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_FM);
|
||||
|
|
|
|||
|
|
@ -867,31 +867,30 @@ void DivPlatformYM2610::tick(bool sysTick) {
|
|||
|
||||
// ADPCM-A
|
||||
for (int i=adpcmAChanOffs; i<adpcmBChanOffs; i++) {
|
||||
if (chan[i].furnacePCM) {
|
||||
chan[i].std.next();
|
||||
if (chan[i].std.vol.had) {
|
||||
chan[i].outVol=(chan[i].vol*MIN(chan[i].macroVolMul,chan[i].std.vol.val))/chan[i].macroVolMul;
|
||||
}
|
||||
if (chan[i].std.duty.had) {
|
||||
if (globalADPCMAVolume!=(chan[i].std.duty.val&0x3f)) {
|
||||
globalADPCMAVolume=chan[i].std.duty.val&0x3f;
|
||||
immWrite(0x101,globalADPCMAVolume);
|
||||
hardResetElapsed++;
|
||||
}
|
||||
}
|
||||
if (chan[i].std.panL.had) {
|
||||
chan[i].pan=chan[i].std.panL.val&3;
|
||||
}
|
||||
if (chan[i].std.phaseReset.had) {
|
||||
if ((chan[i].std.phaseReset.val==1) && chan[i].active) {
|
||||
chan[i].keyOn=true;
|
||||
}
|
||||
}
|
||||
if (!isMuted[i] && (chan[i].std.vol.had || chan[i].std.panL.had)) {
|
||||
immWrite(0x108+(i-adpcmAChanOffs),isMuted[i]?0:((chan[i].pan<<6)|chan[i].outVol));
|
||||
chan[i].std.next();
|
||||
if (chan[i].std.vol.had) {
|
||||
chan[i].outVol=(chan[i].vol*MIN(chan[i].macroVolMul,chan[i].std.vol.val))/chan[i].macroVolMul;
|
||||
}
|
||||
if (chan[i].std.duty.had) {
|
||||
if (globalADPCMAVolume!=(chan[i].std.duty.val&0x3f)) {
|
||||
globalADPCMAVolume=chan[i].std.duty.val&0x3f;
|
||||
immWrite(0x101,globalADPCMAVolume);
|
||||
hardResetElapsed++;
|
||||
}
|
||||
}
|
||||
if (chan[i].std.panL.had) {
|
||||
chan[i].pan=chan[i].std.panL.val&3;
|
||||
}
|
||||
if (chan[i].std.phaseReset.had) {
|
||||
if ((chan[i].std.phaseReset.val==1) && chan[i].active) {
|
||||
chan[i].keyOn=true;
|
||||
}
|
||||
}
|
||||
if (!isMuted[i] && (chan[i].std.vol.had || chan[i].std.panL.had)) {
|
||||
immWrite(0x108+(i-adpcmAChanOffs),isMuted[i]?0:((chan[i].pan<<6)|chan[i].outVol));
|
||||
hardResetElapsed++;
|
||||
}
|
||||
|
||||
if (chan[i].keyOff) {
|
||||
writeADPCMAOff|=(1<<(i-adpcmAChanOffs));
|
||||
chan[i].keyOff=false;
|
||||
|
|
@ -904,63 +903,61 @@ void DivPlatformYM2610::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
// ADPCM-B
|
||||
if (chan[adpcmBChanOffs].furnacePCM) {
|
||||
chan[adpcmBChanOffs].std.next();
|
||||
chan[adpcmBChanOffs].std.next();
|
||||
|
||||
if (chan[adpcmBChanOffs].std.vol.had) {
|
||||
chan[adpcmBChanOffs].outVol=(chan[adpcmBChanOffs].vol*MIN(chan[adpcmBChanOffs].macroVolMul,chan[adpcmBChanOffs].std.vol.val))/chan[adpcmBChanOffs].macroVolMul;
|
||||
immWrite(0x1b,chan[adpcmBChanOffs].outVol);
|
||||
hardResetElapsed++;
|
||||
}
|
||||
if (chan[adpcmBChanOffs].std.vol.had) {
|
||||
chan[adpcmBChanOffs].outVol=(chan[adpcmBChanOffs].vol*MIN(chan[adpcmBChanOffs].macroVolMul,chan[adpcmBChanOffs].std.vol.val))/chan[adpcmBChanOffs].macroVolMul;
|
||||
immWrite(0x1b,chan[adpcmBChanOffs].outVol);
|
||||
hardResetElapsed++;
|
||||
}
|
||||
|
||||
if (NEW_ARP_STRAT) {
|
||||
chan[adpcmBChanOffs].handleArp();
|
||||
} else if (chan[adpcmBChanOffs].std.arp.had) {
|
||||
if (!chan[adpcmBChanOffs].inPorta) {
|
||||
chan[adpcmBChanOffs].baseFreq=NOTE_ADPCMB(parent->calcArp(chan[adpcmBChanOffs].note,chan[adpcmBChanOffs].std.arp.val));
|
||||
}
|
||||
chan[adpcmBChanOffs].freqChanged=true;
|
||||
if (NEW_ARP_STRAT) {
|
||||
chan[adpcmBChanOffs].handleArp();
|
||||
} else if (chan[adpcmBChanOffs].std.arp.had) {
|
||||
if (!chan[adpcmBChanOffs].inPorta) {
|
||||
chan[adpcmBChanOffs].baseFreq=NOTE_ADPCMB(parent->calcArp(chan[adpcmBChanOffs].note,chan[adpcmBChanOffs].std.arp.val));
|
||||
}
|
||||
chan[adpcmBChanOffs].freqChanged=true;
|
||||
}
|
||||
|
||||
if (chan[adpcmBChanOffs].std.pitch.had) {
|
||||
if (chan[adpcmBChanOffs].std.pitch.mode) {
|
||||
chan[adpcmBChanOffs].pitch2+=chan[adpcmBChanOffs].std.pitch.val;
|
||||
CLAMP_VAR(chan[adpcmBChanOffs].pitch2,-65535,65535);
|
||||
} else {
|
||||
chan[adpcmBChanOffs].pitch2=chan[adpcmBChanOffs].std.pitch.val;
|
||||
}
|
||||
chan[adpcmBChanOffs].freqChanged=true;
|
||||
if (chan[adpcmBChanOffs].std.pitch.had) {
|
||||
if (chan[adpcmBChanOffs].std.pitch.mode) {
|
||||
chan[adpcmBChanOffs].pitch2+=chan[adpcmBChanOffs].std.pitch.val;
|
||||
CLAMP_VAR(chan[adpcmBChanOffs].pitch2,-65535,65535);
|
||||
} else {
|
||||
chan[adpcmBChanOffs].pitch2=chan[adpcmBChanOffs].std.pitch.val;
|
||||
}
|
||||
chan[adpcmBChanOffs].freqChanged=true;
|
||||
}
|
||||
|
||||
if (chan[adpcmBChanOffs].std.panL.had) {
|
||||
if (chan[adpcmBChanOffs].pan!=(chan[adpcmBChanOffs].std.panL.val&3)) {
|
||||
chan[adpcmBChanOffs].pan=chan[adpcmBChanOffs].std.panL.val&3;
|
||||
if (!isMuted[adpcmBChanOffs]) {
|
||||
immWrite(0x11,(isMuted[adpcmBChanOffs]?0:(chan[adpcmBChanOffs].pan<<6)));
|
||||
hardResetElapsed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chan[adpcmBChanOffs].std.phaseReset.had) {
|
||||
if ((chan[adpcmBChanOffs].std.phaseReset.val==1) && chan[adpcmBChanOffs].active) {
|
||||
chan[adpcmBChanOffs].keyOn=true;
|
||||
if (chan[adpcmBChanOffs].std.panL.had) {
|
||||
if (chan[adpcmBChanOffs].pan!=(chan[adpcmBChanOffs].std.panL.val&3)) {
|
||||
chan[adpcmBChanOffs].pan=chan[adpcmBChanOffs].std.panL.val&3;
|
||||
if (!isMuted[adpcmBChanOffs]) {
|
||||
immWrite(0x11,(isMuted[adpcmBChanOffs]?0:(chan[adpcmBChanOffs].pan<<6)));
|
||||
hardResetElapsed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chan[adpcmBChanOffs].freqChanged || chan[adpcmBChanOffs].keyOn || chan[adpcmBChanOffs].keyOff) {
|
||||
if (chan[adpcmBChanOffs].furnacePCM) {
|
||||
if (chan[adpcmBChanOffs].sample>=0 && chan[adpcmBChanOffs].sample<parent->song.sampleLen) {
|
||||
double off=65535.0*(double)(parent->getSample(chan[adpcmBChanOffs].sample)->centerRate)/parent->getCenterRate();
|
||||
chan[adpcmBChanOffs].freq=parent->calcFreq(chan[adpcmBChanOffs].baseFreq,chan[adpcmBChanOffs].pitch,chan[adpcmBChanOffs].fixedArp?chan[adpcmBChanOffs].baseNoteOverride:chan[adpcmBChanOffs].arpOff,chan[adpcmBChanOffs].fixedArp,false,4,chan[adpcmBChanOffs].pitch2,(double)chipClock/144,off);
|
||||
} else {
|
||||
chan[adpcmBChanOffs].freq=0;
|
||||
}
|
||||
if (chan[adpcmBChanOffs].freq<0) chan[adpcmBChanOffs].freq=0;
|
||||
if (chan[adpcmBChanOffs].freq>65535) chan[adpcmBChanOffs].freq=65535;
|
||||
immWrite(0x19,chan[adpcmBChanOffs].freq&0xff);
|
||||
immWrite(0x1a,(chan[adpcmBChanOffs].freq>>8)&0xff);
|
||||
hardResetElapsed+=2;
|
||||
if (chan[adpcmBChanOffs].std.phaseReset.had) {
|
||||
if ((chan[adpcmBChanOffs].std.phaseReset.val==1) && chan[adpcmBChanOffs].active) {
|
||||
chan[adpcmBChanOffs].keyOn=true;
|
||||
}
|
||||
}
|
||||
|
||||
if (chan[adpcmBChanOffs].freqChanged || chan[adpcmBChanOffs].keyOn || chan[adpcmBChanOffs].keyOff) {
|
||||
if (chan[adpcmBChanOffs].sample>=0 && chan[adpcmBChanOffs].sample<parent->song.sampleLen) {
|
||||
double off=65535.0*(double)(parent->getSample(chan[adpcmBChanOffs].sample)->centerRate)/parent->getCenterRate();
|
||||
chan[adpcmBChanOffs].freq=parent->calcFreq(chan[adpcmBChanOffs].baseFreq,chan[adpcmBChanOffs].pitch,chan[adpcmBChanOffs].fixedArp?chan[adpcmBChanOffs].baseNoteOverride:chan[adpcmBChanOffs].arpOff,chan[adpcmBChanOffs].fixedArp,false,4,chan[adpcmBChanOffs].pitch2,(double)chipClock/144,off);
|
||||
} else {
|
||||
chan[adpcmBChanOffs].freq=0;
|
||||
}
|
||||
if (chan[adpcmBChanOffs].freq<0) chan[adpcmBChanOffs].freq=0;
|
||||
if (chan[adpcmBChanOffs].freq>65535) chan[adpcmBChanOffs].freq=65535;
|
||||
immWrite(0x19,chan[adpcmBChanOffs].freq&0xff);
|
||||
immWrite(0x1a,(chan[adpcmBChanOffs].freq>>8)&0xff);
|
||||
hardResetElapsed+=2;
|
||||
|
||||
if (chan[adpcmBChanOffs].keyOn || chan[adpcmBChanOffs].keyOff) {
|
||||
immWrite(0x10,0x01); // reset
|
||||
hardResetElapsed++;
|
||||
|
|
@ -1071,92 +1068,74 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
|||
if (c.chan>=adpcmBChanOffs) { // ADPCM-B
|
||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_FM);
|
||||
chan[c.chan].macroVolMul=(ins->type==DIV_INS_AMIGA)?64:255;
|
||||
if (ins->type==DIV_INS_AMIGA || ins->type==DIV_INS_ADPCMB) {
|
||||
chan[c.chan].furnacePCM=true;
|
||||
} else {
|
||||
chan[c.chan].furnacePCM=false;
|
||||
}
|
||||
if (skipRegisterWrites) break;
|
||||
if (chan[c.chan].furnacePCM) {
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].sample=ins->amiga.getSample(c.value);
|
||||
chan[c.chan].sampleNote=c.value;
|
||||
c.value=ins->amiga.getFreq(c.value);
|
||||
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
|
||||
}
|
||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
immWrite(0x12,(sampleOffB[chan[c.chan].sample]>>8)&0xff);
|
||||
immWrite(0x13,sampleOffB[chan[c.chan].sample]>>16);
|
||||
int end=sampleOffB[chan[c.chan].sample]+s->lengthB-1;
|
||||
immWrite(0x14,(end>>8)&0xff);
|
||||
immWrite(0x15,end>>16);
|
||||
immWrite(0x11,isMuted[c.chan]?0:(chan[c.chan].pan<<6));
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].sample=ins->amiga.getSample(c.value);
|
||||
chan[c.chan].sampleNote=c.value;
|
||||
c.value=ins->amiga.getFreq(c.value);
|
||||
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
|
||||
}
|
||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
immWrite(0x12,(sampleOffB[chan[c.chan].sample]>>8)&0xff);
|
||||
immWrite(0x13,sampleOffB[chan[c.chan].sample]>>16);
|
||||
int end=sampleOffB[chan[c.chan].sample]+s->lengthB-1;
|
||||
immWrite(0x14,(end>>8)&0xff);
|
||||
immWrite(0x15,end>>16);
|
||||
immWrite(0x11,isMuted[c.chan]?0:(chan[c.chan].pan<<6));
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].note=c.value;
|
||||
chan[c.chan].baseFreq=NOTE_ADPCMB(chan[c.chan].note);
|
||||
chan[c.chan].freqChanged=true;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
} else {
|
||||
immWrite(0x10,0x01); // reset
|
||||
immWrite(0x12,0);
|
||||
immWrite(0x13,0);
|
||||
immWrite(0x14,0);
|
||||
immWrite(0x15,0);
|
||||
break;
|
||||
chan[c.chan].note=c.value;
|
||||
chan[c.chan].baseFreq=NOTE_ADPCMB(chan[c.chan].note);
|
||||
chan[c.chan].freqChanged=true;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
} else {
|
||||
assert(false && "LEGACY SAMPLE MODE!!!");
|
||||
immWrite(0x10,0x01); // reset
|
||||
immWrite(0x12,0);
|
||||
immWrite(0x13,0);
|
||||
immWrite(0x14,0);
|
||||
immWrite(0x15,0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (c.chan>=adpcmAChanOffs) { // ADPCM-A
|
||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_FM);
|
||||
chan[c.chan].macroVolMul=(ins->type==DIV_INS_AMIGA)?64:31;
|
||||
if (!parent->song.disableSampleMacro && (ins->type==DIV_INS_AMIGA || ins->type==DIV_INS_ADPCMA)) {
|
||||
chan[c.chan].furnacePCM=true;
|
||||
} else {
|
||||
chan[c.chan].furnacePCM=false;
|
||||
}
|
||||
if (skipRegisterWrites) break;
|
||||
if (chan[c.chan].furnacePCM) {
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value);
|
||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
immWrite(0x110+c.chan-adpcmAChanOffs,(sampleOffA[chan[c.chan].sample]>>8)&0xff);
|
||||
immWrite(0x118+c.chan-adpcmAChanOffs,sampleOffA[chan[c.chan].sample]>>16);
|
||||
int end=sampleOffA[chan[c.chan].sample]+s->lengthA-1;
|
||||
immWrite(0x120+c.chan-adpcmAChanOffs,(end>>8)&0xff);
|
||||
immWrite(0x128+c.chan-adpcmAChanOffs,end>>16);
|
||||
immWrite(0x108+c.chan-adpcmAChanOffs,isMuted[c.chan]?0:((chan[c.chan].pan<<6)|chan[c.chan].outVol));
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].note=c.value;
|
||||
chan[c.chan].baseFreq=NOTE_ADPCMB(chan[c.chan].note);
|
||||
chan[c.chan].freqChanged=true;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
} else {
|
||||
writeADPCMAOff|=(1<<(c.chan-adpcmAChanOffs));
|
||||
immWrite(0x110+c.chan-adpcmAChanOffs,0);
|
||||
immWrite(0x118+c.chan-adpcmAChanOffs,0);
|
||||
immWrite(0x120+c.chan-adpcmAChanOffs,0);
|
||||
immWrite(0x128+c.chan-adpcmAChanOffs,0);
|
||||
break;
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value);
|
||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
immWrite(0x110+c.chan-adpcmAChanOffs,(sampleOffA[chan[c.chan].sample]>>8)&0xff);
|
||||
immWrite(0x118+c.chan-adpcmAChanOffs,sampleOffA[chan[c.chan].sample]>>16);
|
||||
int end=sampleOffA[chan[c.chan].sample]+s->lengthA-1;
|
||||
immWrite(0x120+c.chan-adpcmAChanOffs,(end>>8)&0xff);
|
||||
immWrite(0x128+c.chan-adpcmAChanOffs,end>>16);
|
||||
immWrite(0x108+c.chan-adpcmAChanOffs,isMuted[c.chan]?0:((chan[c.chan].pan<<6)|chan[c.chan].outVol));
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].note=c.value;
|
||||
chan[c.chan].baseFreq=NOTE_ADPCMB(chan[c.chan].note);
|
||||
chan[c.chan].freqChanged=true;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
} else {
|
||||
assert(false && "LEGACY SAMPLE MODE!!!");
|
||||
writeADPCMAOff|=(1<<(c.chan-adpcmAChanOffs));
|
||||
immWrite(0x110+c.chan-adpcmAChanOffs,0);
|
||||
immWrite(0x118+c.chan-adpcmAChanOffs,0);
|
||||
immWrite(0x120+c.chan-adpcmAChanOffs,0);
|
||||
immWrite(0x128+c.chan-adpcmAChanOffs,0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -1273,7 +1252,6 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
|||
break;
|
||||
}
|
||||
case DIV_CMD_PITCH: {
|
||||
if (c.chan==adpcmBChanOffs && !chan[c.chan].furnacePCM) break;
|
||||
chan[c.chan].pitch=c.value;
|
||||
chan[c.chan].freqChanged=true;
|
||||
break;
|
||||
|
|
@ -1329,7 +1307,6 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
|||
break;
|
||||
}
|
||||
case DIV_CMD_LEGATO: {
|
||||
if (c.chan==adpcmBChanOffs && !chan[c.chan].furnacePCM) break;
|
||||
if (c.chan==csmChan) {
|
||||
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -936,31 +936,30 @@ void DivPlatformYM2610B::tick(bool sysTick) {
|
|||
|
||||
// ADPCM-A
|
||||
for (int i=adpcmAChanOffs; i<adpcmBChanOffs; i++) {
|
||||
if (chan[i].furnacePCM) {
|
||||
chan[i].std.next();
|
||||
if (chan[i].std.vol.had) {
|
||||
chan[i].outVol=(chan[i].vol*MIN(chan[i].macroVolMul,chan[i].std.vol.val))/chan[i].macroVolMul;
|
||||
}
|
||||
if (chan[i].std.duty.had) {
|
||||
if (globalADPCMAVolume!=(chan[i].std.duty.val&0x3f)) {
|
||||
globalADPCMAVolume=chan[i].std.duty.val&0x3f;
|
||||
immWrite(0x101,globalADPCMAVolume);
|
||||
hardResetElapsed++;
|
||||
}
|
||||
}
|
||||
if (chan[i].std.panL.had) {
|
||||
chan[i].pan=chan[i].std.panL.val&3;
|
||||
}
|
||||
if (chan[i].std.phaseReset.had) {
|
||||
if ((chan[i].std.phaseReset.val==1) && chan[i].active) {
|
||||
chan[i].keyOn=true;
|
||||
}
|
||||
}
|
||||
if (!isMuted[i] && (chan[i].std.vol.had || chan[i].std.panL.had)) {
|
||||
immWrite(0x108+(i-adpcmAChanOffs),isMuted[i]?0:((chan[i].pan<<6)|chan[i].outVol));
|
||||
chan[i].std.next();
|
||||
if (chan[i].std.vol.had) {
|
||||
chan[i].outVol=(chan[i].vol*MIN(chan[i].macroVolMul,chan[i].std.vol.val))/chan[i].macroVolMul;
|
||||
}
|
||||
if (chan[i].std.duty.had) {
|
||||
if (globalADPCMAVolume!=(chan[i].std.duty.val&0x3f)) {
|
||||
globalADPCMAVolume=chan[i].std.duty.val&0x3f;
|
||||
immWrite(0x101,globalADPCMAVolume);
|
||||
hardResetElapsed++;
|
||||
}
|
||||
}
|
||||
if (chan[i].std.panL.had) {
|
||||
chan[i].pan=chan[i].std.panL.val&3;
|
||||
}
|
||||
if (chan[i].std.phaseReset.had) {
|
||||
if ((chan[i].std.phaseReset.val==1) && chan[i].active) {
|
||||
chan[i].keyOn=true;
|
||||
}
|
||||
}
|
||||
if (!isMuted[i] && (chan[i].std.vol.had || chan[i].std.panL.had)) {
|
||||
immWrite(0x108+(i-adpcmAChanOffs),isMuted[i]?0:((chan[i].pan<<6)|chan[i].outVol));
|
||||
hardResetElapsed++;
|
||||
}
|
||||
|
||||
if (chan[i].keyOff) {
|
||||
writeADPCMAOff|=(1<<(i-adpcmAChanOffs));
|
||||
chan[i].keyOff=false;
|
||||
|
|
@ -973,63 +972,61 @@ void DivPlatformYM2610B::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
// ADPCM-B
|
||||
if (chan[adpcmBChanOffs].furnacePCM) {
|
||||
chan[adpcmBChanOffs].std.next();
|
||||
chan[adpcmBChanOffs].std.next();
|
||||
|
||||
if (chan[adpcmBChanOffs].std.vol.had) {
|
||||
chan[adpcmBChanOffs].outVol=(chan[adpcmBChanOffs].vol*MIN(chan[adpcmBChanOffs].macroVolMul,chan[adpcmBChanOffs].std.vol.val))/chan[adpcmBChanOffs].macroVolMul;
|
||||
immWrite(0x1b,chan[adpcmBChanOffs].outVol);
|
||||
hardResetElapsed++;
|
||||
}
|
||||
if (chan[adpcmBChanOffs].std.vol.had) {
|
||||
chan[adpcmBChanOffs].outVol=(chan[adpcmBChanOffs].vol*MIN(chan[adpcmBChanOffs].macroVolMul,chan[adpcmBChanOffs].std.vol.val))/chan[adpcmBChanOffs].macroVolMul;
|
||||
immWrite(0x1b,chan[adpcmBChanOffs].outVol);
|
||||
hardResetElapsed++;
|
||||
}
|
||||
|
||||
if (NEW_ARP_STRAT) {
|
||||
chan[adpcmBChanOffs].handleArp();
|
||||
} else if (chan[adpcmBChanOffs].std.arp.had) {
|
||||
if (!chan[adpcmBChanOffs].inPorta) {
|
||||
chan[adpcmBChanOffs].baseFreq=NOTE_ADPCMB(parent->calcArp(chan[adpcmBChanOffs].note,chan[adpcmBChanOffs].std.arp.val));
|
||||
}
|
||||
chan[adpcmBChanOffs].freqChanged=true;
|
||||
if (NEW_ARP_STRAT) {
|
||||
chan[adpcmBChanOffs].handleArp();
|
||||
} else if (chan[adpcmBChanOffs].std.arp.had) {
|
||||
if (!chan[adpcmBChanOffs].inPorta) {
|
||||
chan[adpcmBChanOffs].baseFreq=NOTE_ADPCMB(parent->calcArp(chan[adpcmBChanOffs].note,chan[adpcmBChanOffs].std.arp.val));
|
||||
}
|
||||
chan[adpcmBChanOffs].freqChanged=true;
|
||||
}
|
||||
|
||||
if (chan[adpcmBChanOffs].std.pitch.had) {
|
||||
if (chan[adpcmBChanOffs].std.pitch.mode) {
|
||||
chan[adpcmBChanOffs].pitch2+=chan[adpcmBChanOffs].std.pitch.val;
|
||||
CLAMP_VAR(chan[adpcmBChanOffs].pitch2,-65535,65535);
|
||||
} else {
|
||||
chan[adpcmBChanOffs].pitch2=chan[adpcmBChanOffs].std.pitch.val;
|
||||
}
|
||||
chan[adpcmBChanOffs].freqChanged=true;
|
||||
if (chan[adpcmBChanOffs].std.pitch.had) {
|
||||
if (chan[adpcmBChanOffs].std.pitch.mode) {
|
||||
chan[adpcmBChanOffs].pitch2+=chan[adpcmBChanOffs].std.pitch.val;
|
||||
CLAMP_VAR(chan[adpcmBChanOffs].pitch2,-65535,65535);
|
||||
} else {
|
||||
chan[adpcmBChanOffs].pitch2=chan[adpcmBChanOffs].std.pitch.val;
|
||||
}
|
||||
chan[adpcmBChanOffs].freqChanged=true;
|
||||
}
|
||||
|
||||
if (chan[adpcmBChanOffs].std.panL.had) {
|
||||
if (chan[adpcmBChanOffs].pan!=(chan[adpcmBChanOffs].std.panL.val&3)) {
|
||||
chan[adpcmBChanOffs].pan=chan[adpcmBChanOffs].std.panL.val&3;
|
||||
if (!isMuted[adpcmBChanOffs]) {
|
||||
immWrite(0x11,(isMuted[adpcmBChanOffs]?0:(chan[adpcmBChanOffs].pan<<6)));
|
||||
hardResetElapsed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chan[adpcmBChanOffs].std.phaseReset.had) {
|
||||
if ((chan[adpcmBChanOffs].std.phaseReset.val==1) && chan[adpcmBChanOffs].active) {
|
||||
chan[adpcmBChanOffs].keyOn=true;
|
||||
if (chan[adpcmBChanOffs].std.panL.had) {
|
||||
if (chan[adpcmBChanOffs].pan!=(chan[adpcmBChanOffs].std.panL.val&3)) {
|
||||
chan[adpcmBChanOffs].pan=chan[adpcmBChanOffs].std.panL.val&3;
|
||||
if (!isMuted[adpcmBChanOffs]) {
|
||||
immWrite(0x11,(isMuted[adpcmBChanOffs]?0:(chan[adpcmBChanOffs].pan<<6)));
|
||||
hardResetElapsed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chan[adpcmBChanOffs].freqChanged || chan[adpcmBChanOffs].keyOn || chan[adpcmBChanOffs].keyOff) {
|
||||
if (chan[adpcmBChanOffs].furnacePCM) {
|
||||
if (chan[adpcmBChanOffs].sample>=0 && chan[adpcmBChanOffs].sample<parent->song.sampleLen) {
|
||||
double off=65535.0*(double)(parent->getSample(chan[adpcmBChanOffs].sample)->centerRate)/parent->getCenterRate();
|
||||
chan[adpcmBChanOffs].freq=parent->calcFreq(chan[adpcmBChanOffs].baseFreq,chan[adpcmBChanOffs].pitch,chan[adpcmBChanOffs].fixedArp?chan[adpcmBChanOffs].baseNoteOverride:chan[adpcmBChanOffs].arpOff,chan[adpcmBChanOffs].fixedArp,false,4,chan[adpcmBChanOffs].pitch2,(double)chipClock/144,off);
|
||||
} else {
|
||||
chan[adpcmBChanOffs].freq=0;
|
||||
}
|
||||
if (chan[adpcmBChanOffs].freq<0) chan[adpcmBChanOffs].freq=0;
|
||||
if (chan[adpcmBChanOffs].freq>65535) chan[adpcmBChanOffs].freq=65535;
|
||||
immWrite(0x19,chan[adpcmBChanOffs].freq&0xff);
|
||||
immWrite(0x1a,(chan[adpcmBChanOffs].freq>>8)&0xff);
|
||||
hardResetElapsed+=2;
|
||||
if (chan[adpcmBChanOffs].std.phaseReset.had) {
|
||||
if ((chan[adpcmBChanOffs].std.phaseReset.val==1) && chan[adpcmBChanOffs].active) {
|
||||
chan[adpcmBChanOffs].keyOn=true;
|
||||
}
|
||||
}
|
||||
|
||||
if (chan[adpcmBChanOffs].freqChanged || chan[adpcmBChanOffs].keyOn || chan[adpcmBChanOffs].keyOff) {
|
||||
if (chan[adpcmBChanOffs].sample>=0 && chan[adpcmBChanOffs].sample<parent->song.sampleLen) {
|
||||
double off=65535.0*(double)(parent->getSample(chan[adpcmBChanOffs].sample)->centerRate)/parent->getCenterRate();
|
||||
chan[adpcmBChanOffs].freq=parent->calcFreq(chan[adpcmBChanOffs].baseFreq,chan[adpcmBChanOffs].pitch,chan[adpcmBChanOffs].fixedArp?chan[adpcmBChanOffs].baseNoteOverride:chan[adpcmBChanOffs].arpOff,chan[adpcmBChanOffs].fixedArp,false,4,chan[adpcmBChanOffs].pitch2,(double)chipClock/144,off);
|
||||
} else {
|
||||
chan[adpcmBChanOffs].freq=0;
|
||||
}
|
||||
if (chan[adpcmBChanOffs].freq<0) chan[adpcmBChanOffs].freq=0;
|
||||
if (chan[adpcmBChanOffs].freq>65535) chan[adpcmBChanOffs].freq=65535;
|
||||
immWrite(0x19,chan[adpcmBChanOffs].freq&0xff);
|
||||
immWrite(0x1a,(chan[adpcmBChanOffs].freq>>8)&0xff);
|
||||
hardResetElapsed+=2;
|
||||
|
||||
if (chan[adpcmBChanOffs].keyOn || chan[adpcmBChanOffs].keyOff) {
|
||||
immWrite(0x10,0x01); // reset
|
||||
hardResetElapsed++;
|
||||
|
|
@ -1140,92 +1137,74 @@ int DivPlatformYM2610B::dispatch(DivCommand c) {
|
|||
if (c.chan>=adpcmBChanOffs) { // ADPCM-B
|
||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_FM);
|
||||
chan[c.chan].macroVolMul=(ins->type==DIV_INS_AMIGA)?64:255;
|
||||
if (ins->type==DIV_INS_AMIGA || ins->type==DIV_INS_ADPCMB) {
|
||||
chan[c.chan].furnacePCM=true;
|
||||
} else {
|
||||
chan[c.chan].furnacePCM=false;
|
||||
}
|
||||
if (skipRegisterWrites) break;
|
||||
if (chan[c.chan].furnacePCM) {
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].sample=ins->amiga.getSample(c.value);
|
||||
chan[c.chan].sampleNote=c.value;
|
||||
c.value=ins->amiga.getFreq(c.value);
|
||||
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
|
||||
}
|
||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
immWrite(0x12,(sampleOffB[chan[c.chan].sample]>>8)&0xff);
|
||||
immWrite(0x13,sampleOffB[chan[c.chan].sample]>>16);
|
||||
int end=sampleOffB[chan[c.chan].sample]+s->lengthB-1;
|
||||
immWrite(0x14,(end>>8)&0xff);
|
||||
immWrite(0x15,end>>16);
|
||||
immWrite(0x11,isMuted[c.chan]?0:(chan[c.chan].pan<<6));
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].sample=ins->amiga.getSample(c.value);
|
||||
chan[c.chan].sampleNote=c.value;
|
||||
c.value=ins->amiga.getFreq(c.value);
|
||||
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
|
||||
}
|
||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
immWrite(0x12,(sampleOffB[chan[c.chan].sample]>>8)&0xff);
|
||||
immWrite(0x13,sampleOffB[chan[c.chan].sample]>>16);
|
||||
int end=sampleOffB[chan[c.chan].sample]+s->lengthB-1;
|
||||
immWrite(0x14,(end>>8)&0xff);
|
||||
immWrite(0x15,end>>16);
|
||||
immWrite(0x11,isMuted[c.chan]?0:(chan[c.chan].pan<<6));
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].note=c.value;
|
||||
chan[c.chan].baseFreq=NOTE_ADPCMB(chan[c.chan].note);
|
||||
chan[c.chan].freqChanged=true;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
} else {
|
||||
immWrite(0x10,0x01); // reset
|
||||
immWrite(0x12,0);
|
||||
immWrite(0x13,0);
|
||||
immWrite(0x14,0);
|
||||
immWrite(0x15,0);
|
||||
break;
|
||||
chan[c.chan].note=c.value;
|
||||
chan[c.chan].baseFreq=NOTE_ADPCMB(chan[c.chan].note);
|
||||
chan[c.chan].freqChanged=true;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
} else {
|
||||
assert(false && "LEGACY SAMPLE MODE!!!");
|
||||
immWrite(0x10,0x01); // reset
|
||||
immWrite(0x12,0);
|
||||
immWrite(0x13,0);
|
||||
immWrite(0x14,0);
|
||||
immWrite(0x15,0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (c.chan>=adpcmAChanOffs) { // ADPCM-A
|
||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_FM);
|
||||
chan[c.chan].macroVolMul=(ins->type==DIV_INS_AMIGA)?64:31;
|
||||
if (!parent->song.disableSampleMacro && (ins->type==DIV_INS_AMIGA || ins->type==DIV_INS_ADPCMA)) {
|
||||
chan[c.chan].furnacePCM=true;
|
||||
} else {
|
||||
chan[c.chan].furnacePCM=false;
|
||||
}
|
||||
if (skipRegisterWrites) break;
|
||||
if (chan[c.chan].furnacePCM) {
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value);
|
||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
immWrite(0x110+c.chan-adpcmAChanOffs,(sampleOffA[chan[c.chan].sample]>>8)&0xff);
|
||||
immWrite(0x118+c.chan-adpcmAChanOffs,sampleOffA[chan[c.chan].sample]>>16);
|
||||
int end=sampleOffA[chan[c.chan].sample]+s->lengthA-1;
|
||||
immWrite(0x120+c.chan-adpcmAChanOffs,(end>>8)&0xff);
|
||||
immWrite(0x128+c.chan-adpcmAChanOffs,end>>16);
|
||||
immWrite(0x108+c.chan-adpcmAChanOffs,isMuted[c.chan]?0:((chan[c.chan].pan<<6)|chan[c.chan].outVol));
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].note=c.value;
|
||||
chan[c.chan].baseFreq=NOTE_ADPCMB(chan[c.chan].note);
|
||||
chan[c.chan].freqChanged=true;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
} else {
|
||||
writeADPCMAOff|=(1<<(c.chan-adpcmAChanOffs));
|
||||
immWrite(0x110+c.chan-adpcmAChanOffs,0);
|
||||
immWrite(0x118+c.chan-adpcmAChanOffs,0);
|
||||
immWrite(0x120+c.chan-adpcmAChanOffs,0);
|
||||
immWrite(0x128+c.chan-adpcmAChanOffs,0);
|
||||
break;
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (!chan[c.chan].std.vol.will) {
|
||||
chan[c.chan].outVol=chan[c.chan].vol;
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value);
|
||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
immWrite(0x110+c.chan-adpcmAChanOffs,(sampleOffA[chan[c.chan].sample]>>8)&0xff);
|
||||
immWrite(0x118+c.chan-adpcmAChanOffs,sampleOffA[chan[c.chan].sample]>>16);
|
||||
int end=sampleOffA[chan[c.chan].sample]+s->lengthA-1;
|
||||
immWrite(0x120+c.chan-adpcmAChanOffs,(end>>8)&0xff);
|
||||
immWrite(0x128+c.chan-adpcmAChanOffs,end>>16);
|
||||
immWrite(0x108+c.chan-adpcmAChanOffs,isMuted[c.chan]?0:((chan[c.chan].pan<<6)|chan[c.chan].outVol));
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].note=c.value;
|
||||
chan[c.chan].baseFreq=NOTE_ADPCMB(chan[c.chan].note);
|
||||
chan[c.chan].freqChanged=true;
|
||||
}
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
} else {
|
||||
assert(false && "LEGACY SAMPLE MODE!!!");
|
||||
writeADPCMAOff|=(1<<(c.chan-adpcmAChanOffs));
|
||||
immWrite(0x110+c.chan-adpcmAChanOffs,0);
|
||||
immWrite(0x118+c.chan-adpcmAChanOffs,0);
|
||||
immWrite(0x120+c.chan-adpcmAChanOffs,0);
|
||||
immWrite(0x128+c.chan-adpcmAChanOffs,0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -1342,7 +1321,6 @@ int DivPlatformYM2610B::dispatch(DivCommand c) {
|
|||
break;
|
||||
}
|
||||
case DIV_CMD_PITCH: {
|
||||
if (c.chan==adpcmBChanOffs && !chan[c.chan].furnacePCM) break;
|
||||
chan[c.chan].pitch=c.value;
|
||||
chan[c.chan].freqChanged=true;
|
||||
break;
|
||||
|
|
@ -1398,7 +1376,6 @@ int DivPlatformYM2610B::dispatch(DivCommand c) {
|
|||
break;
|
||||
}
|
||||
case DIV_CMD_LEGATO: {
|
||||
if (c.chan==adpcmBChanOffs && !chan[c.chan].furnacePCM) break;
|
||||
if (c.chan==csmChan) {
|
||||
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -164,7 +164,6 @@
|
|||
ImGui::Text("- pan: %x",ch->pan); \
|
||||
ImGui::Text("- opMask: %x",ch->opMask); \
|
||||
COMMON_CHAN_DEBUG_BOOL; \
|
||||
ImGui::TextColored(ch->furnaceDac?colorOn:colorOff,">> FurnaceDAC"); \
|
||||
ImGui::TextColored(ch->hardReset?colorOn:colorOff,">> hardReset"); \
|
||||
ImGui::TextColored(ch->opMaskChanged?colorOn:colorOff,">> opMaskChanged"); \
|
||||
ImGui::TextColored(ch->dacMode?colorOn:colorOff,">> DACMode"); \
|
||||
|
|
@ -201,7 +200,6 @@
|
|||
COMMON_CHAN_DEBUG_BOOL; \
|
||||
ImGui::TextColored(ch->hardReset?colorOn:colorOff,">> hardReset"); \
|
||||
ImGui::TextColored(ch->opMaskChanged?colorOn:colorOff,">> opMaskChanged"); \
|
||||
ImGui::TextColored(ch->furnacePCM?colorOn:colorOff,">> FurnacePCM");
|
||||
|
||||
#define OPN_OPCHAN_DEBUG \
|
||||
DivPlatformOPN::OPNOpChannel* ch=(DivPlatformOPN::OPNOpChannel*)data; \
|
||||
|
|
@ -227,7 +225,6 @@
|
|||
COMMON_CHAN_DEBUG_BOOL; \
|
||||
ImGui::TextColored(ch->hardReset?colorOn:colorOff,">> hardReset"); \
|
||||
ImGui::TextColored(ch->opMaskChanged?colorOn:colorOff,">> opMaskChanged"); \
|
||||
ImGui::TextColored(ch->furnacePCM?colorOn:colorOff,">> FurnacePCM");
|
||||
|
||||
#define OPNB_OPCHAN_DEBUG \
|
||||
ImGui::Text("- freqHL: %.2x%.2x",ch->freqH,ch->freqL); \
|
||||
|
|
@ -697,7 +694,6 @@ void putDispatchChan(void* data, int chanNum, int type) {
|
|||
COMMON_CHAN_DEBUG_BOOL;
|
||||
ImGui::TextColored(ch->noise?colorOn:colorOff,">> Noise");
|
||||
ImGui::TextColored(ch->pcm?colorOn:colorOff,">> DAC");
|
||||
ImGui::TextColored(ch->furnaceDac?colorOn:colorOff,">> FurnaceDAC");
|
||||
break;
|
||||
}
|
||||
case DIV_SYSTEM_NES: {
|
||||
|
|
@ -709,7 +705,6 @@ void putDispatchChan(void* data, int chanNum, int type) {
|
|||
ImGui::Text("- sweep: %.2x",ch->sweep);
|
||||
COMMON_CHAN_DEBUG_BOOL;
|
||||
ImGui::TextColored(ch->sweepChanged?colorOn:colorOff,">> SweepChanged");
|
||||
ImGui::TextColored(ch->furnaceDac?colorOn:colorOff,">> FurnaceDAC");
|
||||
break;
|
||||
}
|
||||
case DIV_SYSTEM_C64_6581: case DIV_SYSTEM_C64_8580: {
|
||||
|
|
@ -760,7 +755,6 @@ void putDispatchChan(void* data, int chanNum, int type) {
|
|||
ImGui::Text("- chPanR: %.2x",ch->chPanR);
|
||||
ImGui::Text("- macroVolMul: %.2x",ch->macroVolMul);
|
||||
COMMON_CHAN_DEBUG_BOOL;
|
||||
ImGui::TextColored(ch->furnacePCM?colorOn:colorOff,">> FurnacePCM");
|
||||
ImGui::TextColored(ch->isNewSegaPCM?colorOn:colorOff,">> IsNewSegaPCM");
|
||||
break;
|
||||
}
|
||||
|
|
@ -777,7 +771,6 @@ void putDispatchChan(void* data, int chanNum, int type) {
|
|||
ImGui::Text("- autoEnvNum: %.2x",ch->autoEnvNum);
|
||||
ImGui::Text("- autoEnvDen: %.2x",ch->autoEnvDen);
|
||||
COMMON_CHAN_DEBUG_BOOL;
|
||||
ImGui::TextColored(ch->dac.furnaceDAC?colorOn:colorOff,">> furnaceDAC");
|
||||
break;
|
||||
}
|
||||
case DIV_SYSTEM_AY8930: {
|
||||
|
|
@ -794,7 +787,6 @@ void putDispatchChan(void* data, int chanNum, int type) {
|
|||
ImGui::Text("- autoEnvNum: %.2x",ch->autoEnvNum);
|
||||
ImGui::Text("- autoEnvDen: %.2x",ch->autoEnvDen);
|
||||
COMMON_CHAN_DEBUG_BOOL;
|
||||
ImGui::TextColored(ch->dac.furnaceDAC?colorOn:colorOff,">> furnaceDAC");
|
||||
break;
|
||||
}
|
||||
case DIV_SYSTEM_QSOUND: {
|
||||
|
|
@ -831,7 +823,6 @@ void putDispatchChan(void* data, int chanNum, int type) {
|
|||
ImGui::Text("- Rvol: %.2x",ch->rvol);
|
||||
COMMON_CHAN_DEBUG_BOOL;
|
||||
ImGui::TextColored(ch->envChanged?colorOn:colorOff,">> EnvChanged");
|
||||
ImGui::TextColored(ch->furnacePCM?colorOn:colorOff,">> FurnacePCM");
|
||||
ImGui::TextColored(ch->pcm?colorOn:colorOff,">> PCM");
|
||||
ImGui::TextColored(ch->env.flag.envEnable?colorOn:colorOff,">> EnvEnable");
|
||||
ImGui::TextColored(ch->env.flag.envOneshot?colorOn:colorOff,">> EnvOneshot");
|
||||
|
|
@ -870,7 +861,6 @@ void putDispatchChan(void* data, int chanNum, int type) {
|
|||
ImGui::Text("- duty: %d",ch->duty);
|
||||
COMMON_CHAN_DEBUG_BOOL;
|
||||
ImGui::TextColored(ch->pcm?colorOn:colorOff,">> DAC");
|
||||
ImGui::TextColored(ch->furnaceDac?colorOn:colorOff,">> FurnaceDAC");
|
||||
break;
|
||||
}
|
||||
case DIV_SYSTEM_ES5506: {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue