Merge branch 'master' of https://github.com/tildearrow/furnace into es5506_alt
* 'master' of https://github.com/tildearrow/furnace: (77 commits) GUI: use pattern font for input latch GUI: partially implement note input latch UI GUI: transpose value does not transpose effect ID GUI: prepare for note input latch UI GUI: min ins selector width fix GUI: separate operation masks GUI: add missing FDS preset GUI: prepare for separate operation mask GUI: "none" instrument should not remove inscolumn GUI: fix ins 0 being inserted on blank song GUI: add a "none" option to instrument list update to-do list GUI: add "absorb" instrument input mode use good default instrument when adding ins better default instrument for OPL/OPLL GUI: fix selection being visible in dummy row area Further fix looped sample preview GUI: fix about screen in power saving mode VRC6: saw volume 63 GUI: add an effect list window ... # Conflicts: # src/engine/platform/amiga.cpp # src/engine/vgmOps.cpp # src/gui/dataList.cpp # src/gui/guiConst.cpp # src/gui/insEdit.cpp # src/gui/sampleEdit.cpp
This commit is contained in:
commit
49a41ff862
116 changed files with 2535 additions and 993 deletions
|
|
@ -23,7 +23,7 @@
|
|||
#include <math.h>
|
||||
#include <map>
|
||||
|
||||
#define CHIP_FREQBASE (16*2048)
|
||||
#define CHIP_FREQBASE (16*2048*(chanMax+1))
|
||||
#define NOTE_ES5506(c,note) (chan[c].pcm.freqOffs*NOTE_FREQUENCY(note))
|
||||
|
||||
#define rWrite(a,...) {if(!skipRegisterWrites) {hostIntf32.emplace(4,(a),__VA_ARGS__); }}
|
||||
|
|
@ -106,14 +106,40 @@ const char** DivPlatformES5506::getRegisterSheet() {
|
|||
const char* DivPlatformES5506::getEffectName(unsigned char effect) {
|
||||
switch (effect) {
|
||||
case 0x10:
|
||||
return "10xx: Set echo feedback level (00 to FF)";
|
||||
return "10xx: Change waveform";
|
||||
break;
|
||||
case 0x11:
|
||||
return "11xx: Set channel echo level (00 to FF)";
|
||||
return "11xx: Set filter mode (00 to 03)";
|
||||
break;
|
||||
case 0x20:
|
||||
return "20xx: Set envelope count (000 to 0FF)";
|
||||
break;
|
||||
case 0x21:
|
||||
return "21xx: Set envelope count (100 to 1FF)";
|
||||
break;
|
||||
case 0x22:
|
||||
return "22xx: Set envelope left volume ramp (signed)";
|
||||
break;
|
||||
case 0x23:
|
||||
return "23xx: Set envelope right volume ramp (signed)";
|
||||
break;
|
||||
case 0x24:
|
||||
return "24xx: Set envelope k1 ramp (signed)";
|
||||
break;
|
||||
case 0x25:
|
||||
return "25xx: Set envelope k1 ramp (signed, slower)";
|
||||
break;
|
||||
case 0x26:
|
||||
return "26xx: Set envelope k2 ramp (signed)";
|
||||
break;
|
||||
case 0x27:
|
||||
return "27xx: Set envelope k2 ramp (signed, slower)";
|
||||
break;
|
||||
default:
|
||||
if ((effect & 0xf0) == 0x30) {
|
||||
return "3xxx: Set echo delay buffer length (000 to AA5)";
|
||||
if ((effect&0xf0)==0x30) {
|
||||
return "3xxx: Set filter K1";
|
||||
} else if ((effect&0xf0)==0x40) {
|
||||
return "4xxx: Set filter K2";
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
|
@ -190,9 +216,9 @@ void DivPlatformES5506::e(bool state)
|
|||
irqTrigger=false;
|
||||
if ((irqv&0x80)==0) {
|
||||
unsigned char ch=irqv&0x1f;
|
||||
if (chan[ch].isReversed) { // Reversed loop
|
||||
pageWriteMask(0x00|ch,0x5f,0x00,0x48,0x78);
|
||||
chan[ch].isReversed=false;
|
||||
if (chan[ch].isReverseLoop) { // Reversed loop
|
||||
pageWriteMask(0x00|ch,0x5f,0x00,(chan[ch].pcm.reversed?0x0040:0x0000)|0x08,0x78);
|
||||
chan[ch].isReverseLoop=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -204,7 +230,7 @@ void DivPlatformES5506::irqb(bool state) {
|
|||
irqTrigger=true;
|
||||
}
|
||||
|
||||
void DivPlatformES5506::tick() {
|
||||
void DivPlatformES5506::tick(bool sysTick) {
|
||||
for (int i=0; i<=chanMax; i++) {
|
||||
chan[i].std.next();
|
||||
DivInstrument* ins=parent->getIns(chan[i].ins);
|
||||
|
|
@ -252,6 +278,104 @@ void DivPlatformES5506::tick() {
|
|||
chan[i].keyOn=true;
|
||||
}
|
||||
}
|
||||
// filter macros
|
||||
if (chan[i].std.duty.had) {
|
||||
if (chan[i].filter.mode!=DivInstrumentES5506::Filter::FilterMode(chan[i].std.duty.val&3)) {
|
||||
chan[i].filter.mode=DivInstrumentES5506::Filter::FilterMode(chan[i].std.duty.val&3);
|
||||
chan[i].filterChanged.mode=1;
|
||||
}
|
||||
}
|
||||
if (chan[i].std.ex1.had) {
|
||||
switch (chan[i].std.ex1.mode) {
|
||||
case 0: // relative
|
||||
if (chan[i].k1Offs!=chan[i].std.ex1.val) {
|
||||
chan[i].k1Offs=chan[i].std.ex1.val;
|
||||
chan[i].filterChanged.k1=1;
|
||||
}
|
||||
case 1: // absolute
|
||||
if (chan[i].filter.k1!=(chan[i].std.ex1.val&0xffff)) {
|
||||
chan[i].filter.k1=chan[i].std.ex1.val&0xffff;
|
||||
chan[i].filterChanged.k1=1;
|
||||
}
|
||||
break;
|
||||
case 2: { // delta
|
||||
signed int next_k1=MAX(0,MIN(65535,chan[i].filter.k1+chan[i].std.ex1.val));
|
||||
if (chan[i].filter.k1!=next_k1) {
|
||||
chan[i].filter.k1=next_k1;
|
||||
chan[i].filterChanged.k1=1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (chan[i].std.ex2.had) {
|
||||
switch (chan[i].std.ex2.mode) {
|
||||
case 0: // relative
|
||||
if (chan[i].k2Offs!=chan[i].std.ex1.val) {
|
||||
chan[i].k2Offs=chan[i].std.ex1.val;
|
||||
chan[i].filterChanged.k2=1;
|
||||
}
|
||||
case 1: // absolute
|
||||
if (chan[i].filter.k2!=(chan[i].std.ex2.val&0xffff)) {
|
||||
chan[i].filter.k2=chan[i].std.ex2.val&0xffff;
|
||||
chan[i].filterChanged.k2=1;
|
||||
}
|
||||
break;
|
||||
case 2: { // delta
|
||||
signed int next_k2=MAX(0,MIN(65535,chan[i].filter.k2+chan[i].std.ex2.val));
|
||||
if (chan[i].filter.k2!=next_k2) {
|
||||
chan[i].filter.k2=next_k2;
|
||||
chan[i].filterChanged.k2=1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// envelope macros
|
||||
if (chan[i].std.ex3.had) {
|
||||
if (chan[i].envelope.ecount!=(chan[i].std.ex3.val&0x1ff)) {
|
||||
chan[i].envelope.ecount=chan[i].std.ex3.val&0x1ff;
|
||||
chan[i].envChanged.ecount=1;
|
||||
}
|
||||
}
|
||||
if (chan[i].std.ex4.had) {
|
||||
if (chan[i].envelope.lVRamp!=chan[i].std.ex4.val) {
|
||||
chan[i].envelope.lVRamp=chan[i].std.ex4.val;
|
||||
chan[i].envChanged.lVRamp=1;
|
||||
}
|
||||
}
|
||||
if (chan[i].std.ex5.had) {
|
||||
if (chan[i].envelope.rVRamp!=chan[i].std.ex5.val) {
|
||||
chan[i].envelope.rVRamp=chan[i].std.ex5.val;
|
||||
chan[i].envChanged.rVRamp=1;
|
||||
}
|
||||
}
|
||||
if (chan[i].std.ex6.had) {
|
||||
if (chan[i].envelope.k1Ramp!=chan[i].std.ex6.val) {
|
||||
chan[i].envelope.k1Ramp=chan[i].std.ex6.val;
|
||||
chan[i].envChanged.k1Ramp=1;
|
||||
}
|
||||
}
|
||||
if (chan[i].std.ex7.had) {
|
||||
if (chan[i].envelope.k2Ramp!=chan[i].std.ex7.val) {
|
||||
chan[i].envelope.k2Ramp=chan[i].std.ex7.val;
|
||||
chan[i].envChanged.k2Ramp=1;
|
||||
}
|
||||
}
|
||||
if (chan[i].std.ex8.had) {
|
||||
if (chan[i].envelope.k1Slow!=(chan[i].std.ex8.val&1)) {
|
||||
chan[i].envelope.k1Slow=chan[i].std.ex8.val&1;
|
||||
chan[i].envChanged.k1Ramp=1;
|
||||
}
|
||||
if (chan[i].envelope.k2Slow!=(chan[i].std.ex8.val&2)) {
|
||||
chan[i].envelope.k2Slow=chan[i].std.ex8.val&2;
|
||||
chan[i].envChanged.k2Ramp=1;
|
||||
}
|
||||
}
|
||||
// update registers
|
||||
if (chan[i].volChanged) {
|
||||
if (!isMuted[i]) { // calculate volume (16 bit)
|
||||
|
|
@ -267,72 +391,96 @@ void DivPlatformES5506::tick() {
|
|||
}
|
||||
chan[i].volChanged=false;
|
||||
}
|
||||
if (chan[i].filterChanged) {
|
||||
pageWriteMask(0x00|i,0x5f,0x00,(chan[i].filter.mode<<8),0x0300);
|
||||
if (chan[i].filterChanged.changed) {
|
||||
if (!chan[i].keyOn) {
|
||||
pageWrite(0x00|i,0x07,chan[i].filter.k2);
|
||||
pageWrite(0x00|i,0x09,chan[i].filter.k1);
|
||||
if (chan[i].filterChanged.mode) {
|
||||
pageWriteMask(0x00|i,0x5f,0x00,(chan[i].filter.mode<<8),0x0300);
|
||||
}
|
||||
if (chan[i].filterChanged.k2) {
|
||||
if (chan[i].std.ex2.mode==0) { // Relative
|
||||
pageWrite(0x00|i,0x07,MAX(0,MIN(65535,chan[i].filter.k2+chan[i].k2Offs)));
|
||||
} else {
|
||||
pageWrite(0x00|i,0x07,chan[i].filter.k2);
|
||||
}
|
||||
}
|
||||
if (chan[i].filterChanged.k1) {
|
||||
if (chan[i].std.ex1.mode==0) { // Relative
|
||||
pageWrite(0x00|i,0x09,MAX(0,MIN(65535,chan[i].filter.k1+chan[i].k1Offs)));
|
||||
} else {
|
||||
pageWrite(0x00|i,0x09,chan[i].filter.k1);
|
||||
}
|
||||
}
|
||||
}
|
||||
chan[i].filterChanged=false;
|
||||
chan[i].filterChanged.changed=0;
|
||||
}
|
||||
if (chan[i].envChanged) {
|
||||
if (chan[i].envChanged.changed) {
|
||||
if (!chan[i].keyOn) {
|
||||
pageWrite(0x00|i,0x06,chan[i].envelope.ecount);
|
||||
if (chan[i].envChanged.lVRamp) {
|
||||
pageWrite(0x00|i,0x03,((unsigned char)chan[i].envelope.lVRamp)<<8);
|
||||
}
|
||||
if (chan[i].envChanged.rVRamp) {
|
||||
pageWrite(0x00|i,0x05,((unsigned char)chan[i].envelope.rVRamp)<<8);
|
||||
}
|
||||
if (chan[i].envChanged.ecount) {
|
||||
pageWrite(0x00|i,0x06,chan[i].envelope.ecount);
|
||||
}
|
||||
if (chan[i].envChanged.k2Ramp) {
|
||||
pageWrite(0x00|i,0x08,(((unsigned char)chan[i].envelope.k2Ramp)<<8)|(chan[i].envelope.k2Slow?1:0));
|
||||
}
|
||||
if (chan[i].envChanged.k1Ramp) {
|
||||
pageWrite(0x00|i,0x0a,(((unsigned char)chan[i].envelope.k1Ramp)<<8)|(chan[i].envelope.k1Slow?1:0));
|
||||
}
|
||||
}
|
||||
chan[i].envChanged=false;
|
||||
}
|
||||
if (chan[i].rampChanged) {
|
||||
if (!chan[i].keyOn) {
|
||||
pageWrite(0x00|i,0x03,((unsigned char)chan[i].envelope.lVRamp)<<8);
|
||||
pageWrite(0x00|i,0x05,((unsigned char)chan[i].envelope.rVRamp)<<8);
|
||||
pageWrite(0x00|i,0x0a,(((unsigned char)chan[i].envelope.k1Ramp)<<8)|(chan[i].envelope.k1Slow?1:0));
|
||||
pageWrite(0x00|i,0x08,(((unsigned char)chan[i].envelope.k2Ramp)<<8)|(chan[i].envelope.k2Slow?1:0));
|
||||
}
|
||||
chan[i].rampChanged=false;
|
||||
chan[i].envChanged.changed=0;
|
||||
}
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq*(chanMax+1),chan[i].pitch,false)+chan[i].std.pitch.val;
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false)+chan[i].std.pitch.val;
|
||||
if (chan[i].freq<0) chan[i].freq=0;
|
||||
if (chan[i].freq>0x1ffff) chan[i].freq=0x1ffff;
|
||||
if (chan[i].keyOn) {
|
||||
if (chan[i].pcm.index>=0) {
|
||||
pageWriteMask(0x00|i,0x5f,0x00,0x0303); // Wipeout CR
|
||||
pageWrite(0x00|i,0x06,0); // Clear ECOUNT
|
||||
pageWrite(0x20|i,0x03,chan[i].pcm.base); // Set ACCUM to start address
|
||||
pageWrite(0x00|i,0x09,0xffff); // Set K1 and K2 to 0xffff
|
||||
pageWrite(0x00|i,0x07,0xffff,~0,(chanMax+1)*4*2); // needs to 4 sample period delay
|
||||
pageWrite(0x20|i,0x03,chan[i].pcm.reversed?chan[i].pcm.end:chan[i].pcm.start); // Set ACCUM to start address
|
||||
pageWrite(0x00|i,0x07,0xffff); // Set K1 and K2 to 0xffff
|
||||
pageWrite(0x00|i,0x09,0xffff);
|
||||
pageWrite(0x00|i,0x01,chan[i].freq);
|
||||
if (chan[i].pcm.loopMode!=DIV_SAMPLE_LOOPMODE_ONESHOT) {
|
||||
pageWrite(0x20|i,0x01,chan[i].pcm.loopStart);
|
||||
}
|
||||
pageWrite(0x20|i,0x02,chan[i].pcm.loopEnd);
|
||||
pageWrite(0x20|i,0x01,(chan[i].pcm.loopMode==DIV_SAMPLE_LOOPMODE_ONESHOT)?chan[i].pcm.start:chan[i].pcm.loopStart);
|
||||
pageWrite(0x20|i,0x02,(chan[i].pcm.loopMode==DIV_SAMPLE_LOOPMODE_ONESHOT)?chan[i].pcm.end:chan[i].pcm.loopEnd);
|
||||
// initialize envelope
|
||||
pageWrite(0x00|i,0x03,((unsigned char)chan[i].envelope.lVRamp)<<8);
|
||||
pageWrite(0x00|i,0x05,((unsigned char)chan[i].envelope.rVRamp)<<8);
|
||||
pageWrite(0x00|i,0x0a,(((unsigned char)chan[i].envelope.k1Ramp)<<8)|(chan[i].envelope.k1Slow?1:0));
|
||||
pageWrite(0x00|i,0x08,(((unsigned char)chan[i].envelope.k2Ramp)<<8)|(chan[i].envelope.k2Slow?1:0));
|
||||
pageWrite(0x00|i,0x08,(((unsigned char)chan[i].envelope.k2Ramp)<<8)|(chan[i].envelope.k2Slow?1:0),~0,(chanMax+1)*4*2); // needs to 4 sample period delay
|
||||
// initialize filter
|
||||
pageWriteMask(0x00|i,0x5f,0x00,(chan[i].pcm.bank<<14)|(chan[i].filter.mode<<8),0xc300);
|
||||
pageWrite(0x00|i,0x09,chan[i].filter.k1);
|
||||
pageWrite(0x00|i,0x07,chan[i].filter.k2);
|
||||
if ((chan[i].std.ex2.mode==0) && (chan[i].std.ex2.had)) {
|
||||
pageWrite(0x00|i,0x07,MAX(0,MIN(65535,chan[i].filter.k2+chan[i].k2Offs)));
|
||||
} else {
|
||||
pageWrite(0x00|i,0x07,chan[i].filter.k2);
|
||||
}
|
||||
if ((chan[i].std.ex1.mode==0) && (chan[i].std.ex1.had)) {
|
||||
pageWrite(0x00|i,0x09,MAX(0,MIN(65535,chan[i].filter.k1+chan[i].k1Offs)));
|
||||
} else {
|
||||
pageWrite(0x00|i,0x09,chan[i].filter.k1);
|
||||
}
|
||||
pageWrite(0x00|i,0x02,chan[i].resLVol);
|
||||
pageWrite(0x00|i,0x04,chan[i].resRVol);
|
||||
unsigned int loopFlag=0x0000;
|
||||
chan[i].isReversed=false;
|
||||
unsigned int loopFlag=chan[i].pcm.reversed?0x0040:0x0000;
|
||||
chan[i].isReverseLoop=false;
|
||||
switch (chan[i].pcm.loopMode) {
|
||||
case DIV_SAMPLE_LOOPMODE_ONESHOT: // One shot (no loop)
|
||||
default:
|
||||
loopFlag=0x0000;
|
||||
break;
|
||||
case DIV_SAMPLE_LOOPMODE_FOWARD: // Foward loop
|
||||
loopFlag=0x0008;
|
||||
loopFlag|=0x0008;
|
||||
break;
|
||||
case DIV_SAMPLE_LOOPMODE_BACKWARD: // Backward loop: IRQ enable
|
||||
loopFlag=0x0038;
|
||||
chan[i].isReversed=true;
|
||||
loopFlag|=0x0038;
|
||||
chan[i].isReverseLoop=true;
|
||||
break;
|
||||
case DIV_SAMPLE_LOOPMODE_PINGPONG: // Pingpong loop: Hardware support
|
||||
loopFlag=0x0018;
|
||||
loopFlag|=0x0018;
|
||||
break;
|
||||
}
|
||||
// Run sample
|
||||
|
|
@ -341,7 +489,7 @@ void DivPlatformES5506::tick() {
|
|||
}
|
||||
}
|
||||
if (chan[i].keyOff) {
|
||||
pageWriteMask(0x00|i,0x5f,0x00,0x0003); // Wipeout CR
|
||||
pageWriteMask(0x00|i,0x5f,0x00,0x0303); // Wipeout CR
|
||||
} else if (chan[i].active) {
|
||||
pageWrite(0x00|i,0x01,chan[i].freq);
|
||||
}
|
||||
|
|
@ -356,30 +504,38 @@ int DivPlatformES5506::dispatch(DivCommand c) {
|
|||
switch (c.cmd) {
|
||||
case DIV_CMD_NOTE_ON: {
|
||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins);
|
||||
chan[c.chan].sample=ins->amiga.useNoteMap?ins->amiga.noteMap[c.value].ind:ins->amiga.initSample;
|
||||
double off=1.0;
|
||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||
chan[c.chan].pcm.index=chan[c.chan].sample;
|
||||
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
if (s->centerRate<1) {
|
||||
off=1.0;
|
||||
if (chan[c.chan].insChanged) {
|
||||
chan[c.chan].sample=ins->amiga.useNoteMap?ins->amiga.noteMap[c.value].ind:ins->amiga.initSample;
|
||||
double off=1.0;
|
||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||
chan[c.chan].pcm.index=chan[c.chan].sample;
|
||||
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||
if (s->centerRate<1) {
|
||||
off=1.0;
|
||||
} else {
|
||||
off=ins->amiga.useNoteMap?((double)ins->amiga.noteMap[c.value].freq/((double)s->centerRate*pow(2.0,((double)c.value-48.0)/12.0))):((double)s->centerRate/8363.0);
|
||||
}
|
||||
const unsigned int start=s->offES5506<<10;
|
||||
const unsigned int length=s->samples-1;
|
||||
const unsigned int end=start+(length<<11);
|
||||
chan[c.chan].pcm.loopMode=s->isLoopable()?s->loopMode:DIV_SAMPLE_LOOPMODE_ONESHOT;
|
||||
chan[c.chan].pcm.freqOffs=off;
|
||||
chan[c.chan].pcm.reversed=ins->amiga.reversed;
|
||||
chan[c.chan].pcm.bank=(s->offES5506>>22)&3;
|
||||
chan[c.chan].pcm.start=start;
|
||||
chan[c.chan].pcm.end=end;
|
||||
chan[c.chan].pcm.length=length;
|
||||
chan[c.chan].pcm.loopStart=(start+(s->loopStart<<11))&0xfffff800;
|
||||
chan[c.chan].pcm.loopEnd=(start+((s->loopEnd-1)<<11))&0xffffff80;
|
||||
chan[c.chan].filter=ins->es5506.filter;
|
||||
chan[c.chan].envelope=ins->es5506.envelope;
|
||||
} else {
|
||||
off=ins->amiga.useNoteMap?((double)ins->amiga.noteMap[c.value].freq/((double)s->centerRate*pow(2.0,((double)c.value-48.0)/12.0))):((double)s->centerRate/8363.0);
|
||||
chan[c.chan].sample=-1;
|
||||
chan[c.chan].pcm.index=-1;
|
||||
chan[c.chan].filter=DivInstrumentES5506::Filter();
|
||||
chan[c.chan].envelope=DivInstrumentES5506::Envelope();
|
||||
}
|
||||
unsigned int base=s->offES5506<<10;
|
||||
chan[c.chan].pcm.loopMode=s->isLoopable()?s->loopMode:DIV_SAMPLE_LOOPMODE_ONESHOT;
|
||||
chan[c.chan].pcm.freqOffs=off;
|
||||
chan[c.chan].pcm.bank=(s->offES5506>>22)&3;
|
||||
chan[c.chan].pcm.base=base;
|
||||
chan[c.chan].pcm.loopStart=(base+(s->loopStart<<11))&0xfffff800;
|
||||
chan[c.chan].pcm.loopEnd=((base+(s->loopEnd<<11))-0x800)&0xffffff80;
|
||||
chan[c.chan].filter=ins->es5506.filter;
|
||||
chan[c.chan].envelope=ins->es5506.envelope;
|
||||
} else {
|
||||
chan[c.chan].sample=-1;
|
||||
chan[c.chan].pcm.index=-1;
|
||||
chan[c.chan].filter=DivInstrumentES5506::Filter();
|
||||
chan[c.chan].envelope=DivInstrumentES5506::Envelope();
|
||||
chan[c.chan].insChanged=false;
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].baseFreq=NOTE_ES5506(c.chan,c.value);
|
||||
|
|
@ -466,6 +622,45 @@ int DivPlatformES5506::dispatch(DivCommand c) {
|
|||
chan[c.chan].pitch=c.value;
|
||||
chan[c.chan].freqChanged=true;
|
||||
break;
|
||||
case DIV_CMD_WAVE:
|
||||
// reserved for useWave
|
||||
break;
|
||||
// Filter commands
|
||||
case DIV_CMD_ES5506_FILTER_MODE:
|
||||
chan[c.chan].filter.mode=DivInstrumentES5506::Filter::FilterMode(c.value&3);
|
||||
chan[c.chan].filterChanged.mode=1;
|
||||
break;
|
||||
case DIV_CMD_ES5506_FILTER_K1:
|
||||
chan[c.chan].filter.k1=(chan[c.chan].filter.k1&0xf)|((c.value&0xfff)<<4);
|
||||
chan[c.chan].filterChanged.k1=1;
|
||||
break;
|
||||
case DIV_CMD_ES5506_FILTER_K2:
|
||||
chan[c.chan].filter.k2=(chan[c.chan].filter.k2&0xf)|((c.value&0xfff)<<4);
|
||||
chan[c.chan].filterChanged.k2=1;
|
||||
break;
|
||||
// Envelope commands
|
||||
case DIV_CMD_ES5506_ENVELOPE_COUNT:
|
||||
chan[c.chan].envelope.ecount=c.value&0x1ff;
|
||||
chan[c.chan].envChanged.ecount=1;
|
||||
break;
|
||||
case DIV_CMD_ES5506_ENVELOPE_LVRAMP:
|
||||
chan[c.chan].envelope.lVRamp=(signed char)(c.value&0xff);
|
||||
chan[c.chan].envChanged.lVRamp=1;
|
||||
break;
|
||||
case DIV_CMD_ES5506_ENVELOPE_RVRAMP:
|
||||
chan[c.chan].envelope.rVRamp=(signed char)(c.value&0xff);
|
||||
chan[c.chan].envChanged.rVRamp=1;
|
||||
break;
|
||||
case DIV_CMD_ES5506_ENVELOPE_K1RAMP:
|
||||
chan[c.chan].envelope.k1Ramp=(signed char)(c.value&0xff);
|
||||
chan[c.chan].envelope.k1Slow=c.value2&1;
|
||||
chan[c.chan].envChanged.k1Ramp=1;
|
||||
break;
|
||||
case DIV_CMD_ES5506_ENVELOPE_K2RAMP:
|
||||
chan[c.chan].envelope.k2Ramp=(signed char)(c.value&0xff);
|
||||
chan[c.chan].envelope.k2Slow=c.value2&1;
|
||||
chan[c.chan].envChanged.k2Ramp=1;
|
||||
break;
|
||||
case DIV_CMD_NOTE_PORTA: {
|
||||
int destFreq=NOTE_ES5506(c.chan,c.value2);
|
||||
bool return2=false;
|
||||
|
|
@ -501,6 +696,16 @@ int DivPlatformES5506::dispatch(DivCommand c) {
|
|||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
case DIV_CMD_SAMPLE_POS: {
|
||||
if (chan[c.chan].useWave) break;
|
||||
if (chan[c.chan].active) {
|
||||
unsigned int pos=chan[c.chan].pcm.reversed?(chan[c.chan].pcm.length-c.value):c.value;
|
||||
if ((chan[c.chan].pcm.reversed && pos>0) || ((!chan[c.chan].pcm.reversed) && pos<chan[c.chan].pcm.length)) {
|
||||
pageWrite(0x20|c.chan,0x03,chan[c.chan].pcm.start+(pos<<11));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_GET_VOLMAX:
|
||||
return 255;
|
||||
break;
|
||||
|
|
@ -523,6 +728,8 @@ void DivPlatformES5506::forceIns() {
|
|||
chan[i].insChanged=true;
|
||||
chan[i].freqChanged=true;
|
||||
chan[i].volChanged=true;
|
||||
chan[i].filterChanged.changed=(unsigned char)(~0);
|
||||
chan[i].envChanged.changed=(unsigned char)(~0);
|
||||
chan[i].sample=-1;
|
||||
}
|
||||
}
|
||||
|
|
@ -629,7 +836,7 @@ int DivPlatformES5506::init(DivEngine* p, int channels, int sugRate, unsigned in
|
|||
setFlags(flags);
|
||||
|
||||
chipClock=16000000;
|
||||
rate=chipClock/16;
|
||||
rate=chipClock/16; // 2 E clock tick (16 CLKIN tick) per voice
|
||||
reset();
|
||||
return 32;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue