From e2a41974ff96c1704912f535e56dbe020ad6b801 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 9 Dec 2021 03:13:37 -0500 Subject: [PATCH] PCM sample bank support --- src/engine/dispatch.h | 1 + src/engine/platform/arcade.cpp | 9 ++++++++- src/engine/platform/arcade.h | 2 +- src/engine/platform/genesis.cpp | 9 ++++++++- src/engine/platform/genesis.h | 1 + src/engine/platform/nes.cpp | 9 ++++++++- src/engine/platform/nes.h | 2 +- src/engine/platform/pce.cpp | 9 ++++++++- src/engine/platform/pce.h | 1 + src/engine/playback.cpp | 4 ++++ 10 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index e93708b47..bce4cd321 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -21,6 +21,7 @@ enum DivDispatchCmds { DIV_CMD_SAMPLE_MODE, DIV_CMD_SAMPLE_FREQ, + DIV_CMD_SAMPLE_BANK, DIV_CMD_FM_LFO, DIV_CMD_FM_LFO_WAVE, diff --git a/src/engine/platform/arcade.cpp b/src/engine/platform/arcade.cpp index 605d9399d..ccab36b81 100644 --- a/src/engine/platform/arcade.cpp +++ b/src/engine/platform/arcade.cpp @@ -133,7 +133,7 @@ int DivPlatformArcade::dispatch(DivCommand c) { switch (c.cmd) { case DIV_CMD_NOTE_ON: { if (c.chan>7) { - chan[c.chan].pcm.sample=c.value%12; + chan[c.chan].pcm.sample=12*sampleBank+c.value%12; if (chan[c.chan].pcm.sample>=parent->song.sampleLen) { chan[c.chan].pcm.sample=-1; break; @@ -314,6 +314,12 @@ int DivPlatformArcade::dispatch(DivCommand c) { rWrite(0x0f,0); } } + case DIV_CMD_SAMPLE_BANK: + sampleBank=c.value; + if (sampleBank>(parent->song.sample.size()/12)) { + sampleBank=parent->song.sample.size()/12; + } + break; case DIV_ALWAYS_SET_VOLUME: return 0; break; @@ -356,6 +362,7 @@ int DivPlatformArcade::init(DivEngine* p, int channels, int sugRate, bool pal) { pcmCycles=0; pcmL=0; pcmR=0; + sampleBank=0; rWrite(0x19,0xff); diff --git a/src/engine/platform/arcade.h b/src/engine/platform/arcade.h index 23b162bee..c0777cd5a 100644 --- a/src/engine/platform/arcade.h +++ b/src/engine/platform/arcade.h @@ -34,7 +34,7 @@ class DivPlatformArcade: public DivDispatch { std::queue writes; opm_t fm; int delay; - int pcmL, pcmR, pcmCycles; + int pcmL, pcmR, pcmCycles, sampleBank; unsigned char lastBusy; bool extMode; diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index e6c01ef8c..ae939a2bd 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -158,7 +158,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) { switch (c.cmd) { case DIV_CMD_NOTE_ON: { if (c.chan==5 && dacMode) { - dacSample=c.value%12; + dacSample=12*sampleBank+c.value%12; if (dacSample>=parent->song.sampleLen) { dacSample=-1; break; @@ -289,6 +289,12 @@ int DivPlatformGenesis::dispatch(DivCommand c) { } break; } + case DIV_CMD_SAMPLE_BANK: + sampleBank=c.value; + if (sampleBank>(parent->song.sample.size()/12)) { + sampleBank=parent->song.sample.size()/12; + } + break; case DIV_CMD_LEGATO: { chan[c.chan].baseFreq=644.0f*pow(2.0f,((float)c.value/12.0f)); chan[c.chan].freqChanged=true; @@ -379,6 +385,7 @@ int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate, bool pal) dacPos=0; dacRate=0; dacSample=-1; + sampleBank=0; extMode=false; diff --git a/src/engine/platform/genesis.h b/src/engine/platform/genesis.h index 786fedc27..7d2b546b8 100644 --- a/src/engine/platform/genesis.h +++ b/src/engine/platform/genesis.h @@ -38,6 +38,7 @@ class DivPlatformGenesis: public DivDispatch { int dacRate; int dacPos; int dacSample; + int sampleBank; bool extMode; diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index 917810680..691d20a95 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -161,7 +161,7 @@ int DivPlatformNES::dispatch(DivCommand c) { switch (c.cmd) { case DIV_CMD_NOTE_ON: if (c.chan==4) { // PCM - dacSample=c.value%12; + dacSample=12*sampleBank+c.value%12; if (dacSample>=parent->song.sampleLen) { dacSample=-1; break; @@ -245,6 +245,12 @@ int DivPlatformNES::dispatch(DivCommand c) { chan[c.chan].freqChanged=true; } break; + case DIV_CMD_SAMPLE_BANK: + sampleBank=c.value; + if (sampleBank>(parent->song.sample.size()/12)) { + sampleBank=parent->song.sample.size()/12; + } + break; case DIV_CMD_PANNING: { lastPan&=~(0x11<=parent->song.sampleLen) { chan[c.chan].dacSample=-1; break; @@ -231,6 +231,12 @@ int DivPlatformPCE::dispatch(DivCommand c) { case DIV_CMD_SAMPLE_MODE: chan[c.chan].pcm=c.value; break; + case DIV_CMD_SAMPLE_BANK: + sampleBank=c.value; + if (sampleBank>(parent->song.sample.size()/12)) { + sampleBank=parent->song.sample.size()/12; + } + break; case DIV_CMD_PANNING: { chan[c.chan].pan=c.value; chWrite(c.chan,0x05,chan[c.chan].pan); @@ -279,6 +285,7 @@ int DivPlatformPCE::init(DivEngine* p, int channels, int sugRate, bool pal) { tempR=0; cycles=0; curChan=-1; + sampleBank=0; // set global volume rWrite(0,0); rWrite(0x01,0xff); diff --git a/src/engine/platform/pce.h b/src/engine/platform/pce.h index dc45449b9..f3911dd7d 100644 --- a/src/engine/platform/pce.h +++ b/src/engine/platform/pce.h @@ -47,6 +47,7 @@ class DivPlatformPCE: public DivDispatch { unsigned char lastPan; int tempL, tempR, cycles, curChan, delay; + int sampleBank; PCE_PSG* pce; void updateWave(int ch); public: diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 58382aae0..ed2374e38 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -31,6 +31,7 @@ const char* cmdName[DIV_CMD_MAX]={ "SAMPLE_MODE", "SAMPLE_FREQ", + "SAMPLE_BANK", "FM_LFO", "FM_LFO_WAVE", @@ -462,6 +463,9 @@ void DivEngine::processRow(int i, bool afterDelay) { case 0xea: // legato mode chan[i].legato=effectVal; break; + case 0xeb: // sample bank + dispatchCmd(DivCommand(DIV_CMD_SAMPLE_BANK,i,effectVal)); + break; case 0xec: // delayed note cut if (effectVal>0 && effectVal