dev152 - sample map notes, part 1

This commit is contained in:
tildearrow 2023-04-07 16:54:05 -05:00
parent 0151fff2d4
commit 99d2199db6
32 changed files with 154 additions and 55 deletions

View file

@ -32,6 +32,15 @@ these fields are 0 in format versions prior to 100 (0.6pre1).
the format versions are: the format versions are:
- 152: Furnace dev152
- 151: Furnace dev151
- 150: Furnace dev150
- 149: Furnace dev149
- 148: Furnace dev148
- 147: Furnace dev147
- 146: Furnace Pro (joke version)
- 145: Furnace dev145
- 144: Furnace dev144
- 143: Furnace 0.6pre4 - 143: Furnace 0.6pre4
- 142: Furnace dev142 - 142: Furnace dev142
- 141: Furnace Tournament Edition (for intro tune contest) - 141: Furnace Tournament Edition (for intro tune contest)

View file

@ -389,7 +389,7 @@ the sample map format:
``` ```
size | description size | description
-----|------------------------------------ -----|------------------------------------
2 | note to play 2 | note to play (>=152) or reserved
2 | sample to play 2 | sample to play
``` ```

View file

@ -53,8 +53,8 @@
#define EXTERN_BUSY_BEGIN_SOFT e->softLocked=true; e->isBusy.lock(); #define EXTERN_BUSY_BEGIN_SOFT e->softLocked=true; e->isBusy.lock();
#define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false; #define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false;
#define DIV_VERSION "dev151" #define DIV_VERSION "dev152"
#define DIV_ENGINE_VERSION 151 #define DIV_ENGINE_VERSION 152
// for imports // for imports
#define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_MOD 0xff01
#define DIV_VERSION_FC 0xff02 #define DIV_VERSION_FC 0xff02

View file

@ -2098,6 +2098,12 @@ void DivInstrument::readFeatureSM(SafeReader& reader, short version) {
amiga.noteMap[note].freq=reader.readS(); amiga.noteMap[note].freq=reader.readS();
amiga.noteMap[note].map=reader.readS(); amiga.noteMap[note].map=reader.readS();
} }
if (version<152) {
for (int note=0; note<120; note++) {
amiga.noteMap[note].freq=note;
}
}
} }
READ_FEAT_END; READ_FEAT_END;
@ -2965,6 +2971,12 @@ DivDataErrors DivInstrument::readInsDataOld(SafeReader &reader, short version) {
for (int note=0; note<120; note++) { for (int note=0; note<120; note++) {
amiga.noteMap[note].map=reader.readS(); amiga.noteMap[note].map=reader.readS();
} }
if (version<152) {
for (int note=0; note<120; note++) {
amiga.noteMap[note].freq=note;
}
}
} }
} }

View file

@ -414,7 +414,7 @@ struct DivInstrumentAmiga {
if (note>119) note=119; if (note>119) note=119;
return noteMap[note].freq; return noteMap[note].freq;
} }
return -1; return note;
} }
DivInstrumentAmiga(): DivInstrumentAmiga():
@ -423,8 +423,9 @@ struct DivInstrumentAmiga {
useSample(false), useSample(false),
useWave(false), useWave(false),
waveLen(31) { waveLen(31) {
for (SampleMap& elem: noteMap) { for (int i=0; i<120; i++) {
elem=SampleMap(); noteMap[i].map=-1;
noteMap[i].freq=i;
} }
} }
}; };

View file

@ -560,7 +560,10 @@ int DivPlatformAmiga::dispatch(DivCommand c) {
} }
} }
} else { } else {
if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value); if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].sample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
}
chan[c.chan].useWave=false; chan[c.chan].useWave=false;
} }
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {

View file

@ -292,8 +292,6 @@ void DivPlatformAY8910::tick(bool sysTick) {
if (chan[i].std.phaseReset.val==1) { if (chan[i].std.phaseReset.val==1) {
if (chan[i].nextPSGMode.dac) { if (chan[i].nextPSGMode.dac) {
if (dumpWrites) addWrite(0xffff0002+(i<<8),0); if (dumpWrites) addWrite(0xffff0002+(i<<8),0);
DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_AY);
chan[i].dac.sample=ins->amiga.getSample(chan[i].note);
if (chan[i].dac.sample<0 || chan[i].dac.sample>=parent->song.sampleLen) { if (chan[i].dac.sample<0 || chan[i].dac.sample>=parent->song.sampleLen) {
if (dumpWrites) { if (dumpWrites) {
rWrite(0x08+i,0); rWrite(0x08+i,0);
@ -405,7 +403,10 @@ int DivPlatformAY8910::dispatch(DivCommand c) {
if (chan[c.chan].nextPSGMode.dac) { if (chan[c.chan].nextPSGMode.dac) {
if (skipRegisterWrites) break; if (skipRegisterWrites) break;
if (!parent->song.disableSampleMacro && (ins->type==DIV_INS_AMIGA || ins->amiga.useSample)) { 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); if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].dac.sample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
}
if (chan[c.chan].dac.sample<0 || chan[c.chan].dac.sample>=parent->song.sampleLen) { if (chan[c.chan].dac.sample<0 || chan[c.chan].dac.sample>=parent->song.sampleLen) {
chan[c.chan].dac.sample=-1; chan[c.chan].dac.sample=-1;
if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0); if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0);

View file

@ -280,8 +280,6 @@ void DivPlatformAY8930::tick(bool sysTick) {
if (chan[i].std.phaseReset.val==1) { if (chan[i].std.phaseReset.val==1) {
if (chan[i].nextPSGMode.dac) { if (chan[i].nextPSGMode.dac) {
if (dumpWrites) addWrite(0xffff0002+(i<<8),0); if (dumpWrites) addWrite(0xffff0002+(i<<8),0);
DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_AY8930);
chan[i].dac.sample=ins->amiga.getSample(chan[i].note);
if (chan[i].dac.sample<0 || chan[i].dac.sample>=parent->song.sampleLen) { if (chan[i].dac.sample<0 || chan[i].dac.sample>=parent->song.sampleLen) {
if (dumpWrites) { if (dumpWrites) {
rWrite(0x08+i,0); rWrite(0x08+i,0);
@ -406,7 +404,10 @@ int DivPlatformAY8930::dispatch(DivCommand c) {
if (chan[c.chan].nextPSGMode.dac) { if (chan[c.chan].nextPSGMode.dac) {
if (skipRegisterWrites) break; if (skipRegisterWrites) break;
if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) { 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); if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].dac.sample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
}
if (chan[c.chan].dac.sample<0 || chan[c.chan].dac.sample>=parent->song.sampleLen) { if (chan[c.chan].dac.sample<0 || chan[c.chan].dac.sample>=parent->song.sampleLen) {
chan[c.chan].dac.sample=-1; chan[c.chan].dac.sample=-1;
if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0); if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0);

View file

@ -410,7 +410,7 @@ void DivPlatformES5506::tick(bool sysTick) {
if (chan[i].pcmChanged.changed) { if (chan[i].pcmChanged.changed) {
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 sampleValid=false;
if (((ins->amiga.useNoteMap) && (next>=0 && next<120)) || if (((ins->amiga.useNoteMap) && (next>=0 && next<120)) ||
((!ins->amiga.useNoteMap) && (next>=0 && next<parent->song.sampleLen))) { ((!ins->amiga.useNoteMap) && (next>=0 && next<parent->song.sampleLen))) {
DivInstrumentAmiga::SampleMap& noteMapind=ins->amiga.noteMap[next]; DivInstrumentAmiga::SampleMap& noteMapind=ins->amiga.noteMap[next];
@ -420,7 +420,7 @@ void DivPlatformES5506::tick(bool sysTick) {
} }
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; sampleValid=true;
chan[i].pcm.index=sample; chan[i].pcm.index=sample;
chan[i].pcm.isNoteMap=ins->amiga.useNoteMap; chan[i].pcm.isNoteMap=ins->amiga.useNoteMap;
DivSample* s=parent->getSample(sample); DivSample* s=parent->getSample(sample);
@ -459,7 +459,7 @@ void DivPlatformES5506::tick(bool sysTick) {
} }
} }
} }
if (sampleVaild) { if (sampleValid) {
if (!chan[i].keyOn) { if (!chan[i].keyOn) {
pageWrite(0x20|i,0x03,(chan[i].pcm.direction)?chan[i].pcm.end:chan[i].pcm.start); pageWrite(0x20|i,0x03,(chan[i].pcm.direction)?chan[i].pcm.end:chan[i].pcm.start);
} }
@ -750,12 +750,13 @@ int DivPlatformES5506::dispatch(DivCommand c) {
switch (c.cmd) { switch (c.cmd) {
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 sampleValid=false;
if (((ins->amiga.useNoteMap) && (c.value>=0 && c.value<120)) || if (((ins->amiga.useNoteMap) && (c.value>=0 && c.value<120)) ||
((!ins->amiga.useNoteMap) && (ins->amiga.initSample>=0 && ins->amiga.initSample<parent->song.sampleLen))) { ((!ins->amiga.useNoteMap) && (ins->amiga.initSample>=0 && ins->amiga.initSample<parent->song.sampleLen))) {
int sample=ins->amiga.getSample(c.value); int sample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
if (sample>=0 && sample<parent->song.sampleLen) { if (sample>=0 && sample<parent->song.sampleLen) {
sampleVaild=true; sampleValid=true;
chan[c.chan].volMacroMax=ins->type==DIV_INS_AMIGA?64:0xfff; chan[c.chan].volMacroMax=ins->type==DIV_INS_AMIGA?64:0xfff;
chan[c.chan].panMacroMax=ins->type==DIV_INS_AMIGA?127:0xfff; chan[c.chan].panMacroMax=ins->type==DIV_INS_AMIGA?127:0xfff;
chan[c.chan].pcm.note=c.value; chan[c.chan].pcm.note=c.value;
@ -764,7 +765,7 @@ int DivPlatformES5506::dispatch(DivCommand c) {
chan[c.chan].envelope=ins->es5506.envelope; chan[c.chan].envelope=ins->es5506.envelope;
} }
} }
if (!sampleVaild) { if (!sampleValid) {
chan[c.chan].pcm.index=chan[c.chan].pcm.next=-1; chan[c.chan].pcm.index=chan[c.chan].pcm.next=-1;
chan[c.chan].filter=DivInstrumentES5506::Filter(); chan[c.chan].filter=DivInstrumentES5506::Filter();
chan[c.chan].envelope=DivInstrumentES5506::Envelope(); chan[c.chan].envelope=DivInstrumentES5506::Envelope();

View file

@ -200,7 +200,10 @@ int DivPlatformGA20::dispatch(DivCommand c) {
case DIV_CMD_NOTE_ON: { case DIV_CMD_NOTE_ON: {
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA); DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA);
chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:255; chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:255;
if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value); if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].sample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
}
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
} }

View file

@ -681,7 +681,10 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
if (c.chan>=5 && chan[c.chan].dacMode) { if (c.chan>=5 && chan[c.chan].dacMode) {
//if (skipRegisterWrites) break; //if (skipRegisterWrites) break;
if (ins->type==DIV_INS_AMIGA) { // Furnace mode if (ins->type==DIV_INS_AMIGA) { // Furnace mode
if (c.value!=DIV_NOTE_NULL) chan[c.chan].dacSample=ins->amiga.getSample(c.value); if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].dacSample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
}
if (chan[c.chan].dacSample<0 || chan[c.chan].dacSample>=parent->song.sampleLen) { if (chan[c.chan].dacSample<0 || chan[c.chan].dacSample>=parent->song.sampleLen) {
chan[c.chan].dacSample=-1; chan[c.chan].dacSample=-1;
if (dumpWrites) addWrite(0xffff0002,0); if (dumpWrites) addWrite(0xffff0002,0);

View file

@ -274,7 +274,10 @@ int DivPlatformK007232::dispatch(DivCommand c) {
case DIV_CMD_NOTE_ON: { case DIV_CMD_NOTE_ON: {
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA); DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA);
chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:15; chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:15;
if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value); if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].sample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
}
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
} }

View file

@ -261,13 +261,14 @@ int DivPlatformLynx::dispatch(DivCommand c) {
chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:127; chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:127;
chan[c.chan].pcm=(ins->type==DIV_INS_AMIGA || ins->amiga.useSample); chan[c.chan].pcm=(ins->type==DIV_INS_AMIGA || ins->amiga.useSample);
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
if (chan[c.chan].pcm) { if (chan[c.chan].pcm) {
chan[c.chan].sample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
chan[c.chan].sampleBaseFreq=NOTE_FREQUENCY(c.value); chan[c.chan].sampleBaseFreq=NOTE_FREQUENCY(c.value);
if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value);
chan[c.chan].sampleAccum=0; chan[c.chan].sampleAccum=0;
chan[c.chan].samplePos=0; chan[c.chan].samplePos=0;
} }
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
chan[c.chan].note=c.value; chan[c.chan].note=c.value;
chan[c.chan].actualNote=c.value; chan[c.chan].actualNote=c.value;

View file

@ -176,7 +176,10 @@ int DivPlatformMMC5::dispatch(DivCommand c) {
if (c.chan==2) { // PCM if (c.chan==2) { // PCM
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_STD); DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_STD);
if (ins->type==DIV_INS_AMIGA) { if (ins->type==DIV_INS_AMIGA) {
if (c.value!=DIV_NOTE_NULL) dacSample=ins->amiga.getSample(c.value); if (c.value!=DIV_NOTE_NULL) {
dacSample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
}
if (dacSample<0 || dacSample>=parent->song.sampleLen) { if (dacSample<0 || dacSample>=parent->song.sampleLen) {
dacSample=-1; dacSample=-1;
if (dumpWrites) addWrite(0xffff0002,0); if (dumpWrites) addWrite(0xffff0002,0);

View file

@ -361,7 +361,10 @@ int DivPlatformNES::dispatch(DivCommand c) {
if (c.chan==4) { // PCM if (c.chan==4) { // PCM
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_STD); DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_STD);
if (ins->type==DIV_INS_AMIGA) { if (ins->type==DIV_INS_AMIGA) {
if (c.value!=DIV_NOTE_NULL) dacSample=ins->amiga.getSample(c.value); if (c.value!=DIV_NOTE_NULL) {
dacSample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
}
if (dacSample<0 || dacSample>=parent->song.sampleLen) { if (dacSample<0 || dacSample>=parent->song.sampleLen) {
dacSample=-1; dacSample=-1;
if (dumpWrites && !dpcmMode) addWrite(0xffff0002,0); if (dumpWrites && !dpcmMode) addWrite(0xffff0002,0);

View file

@ -856,7 +856,10 @@ int DivPlatformOPL::dispatch(DivCommand c) {
chan[c.chan].outVol=chan[c.chan].vol; chan[c.chan].outVol=chan[c.chan].vol;
immWrite(18,chan[c.chan].outVol); immWrite(18,chan[c.chan].outVol);
} }
if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value); 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) { if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
DivSample* s=parent->getSample(chan[c.chan].sample); DivSample* s=parent->getSample(chan[c.chan].sample);
immWrite(8,0); immWrite(8,0);

View file

@ -282,7 +282,10 @@ int DivPlatformPCE::dispatch(DivCommand c) {
if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) { if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) {
chan[c.chan].furnaceDac=true; chan[c.chan].furnaceDac=true;
if (skipRegisterWrites) break; if (skipRegisterWrites) break;
if (c.value!=DIV_NOTE_NULL) chan[c.chan].dacSample=ins->amiga.getSample(c.value); if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].dacSample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
}
if (chan[c.chan].dacSample<0 || chan[c.chan].dacSample>=parent->song.sampleLen) { if (chan[c.chan].dacSample<0 || chan[c.chan].dacSample>=parent->song.sampleLen) {
chan[c.chan].dacSample=-1; chan[c.chan].dacSample=-1;
if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0); if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0);

View file

@ -271,7 +271,10 @@ int DivPlatformPCMDAC::dispatch(DivCommand c) {
} }
} }
} else { } else {
if (c.value!=DIV_NOTE_NULL) chan[0].sample=ins->amiga.getSample(c.value); if (c.value!=DIV_NOTE_NULL) {
chan[0].sample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
}
chan[0].useWave=false; chan[0].useWave=false;
} }
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {

View file

@ -450,7 +450,10 @@ int DivPlatformQSound::dispatch(DivCommand c) {
case DIV_CMD_NOTE_ON: { case DIV_CMD_NOTE_ON: {
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA); DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA);
chan[c.chan].isNewQSound=(ins->type==DIV_INS_QSOUND); chan[c.chan].isNewQSound=(ins->type==DIV_INS_QSOUND);
if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value); if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].sample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
}
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].baseFreq=QS_NOTE_FREQUENCY(c.value); chan[c.chan].baseFreq=QS_NOTE_FREQUENCY(c.value);
} }

View file

@ -182,7 +182,10 @@ int DivPlatformRF5C68::dispatch(DivCommand c) {
case DIV_CMD_NOTE_ON: { case DIV_CMD_NOTE_ON: {
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA); DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA);
chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:255; chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:255;
if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value); if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].sample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
}
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value); chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
} }

View file

@ -186,7 +186,10 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) {
if (ins->type==DIV_INS_AMIGA || ins->type==DIV_INS_SEGAPCM) { if (ins->type==DIV_INS_AMIGA || ins->type==DIV_INS_SEGAPCM) {
chan[c.chan].macroVolMul=(ins->type==DIV_INS_AMIGA)?64:127; chan[c.chan].macroVolMul=(ins->type==DIV_INS_AMIGA)?64:127;
chan[c.chan].isNewSegaPCM=(ins->type==DIV_INS_SEGAPCM); chan[c.chan].isNewSegaPCM=(ins->type==DIV_INS_SEGAPCM);
if (c.value!=DIV_NOTE_NULL) chan[c.chan].pcm.sample=ins->amiga.getSample(c.value); if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].pcm.sample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
}
if (chan[c.chan].pcm.sample<0 || chan[c.chan].pcm.sample>=parent->song.sampleLen) { if (chan[c.chan].pcm.sample<0 || chan[c.chan].pcm.sample>=parent->song.sampleLen) {
chan[c.chan].pcm.sample=-1; chan[c.chan].pcm.sample=-1;
rWrite(0x86+(c.chan<<3),3); rWrite(0x86+(c.chan<<3),3);

View file

@ -336,7 +336,10 @@ int DivPlatformSNES::dispatch(DivCommand c) {
} }
chan[c.chan].ws.init(ins,chan[c.chan].wtLen,15,chan[c.chan].insChanged); chan[c.chan].ws.init(ins,chan[c.chan].wtLen,15,chan[c.chan].insChanged);
} else { } else {
if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value); if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].sample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
}
chan[c.chan].useWave=false; chan[c.chan].useWave=false;
} }
if (chan[c.chan].useWave || chan[c.chan].sample<0 || chan[c.chan].sample>=parent->song.sampleLen) { if (chan[c.chan].useWave || chan[c.chan].sample<0 || chan[c.chan].sample>=parent->song.sampleLen) {

View file

@ -261,7 +261,10 @@ int DivPlatformSwan::dispatch(DivCommand c) {
dacPos=0; dacPos=0;
dacPeriod=0; dacPeriod=0;
if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) { if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) {
if (c.value!=DIV_NOTE_NULL) dacSample=ins->amiga.getSample(c.value); if (c.value!=DIV_NOTE_NULL) {
dacSample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
}
if (dacSample<0 || dacSample>=parent->song.sampleLen) { if (dacSample<0 || dacSample>=parent->song.sampleLen) {
dacSample=-1; dacSample=-1;
if (dumpWrites) postWrite(0xffff0002,0); if (dumpWrites) postWrite(0xffff0002,0);

View file

@ -235,7 +235,11 @@ int DivPlatformVERA::dispatch(DivCommand c) {
if (c.chan<16) { if (c.chan<16) {
rWriteLo(c.chan,2,chan[c.chan].vol); rWriteLo(c.chan,2,chan[c.chan].vol);
} else { } else {
if (c.value!=DIV_NOTE_NULL) chan[16].pcm.sample=parent->getIns(chan[16].ins,DIV_INS_VERA)->amiga.getSample(c.value); if (c.value!=DIV_NOTE_NULL) {
DivInstrument* ins=parent->getIns(chan[16].ins,DIV_INS_VERA);
chan[16].pcm.sample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
}
if (chan[16].pcm.sample<0 || chan[16].pcm.sample>=parent->song.sampleLen) { if (chan[16].pcm.sample<0 || chan[16].pcm.sample>=parent->song.sampleLen) {
chan[16].pcm.sample=-1; chan[16].pcm.sample=-1;
} }

View file

@ -179,8 +179,6 @@ void DivPlatformVRC6::tick(bool sysTick) {
if (chan[i].std.phaseReset.val && chan[i].active) { if (chan[i].std.phaseReset.val && chan[i].active) {
if ((i!=2) && (!chan[i].pcm)) { if ((i!=2) && (!chan[i].pcm)) {
if (dumpWrites) addWrite(0xffff0002+(i<<8),0); if (dumpWrites) addWrite(0xffff0002+(i<<8),0);
DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_VRC6);
chan[i].dacSample=ins->amiga.getSample(chan[i].note);
if (chan[i].dacSample<0 || chan[i].dacSample>=parent->song.sampleLen) { if (chan[i].dacSample<0 || chan[i].dacSample>=parent->song.sampleLen) {
if (dumpWrites) { if (dumpWrites) {
chWrite(i,2,0x80); chWrite(i,2,0x80);
@ -242,7 +240,10 @@ int DivPlatformVRC6::dispatch(DivCommand c) {
if (chan[c.chan].pcm) { if (chan[c.chan].pcm) {
if (skipRegisterWrites) break; if (skipRegisterWrites) break;
if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) { if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) {
if (c.value!=DIV_NOTE_NULL) chan[c.chan].dacSample=ins->amiga.getSample(c.value); if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].dacSample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
}
if (chan[c.chan].dacSample<0 || chan[c.chan].dacSample>=parent->song.sampleLen) { if (chan[c.chan].dacSample<0 || chan[c.chan].dacSample>=parent->song.sampleLen) {
chan[c.chan].dacSample=-1; chan[c.chan].dacSample=-1;
if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0); if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0);

View file

@ -540,7 +540,10 @@ int DivPlatformX1_010::dispatch(DivCommand c) {
if (chan[c.chan].furnacePCM) { if (chan[c.chan].furnacePCM) {
chan[c.chan].pcm=true; chan[c.chan].pcm=true;
chan[c.chan].macroInit(ins); chan[c.chan].macroInit(ins);
if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value); 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) { if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
DivSample* s=parent->getSample(chan[c.chan].sample); DivSample* s=parent->getSample(chan[c.chan].sample);
if (isBanked) { if (isBanked) {

View file

@ -896,7 +896,10 @@ int DivPlatformYM2608::dispatch(DivCommand c) {
chan[c.chan].outVol=chan[c.chan].vol; chan[c.chan].outVol=chan[c.chan].vol;
immWrite(0x10b,chan[c.chan].outVol); immWrite(0x10b,chan[c.chan].outVol);
} }
if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value); 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) { if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
DivSample* s=parent->getSample(chan[c.chan].sample); DivSample* s=parent->getSample(chan[c.chan].sample);
immWrite(0x100,0x01); // reset immWrite(0x100,0x01); // reset

View file

@ -827,7 +827,10 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
chan[c.chan].outVol=chan[c.chan].vol; chan[c.chan].outVol=chan[c.chan].vol;
immWrite(0x1b,chan[c.chan].outVol); immWrite(0x1b,chan[c.chan].outVol);
} }
if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value); 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) { if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
DivSample* s=parent->getSample(chan[c.chan].sample); DivSample* s=parent->getSample(chan[c.chan].sample);
immWrite(0x12,(sampleOffB[chan[c.chan].sample]>>8)&0xff); immWrite(0x12,(sampleOffB[chan[c.chan].sample]>>8)&0xff);

View file

@ -894,7 +894,10 @@ int DivPlatformYM2610B::dispatch(DivCommand c) {
chan[c.chan].outVol=chan[c.chan].vol; chan[c.chan].outVol=chan[c.chan].vol;
immWrite(0x1b,chan[c.chan].outVol); immWrite(0x1b,chan[c.chan].outVol);
} }
if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value); 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) { if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
DivSample* s=parent->getSample(chan[c.chan].sample); DivSample* s=parent->getSample(chan[c.chan].sample);
immWrite(0x12,(sampleOffB[chan[c.chan].sample]>>8)&0xff); immWrite(0x12,(sampleOffB[chan[c.chan].sample]>>8)&0xff);

View file

@ -212,7 +212,10 @@ int DivPlatformYMZ280B::dispatch(DivCommand c) {
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA); DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA);
chan[c.chan].isNewYMZ=ins->type==DIV_INS_YMZ280B; chan[c.chan].isNewYMZ=ins->type==DIV_INS_YMZ280B;
chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:255; chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:255;
if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value); if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].sample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
}
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value); chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
} }

View file

@ -169,10 +169,11 @@ int DivPlatformZXBeeperQuadTone::dispatch(DivCommand c) {
} else { } else {
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA); DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA);
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
curSample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
chan[c.chan].note=c.value; chan[c.chan].note=c.value;
curSample=ins->amiga.getSample(c.value);
// TODO support offset commands // TODO support offset commands
curSamplePos=0; curSamplePos=0;
curSamplePeriod=0; curSamplePeriod=0;

View file

@ -4405,11 +4405,10 @@ void FurnaceGUI::drawInsEdit() {
ImGui::BeginDisabled(ins->amiga.useWave); ImGui::BeginDisabled(ins->amiga.useWave);
P(ImGui::Checkbox("Use sample map",&ins->amiga.useNoteMap)); P(ImGui::Checkbox("Use sample map",&ins->amiga.useNoteMap));
if (ins->amiga.useNoteMap) { if (ins->amiga.useNoteMap) {
// TODO: frequency map? if (ImGui::BeginTable("NoteMap",3,ImGuiTableFlags_ScrollY|ImGuiTableFlags_Borders|ImGuiTableFlags_SizingStretchSame)) {
if (ImGui::BeginTable("NoteMap",2/*3*/,ImGuiTableFlags_ScrollY|ImGuiTableFlags_Borders|ImGuiTableFlags_SizingStretchSame)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch);
//ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupScrollFreeze(0,1); ImGui::TableSetupScrollFreeze(0,1);
@ -4417,8 +4416,8 @@ void FurnaceGUI::drawInsEdit() {
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("Sample"); ImGui::Text("Sample");
/*ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("Frequency");*/ ImGui::Text("Note");
for (int i=0; i<120; i++) { for (int i=0; i<120; i++) {
DivInstrumentAmiga::SampleMap& sampleMap=ins->amiga.noteMap[i]; DivInstrumentAmiga::SampleMap& sampleMap=ins->amiga.noteMap[i];
ImGui::TableNextRow(); ImGui::TableNextRow();
@ -4442,17 +4441,28 @@ void FurnaceGUI::drawInsEdit() {
id=fmt::sprintf("%d: %s",j,e->song.sample[j]->name); id=fmt::sprintf("%d: %s",j,e->song.sample[j]->name);
if (ImGui::Selectable(id.c_str(),sampleMap.map==j)) { PARAMETER if (ImGui::Selectable(id.c_str(),sampleMap.map==j)) { PARAMETER
sampleMap.map=j; sampleMap.map=j;
if (sampleMap.freq<=0) sampleMap.freq=(int)((double)e->song.sample[j]->centerRate*pow(2.0,((double)i-48.0)/12.0));
} }
} }
ImGui::EndCombo(); ImGui::EndCombo();
} }
/*ImGui::TableNextColumn();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputInt("##SF",&sampleMap.freq,50,500)) { PARAMETER const char* nName="???";
if (sampleMap.freq<0) sampleMap.freq=0; if ((sampleMap.freq+60)>0 && (sampleMap.freq+60)<180) {
if (sampleMap.freq>262144) sampleMap.freq=262144; nName=noteNames[sampleMap.freq+60];
}*/ }
if (ImGui::BeginCombo("##SN",nName)) {
for (int j=0; j<180; j++) {
const char* nName2="???";
nName2=noteNames[j];
if (ImGui::Selectable(nName2,(sampleMap.freq+60)==j)) {
sampleMap.freq=j-60;
}
}
ImGui::EndCombo();
}
ImGui::PopID(); ImGui::PopID();
} }
ImGui::EndTable(); ImGui::EndTable();