PCM sample bank support
This commit is contained in:
parent
e3f14f3850
commit
e2a41974ff
|
@ -21,6 +21,7 @@ enum DivDispatchCmds {
|
||||||
|
|
||||||
DIV_CMD_SAMPLE_MODE,
|
DIV_CMD_SAMPLE_MODE,
|
||||||
DIV_CMD_SAMPLE_FREQ,
|
DIV_CMD_SAMPLE_FREQ,
|
||||||
|
DIV_CMD_SAMPLE_BANK,
|
||||||
|
|
||||||
DIV_CMD_FM_LFO,
|
DIV_CMD_FM_LFO,
|
||||||
DIV_CMD_FM_LFO_WAVE,
|
DIV_CMD_FM_LFO_WAVE,
|
||||||
|
|
|
@ -133,7 +133,7 @@ int DivPlatformArcade::dispatch(DivCommand c) {
|
||||||
switch (c.cmd) {
|
switch (c.cmd) {
|
||||||
case DIV_CMD_NOTE_ON: {
|
case DIV_CMD_NOTE_ON: {
|
||||||
if (c.chan>7) {
|
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) {
|
if (chan[c.chan].pcm.sample>=parent->song.sampleLen) {
|
||||||
chan[c.chan].pcm.sample=-1;
|
chan[c.chan].pcm.sample=-1;
|
||||||
break;
|
break;
|
||||||
|
@ -314,6 +314,12 @@ int DivPlatformArcade::dispatch(DivCommand c) {
|
||||||
rWrite(0x0f,0);
|
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:
|
case DIV_ALWAYS_SET_VOLUME:
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
@ -356,6 +362,7 @@ int DivPlatformArcade::init(DivEngine* p, int channels, int sugRate, bool pal) {
|
||||||
pcmCycles=0;
|
pcmCycles=0;
|
||||||
pcmL=0;
|
pcmL=0;
|
||||||
pcmR=0;
|
pcmR=0;
|
||||||
|
sampleBank=0;
|
||||||
|
|
||||||
rWrite(0x19,0xff);
|
rWrite(0x19,0xff);
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ class DivPlatformArcade: public DivDispatch {
|
||||||
std::queue<QueuedWrite> writes;
|
std::queue<QueuedWrite> writes;
|
||||||
opm_t fm;
|
opm_t fm;
|
||||||
int delay;
|
int delay;
|
||||||
int pcmL, pcmR, pcmCycles;
|
int pcmL, pcmR, pcmCycles, sampleBank;
|
||||||
unsigned char lastBusy;
|
unsigned char lastBusy;
|
||||||
|
|
||||||
bool extMode;
|
bool extMode;
|
||||||
|
|
|
@ -158,7 +158,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
||||||
switch (c.cmd) {
|
switch (c.cmd) {
|
||||||
case DIV_CMD_NOTE_ON: {
|
case DIV_CMD_NOTE_ON: {
|
||||||
if (c.chan==5 && dacMode) {
|
if (c.chan==5 && dacMode) {
|
||||||
dacSample=c.value%12;
|
dacSample=12*sampleBank+c.value%12;
|
||||||
if (dacSample>=parent->song.sampleLen) {
|
if (dacSample>=parent->song.sampleLen) {
|
||||||
dacSample=-1;
|
dacSample=-1;
|
||||||
break;
|
break;
|
||||||
|
@ -289,6 +289,12 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
break;
|
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: {
|
case DIV_CMD_LEGATO: {
|
||||||
chan[c.chan].baseFreq=644.0f*pow(2.0f,((float)c.value/12.0f));
|
chan[c.chan].baseFreq=644.0f*pow(2.0f,((float)c.value/12.0f));
|
||||||
chan[c.chan].freqChanged=true;
|
chan[c.chan].freqChanged=true;
|
||||||
|
@ -379,6 +385,7 @@ int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate, bool pal)
|
||||||
dacPos=0;
|
dacPos=0;
|
||||||
dacRate=0;
|
dacRate=0;
|
||||||
dacSample=-1;
|
dacSample=-1;
|
||||||
|
sampleBank=0;
|
||||||
|
|
||||||
extMode=false;
|
extMode=false;
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ class DivPlatformGenesis: public DivDispatch {
|
||||||
int dacRate;
|
int dacRate;
|
||||||
int dacPos;
|
int dacPos;
|
||||||
int dacSample;
|
int dacSample;
|
||||||
|
int sampleBank;
|
||||||
|
|
||||||
bool extMode;
|
bool extMode;
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
||||||
switch (c.cmd) {
|
switch (c.cmd) {
|
||||||
case DIV_CMD_NOTE_ON:
|
case DIV_CMD_NOTE_ON:
|
||||||
if (c.chan==4) { // PCM
|
if (c.chan==4) { // PCM
|
||||||
dacSample=c.value%12;
|
dacSample=12*sampleBank+c.value%12;
|
||||||
if (dacSample>=parent->song.sampleLen) {
|
if (dacSample>=parent->song.sampleLen) {
|
||||||
dacSample=-1;
|
dacSample=-1;
|
||||||
break;
|
break;
|
||||||
|
@ -245,6 +245,12 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
||||||
chan[c.chan].freqChanged=true;
|
chan[c.chan].freqChanged=true;
|
||||||
}
|
}
|
||||||
break;
|
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: {
|
case DIV_CMD_PANNING: {
|
||||||
lastPan&=~(0x11<<c.chan);
|
lastPan&=~(0x11<<c.chan);
|
||||||
if (c.value==0) c.value=0x11;
|
if (c.value==0) c.value=0x11;
|
||||||
|
@ -291,6 +297,7 @@ int DivPlatformNES::init(DivEngine* p, int channels, int sugRate, bool pal) {
|
||||||
dacPos=0;
|
dacPos=0;
|
||||||
dacRate=0;
|
dacRate=0;
|
||||||
dacSample=-1;
|
dacSample=-1;
|
||||||
|
sampleBank=0;
|
||||||
|
|
||||||
init_nla_table(500,500);
|
init_nla_table(500,500);
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ class DivPlatformNES: public DivDispatch {
|
||||||
wave(-1) {}
|
wave(-1) {}
|
||||||
};
|
};
|
||||||
Channel chan[5];
|
Channel chan[5];
|
||||||
int dacPeriod, dacRate, dacPos, dacSample;
|
int dacPeriod, dacRate, dacPos, dacSample, sampleBank;
|
||||||
unsigned char lastPan;
|
unsigned char lastPan;
|
||||||
|
|
||||||
float freqBase;
|
float freqBase;
|
||||||
|
|
|
@ -140,7 +140,7 @@ int DivPlatformPCE::dispatch(DivCommand c) {
|
||||||
switch (c.cmd) {
|
switch (c.cmd) {
|
||||||
case DIV_CMD_NOTE_ON:
|
case DIV_CMD_NOTE_ON:
|
||||||
if (chan[c.chan].pcm) {
|
if (chan[c.chan].pcm) {
|
||||||
chan[c.chan].dacSample=c.value%12;
|
chan[c.chan].dacSample=12*sampleBank+c.value%12;
|
||||||
if (chan[c.chan].dacSample>=parent->song.sampleLen) {
|
if (chan[c.chan].dacSample>=parent->song.sampleLen) {
|
||||||
chan[c.chan].dacSample=-1;
|
chan[c.chan].dacSample=-1;
|
||||||
break;
|
break;
|
||||||
|
@ -231,6 +231,12 @@ int DivPlatformPCE::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_SAMPLE_MODE:
|
case DIV_CMD_SAMPLE_MODE:
|
||||||
chan[c.chan].pcm=c.value;
|
chan[c.chan].pcm=c.value;
|
||||||
break;
|
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: {
|
case DIV_CMD_PANNING: {
|
||||||
chan[c.chan].pan=c.value;
|
chan[c.chan].pan=c.value;
|
||||||
chWrite(c.chan,0x05,chan[c.chan].pan);
|
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;
|
tempR=0;
|
||||||
cycles=0;
|
cycles=0;
|
||||||
curChan=-1;
|
curChan=-1;
|
||||||
|
sampleBank=0;
|
||||||
// set global volume
|
// set global volume
|
||||||
rWrite(0,0);
|
rWrite(0,0);
|
||||||
rWrite(0x01,0xff);
|
rWrite(0x01,0xff);
|
||||||
|
|
|
@ -47,6 +47,7 @@ class DivPlatformPCE: public DivDispatch {
|
||||||
unsigned char lastPan;
|
unsigned char lastPan;
|
||||||
|
|
||||||
int tempL, tempR, cycles, curChan, delay;
|
int tempL, tempR, cycles, curChan, delay;
|
||||||
|
int sampleBank;
|
||||||
PCE_PSG* pce;
|
PCE_PSG* pce;
|
||||||
void updateWave(int ch);
|
void updateWave(int ch);
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -31,6 +31,7 @@ const char* cmdName[DIV_CMD_MAX]={
|
||||||
|
|
||||||
"SAMPLE_MODE",
|
"SAMPLE_MODE",
|
||||||
"SAMPLE_FREQ",
|
"SAMPLE_FREQ",
|
||||||
|
"SAMPLE_BANK",
|
||||||
|
|
||||||
"FM_LFO",
|
"FM_LFO",
|
||||||
"FM_LFO_WAVE",
|
"FM_LFO_WAVE",
|
||||||
|
@ -462,6 +463,9 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
case 0xea: // legato mode
|
case 0xea: // legato mode
|
||||||
chan[i].legato=effectVal;
|
chan[i].legato=effectVal;
|
||||||
break;
|
break;
|
||||||
|
case 0xeb: // sample bank
|
||||||
|
dispatchCmd(DivCommand(DIV_CMD_SAMPLE_BANK,i,effectVal));
|
||||||
|
break;
|
||||||
case 0xec: // delayed note cut
|
case 0xec: // delayed note cut
|
||||||
if (effectVal>0 && effectVal<nextSpeed) {
|
if (effectVal>0 && effectVal<nextSpeed) {
|
||||||
chan[i].cut=effectVal+1;
|
chan[i].cut=effectVal+1;
|
||||||
|
|
Loading…
Reference in a new issue