From 451c35f41ba990a011f4d62e16ee4d92489aca5b Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 8 Jun 2021 23:16:29 -0500 Subject: [PATCH] PCE: sample playback --- src/engine/platform/pce.cpp | 41 +++++++++++++++++++++++++++++++++++++ src/engine/platform/pce.h | 4 +++- src/engine/playback.cpp | 3 +++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index 1afe9014..4daecd8f 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -14,6 +14,29 @@ #define FREQ_BASE 1712.0f*2 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()) { QueuedWrite w=writes.front(); 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 }; +static int dacRates[6]={ + 224,224,162,112,81,56 +}; + void DivPlatformPCE::tick() { for (int i=0; i<6; i++) { chan[i].std.next(); @@ -106,6 +133,17 @@ void DivPlatformPCE::tick() { int DivPlatformPCE::dispatch(DivCommand c) { switch (c.cmd) { 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].freqChanged=true; chan[c.chan].note=c.value; @@ -176,6 +214,9 @@ int DivPlatformPCE::dispatch(DivCommand c) { chan[c.chan].noise=c.value; chWrite(c.chan,0x07,chan[c.chan].noise?(0x80|chan[c.chan].note):0); break; + case DIV_CMD_SAMPLE_MODE: + chan[c.chan].pcm=c.value; + break; case DIV_CMD_PANNING: { chan[c.chan].pan=c.value; chWrite(c.chan,0x05,chan[c.chan].pan); diff --git a/src/engine/platform/pce.h b/src/engine/platform/pce.h index 1cf9ecdd..0d981d9d 100644 --- a/src/engine/platform/pce.h +++ b/src/engine/platform/pce.h @@ -9,8 +9,9 @@ class DivPlatformPCE: public DivDispatch { struct Channel { int freq, baseFreq, pitch; + int dacPeriod, dacRate, dacPos, dacSample; 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; DivMacroInt std; Channel(): @@ -27,6 +28,7 @@ class DivPlatformPCE: public DivDispatch { keyOff(false), inPorta(false), noise(false), + pcm(false), vol(31), outVol(31), wave(-1) {} diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 5c01f9db..bc58400d 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -117,6 +117,9 @@ bool DivEngine::perSystemEffect(int ch, unsigned char effect, unsigned char effe case 0x11: // noise mode dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal)); break; + case 0x17: // PCM enable + dispatchCmd(DivCommand(DIV_CMD_SAMPLE_MODE,ch,(effectVal>0))); + break; default: return false; }