diff --git a/src/engine/platform/lynx.cpp b/src/engine/platform/lynx.cpp index 42cd1b24d..5d9100f8c 100644 --- a/src/engine/platform/lynx.cpp +++ b/src/engine/platform/lynx.cpp @@ -228,21 +228,28 @@ int DivPlatformLynx::dispatch(DivCommand c) { WRITE_CONTROL(c.chan,0x18); WRITE_BACKUP(c.chan,0); } else { + chan[c.chan].sampleNote=DIV_NOTE_NULL; + chan[c.chan].sampleNoteDelta=0; WRITE_FEEDBACK(c.chan,chan[c.chan].duty.feedback); WRITE_CONTROL(c.chan,(chan[c.chan].fd.clockDivider|0x18|chan[c.chan].duty.int_feedback7)); WRITE_BACKUP(c.chan,chan[c.chan].fd.backup); } } - if (c.value!=DIV_NOTE_NULL) { - if (chan[c.chan].pcm) { + if (chan[c.chan].pcm) { + 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; chan[c.chan].sampleBaseFreq=NOTE_FREQUENCY(c.value); - chan[c.chan].sampleAccum=0; - chan[c.chan].samplePos=0; + } else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) { + chan[c.chan].sample=ins->amiga.getSample(chan[c.chan].sampleNote); + c.value=ins->amiga.getFreq(chan[c.chan].sampleNote); } + chan[c.chan].sampleAccum=0; + chan[c.chan].samplePos=0; + } + if (c.value!=DIV_NOTE_NULL) { chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; diff --git a/src/engine/platform/mmc5.cpp b/src/engine/platform/mmc5.cpp index 15d859115..49a19e8c8 100644 --- a/src/engine/platform/mmc5.cpp +++ b/src/engine/platform/mmc5.cpp @@ -181,6 +181,9 @@ int DivPlatformMMC5::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 if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) { + dacSample=ins->amiga.getSample(chan[c.chan].sampleNote); + c.value=ins->amiga.getFreq(chan[c.chan].sampleNote); } if (dacSample<0 || dacSample>=parent->song.sampleLen) { dacSample=-1; @@ -191,8 +194,8 @@ int DivPlatformMMC5::dispatch(DivCommand c) { } dacPos=0; dacPeriod=0; - chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value,false); if (c.value!=DIV_NOTE_NULL) { + chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value,false); chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; } diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index fc54645b1..526944a3d 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -411,6 +411,11 @@ int DivPlatformNES::dispatch(DivCommand c) { 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) { + dacSample=ins->amiga.getSample(chan[c.chan].sampleNote); + if (ins->type==DIV_INS_AMIGA) { + c.value=ins->amiga.getFreq(chan[c.chan].sampleNote); + } } if (dacSample<0 || dacSample>=parent->song.sampleLen) { dacSample=-1; diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index 311ef818b..60800b625 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -278,6 +278,8 @@ int DivPlatformPCE::dispatch(DivCommand c) { chan[c.chan].pcm=true; } else if (chan[c.chan].furnaceDac) { chan[c.chan].pcm=false; + chan[c.chan].sampleNote=DIV_NOTE_NULL; + chan[c.chan].sampleNoteDelta=0; } if (chan[c.chan].pcm) { if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) { @@ -288,6 +290,9 @@ int DivPlatformPCE::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 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; @@ -314,6 +319,8 @@ int DivPlatformPCE::dispatch(DivCommand c) { //chan[c.chan].keyOn=true; } else { chan[c.chan].furnaceDac=false; + chan[c.chan].sampleNote=DIV_NOTE_NULL; + chan[c.chan].sampleNoteDelta=0; if (skipRegisterWrites) break; if (c.value!=DIV_NOTE_NULL) { chan[c.chan].note=c.value; @@ -336,6 +343,8 @@ int DivPlatformPCE::dispatch(DivCommand c) { } break; } + chan[c.chan].sampleNote=DIV_NOTE_NULL; + chan[c.chan].sampleNoteDelta=0; if (c.value!=DIV_NOTE_NULL) { chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); chan[c.chan].freqChanged=true; diff --git a/src/engine/platform/pcmdac.cpp b/src/engine/platform/pcmdac.cpp index 62aed6f95..17776acaa 100644 --- a/src/engine/platform/pcmdac.cpp +++ b/src/engine/platform/pcmdac.cpp @@ -314,6 +314,8 @@ int DivPlatformPCMDAC::dispatch(DivCommand c) { case DIV_CMD_NOTE_ON: { DivInstrument* ins=parent->getIns(chan[0].ins,DIV_INS_AMIGA); if (ins->amiga.useWave) { + chan[c.chan].sampleNote=DIV_NOTE_NULL; + chan[c.chan].sampleNoteDelta=0; chan[0].useWave=true; chan[0].audLen=ins->amiga.waveLen+1; if (chan[0].insChanged) { @@ -329,6 +331,9 @@ int DivPlatformPCMDAC::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 if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) { + chan[c.chan].sample=ins->amiga.getSample(chan[c.chan].sampleNote); + c.value=ins->amiga.getFreq(chan[c.chan].sampleNote); } chan[0].useWave=false; } @@ -337,6 +342,8 @@ int DivPlatformPCMDAC::dispatch(DivCommand c) { } if (chan[0].useWave || chan[0].sample<0 || chan[0].sample>=parent->song.sampleLen) { chan[0].sample=-1; + chan[c.chan].sampleNote=DIV_NOTE_NULL; + chan[c.chan].sampleNoteDelta=0; } if (chan[0].setPos) { chan[0].setPos=false; diff --git a/src/engine/platform/snes.cpp b/src/engine/platform/snes.cpp index ed4a86619..cf1143c7f 100644 --- a/src/engine/platform/snes.cpp +++ b/src/engine/platform/snes.cpp @@ -333,6 +333,8 @@ int DivPlatformSNES::dispatch(DivCommand c) { DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_SNES); if (ins->amiga.useWave) { chan[c.chan].useWave=true; + chan[c.chan].sampleNote=DIV_NOTE_NULL; + chan[c.chan].sampleNoteDelta=0; chan[c.chan].wtLen=ins->amiga.waveLen+1; if (chan[c.chan].insChanged) { if (chan[c.chan].wave<0) { diff --git a/src/engine/platform/su.cpp b/src/engine/platform/su.cpp index 61386d6be..8a80ee7c2 100644 --- a/src/engine/platform/su.cpp +++ b/src/engine/platform/su.cpp @@ -286,6 +286,9 @@ int DivPlatformSoundUnit::dispatch(DivCommand c) { c.value=ins->amiga.getFreq(c.value); chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote; } + } else { + chan[c.chan].sampleNote=DIV_NOTE_NULL; + chan[c.chan].sampleNoteDelta=0; } if (c.value!=DIV_NOTE_NULL) { chan[c.chan].baseFreq=NOTE_SU(c.chan,c.value); diff --git a/src/engine/platform/swan.cpp b/src/engine/platform/swan.cpp index 25ed55f07..51abfef28 100644 --- a/src/engine/platform/swan.cpp +++ b/src/engine/platform/swan.cpp @@ -257,6 +257,8 @@ int DivPlatformSwan::dispatch(DivCommand c) { pcm=true; } else if (furnaceDac) { pcm=false; + chan[c.chan].sampleNote=DIV_NOTE_NULL; + chan[c.chan].sampleNoteDelta=0; } if (pcm) { if (skipRegisterWrites) break; @@ -268,6 +270,9 @@ int DivPlatformSwan::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 if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) { + dacSample=ins->amiga.getSample(chan[c.chan].sampleNote); + c.value=ins->amiga.getFreq(chan[c.chan].sampleNote); } if (dacSample<0 || dacSample>=parent->song.sampleLen) { dacSample=-1; @@ -334,6 +339,8 @@ int DivPlatformSwan::dispatch(DivCommand c) { dacSample=-1; if (dumpWrites) postWrite(0xffff0002,0); pcm=false; + chan[c.chan].sampleNote=DIV_NOTE_NULL; + chan[c.chan].sampleNoteDelta=0; } chan[c.chan].active=false; chan[c.chan].keyOff=true; @@ -414,7 +421,13 @@ int DivPlatformSwan::dispatch(DivCommand c) { } break; case DIV_CMD_SAMPLE_MODE: - if (c.chan==1) pcm=c.value; + if (c.chan==1) { + pcm=c.value; + if (!pcm) { + chan[c.chan].sampleNote=DIV_NOTE_NULL; + chan[c.chan].sampleNoteDelta=0; + } + } break; case DIV_CMD_SAMPLE_BANK: sampleBank=c.value; diff --git a/src/engine/platform/vera.cpp b/src/engine/platform/vera.cpp index cfd3dfff7..fcd13b8ed 100644 --- a/src/engine/platform/vera.cpp +++ b/src/engine/platform/vera.cpp @@ -299,12 +299,15 @@ int DivPlatformVERA::dispatch(DivCommand c) { if (c.chan<16) { rWriteLo(c.chan,2,chan[c.chan].vol); } else { + DivInstrument* ins=parent->getIns(chan[16].ins,DIV_INS_VERA); 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); chan[16].sampleNote=c.value; c.value=ins->amiga.getFreq(c.value); chan[16].sampleNoteDelta=c.value-chan[c.chan].sampleNote; + } else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) { + chan[16].pcm.sample=ins->amiga.getSample(chan[c.chan].sampleNote); + c.value=ins->amiga.getFreq(chan[c.chan].sampleNote); } 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 66955408e..c87a747db 100644 --- a/src/engine/platform/vrc6.cpp +++ b/src/engine/platform/vrc6.cpp @@ -236,6 +236,8 @@ int DivPlatformVRC6::dispatch(DivCommand c) { chan[c.chan].pcm=true; } else if (chan[c.chan].furnaceDac) { chan[c.chan].pcm=false; + chan[c.chan].sampleNote=DIV_NOTE_NULL; + chan[c.chan].sampleNoteDelta=0; } if (chan[c.chan].pcm) { if (skipRegisterWrites) break; @@ -245,6 +247,9 @@ int DivPlatformVRC6::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 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; @@ -272,6 +277,8 @@ int DivPlatformVRC6::dispatch(DivCommand c) { //chan[c.chan].keyOn=true; chan[c.chan].furnaceDac=true; } else { + chan[c.chan].sampleNote=DIV_NOTE_NULL; + chan[c.chan].sampleNoteDelta=0; if (c.value!=DIV_NOTE_NULL) { chan[c.chan].note=c.value; } @@ -316,6 +323,8 @@ int DivPlatformVRC6::dispatch(DivCommand c) { chan[c.chan].dacSample=-1; if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0); chan[c.chan].pcm=false; + chan[c.chan].sampleNote=DIV_NOTE_NULL; + chan[c.chan].sampleNoteDelta=0; chan[c.chan].active=false; chan[c.chan].keyOff=true; chan[c.chan].macroInit(NULL); @@ -384,6 +393,10 @@ int DivPlatformVRC6::dispatch(DivCommand c) { case DIV_CMD_SAMPLE_MODE: if (c.chan!=2) { // pulse chan[c.chan].pcm=c.value; + if (!chan[c.chan].pcm) { + chan[c.chan].sampleNote=DIV_NOTE_NULL; + chan[c.chan].sampleNoteDelta=0; + } } break; case DIV_CMD_SAMPLE_BANK: diff --git a/src/engine/platform/x1_010.cpp b/src/engine/platform/x1_010.cpp index f5625ef87..77d34b668 100644 --- a/src/engine/platform/x1_010.cpp +++ b/src/engine/platform/x1_010.cpp @@ -536,6 +536,8 @@ int DivPlatformX1_010::dispatch(DivCommand c) { chan[c.chan].furnacePCM=true; } else { chan[c.chan].furnacePCM=false; + chan[c.chan].sampleNote=DIV_NOTE_NULL; + chan[c.chan].sampleNoteDelta=0; } if (skipRegisterWrites) break; if (chan[c.chan].furnacePCM) { @@ -610,6 +612,8 @@ int DivPlatformX1_010::dispatch(DivCommand c) { } } else 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].baseFreq=NoteX1_010(c.chan,chan[c.chan].note); chan[c.chan].fixedFreq=0; chan[c.chan].freqChanged=true; diff --git a/src/engine/platform/zxbeeperquadtone.cpp b/src/engine/platform/zxbeeperquadtone.cpp index d44f8d186..e9c9e5d68 100644 --- a/src/engine/platform/zxbeeperquadtone.cpp +++ b/src/engine/platform/zxbeeperquadtone.cpp @@ -196,6 +196,12 @@ int DivPlatformZXBeeperQuadTone::dispatch(DivCommand c) { // TODO support offset commands curSamplePos=0; curSamplePeriod=0; + } else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) { + curSample=ins->amiga.getSample(chan[c.chan].sampleNote); + c.value=ins->amiga.getFreq(chan[c.chan].sampleNote); + // TODO support offset commands + curSamplePos=0; + curSamplePeriod=0; } chan[c.chan].active=true; chan[c.chan].keyOn=true;