From 99d2199db6d9ddb617dce5a65c9bda19b26c5c6b Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 7 Apr 2023 16:54:05 -0500 Subject: [PATCH] dev152 - sample map notes, part 1 --- papers/format.md | 9 +++++++ papers/newIns.md | 2 +- src/engine/engine.h | 4 +-- src/engine/instrument.cpp | 12 +++++++++ src/engine/instrument.h | 7 +++--- src/engine/platform/amiga.cpp | 5 +++- src/engine/platform/ay.cpp | 7 +++--- src/engine/platform/ay8930.cpp | 7 +++--- src/engine/platform/es5506.cpp | 13 +++++----- src/engine/platform/ga20.cpp | 5 +++- src/engine/platform/genesis.cpp | 5 +++- src/engine/platform/k007232.cpp | 5 +++- src/engine/platform/lynx.cpp | 5 ++-- src/engine/platform/mmc5.cpp | 5 +++- src/engine/platform/nes.cpp | 5 +++- src/engine/platform/opl.cpp | 5 +++- src/engine/platform/pce.cpp | 5 +++- src/engine/platform/pcmdac.cpp | 5 +++- src/engine/platform/qsound.cpp | 5 +++- src/engine/platform/rf5c68.cpp | 5 +++- src/engine/platform/segapcm.cpp | 5 +++- src/engine/platform/snes.cpp | 5 +++- src/engine/platform/swan.cpp | 5 +++- src/engine/platform/vera.cpp | 6 ++++- src/engine/platform/vrc6.cpp | 7 +++--- src/engine/platform/x1_010.cpp | 5 +++- src/engine/platform/ym2608.cpp | 5 +++- src/engine/platform/ym2610.cpp | 5 +++- src/engine/platform/ym2610b.cpp | 5 +++- src/engine/platform/ymz280b.cpp | 5 +++- src/engine/platform/zxbeeperquadtone.cpp | 3 ++- src/gui/insEdit.cpp | 32 ++++++++++++++++-------- 32 files changed, 154 insertions(+), 55 deletions(-) diff --git a/papers/format.md b/papers/format.md index f166d43ef..a2c42f04d 100644 --- a/papers/format.md +++ b/papers/format.md @@ -32,6 +32,15 @@ these fields are 0 in format versions prior to 100 (0.6pre1). 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 - 142: Furnace dev142 - 141: Furnace Tournament Edition (for intro tune contest) diff --git a/papers/newIns.md b/papers/newIns.md index 9176bd1ac..84369a6c7 100644 --- a/papers/newIns.md +++ b/papers/newIns.md @@ -389,7 +389,7 @@ the sample map format: ``` size | description -----|------------------------------------ - 2 | note to play + 2 | note to play (>=152) or reserved 2 | sample to play ``` diff --git a/src/engine/engine.h b/src/engine/engine.h index c896b082c..85da26ea9 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -53,8 +53,8 @@ #define EXTERN_BUSY_BEGIN_SOFT e->softLocked=true; e->isBusy.lock(); #define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false; -#define DIV_VERSION "dev151" -#define DIV_ENGINE_VERSION 151 +#define DIV_VERSION "dev152" +#define DIV_ENGINE_VERSION 152 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index c34cc82fe..97fd65cc1 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -2098,6 +2098,12 @@ void DivInstrument::readFeatureSM(SafeReader& reader, short version) { amiga.noteMap[note].freq=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; @@ -2965,6 +2971,12 @@ DivDataErrors DivInstrument::readInsDataOld(SafeReader &reader, short version) { for (int note=0; note<120; note++) { amiga.noteMap[note].map=reader.readS(); } + + if (version<152) { + for (int note=0; note<120; note++) { + amiga.noteMap[note].freq=note; + } + } } } diff --git a/src/engine/instrument.h b/src/engine/instrument.h index c53688ec6..c2e4a7313 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -414,7 +414,7 @@ struct DivInstrumentAmiga { if (note>119) note=119; return noteMap[note].freq; } - return -1; + return note; } DivInstrumentAmiga(): @@ -423,8 +423,9 @@ struct DivInstrumentAmiga { useSample(false), useWave(false), waveLen(31) { - for (SampleMap& elem: noteMap) { - elem=SampleMap(); + for (int i=0; i<120; i++) { + noteMap[i].map=-1; + noteMap[i].freq=i; } } }; diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index b04eefbeb..7c0b8c243 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -560,7 +560,10 @@ int DivPlatformAmiga::dispatch(DivCommand c) { } } } 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; } if (c.value!=DIV_NOTE_NULL) { diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index 145ab5622..76637f38e 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -292,8 +292,6 @@ void DivPlatformAY8910::tick(bool sysTick) { if (chan[i].std.phaseReset.val==1) { if (chan[i].nextPSGMode.dac) { 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 (dumpWrites) { rWrite(0x08+i,0); @@ -405,7 +403,10 @@ int DivPlatformAY8910::dispatch(DivCommand c) { if (chan[c.chan].nextPSGMode.dac) { if (skipRegisterWrites) break; if (!parent->song.disableSampleMacro && (ins->type==DIV_INS_AMIGA || ins->amiga.useSample)) { - if (c.value!=DIV_NOTE_NULL) chan[c.chan].dac.sample=ins->amiga.getSample(c.value); + 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) { chan[c.chan].dac.sample=-1; if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0); diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index ba4e8099a..8561548d0 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -280,8 +280,6 @@ void DivPlatformAY8930::tick(bool sysTick) { if (chan[i].std.phaseReset.val==1) { if (chan[i].nextPSGMode.dac) { 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 (dumpWrites) { rWrite(0x08+i,0); @@ -406,7 +404,10 @@ int DivPlatformAY8930::dispatch(DivCommand c) { if (chan[c.chan].nextPSGMode.dac) { if (skipRegisterWrites) break; if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) { - if (c.value!=DIV_NOTE_NULL) chan[c.chan].dac.sample=ins->amiga.getSample(c.value); + 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) { chan[c.chan].dac.sample=-1; if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0); diff --git a/src/engine/platform/es5506.cpp b/src/engine/platform/es5506.cpp index 7244426b7..28ad45eb2 100644 --- a/src/engine/platform/es5506.cpp +++ b/src/engine/platform/es5506.cpp @@ -410,7 +410,7 @@ void DivPlatformES5506::tick(bool sysTick) { if (chan[i].pcmChanged.changed) { if (chan[i].pcmChanged.index) { const int next=chan[i].pcm.next; - bool sampleVaild=false; + bool sampleValid=false; if (((ins->amiga.useNoteMap) && (next>=0 && next<120)) || ((!ins->amiga.useNoteMap) && (next>=0 && nextsong.sampleLen))) { DivInstrumentAmiga::SampleMap& noteMapind=ins->amiga.noteMap[next]; @@ -420,7 +420,7 @@ void DivPlatformES5506::tick(bool sysTick) { } if (sample>=0 && samplesong.sampleLen) { const unsigned int offES5506=sampleOffES5506[sample]; - sampleVaild=true; + sampleValid=true; chan[i].pcm.index=sample; chan[i].pcm.isNoteMap=ins->amiga.useNoteMap; DivSample* s=parent->getSample(sample); @@ -459,7 +459,7 @@ void DivPlatformES5506::tick(bool sysTick) { } } } - if (sampleVaild) { + if (sampleValid) { if (!chan[i].keyOn) { 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) { case DIV_CMD_NOTE_ON: { 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)) || ((!ins->amiga.useNoteMap) && (ins->amiga.initSample>=0 && ins->amiga.initSamplesong.sampleLen))) { int sample=ins->amiga.getSample(c.value); + c.value=ins->amiga.getFreq(c.value); if (sample>=0 && samplesong.sampleLen) { - sampleVaild=true; + sampleValid=true; 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].pcm.note=c.value; @@ -764,7 +765,7 @@ int DivPlatformES5506::dispatch(DivCommand c) { 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].filter=DivInstrumentES5506::Filter(); chan[c.chan].envelope=DivInstrumentES5506::Envelope(); diff --git a/src/engine/platform/ga20.cpp b/src/engine/platform/ga20.cpp index 527e80f1d..7b9d86a19 100644 --- a/src/engine/platform/ga20.cpp +++ b/src/engine/platform/ga20.cpp @@ -200,7 +200,10 @@ int DivPlatformGA20::dispatch(DivCommand c) { case DIV_CMD_NOTE_ON: { DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA); 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) { chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); } diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 089d33e27..e32ec528b 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -681,7 +681,10 @@ int DivPlatformGenesis::dispatch(DivCommand c) { if (c.chan>=5 && chan[c.chan].dacMode) { //if (skipRegisterWrites) break; 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) { chan[c.chan].dacSample=-1; if (dumpWrites) addWrite(0xffff0002,0); diff --git a/src/engine/platform/k007232.cpp b/src/engine/platform/k007232.cpp index daa661f6f..04e1bde5e 100644 --- a/src/engine/platform/k007232.cpp +++ b/src/engine/platform/k007232.cpp @@ -274,7 +274,10 @@ int DivPlatformK007232::dispatch(DivCommand c) { case DIV_CMD_NOTE_ON: { DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA); 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) { chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); } diff --git a/src/engine/platform/lynx.cpp b/src/engine/platform/lynx.cpp index a8b2cb88d..6e87fea78 100644 --- a/src/engine/platform/lynx.cpp +++ b/src/engine/platform/lynx.cpp @@ -261,13 +261,14 @@ int DivPlatformLynx::dispatch(DivCommand c) { chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:127; chan[c.chan].pcm=(ins->type==DIV_INS_AMIGA || ins->amiga.useSample); if (c.value!=DIV_NOTE_NULL) { - chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); 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); - if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value); chan[c.chan].sampleAccum=0; chan[c.chan].samplePos=0; } + chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; chan[c.chan].actualNote=c.value; diff --git a/src/engine/platform/mmc5.cpp b/src/engine/platform/mmc5.cpp index b130f2cbf..11b04e815 100644 --- a/src/engine/platform/mmc5.cpp +++ b/src/engine/platform/mmc5.cpp @@ -176,7 +176,10 @@ int DivPlatformMMC5::dispatch(DivCommand c) { if (c.chan==2) { // PCM DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_STD); if (ins->type==DIV_INS_AMIGA) { - if (c.value!=DIV_NOTE_NULL) dacSample=ins->amiga.getSample(c.value); + 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) { dacSample=-1; if (dumpWrites) addWrite(0xffff0002,0); diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index 88c7253ee..67cdc620c 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -361,7 +361,10 @@ int DivPlatformNES::dispatch(DivCommand c) { if (c.chan==4) { // PCM DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_STD); if (ins->type==DIV_INS_AMIGA) { - if (c.value!=DIV_NOTE_NULL) dacSample=ins->amiga.getSample(c.value); + 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) { dacSample=-1; if (dumpWrites && !dpcmMode) addWrite(0xffff0002,0); diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index ff57f9afb..6fea25c3c 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -856,7 +856,10 @@ int DivPlatformOPL::dispatch(DivCommand c) { chan[c.chan].outVol=chan[c.chan].vol; 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].samplesong.sampleLen) { DivSample* s=parent->getSample(chan[c.chan].sample); immWrite(8,0); diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index 95d483264..a920a4d06 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -282,7 +282,10 @@ int DivPlatformPCE::dispatch(DivCommand c) { if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) { chan[c.chan].furnaceDac=true; if (skipRegisterWrites) break; - if (c.value!=DIV_NOTE_NULL) chan[c.chan].dacSample=ins->amiga.getSample(c.value); + 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) { chan[c.chan].dacSample=-1; if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0); diff --git a/src/engine/platform/pcmdac.cpp b/src/engine/platform/pcmdac.cpp index f7b3af715..0b59accb1 100644 --- a/src/engine/platform/pcmdac.cpp +++ b/src/engine/platform/pcmdac.cpp @@ -271,7 +271,10 @@ int DivPlatformPCMDAC::dispatch(DivCommand c) { } } } 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; } if (c.value!=DIV_NOTE_NULL) { diff --git a/src/engine/platform/qsound.cpp b/src/engine/platform/qsound.cpp index f73f85dab..2e23abb4e 100644 --- a/src/engine/platform/qsound.cpp +++ b/src/engine/platform/qsound.cpp @@ -450,7 +450,10 @@ int DivPlatformQSound::dispatch(DivCommand c) { case DIV_CMD_NOTE_ON: { DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA); 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) { chan[c.chan].baseFreq=QS_NOTE_FREQUENCY(c.value); } diff --git a/src/engine/platform/rf5c68.cpp b/src/engine/platform/rf5c68.cpp index 149098b8c..fbf8e00dd 100644 --- a/src/engine/platform/rf5c68.cpp +++ b/src/engine/platform/rf5c68.cpp @@ -182,7 +182,10 @@ int DivPlatformRF5C68::dispatch(DivCommand c) { case DIV_CMD_NOTE_ON: { DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA); 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) { chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value); } diff --git a/src/engine/platform/segapcm.cpp b/src/engine/platform/segapcm.cpp index 37fa9ecab..9c7f6a631 100644 --- a/src/engine/platform/segapcm.cpp +++ b/src/engine/platform/segapcm.cpp @@ -186,7 +186,10 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) { 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].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) { chan[c.chan].pcm.sample=-1; rWrite(0x86+(c.chan<<3),3); diff --git a/src/engine/platform/snes.cpp b/src/engine/platform/snes.cpp index 1fb5a12cd..48351493c 100644 --- a/src/engine/platform/snes.cpp +++ b/src/engine/platform/snes.cpp @@ -336,7 +336,10 @@ int DivPlatformSNES::dispatch(DivCommand c) { } chan[c.chan].ws.init(ins,chan[c.chan].wtLen,15,chan[c.chan].insChanged); } 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; } if (chan[c.chan].useWave || chan[c.chan].sample<0 || chan[c.chan].sample>=parent->song.sampleLen) { diff --git a/src/engine/platform/swan.cpp b/src/engine/platform/swan.cpp index 4e0b83724..209e2fc2c 100644 --- a/src/engine/platform/swan.cpp +++ b/src/engine/platform/swan.cpp @@ -261,7 +261,10 @@ int DivPlatformSwan::dispatch(DivCommand c) { dacPos=0; dacPeriod=0; if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) { - if (c.value!=DIV_NOTE_NULL) dacSample=ins->amiga.getSample(c.value); + 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) { dacSample=-1; if (dumpWrites) postWrite(0xffff0002,0); diff --git a/src/engine/platform/vera.cpp b/src/engine/platform/vera.cpp index 820f399a5..6b2dd56cb 100644 --- a/src/engine/platform/vera.cpp +++ b/src/engine/platform/vera.cpp @@ -235,7 +235,11 @@ int DivPlatformVERA::dispatch(DivCommand c) { if (c.chan<16) { rWriteLo(c.chan,2,chan[c.chan].vol); } 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) { chan[16].pcm.sample=-1; } diff --git a/src/engine/platform/vrc6.cpp b/src/engine/platform/vrc6.cpp index 912a589ea..2aeb3897d 100644 --- a/src/engine/platform/vrc6.cpp +++ b/src/engine/platform/vrc6.cpp @@ -179,8 +179,6 @@ void DivPlatformVRC6::tick(bool sysTick) { if (chan[i].std.phaseReset.val && chan[i].active) { if ((i!=2) && (!chan[i].pcm)) { 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 (dumpWrites) { chWrite(i,2,0x80); @@ -242,7 +240,10 @@ int DivPlatformVRC6::dispatch(DivCommand c) { if (chan[c.chan].pcm) { if (skipRegisterWrites) break; 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) { chan[c.chan].dacSample=-1; if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0); diff --git a/src/engine/platform/x1_010.cpp b/src/engine/platform/x1_010.cpp index 66e4d7bb3..638001740 100644 --- a/src/engine/platform/x1_010.cpp +++ b/src/engine/platform/x1_010.cpp @@ -540,7 +540,10 @@ int DivPlatformX1_010::dispatch(DivCommand c) { if (chan[c.chan].furnacePCM) { chan[c.chan].pcm=true; 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].samplesong.sampleLen) { DivSample* s=parent->getSample(chan[c.chan].sample); if (isBanked) { diff --git a/src/engine/platform/ym2608.cpp b/src/engine/platform/ym2608.cpp index 523ee701b..92c1caa13 100644 --- a/src/engine/platform/ym2608.cpp +++ b/src/engine/platform/ym2608.cpp @@ -896,7 +896,10 @@ int DivPlatformYM2608::dispatch(DivCommand c) { chan[c.chan].outVol=chan[c.chan].vol; immWrite(0x10b,chan[c.chan].outVol); } - if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value); + 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].samplesong.sampleLen) { DivSample* s=parent->getSample(chan[c.chan].sample); immWrite(0x100,0x01); // reset diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index 044fe2c2e..cbc2847c9 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -827,7 +827,10 @@ int DivPlatformYM2610::dispatch(DivCommand c) { chan[c.chan].outVol=chan[c.chan].vol; immWrite(0x1b,chan[c.chan].outVol); } - if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value); + 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].samplesong.sampleLen) { DivSample* s=parent->getSample(chan[c.chan].sample); immWrite(0x12,(sampleOffB[chan[c.chan].sample]>>8)&0xff); diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index 20d83dc1f..28ded57d9 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -894,7 +894,10 @@ int DivPlatformYM2610B::dispatch(DivCommand c) { chan[c.chan].outVol=chan[c.chan].vol; immWrite(0x1b,chan[c.chan].outVol); } - if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value); + 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].samplesong.sampleLen) { DivSample* s=parent->getSample(chan[c.chan].sample); immWrite(0x12,(sampleOffB[chan[c.chan].sample]>>8)&0xff); diff --git a/src/engine/platform/ymz280b.cpp b/src/engine/platform/ymz280b.cpp index e10dda43f..a8838ae9a 100644 --- a/src/engine/platform/ymz280b.cpp +++ b/src/engine/platform/ymz280b.cpp @@ -212,7 +212,10 @@ int DivPlatformYMZ280B::dispatch(DivCommand c) { DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA); chan[c.chan].isNewYMZ=ins->type==DIV_INS_YMZ280B; 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) { chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value); } diff --git a/src/engine/platform/zxbeeperquadtone.cpp b/src/engine/platform/zxbeeperquadtone.cpp index 114c8b66d..8bfce1701 100644 --- a/src/engine/platform/zxbeeperquadtone.cpp +++ b/src/engine/platform/zxbeeperquadtone.cpp @@ -169,10 +169,11 @@ int DivPlatformZXBeeperQuadTone::dispatch(DivCommand c) { } else { DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA); 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].freqChanged=true; chan[c.chan].note=c.value; - curSample=ins->amiga.getSample(c.value); // TODO support offset commands curSamplePos=0; curSamplePeriod=0; diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index abac70c1a..f2d97ac04 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -4405,11 +4405,10 @@ void FurnaceGUI::drawInsEdit() { ImGui::BeginDisabled(ins->amiga.useWave); P(ImGui::Checkbox("Use sample map",&ins->amiga.useNoteMap)); if (ins->amiga.useNoteMap) { - // TODO: frequency map? - if (ImGui::BeginTable("NoteMap",2/*3*/,ImGuiTableFlags_ScrollY|ImGuiTableFlags_Borders|ImGuiTableFlags_SizingStretchSame)) { + if (ImGui::BeginTable("NoteMap",3,ImGuiTableFlags_ScrollY|ImGuiTableFlags_Borders|ImGuiTableFlags_SizingStretchSame)) { ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch); - //ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch); + ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupScrollFreeze(0,1); @@ -4417,8 +4416,8 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextColumn(); ImGui::TableNextColumn(); ImGui::Text("Sample"); - /*ImGui::TableNextColumn(); - ImGui::Text("Frequency");*/ + ImGui::TableNextColumn(); + ImGui::Text("Note"); for (int i=0; i<120; i++) { DivInstrumentAmiga::SampleMap& sampleMap=ins->amiga.noteMap[i]; ImGui::TableNextRow(); @@ -4442,17 +4441,28 @@ void FurnaceGUI::drawInsEdit() { id=fmt::sprintf("%d: %s",j,e->song.sample[j]->name); if (ImGui::Selectable(id.c_str(),sampleMap.map==j)) { PARAMETER 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::TableNextColumn(); + + ImGui::TableNextColumn(); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - if (ImGui::InputInt("##SF",&sampleMap.freq,50,500)) { PARAMETER - if (sampleMap.freq<0) sampleMap.freq=0; - if (sampleMap.freq>262144) sampleMap.freq=262144; - }*/ + const char* nName="???"; + if ((sampleMap.freq+60)>0 && (sampleMap.freq+60)<180) { + 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::EndTable();