mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-23 13:05:11 +00:00
PCE: sample playback
This commit is contained in:
parent
5b2684b5e1
commit
451c35f41b
3 changed files with 47 additions and 1 deletions
|
@ -14,6 +14,29 @@
|
||||||
#define FREQ_BASE 1712.0f*2
|
#define FREQ_BASE 1712.0f*2
|
||||||
|
|
||||||
void DivPlatformPCE::acquire(int& l, int& r) {
|
void DivPlatformPCE::acquire(int& l, int& r) {
|
||||||
|
// PCM part
|
||||||
|
for (int i=0; i<6; i++) {
|
||||||
|
if (chan[i].pcm && chan[i].dacSample!=-1) {
|
||||||
|
if (--chan[i].dacPeriod<1) {
|
||||||
|
DivSample* s=parent->song.sample[chan[i].dacSample];
|
||||||
|
chWrite(i,0x07,0);
|
||||||
|
if (s->depth==8) {
|
||||||
|
printf("Screw your 8 bit samples\n");
|
||||||
|
//writes.emplace(0x2a,(unsigned char)s->rendData[chan[i].dacPos++]+0x80);
|
||||||
|
} else {
|
||||||
|
chWrite(i,0x04,0xdf);
|
||||||
|
chWrite(i,0x06,(((unsigned short)s->rendData[chan[i].dacPos++]+0x8000)>>11));
|
||||||
|
//writes.emplace(0x2a,((unsigned short)s->rendData[chan[i].dacPos++]+0x8000)>>8);
|
||||||
|
}
|
||||||
|
if (chan[i].dacPos>=s->rendLength) {
|
||||||
|
chan[i].dacSample=-1;
|
||||||
|
}
|
||||||
|
chan[i].dacPeriod=chan[i].dacRate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PCE part
|
||||||
while (!writes.empty()) {
|
while (!writes.empty()) {
|
||||||
QueuedWrite w=writes.front();
|
QueuedWrite w=writes.front();
|
||||||
pce->Write(cycles,w.addr,w.val);
|
pce->Write(cycles,w.addr,w.val);
|
||||||
|
@ -45,6 +68,10 @@ static unsigned char noiseFreq[12]={
|
||||||
4,13,15,18,21,23,25,27,29,31,0,2
|
4,13,15,18,21,23,25,27,29,31,0,2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int dacRates[6]={
|
||||||
|
224,224,162,112,81,56
|
||||||
|
};
|
||||||
|
|
||||||
void DivPlatformPCE::tick() {
|
void DivPlatformPCE::tick() {
|
||||||
for (int i=0; i<6; i++) {
|
for (int i=0; i<6; i++) {
|
||||||
chan[i].std.next();
|
chan[i].std.next();
|
||||||
|
@ -106,6 +133,17 @@ void DivPlatformPCE::tick() {
|
||||||
int DivPlatformPCE::dispatch(DivCommand c) {
|
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) {
|
||||||
|
chan[c.chan].dacSample=c.value%12;
|
||||||
|
if (chan[c.chan].dacSample>=parent->song.sampleLen) {
|
||||||
|
chan[c.chan].dacSample=-1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
chan[c.chan].dacPos=0;
|
||||||
|
chan[c.chan].dacPeriod=0;
|
||||||
|
chan[c.chan].dacRate=dacRates[parent->song.sample[chan[c.chan].dacSample]->rate];
|
||||||
|
break;
|
||||||
|
}
|
||||||
chan[c.chan].baseFreq=round(FREQ_BASE/pow(2.0f,((float)c.value/12.0f)));
|
chan[c.chan].baseFreq=round(FREQ_BASE/pow(2.0f,((float)c.value/12.0f)));
|
||||||
chan[c.chan].freqChanged=true;
|
chan[c.chan].freqChanged=true;
|
||||||
chan[c.chan].note=c.value;
|
chan[c.chan].note=c.value;
|
||||||
|
@ -176,6 +214,9 @@ int DivPlatformPCE::dispatch(DivCommand c) {
|
||||||
chan[c.chan].noise=c.value;
|
chan[c.chan].noise=c.value;
|
||||||
chWrite(c.chan,0x07,chan[c.chan].noise?(0x80|chan[c.chan].note):0);
|
chWrite(c.chan,0x07,chan[c.chan].noise?(0x80|chan[c.chan].note):0);
|
||||||
break;
|
break;
|
||||||
|
case DIV_CMD_SAMPLE_MODE:
|
||||||
|
chan[c.chan].pcm=c.value;
|
||||||
|
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);
|
||||||
|
|
|
@ -9,8 +9,9 @@
|
||||||
class DivPlatformPCE: public DivDispatch {
|
class DivPlatformPCE: public DivDispatch {
|
||||||
struct Channel {
|
struct Channel {
|
||||||
int freq, baseFreq, pitch;
|
int freq, baseFreq, pitch;
|
||||||
|
int dacPeriod, dacRate, dacPos, dacSample;
|
||||||
unsigned char ins, note, pan;
|
unsigned char ins, note, pan;
|
||||||
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, noise;
|
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, noise, pcm;
|
||||||
signed char vol, outVol, wave;
|
signed char vol, outVol, wave;
|
||||||
DivMacroInt std;
|
DivMacroInt std;
|
||||||
Channel():
|
Channel():
|
||||||
|
@ -27,6 +28,7 @@ class DivPlatformPCE: public DivDispatch {
|
||||||
keyOff(false),
|
keyOff(false),
|
||||||
inPorta(false),
|
inPorta(false),
|
||||||
noise(false),
|
noise(false),
|
||||||
|
pcm(false),
|
||||||
vol(31),
|
vol(31),
|
||||||
outVol(31),
|
outVol(31),
|
||||||
wave(-1) {}
|
wave(-1) {}
|
||||||
|
|
|
@ -117,6 +117,9 @@ bool DivEngine::perSystemEffect(int ch, unsigned char effect, unsigned char effe
|
||||||
case 0x11: // noise mode
|
case 0x11: // noise mode
|
||||||
dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal));
|
dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal));
|
||||||
break;
|
break;
|
||||||
|
case 0x17: // PCM enable
|
||||||
|
dispatchCmd(DivCommand(DIV_CMD_SAMPLE_MODE,ch,(effectVal>0)));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue