mirror of
https://github.com/tildearrow/furnace.git
synced 2024-12-04 18:27:25 +00:00
Update ES5506:
Remove transwave for now - It consumes high CPU usage, so possibly little headroom for anything else. Fix per-voice OSC via git master Fix default channel for ES5506 Fix macro order - Filter macro must be executed after key on Add SSV preset
This commit is contained in:
parent
683abd8c69
commit
87cb3c49a4
10 changed files with 168 additions and 689 deletions
|
@ -73,8 +73,6 @@ enum DivDispatchCmds {
|
||||||
DIV_CMD_SAMPLE_BANK, // (bank)
|
DIV_CMD_SAMPLE_BANK, // (bank)
|
||||||
DIV_CMD_SAMPLE_POS, // (pos)
|
DIV_CMD_SAMPLE_POS, // (pos)
|
||||||
DIV_CMD_SAMPLE_DIR, // (direction)
|
DIV_CMD_SAMPLE_DIR, // (direction)
|
||||||
DIV_CMD_SAMPLE_TRANSWAVE_SLICE_MODE, // (enabled)
|
|
||||||
DIV_CMD_SAMPLE_TRANSWAVE_SLICE_POS, // (slice)
|
|
||||||
|
|
||||||
DIV_CMD_FM_HARD_RESET, // (enabled)
|
DIV_CMD_FM_HARD_RESET, // (enabled)
|
||||||
DIV_CMD_FM_LFO, // (speed)
|
DIV_CMD_FM_LFO, // (speed)
|
||||||
|
|
|
@ -361,65 +361,6 @@ struct DivInstrumentAmiga {
|
||||||
reversed(r) {}
|
reversed(r) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TransWaveSlice {
|
|
||||||
// states
|
|
||||||
double sliceSize;
|
|
||||||
double sliceBound;
|
|
||||||
double sliceStart;
|
|
||||||
double sliceEnd;
|
|
||||||
|
|
||||||
// inlines
|
|
||||||
inline void updateSize(double length, double loopStart, double loopEnd) {
|
|
||||||
sliceSize=loopEnd-loopStart;
|
|
||||||
sliceBound=(length-sliceSize);
|
|
||||||
}
|
|
||||||
inline double slicePos(double slice) {
|
|
||||||
double pos=sliceBound*slice;
|
|
||||||
if (sliceStart!=pos) {
|
|
||||||
sliceStart=pos;
|
|
||||||
}
|
|
||||||
if (sliceEnd!=(sliceSize+pos)) {
|
|
||||||
sliceEnd=(sliceSize+pos);
|
|
||||||
}
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
TransWaveSlice():
|
|
||||||
sliceSize(0),
|
|
||||||
sliceBound(0),
|
|
||||||
sliceStart(0),
|
|
||||||
sliceEnd(0) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TransWave: TransWaveSlice {
|
|
||||||
bool enable;
|
|
||||||
bool sliceEnable;
|
|
||||||
int ind;
|
|
||||||
unsigned short slice;
|
|
||||||
|
|
||||||
TransWave():
|
|
||||||
TransWaveSlice(),
|
|
||||||
enable(false),
|
|
||||||
sliceEnable(false),
|
|
||||||
ind(0),
|
|
||||||
slice(0) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TransWaveMap: TransWaveSlice {
|
|
||||||
short ind;
|
|
||||||
DivReverseMode reversed;
|
|
||||||
int loopStart, loopEnd;
|
|
||||||
DivSampleLoopMode loopMode;
|
|
||||||
|
|
||||||
TransWaveMap():
|
|
||||||
TransWaveSlice(),
|
|
||||||
ind(-1),
|
|
||||||
reversed(DivInstrumentAmiga::DivReverseMode::DIV_REVERSE_DEFAULT),
|
|
||||||
loopStart(-1),
|
|
||||||
loopEnd(-1),
|
|
||||||
loopMode(DIV_SAMPLE_LOOP_MAX) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
short initSample;
|
short initSample;
|
||||||
DivInstrumentAmiga::DivReverseMode reversed;
|
DivInstrumentAmiga::DivReverseMode reversed;
|
||||||
bool useNoteMap;
|
bool useNoteMap;
|
||||||
|
@ -427,8 +368,6 @@ struct DivInstrumentAmiga {
|
||||||
bool useWave;
|
bool useWave;
|
||||||
unsigned char waveLen;
|
unsigned char waveLen;
|
||||||
SampleMap noteMap[120];
|
SampleMap noteMap[120];
|
||||||
TransWave transWave;
|
|
||||||
std::vector<TransWaveMap> transWaveMap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the sample at specified note.
|
* get the sample at specified note.
|
||||||
|
@ -475,9 +414,7 @@ struct DivInstrumentAmiga {
|
||||||
useNoteMap(false),
|
useNoteMap(false),
|
||||||
useSample(false),
|
useSample(false),
|
||||||
useWave(false),
|
useWave(false),
|
||||||
waveLen(31),
|
waveLen(31) {
|
||||||
transWave(TransWave()),
|
|
||||||
transWaveMap(1) {
|
|
||||||
for (SampleMap& elem: noteMap) {
|
for (SampleMap& elem: noteMap) {
|
||||||
elem=SampleMap();
|
elem=SampleMap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,97 +206,6 @@ void DivPlatformES5506::e_pin(bool state) {
|
||||||
}
|
}
|
||||||
irqTrigger=false;
|
irqTrigger=false;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
unsigned char ch=w.state&0x1f;
|
|
||||||
if (chan[ch].transwaveIRQ) {
|
|
||||||
if ((chan[ch].cr&0x37)==0x34) { // IRQE = 1, BLE = 1, LPE = 0, LEI = 1
|
|
||||||
DivInstrument* ins=parent->getIns(chan[ch].ins);
|
|
||||||
if (!ins->amiga.useNoteMap && ins->amiga.transWave.enable) {
|
|
||||||
const int next=chan[ch].pcm.next;
|
|
||||||
if (next>=0 && next<(int)ins->amiga.transWaveMap.size()) {
|
|
||||||
DivInstrumentAmiga::TransWaveMap& transWaveInd=ins->amiga.transWaveMap[next];
|
|
||||||
int sample=transWaveInd.ind;
|
|
||||||
if (sample>=0 && sample<parent->song.sampleLen) {
|
|
||||||
const unsigned int offES5506=sampleOffES5506[sample];
|
|
||||||
chan[ch].pcm.index=sample;
|
|
||||||
chan[ch].transWave.ind=next;
|
|
||||||
DivSample* s=parent->getSample(sample);
|
|
||||||
// get frequency offset
|
|
||||||
double off=1.0;
|
|
||||||
double center=(double)s->centerRate;
|
|
||||||
if (center<1) {
|
|
||||||
off=1.0;
|
|
||||||
} else {
|
|
||||||
off=(double)center/8363.0;
|
|
||||||
}
|
|
||||||
// get loop mode, transwave loop
|
|
||||||
double loopStart=(double)s->loopStart;
|
|
||||||
double loopEnd=(double)s->loopEnd;
|
|
||||||
DivSampleLoopMode loopMode=s->isLoopable()?s->loopMode:DIV_SAMPLE_LOOP_MAX;
|
|
||||||
if (transWaveInd.loopMode!=DIV_SAMPLE_LOOP_MAX) {
|
|
||||||
loopMode=transWaveInd.loopMode;
|
|
||||||
} else if ((chan[ch].pcm.loopMode==DIV_SAMPLE_LOOP_MAX) || (!s->isLoopable())) { // default
|
|
||||||
loopMode=DIV_SAMPLE_LOOP_PINGPONG;
|
|
||||||
}
|
|
||||||
// get loop position
|
|
||||||
loopStart=(double)transWaveInd.loopStart;
|
|
||||||
loopEnd=(double)transWaveInd.loopEnd;
|
|
||||||
if (ins->amiga.transWave.sliceEnable) { // sliced loop position?
|
|
||||||
chan[ch].transWave.updateSize(s->samples,loopStart,loopEnd);
|
|
||||||
chan[ch].transWave.slicePos(double(chan[ch].transWave.slice)/4095.0);
|
|
||||||
loopStart=transWaveInd.sliceStart;
|
|
||||||
loopEnd=transWaveInd.sliceEnd;
|
|
||||||
}
|
|
||||||
// get reversed
|
|
||||||
bool reversed=ins->amiga.reversed;
|
|
||||||
if (transWaveInd.reversed!=DivInstrumentAmiga::DivReverseMode::DIV_REVERSE_DEFAULT) {
|
|
||||||
reversed=transWaveInd.reversed;
|
|
||||||
}
|
|
||||||
const unsigned int start=offES5506<<10;
|
|
||||||
const unsigned int length=s->samples-1;
|
|
||||||
const unsigned int end=start+(length<<11);
|
|
||||||
const double nextFreqOffs=PITCH_OFFSET*off;
|
|
||||||
chan[ch].pcm.loopMode=loopMode;
|
|
||||||
chan[ch].pcm.reversed=reversed;
|
|
||||||
chan[ch].pcm.bank=(offES5506>>22)&3;
|
|
||||||
chan[ch].pcm.start=start;
|
|
||||||
chan[ch].pcm.loopStart=(start+(unsigned int)(loopStart*2048.0))&0xfffff800;
|
|
||||||
chan[ch].pcm.loopEnd=(start+(unsigned int)((loopEnd-1.0)*2048.0))&0xffffff80;
|
|
||||||
chan[ch].pcm.end=end;
|
|
||||||
chan[ch].pcm.length=length;
|
|
||||||
pageWrite(0x20|ch,0x01,chan[ch].pcm.loopStart);
|
|
||||||
pageWrite(0x20|ch,0x02,chan[ch].pcm.loopEnd);
|
|
||||||
pageWrite(0x20|ch,0x03,(chan[ch].pcm.reversed)?chan[ch].pcm.loopEnd:chan[ch].pcm.loopStart);
|
|
||||||
unsigned int loopFlag=(chan[ch].pcm.bank<<14)|(chan[ch].pcm.reversed?0x0040:0x0000);
|
|
||||||
chan[ch].isReverseLoop=false;
|
|
||||||
switch (chan[ch].pcm.loopMode) {
|
|
||||||
case DIV_SAMPLE_LOOP_FORWARD: // Foward loop
|
|
||||||
loopFlag|=0x0008;
|
|
||||||
break;
|
|
||||||
case DIV_SAMPLE_LOOP_BACKWARD: // Backward loop: IRQ enable
|
|
||||||
loopFlag|=0x0038;
|
|
||||||
chan[ch].isReverseLoop=true;
|
|
||||||
break;
|
|
||||||
case DIV_SAMPLE_LOOP_PINGPONG: // Pingpong loop: Hardware support
|
|
||||||
loopFlag|=0x0018;
|
|
||||||
break;
|
|
||||||
case DIV_SAMPLE_LOOP_MAX: // no loop
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// Set loop mode & Bank
|
|
||||||
pageWriteMask(0x00|ch,0x5f,0x00,loopFlag,0xfcfc);
|
|
||||||
if (chan[ch].pcm.nextFreqOffs!=nextFreqOffs) {
|
|
||||||
chan[ch].pcm.nextFreqOffs=nextFreqOffs;
|
|
||||||
chan[ch].noteChanged.offs=1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
chan[ch].pcmChanged.changed=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
chan[ch].transwaveIRQ=false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
queuedReadState.pop();
|
queuedReadState.pop();
|
||||||
}
|
}
|
||||||
|
@ -306,11 +215,6 @@ void DivPlatformES5506::e_pin(bool state) {
|
||||||
pageWriteMask(0x00|ch,0x5f,0x00,(chan[ch].pcm.reversed?0x0000:0x0040)|0x08,0x78);
|
pageWriteMask(0x00|ch,0x5f,0x00,(chan[ch].pcm.reversed?0x0000:0x0040)|0x08,0x78);
|
||||||
chan[ch].isReverseLoop=false;
|
chan[ch].isReverseLoop=false;
|
||||||
}
|
}
|
||||||
if (chan[ch].isTranswave) {
|
|
||||||
pageReadMask(0x00|ch,0x5f,0x00,ch,&chan[ch].cr);
|
|
||||||
chan[ch].transwaveIRQ=true;
|
|
||||||
chan[ch].isTranswave=false;
|
|
||||||
}
|
|
||||||
queuedRead.pop();
|
queuedRead.pop();
|
||||||
}
|
}
|
||||||
isReaded=false;
|
isReaded=false;
|
||||||
|
@ -504,29 +408,7 @@ void DivPlatformES5506::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// transwave macros
|
if (chan[i].pcm.isNoteMap) {
|
||||||
if (chan[i].transWave.enable) {
|
|
||||||
if (chan[i].std.wave.had) {
|
|
||||||
if (chan[i].std.wave.val>=0 && chan[i].std.wave.val<(int)ins->amiga.transWaveMap.size()) {
|
|
||||||
if (chan[i].pcm.next!=chan[i].std.wave.val) {
|
|
||||||
chan[i].pcm.next=chan[i].std.wave.val;
|
|
||||||
chan[i].pcmChanged.transwaveInd=1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (chan[i].std.fb.had) {
|
|
||||||
if (chan[i].transWave.sliceEnable!=(bool)(chan[i].std.fb.val&1)) {
|
|
||||||
chan[i].transWave.sliceEnable=chan[i].std.fb.val&1;
|
|
||||||
chan[i].pcmChanged.slice=1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (chan[i].std.fms.had) {
|
|
||||||
if (chan[i].transWave.slice!=(unsigned short)(chan[i].std.fms.val&0xfff)) {
|
|
||||||
chan[i].transWave.slice=chan[i].std.fms.val&0xfff;
|
|
||||||
chan[i].pcmChanged.slice=1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (chan[i].pcm.isNoteMap) {
|
|
||||||
// note map macros
|
// note map macros
|
||||||
if (chan[i].std.wave.had) {
|
if (chan[i].std.wave.had) {
|
||||||
if (chan[i].std.wave.val>=0 && chan[i].std.wave.val<120) {
|
if (chan[i].std.wave.val>=0 && chan[i].std.wave.val<120) {
|
||||||
|
@ -536,7 +418,7 @@ void DivPlatformES5506::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!chan[i].transWave.enable && !chan[i].pcm.isNoteMap) {
|
} else if (!chan[i].pcm.isNoteMap) {
|
||||||
if (chan[i].std.wave.had) {
|
if (chan[i].std.wave.had) {
|
||||||
if (chan[i].std.wave.val>=0 && chan[i].std.wave.val<parent->song.sampleLen) {
|
if (chan[i].std.wave.val>=0 && chan[i].std.wave.val<parent->song.sampleLen) {
|
||||||
if (chan[i].pcm.next!=chan[i].std.wave.val) {
|
if (chan[i].pcm.next!=chan[i].std.wave.val) {
|
||||||
|
@ -551,13 +433,13 @@ void DivPlatformES5506::tick(bool sysTick) {
|
||||||
if (!isMuted[i]) { // calculate volume (16 bit)
|
if (!isMuted[i]) { // calculate volume (16 bit)
|
||||||
if (chan[i].volChanged.lVol) {
|
if (chan[i].volChanged.lVol) {
|
||||||
chan[i].resLVol=VOL_SCALE_LOG(chan[i].outVol,chan[i].outLVol,0xffff);
|
chan[i].resLVol=VOL_SCALE_LOG(chan[i].outVol,chan[i].outLVol,0xffff);
|
||||||
if (!chan[i].keyOn) {
|
if (!chan[i].keyOn && chan[i].active) {
|
||||||
pageWrite(0x00|i,0x02,chan[i].resLVol);
|
pageWrite(0x00|i,0x02,chan[i].resLVol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chan[i].volChanged.rVol) {
|
if (chan[i].volChanged.rVol) {
|
||||||
chan[i].resRVol=VOL_SCALE_LOG(chan[i].outVol,chan[i].outRVol,0xffff);
|
chan[i].resRVol=VOL_SCALE_LOG(chan[i].outVol,chan[i].outRVol,0xffff);
|
||||||
if (!chan[i].keyOn) {
|
if (!chan[i].keyOn && chan[i].active) {
|
||||||
pageWrite(0x00|i,0x04,chan[i].resRVol);
|
pageWrite(0x00|i,0x04,chan[i].resRVol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -568,75 +450,21 @@ void DivPlatformES5506::tick(bool sysTick) {
|
||||||
chan[i].volChanged.changed=0;
|
chan[i].volChanged.changed=0;
|
||||||
}
|
}
|
||||||
if (chan[i].pcmChanged.changed) {
|
if (chan[i].pcmChanged.changed) {
|
||||||
if (!chan[i].isTranswave) {
|
|
||||||
if (chan[i].pcmChanged.transwaveInd && (!ins->amiga.useNoteMap && ins->amiga.transWave.enable)) {
|
|
||||||
const int next=chan[i].pcm.next;
|
|
||||||
if (next>=0 && next<(int)ins->amiga.transWaveMap.size()) {
|
|
||||||
DivInstrumentAmiga::TransWaveMap& transWaveInd=ins->amiga.transWaveMap[next];
|
|
||||||
int sample=transWaveInd.ind;
|
|
||||||
if (sample>=0 && sample<parent->song.sampleLen) {
|
|
||||||
if (chan[i].pcm.index!=sample) {
|
|
||||||
pageWriteMask(0x00|i,0x5f,0x00,0x0034,0x00ff); // Set IRQ
|
|
||||||
chan[i].isTranswave=true;
|
|
||||||
} else {
|
|
||||||
chan[i].transWave.ind=next;
|
|
||||||
DivSample* s=parent->getSample(sample);
|
|
||||||
// get loop mode, transwave loop
|
|
||||||
double loopStart=(double)s->loopStart;
|
|
||||||
double loopEnd=(double)s->loopEnd;
|
|
||||||
DivSampleLoopMode loopMode=s->isLoopable()?s->loopMode:DIV_SAMPLE_LOOP_MAX;
|
|
||||||
if (transWaveInd.loopMode!=DIV_SAMPLE_LOOP_MAX) {
|
|
||||||
loopMode=transWaveInd.loopMode;
|
|
||||||
} else if ((chan[i].pcm.loopMode==DIV_SAMPLE_LOOP_MAX) || (!s->isLoopable())) { // default
|
|
||||||
loopMode=DIV_SAMPLE_LOOP_PINGPONG;
|
|
||||||
}
|
|
||||||
// get loop position
|
|
||||||
loopStart=(double)transWaveInd.loopStart;
|
|
||||||
loopEnd=(double)transWaveInd.loopEnd;
|
|
||||||
if (ins->amiga.transWave.sliceEnable) { // sliced loop position?
|
|
||||||
chan[i].transWave.updateSize(s->samples,loopStart,loopEnd);
|
|
||||||
chan[i].transWave.slicePos(double(chan[i].transWave.slice)/4095.0);
|
|
||||||
loopStart=transWaveInd.sliceStart;
|
|
||||||
loopEnd=transWaveInd.sliceEnd;
|
|
||||||
}
|
|
||||||
// get reversed
|
|
||||||
bool reversed=ins->amiga.reversed;
|
|
||||||
if (transWaveInd.reversed!=DivInstrumentAmiga::DivReverseMode::DIV_REVERSE_DEFAULT) {
|
|
||||||
reversed=transWaveInd.reversed;
|
|
||||||
}
|
|
||||||
chan[i].pcmChanged.slice=1;
|
|
||||||
if ((chan[i].pcm.loopMode!=loopMode) || (chan[i].pcm.reversed!=reversed)) {
|
|
||||||
chan[i].pcm.loopMode=loopMode;
|
|
||||||
chan[i].pcm.reversed=reversed;
|
|
||||||
chan[i].pcmChanged.loopBank=1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
chan[i].pcmChanged.transwaveInd=0;
|
|
||||||
}
|
|
||||||
if ((!chan[i].pcmChanged.transwaveInd) && (!chan[i].isTranswave)) {
|
|
||||||
if (chan[i].pcmChanged.index) {
|
if (chan[i].pcmChanged.index) {
|
||||||
const int next=chan[i].pcm.next;
|
const int next=chan[i].pcm.next;
|
||||||
bool sampleVaild=false;
|
bool sampleVaild=false;
|
||||||
if (((ins->amiga.useNoteMap && !ins->amiga.transWave.enable) && (next>=0 && next<120)) ||
|
if (((ins->amiga.useNoteMap) && (next>=0 && next<120)) ||
|
||||||
((!ins->amiga.useNoteMap && ins->amiga.transWave.enable) && (next>=0 && next<(int)ins->amiga.transWaveMap.size())) ||
|
((!ins->amiga.useNoteMap) && (next>=0 && next<parent->song.sampleLen))) {
|
||||||
((!ins->amiga.useNoteMap && !ins->amiga.transWave.enable) && (next>=0 && next<parent->song.sampleLen))) {
|
|
||||||
DivInstrumentAmiga::SampleMap& noteMapind=ins->amiga.noteMap[next];
|
DivInstrumentAmiga::SampleMap& noteMapind=ins->amiga.noteMap[next];
|
||||||
DivInstrumentAmiga::TransWaveMap& transWaveInd=ins->amiga.transWaveMap[next];
|
|
||||||
int sample=next;
|
int sample=next;
|
||||||
if (ins->amiga.transWave.enable) {
|
if (ins->amiga.useNoteMap) {
|
||||||
sample=transWaveInd.ind;
|
|
||||||
} else if (ins->amiga.useNoteMap) {
|
|
||||||
sample=noteMapind.map;
|
sample=noteMapind.map;
|
||||||
}
|
}
|
||||||
if (sample>=0 && sample<parent->song.sampleLen) {
|
if (sample>=0 && sample<parent->song.sampleLen) {
|
||||||
const unsigned int offES5506=sampleOffES5506[sample];
|
const unsigned int offES5506=sampleOffES5506[sample];
|
||||||
sampleVaild=true;
|
sampleVaild=true;
|
||||||
chan[i].pcm.index=sample;
|
chan[i].pcm.index=sample;
|
||||||
chan[i].pcm.isNoteMap=ins->amiga.useNoteMap && !ins->amiga.transWave.enable;
|
chan[i].pcm.isNoteMap=ins->amiga.useNoteMap;
|
||||||
chan[i].transWave.enable=!ins->amiga.useNoteMap && ins->amiga.transWave.enable;
|
|
||||||
chan[i].transWave.ind=next;
|
|
||||||
DivSample* s=parent->getSample(sample);
|
DivSample* s=parent->getSample(sample);
|
||||||
// get frequency offset
|
// get frequency offset
|
||||||
double off=1.0;
|
double off=1.0;
|
||||||
|
@ -650,31 +478,13 @@ void DivPlatformES5506::tick(bool sysTick) {
|
||||||
off*=(double)noteMapind.freq/((double)MAX(1,center)*pow(2.0,((double)next-48.0)/12.0));
|
off*=(double)noteMapind.freq/((double)MAX(1,center)*pow(2.0,((double)next-48.0)/12.0));
|
||||||
chan[i].pcm.note=next;
|
chan[i].pcm.note=next;
|
||||||
}
|
}
|
||||||
// get loop mode, transwave loop
|
// get loop mode
|
||||||
double loopStart=(double)s->loopStart;
|
double loopStart=(double)s->loopStart;
|
||||||
double loopEnd=(double)s->loopEnd;
|
double loopEnd=(double)s->loopEnd;
|
||||||
DivSampleLoopMode loopMode=s->isLoopable()?s->loopMode:DIV_SAMPLE_LOOP_MAX;
|
DivSampleLoopMode loopMode=s->isLoopable()?s->loopMode:DIV_SAMPLE_LOOP_MAX;
|
||||||
if (ins->amiga.transWave.enable) {
|
|
||||||
if (transWaveInd.loopMode!=DIV_SAMPLE_LOOP_MAX) {
|
|
||||||
loopMode=transWaveInd.loopMode;
|
|
||||||
} else if ((chan[i].pcm.loopMode==DIV_SAMPLE_LOOP_MAX) || (!s->isLoopable())) { // default
|
|
||||||
loopMode=DIV_SAMPLE_LOOP_PINGPONG;
|
|
||||||
}
|
|
||||||
// get loop position
|
|
||||||
loopStart=(double)transWaveInd.loopStart;
|
|
||||||
loopEnd=(double)transWaveInd.loopEnd;
|
|
||||||
if (ins->amiga.transWave.sliceEnable) { // sliced loop position?
|
|
||||||
chan[i].transWave.updateSize(s->samples,loopStart,loopEnd);
|
|
||||||
chan[i].transWave.slicePos(double(chan[i].transWave.slice)/4095.0);
|
|
||||||
loopStart=transWaveInd.sliceStart;
|
|
||||||
loopEnd=transWaveInd.sliceEnd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// get reversed
|
// get reversed
|
||||||
bool reversed=ins->amiga.reversed;
|
bool reversed=ins->amiga.reversed;
|
||||||
if (ins->amiga.transWave.enable&&transWaveInd.reversed!=DivInstrumentAmiga::DivReverseMode::DIV_REVERSE_DEFAULT) {
|
if (ins->amiga.useNoteMap&¬eMapind.reversed!=DivInstrumentAmiga::DivReverseMode::DIV_REVERSE_DEFAULT) {
|
||||||
reversed=transWaveInd.reversed;
|
|
||||||
} else if (ins->amiga.useNoteMap&¬eMapind.reversed!=DivInstrumentAmiga::DivReverseMode::DIV_REVERSE_DEFAULT) {
|
|
||||||
reversed=noteMapind.reversed;
|
reversed=noteMapind.reversed;
|
||||||
}
|
}
|
||||||
const unsigned int start=offES5506<<10;
|
const unsigned int start=offES5506<<10;
|
||||||
|
@ -711,16 +521,10 @@ void DivPlatformES5506::tick(bool sysTick) {
|
||||||
if (chan[i].pcmChanged.slice) {
|
if (chan[i].pcmChanged.slice) {
|
||||||
if (!chan[i].keyOn) {
|
if (!chan[i].keyOn) {
|
||||||
if (chan[i].pcm.index>=0 && chan[i].pcm.index<parent->song.sampleLen) {
|
if (chan[i].pcm.index>=0 && chan[i].pcm.index<parent->song.sampleLen) {
|
||||||
// get loop mode, transwave loop
|
// get loop mode
|
||||||
DivSample* s=parent->getSample(chan[i].pcm.index);
|
DivSample* s=parent->getSample(chan[i].pcm.index);
|
||||||
double loopStart=(double)s->loopStart;
|
double loopStart=(double)s->loopStart;
|
||||||
double loopEnd=(double)s->loopEnd;
|
double loopEnd=(double)s->loopEnd;
|
||||||
if (ins->amiga.transWave.sliceEnable) { // sliced loop position?
|
|
||||||
chan[i].transWave.updateSize(s->samples,loopStart,loopEnd);
|
|
||||||
chan[i].transWave.slicePos(double(chan[i].transWave.slice)/4095.0);
|
|
||||||
loopStart=chan[i].transWave.sliceStart;
|
|
||||||
loopEnd=chan[i].transWave.sliceEnd;
|
|
||||||
}
|
|
||||||
const unsigned int start=sampleOffES5506[chan[i].pcm.index]<<10;
|
const unsigned int start=sampleOffES5506[chan[i].pcm.index]<<10;
|
||||||
const unsigned int nextLoopStart=(start+(unsigned int)(loopStart*2048.0))&0xfffff800;
|
const unsigned int nextLoopStart=(start+(unsigned int)(loopStart*2048.0))&0xfffff800;
|
||||||
const unsigned int nextLoopEnd=(start+(unsigned int)((loopEnd-1.0)*2048.0))&0xffffff80;
|
const unsigned int nextLoopEnd=(start+(unsigned int)((loopEnd-1.0)*2048.0))&0xffffff80;
|
||||||
|
@ -766,8 +570,6 @@ void DivPlatformES5506::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
chan[i].pcmChanged.dummy=0;
|
chan[i].pcmChanged.dummy=0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
if (chan[i].filterChanged.changed) {
|
if (chan[i].filterChanged.changed) {
|
||||||
if (!chan[i].keyOn) {
|
if (!chan[i].keyOn) {
|
||||||
if (chan[i].filterChanged.mode) {
|
if (chan[i].filterChanged.mode) {
|
||||||
|
@ -843,11 +645,18 @@ void DivPlatformES5506::tick(bool sysTick) {
|
||||||
chan[i].freq=CLAMP(parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,2,chan[i].pitch2,chipClock,chan[i].pcm.freqOffs),0,0x1ffff);
|
chan[i].freq=CLAMP(parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,2,chan[i].pitch2,chipClock,chan[i].pcm.freqOffs),0,0x1ffff);
|
||||||
if (chan[i].keyOn) {
|
if (chan[i].keyOn) {
|
||||||
if (chan[i].pcm.index>=0 && chan[i].pcm.index<parent->song.sampleLen) {
|
if (chan[i].pcm.index>=0 && chan[i].pcm.index<parent->song.sampleLen) {
|
||||||
|
unsigned int startPos=chan[i].pcm.reversed?chan[i].pcm.end:chan[i].pcm.start;
|
||||||
|
if (chan[i].pcm.nextPos) {
|
||||||
|
const unsigned int start=chan[i].pcm.start;
|
||||||
|
const unsigned int end=chan[i].pcm.length;
|
||||||
|
startPos+=(chan[i].pcm.reversed?(end-chan[i].pcm.nextPos):chan[i].pcm.nextPos)<<11;
|
||||||
|
chan[i].pcm.nextPos=0;
|
||||||
|
}
|
||||||
chan[i].k1Prev=0xffff;
|
chan[i].k1Prev=0xffff;
|
||||||
chan[i].k2Prev=0xffff;
|
chan[i].k2Prev=0xffff;
|
||||||
pageWriteMask(0x00|i,0x5f,0x00,0x0303); // Wipeout CR
|
pageWriteMask(0x00|i,0x5f,0x00,0x0303); // Wipeout CR
|
||||||
pageWrite(0x00|i,0x06,0); // Clear ECOUNT
|
pageWrite(0x00|i,0x06,0); // Clear ECOUNT
|
||||||
pageWrite(0x20|i,0x03,chan[i].pcm.reversed?chan[i].pcm.end:chan[i].pcm.start); // Set ACCUM to start address
|
pageWrite(0x20|i,0x03,startPos); // Set ACCUM to start address
|
||||||
pageWrite(0x00|i,0x07,0xffff); // Set K1 and K2 to 0xffff
|
pageWrite(0x00|i,0x07,0xffff); // Set K1 and K2 to 0xffff
|
||||||
pageWrite(0x00|i,0x09,0xffff,~0,(chanMax+1)*4*2); // needs to 4 sample period delay
|
pageWrite(0x00|i,0x09,0xffff,~0,(chanMax+1)*4*2); // needs to 4 sample period delay
|
||||||
pageWrite(0x00|i,0x01,chan[i].freq);
|
pageWrite(0x00|i,0x01,chan[i].freq);
|
||||||
|
@ -910,7 +719,7 @@ void DivPlatformES5506::tick(bool sysTick) {
|
||||||
if (chan[i].keyOff) chan[i].keyOff=false;
|
if (chan[i].keyOff) chan[i].keyOff=false;
|
||||||
chan[i].freqChanged=false;
|
chan[i].freqChanged=false;
|
||||||
}
|
}
|
||||||
if (!chan[i].keyOn) {
|
if (!chan[i].keyOn && chan[i].active) {
|
||||||
if (chan[i].k2Prev!=k2) {
|
if (chan[i].k2Prev!=k2) {
|
||||||
pageWrite(0x00|i,0x07,k2);
|
pageWrite(0x00|i,0x07,k2);
|
||||||
chan[i].k2Prev=k2;
|
chan[i].k2Prev=k2;
|
||||||
|
@ -928,81 +737,18 @@ int DivPlatformES5506::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_NOTE_ON: {
|
case DIV_CMD_NOTE_ON: {
|
||||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_ES5506);
|
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_ES5506);
|
||||||
bool sampleVaild=false;
|
bool sampleVaild=false;
|
||||||
if (((ins->amiga.useNoteMap && !ins->amiga.transWave.enable) && (c.value>=0 && c.value<120)) ||
|
if (((ins->amiga.useNoteMap) && (c.value>=0 && c.value<120)) ||
|
||||||
((!ins->amiga.useNoteMap && ins->amiga.transWave.enable) && (ins->amiga.transWave.ind>=0 && ins->amiga.transWave.ind<(int)ins->amiga.transWaveMap.size())) ||
|
((!ins->amiga.useNoteMap) && (ins->amiga.initSample>=0 && ins->amiga.initSample<parent->song.sampleLen))) {
|
||||||
((!ins->amiga.useNoteMap && !ins->amiga.transWave.enable) && (ins->amiga.initSample>=0 && ins->amiga.initSample<parent->song.sampleLen))) {
|
|
||||||
DivInstrumentAmiga::SampleMap& noteMapind=ins->amiga.noteMap[c.value];
|
DivInstrumentAmiga::SampleMap& noteMapind=ins->amiga.noteMap[c.value];
|
||||||
DivInstrumentAmiga::TransWaveMap& transWaveInd=ins->amiga.transWaveMap[ins->amiga.transWave.ind];
|
|
||||||
int sample=ins->amiga.initSample;
|
int sample=ins->amiga.initSample;
|
||||||
if (ins->amiga.transWave.enable) {
|
if (ins->amiga.useNoteMap) {
|
||||||
sample=transWaveInd.ind;
|
|
||||||
} else if (ins->amiga.useNoteMap) {
|
|
||||||
sample=noteMapind.map;
|
sample=noteMapind.map;
|
||||||
}
|
}
|
||||||
if (sample>=0 && sample<parent->song.sampleLen) {
|
if (sample>=0 && sample<parent->song.sampleLen) {
|
||||||
const unsigned int offES5506=sampleOffES5506[sample];
|
|
||||||
sampleVaild=true;
|
sampleVaild=true;
|
||||||
chan[c.chan].pcm.index=chan[c.chan].pcm.next=sample;
|
|
||||||
chan[c.chan].pcm.pause=(chan[c.chan].std.alg.will)?(chan[c.chan].std.alg.val&1):false;
|
|
||||||
chan[c.chan].pcm.isNoteMap=ins->amiga.useNoteMap && !ins->amiga.transWave.enable;
|
|
||||||
chan[c.chan].transWave.enable=!ins->amiga.useNoteMap && ins->amiga.transWave.enable;
|
|
||||||
chan[c.chan].transWave.sliceEnable=ins->amiga.transWave.sliceEnable;
|
|
||||||
chan[c.chan].transWave.ind=ins->amiga.transWave.ind;
|
|
||||||
DivSample* s=parent->getSample(sample);
|
|
||||||
// get frequency offset
|
|
||||||
double off=1.0;
|
|
||||||
double center=(double)s->centerRate;
|
|
||||||
if (center<1) {
|
|
||||||
off=1.0;
|
|
||||||
} else {
|
|
||||||
off=(double)center/8363.0;
|
|
||||||
}
|
|
||||||
if (ins->amiga.useNoteMap) {
|
|
||||||
off*=(double)noteMapind.freq/((double)MAX(1,center)*pow(2.0,((double)c.value-48.0)/12.0));
|
|
||||||
chan[c.chan].pcm.note=c.value;
|
|
||||||
}
|
|
||||||
// get loop mode, transwave loop
|
|
||||||
double loopStart=(double)s->loopStart;
|
|
||||||
double loopEnd=(double)s->loopEnd;
|
|
||||||
DivSampleLoopMode loopMode=s->isLoopable()?s->loopMode:DIV_SAMPLE_LOOP_MAX;
|
|
||||||
if (ins->amiga.transWave.enable) {
|
|
||||||
if (transWaveInd.loopMode!=DIV_SAMPLE_LOOP_MAX) {
|
|
||||||
loopMode=transWaveInd.loopMode;
|
|
||||||
} else if ((chan[c.chan].pcm.loopMode==DIV_SAMPLE_LOOP_MAX) || (!s->isLoopable())) { // default
|
|
||||||
loopMode=DIV_SAMPLE_LOOP_PINGPONG;
|
|
||||||
}
|
|
||||||
// get loop position
|
|
||||||
loopStart=(double)transWaveInd.loopStart;
|
|
||||||
loopEnd=(double)transWaveInd.loopEnd;
|
|
||||||
if (ins->amiga.transWave.sliceEnable) { // sliced loop position?
|
|
||||||
chan[c.chan].transWave.updateSize(s->samples,loopStart,loopEnd);
|
|
||||||
chan[c.chan].transWave.slice=ins->amiga.transWave.slice;
|
|
||||||
chan[c.chan].transWave.slicePos(double(ins->amiga.transWave.slice)/4095.0);
|
|
||||||
loopStart=transWaveInd.sliceStart;
|
|
||||||
loopEnd=transWaveInd.sliceEnd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// get reversed
|
|
||||||
bool reversed=ins->amiga.reversed;
|
|
||||||
if (ins->amiga.transWave.enable&&transWaveInd.reversed!=DivInstrumentAmiga::DivReverseMode::DIV_REVERSE_DEFAULT) {
|
|
||||||
reversed=transWaveInd.reversed;
|
|
||||||
} else if (ins->amiga.useNoteMap&¬eMapind.reversed!=DivInstrumentAmiga::DivReverseMode::DIV_REVERSE_DEFAULT) {
|
|
||||||
reversed=noteMapind.reversed;
|
|
||||||
}
|
|
||||||
const unsigned int start=offES5506<<10;
|
|
||||||
const unsigned int length=s->samples-1;
|
|
||||||
const unsigned int end=start+(length<<11);
|
|
||||||
chan[c.chan].pcm.loopMode=loopMode;
|
|
||||||
chan[c.chan].pcm.freqOffs=PITCH_OFFSET*off;
|
|
||||||
chan[c.chan].pcm.reversed=reversed;
|
|
||||||
chan[c.chan].pcm.bank=(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+(unsigned int)(loopStart*2048.0))&0xfffff800;
|
|
||||||
chan[c.chan].pcm.loopEnd=(start+(unsigned int)((loopEnd-1.0)*2048.0))&0xffffff80;
|
|
||||||
chan[c.chan].volMacroMax=ins->type==DIV_INS_AMIGA?64:0xffff;
|
chan[c.chan].volMacroMax=ins->type==DIV_INS_AMIGA?64:0xffff;
|
||||||
chan[c.chan].panMacroMax=ins->type==DIV_INS_AMIGA?127:0xffff;
|
chan[c.chan].panMacroMax=ins->type==DIV_INS_AMIGA?127:0xffff;
|
||||||
|
chan[c.chan].pcm.next=sample;
|
||||||
chan[c.chan].filter=ins->es5506.filter;
|
chan[c.chan].filter=ins->es5506.filter;
|
||||||
chan[c.chan].envelope=ins->es5506.envelope;
|
chan[c.chan].envelope=ins->es5506.envelope;
|
||||||
}
|
}
|
||||||
|
@ -1017,6 +763,7 @@ int DivPlatformES5506::dispatch(DivCommand c) {
|
||||||
chan[c.chan].nextNote=chan[c.chan].note;
|
chan[c.chan].nextNote=chan[c.chan].note;
|
||||||
chan[c.chan].pcm.nextFreqOffs=chan[c.chan].pcm.freqOffs;
|
chan[c.chan].pcm.nextFreqOffs=chan[c.chan].pcm.freqOffs;
|
||||||
chan[c.chan].freqChanged=true;
|
chan[c.chan].freqChanged=true;
|
||||||
|
chan[c.chan].pcmChanged.changed=0xff;
|
||||||
chan[c.chan].noteChanged.changed=0xff;
|
chan[c.chan].noteChanged.changed=0xff;
|
||||||
chan[c.chan].volChanged.changed=0xff;
|
chan[c.chan].volChanged.changed=0xff;
|
||||||
}
|
}
|
||||||
|
@ -1099,32 +846,15 @@ int DivPlatformES5506::dispatch(DivCommand c) {
|
||||||
if (!chan[c.chan].useWave) {
|
if (!chan[c.chan].useWave) {
|
||||||
if (chan[c.chan].active) {
|
if (chan[c.chan].active) {
|
||||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_ES5506);
|
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_ES5506);
|
||||||
if (((ins->amiga.useNoteMap && !ins->amiga.transWave.enable) && (c.value>=0 && c.value<120)) ||
|
if (((ins->amiga.useNoteMap) && (c.value>=0 && c.value<120)) ||
|
||||||
((!ins->amiga.useNoteMap && ins->amiga.transWave.enable) && (c.value>=0 && c.value<(int)ins->amiga.transWaveMap.size())) ||
|
((!ins->amiga.useNoteMap) && (c.value>=0 && c.value<parent->song.sampleLen))) {
|
||||||
((!ins->amiga.useNoteMap && !ins->amiga.transWave.enable) && (c.value>=0 && c.value<parent->song.sampleLen))) {
|
|
||||||
chan[c.chan].pcm.next=c.value;
|
chan[c.chan].pcm.next=c.value;
|
||||||
if (!ins->amiga.useNoteMap && ins->amiga.transWave.enable) {
|
|
||||||
chan[c.chan].pcmChanged.transwaveInd=1;
|
|
||||||
} else {
|
|
||||||
chan[c.chan].pcmChanged.index=1;
|
chan[c.chan].pcmChanged.index=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// reserved for useWave
|
// reserved for useWave
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_SAMPLE_TRANSWAVE_SLICE_MODE:
|
|
||||||
if (chan[c.chan].transWave.sliceEnable!=(bool)(c.value&1)) {
|
|
||||||
chan[c.chan].transWave.sliceEnable=c.value&1;
|
|
||||||
chan[c.chan].pcmChanged.slice=1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DIV_CMD_SAMPLE_TRANSWAVE_SLICE_POS:
|
|
||||||
if (chan[c.chan].transWave.sliceEnable && (chan[c.chan].transWave.slice!=(unsigned short)(c.value&0xfff))) {
|
|
||||||
chan[c.chan].transWave.slice=c.value&0xfff;
|
|
||||||
chan[c.chan].pcmChanged.slice=1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
// Filter commands
|
// Filter commands
|
||||||
case DIV_CMD_ES5506_FILTER_MODE:
|
case DIV_CMD_ES5506_FILTER_MODE:
|
||||||
chan[c.chan].filter.mode=DivInstrumentES5506::Filter::FilterMode(c.value&3);
|
chan[c.chan].filter.mode=DivInstrumentES5506::Filter::FilterMode(c.value&3);
|
||||||
|
@ -1216,13 +946,17 @@ int DivPlatformES5506::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_SAMPLE_POS: {
|
case DIV_CMD_SAMPLE_POS: {
|
||||||
if (chan[c.chan].useWave) break;
|
if (chan[c.chan].useWave) break;
|
||||||
if (chan[c.chan].active) {
|
if (chan[c.chan].active) {
|
||||||
const unsigned int start=chan[c.chan].transWave.enable?chan[c.chan].pcm.loopStart:chan[c.chan].pcm.start;
|
const unsigned int start=chan[c.chan].pcm.start;
|
||||||
const unsigned int end=chan[c.chan].transWave.enable?chan[c.chan].pcm.loopEnd:chan[c.chan].pcm.length;
|
const unsigned int end=chan[c.chan].pcm.length;
|
||||||
const unsigned int pos=chan[c.chan].pcm.reversed?(end-c.value):c.value;
|
const unsigned int pos=chan[c.chan].pcm.reversed?(end-c.value):c.value;
|
||||||
if ((chan[c.chan].pcm.reversed && pos>0) || ((!chan[c.chan].pcm.reversed) && pos<end)) {
|
if ((chan[c.chan].pcm.reversed && pos>0) || ((!chan[c.chan].pcm.reversed) && pos<end)) {
|
||||||
pageWrite(0x20|c.chan,0x03,start+(pos<<11));
|
pageWrite(0x20|c.chan,0x03,start+(pos<<11));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
if (chan[c.chan].pcm.nextPos!=0) {
|
||||||
|
chan[c.chan].pcm.nextPos=c.value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1284,7 +1018,6 @@ void DivPlatformES5506::reset() {
|
||||||
isMasked=false;
|
isMasked=false;
|
||||||
isReaded=false;
|
isReaded=false;
|
||||||
irqTrigger=false;
|
irqTrigger=false;
|
||||||
transwaveCh=0;
|
|
||||||
prevChanCycle=0;
|
prevChanCycle=0;
|
||||||
chanMax=initChanMax;
|
chanMax=initChanMax;
|
||||||
|
|
||||||
|
@ -1325,7 +1058,7 @@ void DivPlatformES5506::notifyInsDeletion(void* ins) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformES5506::setFlags(const DivConfig& flags) {
|
void DivPlatformES5506::setFlags(const DivConfig& flags) {
|
||||||
initChanMax=MAX(4,flags.getInt("channels",0)&0x1f);
|
initChanMax=MAX(4,flags.getInt("channels",0x1f)&0x1f);
|
||||||
chanMax=initChanMax;
|
chanMax=initChanMax;
|
||||||
pageWriteMask(0x00,0x60,0x0b,chanMax);
|
pageWriteMask(0x00,0x60,0x0b,chanMax);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf {
|
||||||
unsigned int length;
|
unsigned int length;
|
||||||
unsigned int loopStart;
|
unsigned int loopStart;
|
||||||
unsigned int loopEnd;
|
unsigned int loopEnd;
|
||||||
|
unsigned int nextPos;
|
||||||
DivSampleLoopMode loopMode;
|
DivSampleLoopMode loopMode;
|
||||||
PCM():
|
PCM():
|
||||||
isNoteMap(false),
|
isNoteMap(false),
|
||||||
|
@ -60,11 +61,12 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf {
|
||||||
length(0),
|
length(0),
|
||||||
loopStart(0),
|
loopStart(0),
|
||||||
loopEnd(0),
|
loopEnd(0),
|
||||||
|
nextPos(0),
|
||||||
loopMode(DIV_SAMPLE_LOOP_MAX) {}
|
loopMode(DIV_SAMPLE_LOOP_MAX) {}
|
||||||
} pcm;
|
} pcm;
|
||||||
int freq, baseFreq, nextFreq, pitch, pitch2, note, nextNote, currNote, ins, wave;
|
int freq, baseFreq, nextFreq, pitch, pitch2, note, nextNote, currNote, ins, wave;
|
||||||
unsigned int volMacroMax, panMacroMax;
|
unsigned int volMacroMax, panMacroMax;
|
||||||
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, useWave, isReverseLoop, isTranswave, transwaveIRQ;
|
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, useWave, isReverseLoop;
|
||||||
unsigned int cr;
|
unsigned int cr;
|
||||||
|
|
||||||
struct NoteChanged { // Note changed flags
|
struct NoteChanged { // Note changed flags
|
||||||
|
@ -135,8 +137,7 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf {
|
||||||
unsigned char slice: 1; // transwave slice
|
unsigned char slice: 1; // transwave slice
|
||||||
unsigned char position: 1; // sample position in memory
|
unsigned char position: 1; // sample position in memory
|
||||||
unsigned char loopBank: 1; // Loop mode and Bank
|
unsigned char loopBank: 1; // Loop mode and Bank
|
||||||
unsigned char transwaveInd: 1; // transwave index
|
unsigned char dummy: 4; // dummy for bit padding
|
||||||
unsigned char dummy: 3; // dummy for bit padding
|
|
||||||
};
|
};
|
||||||
unsigned char changed;
|
unsigned char changed;
|
||||||
};
|
};
|
||||||
|
@ -151,7 +152,6 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf {
|
||||||
signed int lOut, rOut, oscOut;
|
signed int lOut, rOut, oscOut;
|
||||||
DivInstrumentES5506::Filter filter;
|
DivInstrumentES5506::Filter filter;
|
||||||
DivInstrumentES5506::Envelope envelope;
|
DivInstrumentES5506::Envelope envelope;
|
||||||
DivInstrumentAmiga::TransWave transWave;
|
|
||||||
DivMacroInt std;
|
DivMacroInt std;
|
||||||
void macroInit(DivInstrument* which) {
|
void macroInit(DivInstrument* which) {
|
||||||
std.init(which);
|
std.init(which);
|
||||||
|
@ -186,8 +186,6 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf {
|
||||||
inPorta(false),
|
inPorta(false),
|
||||||
useWave(false),
|
useWave(false),
|
||||||
isReverseLoop(false),
|
isReverseLoop(false),
|
||||||
isTranswave(false),
|
|
||||||
transwaveIRQ(false),
|
|
||||||
cr(0),
|
cr(0),
|
||||||
k1Offs(0),
|
k1Offs(0),
|
||||||
k2Offs(0),
|
k2Offs(0),
|
||||||
|
@ -258,7 +256,6 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf {
|
||||||
bool isMasked, isReaded;
|
bool isMasked, isReaded;
|
||||||
bool irqTrigger;
|
bool irqTrigger;
|
||||||
unsigned int curCR;
|
unsigned int curCR;
|
||||||
unsigned char transwaveCh;
|
|
||||||
unsigned char prevChanCycle;
|
unsigned char prevChanCycle;
|
||||||
|
|
||||||
unsigned char initChanMax, chanMax;
|
unsigned char initChanMax, chanMax;
|
||||||
|
|
|
@ -74,8 +74,6 @@ const char* cmdName[]={
|
||||||
"SAMPLE_BANK",
|
"SAMPLE_BANK",
|
||||||
"SAMPLE_POS",
|
"SAMPLE_POS",
|
||||||
"SAMPLE_DIR",
|
"SAMPLE_DIR",
|
||||||
"SAMPLE_TRANSWAVE_SLICE_MODE", // (enabled)
|
|
||||||
"SAMPLE_TRANSWAVE_SLICE_POS", // (slice)
|
|
||||||
|
|
||||||
"FM_HARD_RESET",
|
"FM_HARD_RESET",
|
||||||
"FM_LFO",
|
"FM_LFO",
|
||||||
|
|
|
@ -1466,13 +1466,19 @@ void DivEngine::registerSystems() {
|
||||||
);
|
);
|
||||||
|
|
||||||
EffectHandlerMap es5506PreEffectHandlerMap={
|
EffectHandlerMap es5506PreEffectHandlerMap={
|
||||||
{0x10, {DIV_CMD_WAVE, "10xx: Change waveform or sample, transwave index (00 to FF)",effectVal}},
|
{0x10, {DIV_CMD_WAVE, "10xx: Change waveform or sample (00 to FF)",effectVal}}
|
||||||
|
};
|
||||||
|
EffectHandlerMap es5506PostEffectHandlerMap={
|
||||||
{0x11, {DIV_CMD_ES5506_FILTER_MODE, "11xx: Set filter mode (00 to 03)",effectValAnd<3>}},
|
{0x11, {DIV_CMD_ES5506_FILTER_MODE, "11xx: Set filter mode (00 to 03)",effectValAnd<3>}},
|
||||||
{0x13, {DIV_CMD_SAMPLE_TRANSWAVE_SLICE_MODE, "130x: Set transwave slice mode (bit 0)",effectValAnd<1>}},
|
{0x12, {DIV_CMD_ES5506_PAUSE, "120x: Set pause (bit 0)",effectValAnd<1>}},
|
||||||
{0x14, {DIV_CMD_ES5506_FILTER_K1, "14xx: Set filter coefficient K1 low byte (00 to FF)",effectValShift<0>,constVal<0x00ff>}},
|
{0x14, {DIV_CMD_ES5506_FILTER_K1, "14xx: Set filter coefficient K1 low byte (00 to FF)",effectValShift<0>,constVal<0x00ff>}},
|
||||||
{0x15, {DIV_CMD_ES5506_FILTER_K1, "15xx: Set filter coefficient K1 high byte (00 to FF)",effectValShift<8>,constVal<0xff00>}},
|
{0x15, {DIV_CMD_ES5506_FILTER_K1, "15xx: Set filter coefficient K1 high byte (00 to FF)",effectValShift<8>,constVal<0xff00>}},
|
||||||
{0x16, {DIV_CMD_ES5506_FILTER_K2, "16xx: Set filter coefficient K2 low byte (00 to FF)",effectValShift<0>,constVal<0x00ff>}},
|
{0x16, {DIV_CMD_ES5506_FILTER_K2, "16xx: Set filter coefficient K2 low byte (00 to FF)",effectValShift<0>,constVal<0x00ff>}},
|
||||||
{0x17, {DIV_CMD_ES5506_FILTER_K2, "17xx: Set filter coefficient K2 high byte (00 to FF)",effectValShift<8>,constVal<0xff00>}},
|
{0x17, {DIV_CMD_ES5506_FILTER_K2, "17xx: Set filter coefficient K2 high byte (00 to FF)",effectValShift<8>,constVal<0xff00>}},
|
||||||
|
{0x18, {DIV_CMD_ES5506_FILTER_K1_SLIDE, "18xx: Set filter coefficient K1 slide up (00 to FF)",effectVal,constVal<0>}},
|
||||||
|
{0x19, {DIV_CMD_ES5506_FILTER_K1_SLIDE, "19xx: Set filter coefficient K1 slide down (00 to FF)",effectVal,constVal<1>}},
|
||||||
|
{0x1a, {DIV_CMD_ES5506_FILTER_K2_SLIDE, "1Axx: Set filter coefficient K2 slide up (00 to FF)",effectVal,constVal<0>}},
|
||||||
|
{0x1b, {DIV_CMD_ES5506_FILTER_K2_SLIDE, "1Bxx: Set filter coefficient K2 slide down (00 to FF)",effectVal,constVal<1>}},
|
||||||
{0x22, {DIV_CMD_ES5506_ENVELOPE_LVRAMP, "22xx: Set envelope left volume ramp (signed) (00 to FF)",effectVal}},
|
{0x22, {DIV_CMD_ES5506_ENVELOPE_LVRAMP, "22xx: Set envelope left volume ramp (signed) (00 to FF)",effectVal}},
|
||||||
{0x23, {DIV_CMD_ES5506_ENVELOPE_RVRAMP, "23xx: Set envelope right volume ramp (signed) (00 to FF)",effectVal}},
|
{0x23, {DIV_CMD_ES5506_ENVELOPE_RVRAMP, "23xx: Set envelope right volume ramp (signed) (00 to FF)",effectVal}},
|
||||||
{0x24, {DIV_CMD_ES5506_ENVELOPE_K1RAMP, "24xx: Set envelope filter coefficient k1 ramp (signed) (00 to FF)",effectVal,constVal<0>}},
|
{0x24, {DIV_CMD_ES5506_ENVELOPE_K1RAMP, "24xx: Set envelope filter coefficient k1 ramp (signed) (00 to FF)",effectVal,constVal<0>}},
|
||||||
|
@ -1480,21 +1486,12 @@ void DivEngine::registerSystems() {
|
||||||
{0x26, {DIV_CMD_ES5506_ENVELOPE_K2RAMP, "26xx: Set envelope filter coefficient k2 ramp (signed) (00 to FF)",effectVal,constVal<0>}},
|
{0x26, {DIV_CMD_ES5506_ENVELOPE_K2RAMP, "26xx: Set envelope filter coefficient k2 ramp (signed) (00 to FF)",effectVal,constVal<0>}},
|
||||||
{0x27, {DIV_CMD_ES5506_ENVELOPE_K2RAMP, "27xx: Set envelope filter coefficient k2 ramp (signed, slower) (00 to FF)",effectVal,constVal<1>}}
|
{0x27, {DIV_CMD_ES5506_ENVELOPE_K2RAMP, "27xx: Set envelope filter coefficient k2 ramp (signed, slower) (00 to FF)",effectVal,constVal<1>}}
|
||||||
};
|
};
|
||||||
EffectHandlerMap es5506PostEffectHandlerMap={
|
|
||||||
{0x12, {DIV_CMD_ES5506_PAUSE, "120x: Set pause (bit 0)",effectValAnd<1>}},
|
|
||||||
{0x18, {DIV_CMD_ES5506_FILTER_K1_SLIDE, "18xx: Set filter coefficient K1 slide up (00 to FF)",effectVal,constVal<0>}},
|
|
||||||
{0x19, {DIV_CMD_ES5506_FILTER_K1_SLIDE, "19xx: Set filter coefficient K1 slide down (00 to FF)",effectVal,constVal<1>}},
|
|
||||||
{0x1a, {DIV_CMD_ES5506_FILTER_K2_SLIDE, "1Axx: Set filter coefficient K2 slide up (00 to FF)",effectVal,constVal<0>}},
|
|
||||||
{0x1b, {DIV_CMD_ES5506_FILTER_K2_SLIDE, "1Bxx: Set filter coefficient K2 slide down (00 to FF)",effectVal,constVal<1>}},
|
|
||||||
};
|
|
||||||
const EffectHandler es5506ECountHandler(DIV_CMD_ES5506_ENVELOPE_COUNT, "2xxx: Set envelope count (000 to 1FF)", effectValLong<9>);
|
const EffectHandler es5506ECountHandler(DIV_CMD_ES5506_ENVELOPE_COUNT, "2xxx: Set envelope count (000 to 1FF)", effectValLong<9>);
|
||||||
const EffectHandler es5506K1Handler(DIV_CMD_ES5506_FILTER_K1, "3xxx: Set filter coefficient K1 (000 to FFF)", effectValLongShift<12,4>);
|
const EffectHandler es5506K1Handler(DIV_CMD_ES5506_FILTER_K1, "3xxx: Set filter coefficient K1 (000 to FFF)", effectValLongShift<12,4>);
|
||||||
const EffectHandler es5506K2Handler(DIV_CMD_ES5506_FILTER_K2, "4xxx: Set filter coefficient K2 (000 to FFF)", effectValLongShift<12,4>);
|
const EffectHandler es5506K2Handler(DIV_CMD_ES5506_FILTER_K2, "4xxx: Set filter coefficient K2 (000 to FFF)", effectValLongShift<12,4>);
|
||||||
const EffectHandler transWaveSlicePositionHandler(DIV_CMD_SAMPLE_TRANSWAVE_SLICE_POS, "5xxx: Set transwave slice point (000 to FFF)", effectValLong<12>);
|
for (int i=0; i<2; i++) es5506PostEffectHandlerMap.emplace(0x20+i,es5506ECountHandler);
|
||||||
for (int i=0; i<2; i++) es5506PreEffectHandlerMap.emplace(0x20+i,es5506ECountHandler);
|
for (int i=0; i<16; i++) es5506PostEffectHandlerMap.emplace(0x30+i, es5506K1Handler);
|
||||||
for (int i=0; i<16; i++) es5506PreEffectHandlerMap.emplace(0x30+i, es5506K1Handler);
|
for (int i=0; i<16; i++) es5506PostEffectHandlerMap.emplace(0x40+i, es5506K2Handler);
|
||||||
for (int i=0; i<16; i++) es5506PreEffectHandlerMap.emplace(0x40+i, es5506K2Handler);
|
|
||||||
for (int i=0; i<16; i++) es5506PreEffectHandlerMap.emplace(0x50+i, transWaveSlicePositionHandler);
|
|
||||||
|
|
||||||
// TODO: custom sample format
|
// TODO: custom sample format
|
||||||
sysDefs[DIV_SYSTEM_ES5506]=new DivSysDef(
|
sysDefs[DIV_SYSTEM_ES5506]=new DivSysDef(
|
||||||
|
|
|
@ -1078,6 +1078,7 @@ void putDispatchChan(void* data, int chanNum, int type) {
|
||||||
ImGui::Text(" - loopStart: %.8x",ch->pcm.loopStart);
|
ImGui::Text(" - loopStart: %.8x",ch->pcm.loopStart);
|
||||||
ImGui::Text(" - loopEnd: %.8x",ch->pcm.loopEnd);
|
ImGui::Text(" - loopEnd: %.8x",ch->pcm.loopEnd);
|
||||||
ImGui::Text(" - loopMode: %d",ch->pcm.loopMode);
|
ImGui::Text(" - loopMode: %d",ch->pcm.loopMode);
|
||||||
|
ImGui::Text(" - nextPos: %d",ch->pcm.nextPos);
|
||||||
ImGui::Text("* Filter:");
|
ImGui::Text("* Filter:");
|
||||||
ImGui::Text(" - Mode: %d",ch->filter.mode);
|
ImGui::Text(" - Mode: %d",ch->filter.mode);
|
||||||
ImGui::Text(" - K1: %.4x",ch->filter.k1);
|
ImGui::Text(" - K1: %.4x",ch->filter.k1);
|
||||||
|
@ -1122,10 +1123,7 @@ void putDispatchChan(void* data, int chanNum, int type) {
|
||||||
ImGui::TextColored(ch->pcmChanged.slice?colorOn:colorOff,">> PCMSliceChanged");
|
ImGui::TextColored(ch->pcmChanged.slice?colorOn:colorOff,">> PCMSliceChanged");
|
||||||
ImGui::TextColored(ch->pcmChanged.position?colorOn:colorOff,">> PCMPositionChanged");
|
ImGui::TextColored(ch->pcmChanged.position?colorOn:colorOff,">> PCMPositionChanged");
|
||||||
ImGui::TextColored(ch->pcmChanged.loopBank?colorOn:colorOff,">> PCMLoopBankChanged");
|
ImGui::TextColored(ch->pcmChanged.loopBank?colorOn:colorOff,">> PCMLoopBankChanged");
|
||||||
ImGui::TextColored(ch->pcmChanged.transwaveInd?colorOn:colorOff,">> PCMTranswaveIndexChanged");
|
|
||||||
ImGui::TextColored(ch->isReverseLoop?colorOn:colorOff,">> IsReverseLoop");
|
ImGui::TextColored(ch->isReverseLoop?colorOn:colorOff,">> IsReverseLoop");
|
||||||
ImGui::TextColored(ch->isTranswave?colorOn:colorOff,">> IsTranswave");
|
|
||||||
ImGui::TextColored(ch->transwaveIRQ?colorOn:colorOff,">> TranswaveIRQ");
|
|
||||||
ImGui::TextColored(ch->pcm.reversed?colorOn:colorOff,">> PCMReversed");
|
ImGui::TextColored(ch->pcm.reversed?colorOn:colorOff,">> PCMReversed");
|
||||||
ImGui::TextColored(ch->envelope.k1Slow?colorOn:colorOff,">> EnvK1Slow");
|
ImGui::TextColored(ch->envelope.k1Slow?colorOn:colorOff,">> EnvK1Slow");
|
||||||
ImGui::TextColored(ch->envelope.k2Slow?colorOn:colorOff,">> EnvK2Slow");
|
ImGui::TextColored(ch->envelope.k2Slow?colorOn:colorOff,">> EnvK2Slow");
|
||||||
|
|
|
@ -290,10 +290,6 @@ const char* es5506ControlModes[2]={
|
||||||
"pause", NULL
|
"pause", NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* transwaveControlModes[2]={
|
|
||||||
"slice", NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
const int orderedOps[4]={
|
const int orderedOps[4]={
|
||||||
0, 2, 1, 3
|
0, 2, 1, 3
|
||||||
};
|
};
|
||||||
|
@ -4055,7 +4051,7 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
// Wavetable
|
// Wavetable
|
||||||
if (ins->type==DIV_INS_AMIGA || ins->type==DIV_INS_SNES) {
|
if (ins->type==DIV_INS_AMIGA || ins->type==DIV_INS_SNES) {
|
||||||
ImGui::BeginDisabled(ins->amiga.useNoteMap||ins->amiga.transWave.enable);
|
ImGui::BeginDisabled(ins->amiga.useNoteMap);
|
||||||
P(ImGui::Checkbox("Use wavetable (Amiga/SNES/Generic DAC only)",&ins->amiga.useWave));
|
P(ImGui::Checkbox("Use wavetable (Amiga/SNES/Generic DAC only)",&ins->amiga.useWave));
|
||||||
if (ins->amiga.useWave) {
|
if (ins->amiga.useWave) {
|
||||||
int len=ins->amiga.waveLen+1;
|
int len=ins->amiga.waveLen+1;
|
||||||
|
@ -4080,7 +4076,7 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
}
|
}
|
||||||
// Note map
|
// Note map
|
||||||
ImGui::BeginDisabled(ins->amiga.useWave||ins->amiga.transWave.enable);
|
ImGui::BeginDisabled(ins->amiga.useWave);
|
||||||
P(ImGui::Checkbox("Use sample map (does not work yet!)",&ins->amiga.useNoteMap));
|
P(ImGui::Checkbox("Use sample map (does not work yet!)",&ins->amiga.useNoteMap));
|
||||||
if (ins->amiga.useNoteMap) {
|
if (ins->amiga.useNoteMap) {
|
||||||
// TODO: frequency map?
|
// TODO: frequency map?
|
||||||
|
@ -4151,186 +4147,8 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
// Transwave
|
|
||||||
ImGui::BeginDisabled(ins->amiga.useNoteMap||ins->amiga.useWave||ins->amiga.useNoteMap);
|
|
||||||
P(ImGui::Checkbox("Use Transwave##UseTransWave",&ins->amiga.transWave.enable));
|
|
||||||
if (ins->amiga.transWave.enable) {
|
|
||||||
int size=ins->amiga.transWaveMap.size();
|
|
||||||
if (ImGui::InputInt("Transwave Map Size##TransWaveSize",&size,1,16)) { PARAMETER
|
|
||||||
if (size<=ins->amiga.transWave.ind) size=ins->amiga.transWave.ind+1;
|
|
||||||
if (size<1) size=1;
|
|
||||||
if (size>256) size=256;
|
|
||||||
if (ins->amiga.transWaveMap.size()!=(size_t)(size)) {
|
|
||||||
ins->amiga.transWaveMap.resize(size,DivInstrumentAmiga::TransWaveMap());
|
|
||||||
if (ins->amiga.transWaveMap.capacity()>(size_t)(size)) {
|
|
||||||
ins->amiga.transWaveMap.shrink_to_fit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ImGui::InputInt("Initial Transwave Index##TransWaveInit",&ins->amiga.transWave.ind,1,16)) { PARAMETER
|
|
||||||
if (ins->amiga.transWave.ind<1) ins->amiga.transWave.ind=0;
|
|
||||||
if (ins->amiga.transWave.ind>=(int)(ins->amiga.transWaveMap.size())) ins->amiga.transWave.ind=ins->amiga.transWaveMap.size()-1;
|
|
||||||
if (ins->amiga.transWave.sliceEnable) {
|
|
||||||
DivInstrumentAmiga::TransWaveMap ind=ins->amiga.transWaveMap[ins->amiga.transWave.ind];
|
|
||||||
if (ind.ind>=0 && ind.ind<(short)(e->song.sampleLen)) {
|
|
||||||
DivSample* s=e->song.sample[ind.ind];
|
|
||||||
ins->amiga.transWave.updateSize(s->samples,ind.loopStart,ind.loopEnd);
|
|
||||||
ins->amiga.transWave.slicePos((double)(ins->amiga.transWave.slice)/4095.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ImGui::Checkbox("Use Transwave Slice##UseTransWaveSlice",&ins->amiga.transWave.sliceEnable)) { PARAMETER
|
|
||||||
if (ins->amiga.transWave.sliceEnable) {
|
|
||||||
ins->amiga.transWave.slicePos((double)(ins->amiga.transWave.slice)/4095.0);
|
|
||||||
if (ins->amiga.transWave.sliceEnable) {
|
|
||||||
DivInstrumentAmiga::TransWaveMap ind=ins->amiga.transWaveMap[ins->amiga.transWave.ind];
|
|
||||||
if (ind.ind>=0 && ind.ind<(short)(e->song.sampleLen)) {
|
|
||||||
DivSample* s=e->song.sample[ind.ind];
|
|
||||||
ins->amiga.transWave.updateSize(s->samples,ind.loopStart,ind.loopEnd);
|
|
||||||
ins->amiga.transWave.slicePos((double)(ins->amiga.transWave.slice)/4095.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DivInstrumentAmiga::TransWaveMap ind=ins->amiga.transWaveMap[ins->amiga.transWave.ind];
|
|
||||||
if (ins->amiga.transWave.sliceEnable && (ind.ind>=0 && ind.ind<e->song.sampleLen)) {
|
|
||||||
ins->amiga.transWave.slicePos((double)(ins->amiga.transWave.slice)/4095.0);
|
|
||||||
double sliceStart=ins->amiga.transWave.sliceStart;
|
|
||||||
double sliceEnd=ins->amiga.transWave.sliceEnd;
|
|
||||||
if (CWSliderScalar("Initial Transwave Slice##TransWaveSliceInit",ImGuiDataType_U16,&ins->amiga.transWave.slice,&_ZERO,&_FOUR_THOUSAND_NINETY_FIVE,fmt::sprintf("%d: %.6f - %.6f",ins->amiga.transWave.slice,sliceStart,sliceEnd).c_str())) { PARAMETER
|
|
||||||
ins->amiga.transWave.slicePos((double)(ins->amiga.transWave.slice)/4095.0);
|
|
||||||
} rightClickable
|
|
||||||
}
|
|
||||||
if (ImGui::BeginTable("TransWaveMap",6,ImGuiTableFlags_ScrollY|ImGuiTableFlags_Borders|ImGuiTableFlags_SizingStretchSame)) {
|
|
||||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed); // Number
|
|
||||||
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch); // Sample index
|
|
||||||
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch); // Loop start
|
|
||||||
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthStretch); // Loop end
|
|
||||||
ImGui::TableSetupColumn("c4",ImGuiTableColumnFlags_WidthStretch); // Loop mode
|
|
||||||
ImGui::TableSetupColumn("c5",ImGuiTableColumnFlags_WidthStretch); // Reversed
|
|
||||||
|
|
||||||
ImGui::TableSetupScrollFreeze(0,1);
|
|
||||||
|
|
||||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::Text("Sample");
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::Text("Loop Start");
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::Text("Loop End");
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::Text("Loop Mode");
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::Text("Reversed");
|
|
||||||
for (size_t i=0; i<ins->amiga.transWaveMap.size(); i++) {
|
|
||||||
DivInstrumentAmiga::TransWaveMap& transWaveMap=ins->amiga.transWaveMap[i];
|
|
||||||
ImGui::TableNextRow();
|
|
||||||
ImGui::PushID(fmt::sprintf("TransWaveMap_%d",i).c_str());
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::Text("%d",(int)(i));
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
if (transWaveMap.ind<0 || transWaveMap.ind>=e->song.sampleLen) {
|
|
||||||
sName="-- empty --";
|
|
||||||
transWaveMap.ind=-1;
|
|
||||||
} else {
|
|
||||||
sName=e->song.sample[transWaveMap.ind]->name;
|
|
||||||
}
|
|
||||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
|
||||||
if (ImGui::BeginCombo(fmt::sprintf("##TransWaveMap_Index_%d",i).c_str(),sName.c_str())) {
|
|
||||||
String id;
|
|
||||||
if (ImGui::Selectable("-- empty --",transWaveMap.ind==-1)) { PARAMETER
|
|
||||||
transWaveMap.ind=-1;
|
|
||||||
}
|
|
||||||
for (int j=0; j<e->song.sampleLen; j++) {
|
|
||||||
DivSample* s=e->song.sample[j];
|
|
||||||
id=fmt::sprintf("%d: %s",j,s->name);
|
|
||||||
if (ImGui::Selectable(id.c_str(),transWaveMap.ind==j)) { PARAMETER
|
|
||||||
transWaveMap.ind=j;
|
|
||||||
if (transWaveMap.loopStart<0 || transWaveMap.loopStart>(int)(s->samples)) {
|
|
||||||
transWaveMap.loopStart=CLAMP(s->loopStart,0,(int)s->samples);
|
|
||||||
}
|
|
||||||
if (transWaveMap.loopEnd<0 || transWaveMap.loopEnd>(int)(s->samples)) {
|
|
||||||
transWaveMap.loopEnd=CLAMP(s->loopEnd,0,(int)s->samples);
|
|
||||||
}
|
|
||||||
transWaveMap.updateSize(s->samples,transWaveMap.loopStart,transWaveMap.loopEnd);
|
|
||||||
if (ins->amiga.transWave.sliceEnable && (int)i==ins->amiga.transWave.ind) {
|
|
||||||
ins->amiga.transWave.updateSize(s->samples,transWaveMap.loopStart,transWaveMap.loopEnd);
|
|
||||||
ins->amiga.transWave.slicePos((double)(ins->amiga.transWave.slice)/4095.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::EndCombo();
|
|
||||||
}
|
|
||||||
ImGui::BeginDisabled(transWaveMap.ind<0 || transWaveMap.ind>=e->song.sampleLen);
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
|
||||||
if (ImGui::InputInt(fmt::sprintf("##TransWaveMap_LoopStart_%d",i).c_str(),&transWaveMap.loopStart,256,4096)) { PARAMETER
|
|
||||||
if (transWaveMap.ind>=0 && transWaveMap.ind<e->song.sampleLen) {
|
|
||||||
DivSample* s=e->song.sample[transWaveMap.ind];
|
|
||||||
if (transWaveMap.loopStart<0) transWaveMap.loopStart=0;
|
|
||||||
if (transWaveMap.loopStart>transWaveMap.loopEnd) transWaveMap.loopStart=transWaveMap.loopEnd;
|
|
||||||
transWaveMap.updateSize(s->samples,transWaveMap.loopStart,transWaveMap.loopEnd);
|
|
||||||
if (ins->amiga.transWave.sliceEnable && (int)i==ins->amiga.transWave.ind) {
|
|
||||||
ins->amiga.transWave.updateSize(s->samples,transWaveMap.loopStart,transWaveMap.loopEnd);
|
|
||||||
ins->amiga.transWave.slicePos((double)(ins->amiga.transWave.slice)/4095.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
|
||||||
if (ImGui::InputInt(fmt::sprintf("##TransWaveMap_LoopEnd_%d",i).c_str(),&transWaveMap.loopEnd,256,4096)) { PARAMETER
|
|
||||||
if (transWaveMap.ind>=0 && transWaveMap.ind<e->song.sampleLen) {
|
|
||||||
DivSample* s=e->song.sample[transWaveMap.ind];
|
|
||||||
if (transWaveMap.loopEnd<transWaveMap.loopStart) transWaveMap.loopEnd=transWaveMap.loopStart;
|
|
||||||
if (transWaveMap.loopEnd>(int)(s->samples)) transWaveMap.loopEnd=s->samples;
|
|
||||||
transWaveMap.updateSize(s->samples,transWaveMap.loopStart,transWaveMap.loopEnd);
|
|
||||||
if (ins->amiga.transWave.sliceEnable) {
|
|
||||||
ins->amiga.transWave.updateSize(s->samples,transWaveMap.loopStart,transWaveMap.loopEnd);
|
|
||||||
ins->amiga.transWave.slicePos((double)(ins->amiga.transWave.slice)/4095.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
if (ImGui::RadioButton(fmt::sprintf("Forward##TransWaveMap_LoopMode_Forward_%d",i).c_str(),transWaveMap.loopMode==DIV_SAMPLE_LOOP_FORWARD)) { MARK_MODIFIED
|
|
||||||
transWaveMap.loopMode=DIV_SAMPLE_LOOP_FORWARD;
|
|
||||||
}
|
|
||||||
if (ImGui::RadioButton(fmt::sprintf("Backward##TransWaveMap_LoopMode_Backward_%d",i).c_str(),transWaveMap.loopMode==DIV_SAMPLE_LOOP_BACKWARD)) { MARK_MODIFIED
|
|
||||||
transWaveMap.loopMode=DIV_SAMPLE_LOOP_BACKWARD;
|
|
||||||
}
|
|
||||||
if (ImGui::RadioButton(fmt::sprintf("Pingpong##TransWaveMap_LoopMode_Pingpong_%d",i).c_str(),transWaveMap.loopMode==DIV_SAMPLE_LOOP_PINGPONG)) { MARK_MODIFIED
|
|
||||||
transWaveMap.loopMode=DIV_SAMPLE_LOOP_PINGPONG;
|
|
||||||
}
|
|
||||||
if (ImGui::RadioButton(fmt::sprintf("Use sample setting##TransWaveMap_LoopMode_Default_%d",i).c_str(),transWaveMap.loopMode==DIV_SAMPLE_LOOP_MAX)) { MARK_MODIFIED
|
|
||||||
transWaveMap.loopMode=DIV_SAMPLE_LOOP_MAX;
|
|
||||||
}
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
if (ImGui::RadioButton(fmt::sprintf("Disable##TransWaveMap_Reversed_Disable_%d",i).c_str(),transWaveMap.reversed==DivInstrumentAmiga::DivReverseMode::DIV_REVERSE_DISABLE)) { MARK_MODIFIED
|
|
||||||
transWaveMap.reversed=DivInstrumentAmiga::DivReverseMode::DIV_REVERSE_DISABLE;
|
|
||||||
}
|
|
||||||
if (ImGui::RadioButton(fmt::sprintf("Enable##TransWaveMap_Reversed_Enable_%d",i).c_str(),transWaveMap.reversed==DivInstrumentAmiga::DivReverseMode::DIV_REVERSE_ENABLE)) { MARK_MODIFIED
|
|
||||||
transWaveMap.reversed=DivInstrumentAmiga::DivReverseMode::DIV_REVERSE_ENABLE;
|
|
||||||
}
|
|
||||||
if (ImGui::RadioButton(fmt::sprintf("Use instrument setting##TransWaveMap_Reversed_Default_%d",i).c_str(),transWaveMap.reversed==DivInstrumentAmiga::DivReverseMode::DIV_REVERSE_DEFAULT)) { MARK_MODIFIED
|
|
||||||
transWaveMap.reversed=DivInstrumentAmiga::DivReverseMode::DIV_REVERSE_DEFAULT;
|
|
||||||
}
|
|
||||||
ImGui::EndDisabled();
|
|
||||||
ImGui::PopID();
|
|
||||||
}
|
|
||||||
ImGui::EndTable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::EndDisabled();
|
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
if (ins->amiga.transWave.enable) {
|
|
||||||
if (ImGui::BeginTabItem("Transwave Macros")) {
|
|
||||||
macroList.push_back(FurnaceGUIMacroDesc("Transwave control",&ins->std.fbMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,transwaveControlModes));
|
|
||||||
macroList.push_back(FurnaceGUIMacroDesc("Transwave slice",&ins->std.fmsMacro,0,4095,160,uiColors[GUI_COLOR_MACRO_OTHER]));
|
|
||||||
drawMacros(macroList);
|
|
||||||
ImGui::EndTabItem();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (ins->type==DIV_INS_N163) if (ImGui::BeginTabItem(settings.c163Name.c_str())) {
|
if (ins->type==DIV_INS_N163) if (ImGui::BeginTabItem(settings.c163Name.c_str())) {
|
||||||
if (ImGui::InputInt("Waveform##WAVE",&ins->n163.wave,1,10)) { PARAMETER
|
if (ImGui::InputInt("Waveform##WAVE",&ins->n163.wave,1,10)) { PARAMETER
|
||||||
|
@ -4987,10 +4805,7 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) waveMax=0;
|
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) waveMax=0;
|
||||||
if (ins->type==DIV_INS_MIKEY) waveMax=0;
|
if (ins->type==DIV_INS_MIKEY) waveMax=0;
|
||||||
if ((ins->type==DIV_INS_AMIGA && !ins->amiga.useWave) || ins->type==DIV_INS_ES5506) {
|
if ((ins->type==DIV_INS_AMIGA && !ins->amiga.useWave) || ins->type==DIV_INS_ES5506) {
|
||||||
if (ins->amiga.transWave.enable) {
|
if (!ins->amiga.useWave) {
|
||||||
waveLabel="Transwave index";
|
|
||||||
waveMax=MAX(0,(int)(ins->amiga.transWaveMap.size())-1);
|
|
||||||
} else if (!ins->amiga.useWave) {
|
|
||||||
waveLabel="Sample index";
|
waveLabel="Sample index";
|
||||||
waveMax=ins->amiga.useNoteMap?120:MAX(0,(int)(e->song.sampleLen)-1);
|
waveMax=ins->amiga.useNoteMap?120:MAX(0,(int)(e->song.sampleLen)-1);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2168,6 +2168,12 @@ void FurnaceGUI::initSystemPresets() {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
cat.systems.push_back(FurnaceGUISysDef(
|
||||||
|
"Sammy/Seta/Visco SSV", {
|
||||||
|
DIV_SYSTEM_ES5506, 64, 0, 31,
|
||||||
|
0
|
||||||
|
}
|
||||||
|
));
|
||||||
cat.systems.push_back(FurnaceGUISysDef(
|
cat.systems.push_back(FurnaceGUISysDef(
|
||||||
"Cave 68000", {
|
"Cave 68000", {
|
||||||
DIV_SYSTEM_YMZ280B, 64, 0, 0,
|
DIV_SYSTEM_YMZ280B, 64, 0, 0,
|
||||||
|
|
|
@ -785,7 +785,7 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_SYSTEM_ES5506: {
|
case DIV_SYSTEM_ES5506: {
|
||||||
int channels=flags.getInt("channels",0)+1;
|
int channels=flags.getInt("channels",0x1f)+1;
|
||||||
ImGui::Text("Initial channel limit:");
|
ImGui::Text("Initial channel limit:");
|
||||||
if (CWSliderInt("##OTTO_InitialChannelLimit",&channels,5,32)) {
|
if (CWSliderInt("##OTTO_InitialChannelLimit",&channels,5,32)) {
|
||||||
if (channels<5) channels=5;
|
if (channels<5) channels=5;
|
||||||
|
|
Loading…
Reference in a new issue