diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index e92a3acda..6f50214cc 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -408,7 +408,7 @@ int DivPlatformAY8910::dispatch(DivCommand c) { chan[c.chan].sampleNote=c.value; c.value=ins->amiga.getFreq(c.value); chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote; - } else { + } else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) { chan[c.chan].dac.sample=ins->amiga.getSample(chan[c.chan].sampleNote); c.value=ins->amiga.getFreq(chan[c.chan].sampleNote); } diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index 1a6072717..6fca42e06 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -406,7 +406,12 @@ int DivPlatformAY8930::dispatch(DivCommand c) { if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) { if (c.value!=DIV_NOTE_NULL) { chan[c.chan].dac.sample=ins->amiga.getSample(c.value); + chan[c.chan].sampleNote=c.value; c.value=ins->amiga.getFreq(c.value); + chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote; + } else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) { + chan[c.chan].dac.sample=ins->amiga.getSample(chan[c.chan].sampleNote); + c.value=ins->amiga.getFreq(chan[c.chan].sampleNote); } if (chan[c.chan].dac.sample<0 || chan[c.chan].dac.sample>=parent->song.sampleLen) { chan[c.chan].dac.sample=-1; @@ -458,6 +463,8 @@ int DivPlatformAY8930::dispatch(DivCommand c) { break; } if (c.value!=DIV_NOTE_NULL) { + chan[c.chan].sampleNote=DIV_NOTE_NULL; + chan[c.chan].sampleNoteDelta=0; chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; @@ -520,7 +527,7 @@ int DivPlatformAY8930::dispatch(DivCommand c) { break; } case DIV_CMD_NOTE_PORTA: { - int destFreq=NOTE_PERIODIC(c.value2); + int destFreq=NOTE_PERIODIC(c.value2+chan[c.chan].sampleNoteDelta); bool return2=false; if (destFreq>chan[c.chan].baseFreq) { chan[c.chan].baseFreq+=c.value; @@ -543,7 +550,7 @@ int DivPlatformAY8930::dispatch(DivCommand c) { break; } case DIV_CMD_LEGATO: { - chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); + chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+chan[c.chan].sampleNoteDelta); chan[c.chan].freqChanged=true; break; } diff --git a/src/engine/platform/c140.cpp b/src/engine/platform/c140.cpp index 14d203587..c83a93247 100644 --- a/src/engine/platform/c140.cpp +++ b/src/engine/platform/c140.cpp @@ -320,7 +320,9 @@ int DivPlatformC140::dispatch(DivCommand c) { chan[c.chan].macroPanMul=ins->type==DIV_INS_AMIGA?127:255; if (c.value!=DIV_NOTE_NULL) { chan[c.chan].sample=ins->amiga.getSample(c.value); + chan[c.chan].sampleNote=c.value; c.value=ins->amiga.getFreq(c.value); + chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote; } if (c.value!=DIV_NOTE_NULL) { chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value); @@ -393,7 +395,7 @@ int DivPlatformC140::dispatch(DivCommand c) { chan[c.chan].freqChanged=true; break; case DIV_CMD_NOTE_PORTA: { - int destFreq=NOTE_FREQUENCY(c.value2); + int destFreq=NOTE_FREQUENCY(c.value2+chan[c.chan].sampleNoteDelta); bool return2=false; if (destFreq>chan[c.chan].baseFreq) { chan[c.chan].baseFreq+=c.value; @@ -416,7 +418,7 @@ int DivPlatformC140::dispatch(DivCommand c) { break; } case DIV_CMD_LEGATO: { - chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val-12):(0))); + chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value+chan[c.chan].sampleNoteDelta+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val-12):(0))); chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; break; diff --git a/src/engine/platform/es5506.cpp b/src/engine/platform/es5506.cpp index 6c6e1732f..ee7db20fa 100644 --- a/src/engine/platform/es5506.cpp +++ b/src/engine/platform/es5506.cpp @@ -727,19 +727,24 @@ int DivPlatformES5506::dispatch(DivCommand c) { 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); + chan[c.chan].sampleNote=c.value; if (sample>=0 && samplesong.sampleLen) { 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.next=ins->amiga.useNoteMap?c.value:sample; c.value=ins->amiga.getFreq(c.value); + chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote; chan[c.chan].pcm.note=c.value; chan[c.chan].filter=ins->es5506.filter; chan[c.chan].envelope=ins->es5506.envelope; + } else { + chan[c.chan].sampleNoteDelta=0; } } if (!sampleValid) { chan[c.chan].pcm.index=chan[c.chan].pcm.next=-1; + chan[c.chan].sampleNoteDelta=0; chan[c.chan].filter=DivInstrumentES5506::Filter(); chan[c.chan].envelope=DivInstrumentES5506::Envelope(); } @@ -962,7 +967,7 @@ int DivPlatformES5506::dispatch(DivCommand c) { break; case DIV_CMD_NOTE_PORTA: { int nextFreq=chan[c.chan].baseFreq; - const int destFreq=NOTE_ES5506(c.chan,c.value2); + const int destFreq=NOTE_ES5506(c.chan,c.value2+chan[c.chan].sampleNoteDelta); bool return2=false; if (destFreq>nextFreq) { nextFreq+=c.value; @@ -987,7 +992,7 @@ int DivPlatformES5506::dispatch(DivCommand c) { } case DIV_CMD_LEGATO: { chan[c.chan].note=c.value; - chan[c.chan].nextNote=chan[c.chan].note+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val-12):(0)); + chan[c.chan].nextNote=chan[c.chan].note+chan[c.chan].sampleNoteDelta+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val-12):(0)); chan[c.chan].noteChanged.note=1; break; } diff --git a/src/engine/platform/ga20.cpp b/src/engine/platform/ga20.cpp index df8677584..2098f140b 100644 --- a/src/engine/platform/ga20.cpp +++ b/src/engine/platform/ga20.cpp @@ -207,7 +207,9 @@ int DivPlatformGA20::dispatch(DivCommand c) { 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); + chan[c.chan].sampleNote=c.value; c.value=ins->amiga.getFreq(c.value); + chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote; } if (c.value!=DIV_NOTE_NULL) { chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); @@ -263,7 +265,7 @@ int DivPlatformGA20::dispatch(DivCommand c) { chan[c.chan].freqChanged=true; break; case DIV_CMD_NOTE_PORTA: { - const int destFreq=NOTE_PERIODIC(c.value2); + const int destFreq=NOTE_PERIODIC(c.value2+chan[c.chan].sampleNoteDelta); bool return2=false; if (destFreq>chan[c.chan].baseFreq) { chan[c.chan].baseFreq+=c.value; @@ -286,7 +288,7 @@ int DivPlatformGA20::dispatch(DivCommand c) { break; } case DIV_CMD_LEGATO: { - chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val-12):(0))); + chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+chan[c.chan].sampleNoteDelta+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val-12):(0))); chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; break; diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 57bb640e6..f59cf1975 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -704,8 +704,12 @@ int DivPlatformGenesis::dispatch(DivCommand c) { } else if (chan[c.chan].furnaceDac) { chan[c.chan].dacMode=0; rWrite(0x2b,0<<7); + chan[c.chan].sampleNote=DIV_NOTE_NULL; + chan[c.chan].sampleNoteDelta=0; } else if (!chan[c.chan].dacMode) { rWrite(0x2b,0<<7); + chan[c.chan].sampleNote=DIV_NOTE_NULL; + chan[c.chan].sampleNoteDelta=0; } } if (c.chan>=5 && chan[c.chan].dacMode) { @@ -713,7 +717,12 @@ int DivPlatformGenesis::dispatch(DivCommand c) { if (ins->type==DIV_INS_AMIGA) { // Furnace mode if (c.value!=DIV_NOTE_NULL) { chan[c.chan].dacSample=ins->amiga.getSample(c.value); + chan[c.chan].sampleNote=c.value; c.value=ins->amiga.getFreq(c.value); + chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote; + } else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) { + chan[c.chan].dacSample=ins->amiga.getSample(chan[c.chan].sampleNote); + c.value=ins->amiga.getFreq(chan[c.chan].sampleNote); } if (chan[c.chan].dacSample<0 || chan[c.chan].dacSample>=parent->song.sampleLen) { chan[c.chan].dacSample=-1; @@ -752,6 +761,8 @@ int DivPlatformGenesis::dispatch(DivCommand c) { if (c.value!=DIV_NOTE_NULL) { chan[c.chan].note=c.value; } + chan[c.chan].sampleNote=DIV_NOTE_NULL; + chan[c.chan].sampleNoteDelta=0; chan[c.chan].dacSample=12*chan[c.chan].sampleBank+chan[c.chan].note%12; if (chan[c.chan].dacSample>=parent->song.sampleLen) { chan[c.chan].dacSample=-1; @@ -863,7 +874,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) { } case DIV_CMD_NOTE_PORTA: { if (parent->song.linearPitch==2) { - int destFreq=NOTE_FREQUENCY(c.value2); + int destFreq=NOTE_FREQUENCY(c.value2+chan[c.chan].sampleNoteDelta); bool return2=false; if (destFreq>chan[c.chan].baseFreq) { chan[c.chan].baseFreq+=c.value; @@ -909,7 +920,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) { break; } if (c.chan>=5 && chan[c.chan].furnaceDac && chan[c.chan].dacMode) { - int destFreq=parent->calcBaseFreq(1,1,c.value2,false); + int destFreq=parent->calcBaseFreq(1,1,c.value2+chan[c.chan].sampleNoteDelta,false); bool return2=false; if (destFreq>chan[c.chan].baseFreq) { chan[c.chan].baseFreq+=c.value*16; @@ -963,7 +974,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) { if (c.chan==csmChan) { chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); } else if (c.chan>=5 && chan[c.chan].furnaceDac && chan[c.chan].dacMode) { - chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value,false); + chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value+chan[c.chan].sampleNoteDelta,false); } else { if (chan[c.chan].insChanged) { DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_FM);