From a68f8d0dec9bd7d7febc9fc6ebdf731f53fe1253 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 12 May 2021 05:22:01 -0500 Subject: [PATCH] add some basic playback code! here it begins --- src/engine/dispatch.h | 12 ++++++++- src/engine/engine.h | 5 +++- src/engine/platform/abstract.cpp | 5 +++- src/engine/platform/dummy.cpp | 32 +++++++++++++++++++--- src/engine/platform/dummy.h | 12 ++++++++- src/engine/playback.cpp | 46 ++++++++++++++++++++++++++++++-- 6 files changed, 103 insertions(+), 9 deletions(-) diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index bde0d0210..90edb330c 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -13,6 +13,15 @@ enum DivDispatchCmds { struct DivCommand { DivDispatchCmds cmd; + unsigned char chan, value; + DivCommand(DivDispatchCmds c, unsigned char ch, unsigned char val): + cmd(c), + chan(ch), + value(val) {} + DivCommand(DivDispatchCmds c, unsigned char ch): + cmd(c), + chan(ch), + value(0) {} }; struct DivDelayedCommand { @@ -33,6 +42,7 @@ class DivDispatch { int rate; virtual void acquire(short& l, short& r); virtual int dispatch(DivCommand c); + virtual void tick(); /** * initialize this DivDispatch. @@ -43,4 +53,4 @@ class DivDispatch { */ virtual int init(DivEngine* parent, int channels, int sugRate); }; -#endif \ No newline at end of file +#endif diff --git a/src/engine/engine.h b/src/engine/engine.h index 0472d26a4..d06e38f43 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -22,6 +22,7 @@ class DivEngine { bool playing; bool speedAB; int ticks, cycles, curRow, curOrder; + int changeOrd, changePos; std::vector chan; blip_buffer_t* bb[2]; @@ -53,7 +54,9 @@ class DivEngine { cycles(0), curRow(-1), curOrder(0), + changeOrd(-1), + changePos(0), temp{0,0}, prevSample{0,0} {} }; -#endif \ No newline at end of file +#endif diff --git a/src/engine/platform/abstract.cpp b/src/engine/platform/abstract.cpp index 58fb407d5..7153ac17e 100644 --- a/src/engine/platform/abstract.cpp +++ b/src/engine/platform/abstract.cpp @@ -5,10 +5,13 @@ void DivDispatch::acquire(short& l, short& r) { r=0; } +void DivDispatch::tick() { +} + int DivDispatch::dispatch(DivCommand c) { return 1; } int DivDispatch::init(DivEngine* p, int channels, int sugRate) { return 0; -} \ No newline at end of file +} diff --git a/src/engine/platform/dummy.cpp b/src/engine/platform/dummy.cpp index ea8327ca5..f4a2ebf12 100644 --- a/src/engine/platform/dummy.cpp +++ b/src/engine/platform/dummy.cpp @@ -1,16 +1,42 @@ #include "dummy.h" +#include void DivPlatformDummy::acquire(short& l, short& r) { l=0; - r=0; + for (unsigned char i=0; i=0x8000)?chan[i].vol:-chan[i].vol)<<5; + chan[i].pos+=chan[i].freq; + } + } + r=l; +} + +void DivPlatformDummy::tick() { + for (unsigned char i=0; i>3); + } } int DivPlatformDummy::dispatch(DivCommand c) { + switch (c.cmd) { + case DIV_CMD_NOTE_ON: + chan[c.chan].vol=0x7f; + chan[c.chan].freq=16.4f*pow(2.0f,((float)c.value/12.0f)); + chan[c.chan].active=true; + break; + case DIV_CMD_NOTE_OFF: + chan[c.chan].active=false; + break; + default: + break; + } return 1; } int DivPlatformDummy::init(DivEngine* p, int channels, int sugRate) { parent=p; - rate=sugRate; + rate=65536; + chans=channels; return channels; -} \ No newline at end of file +} diff --git a/src/engine/platform/dummy.h b/src/engine/platform/dummy.h index e3ee07d6b..6bf9495f0 100644 --- a/src/engine/platform/dummy.h +++ b/src/engine/platform/dummy.h @@ -3,8 +3,18 @@ // the dummy platform outputs square waves, interprets STD instruments and plays samples. // used when a DivDispatch for a system is not found. class DivPlatformDummy: public DivDispatch { + struct Channel { + unsigned short freq; + unsigned short pos; + bool active; + unsigned char vol; + Channel(): freq(0), pos(0), active(false), vol(0) {} + }; + Channel chan[17]; + unsigned char chans; public: void acquire(short& l, short& r); int dispatch(DivCommand c); + void tick(); int init(DivEngine* parent, int channels, int sugRate); -}; \ No newline at end of file +}; diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index eccf6d9cd..472db966f 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -30,6 +30,14 @@ void DivEngine::nextRow() { if (++curRow>=song.patLen) { nextOrder(); } + if (changeOrd>=0) { + curRow=changePos; + curOrder=changeOrd; + if (curOrder>=song.ordersLen) { + curOrder=0; + } + changeOrd=-1; + } strcpy(pb1,""); strcpy(pb3,""); for (int i=0; idata[curOrder]; + // note + if (pat->data[curRow][0]==100) { + dispatch->dispatch(DivCommand(DIV_CMD_NOTE_OFF,i)); + } else if (pat->data[curRow][1]!=0) { + dispatch->dispatch(DivCommand(DIV_CMD_NOTE_ON,i,pat->data[curRow][0]+pat->data[curRow][1]*12)); + } + + // effects + for (int j=0; jeffectRows; j++) { + unsigned char effect=pat->data[curRow][4+(j<<1)]; + unsigned char effectVal=pat->data[curRow][5+(j<<1)]; + + switch (effect) { + case 0x09: // speed 1 + song.speed1=effectVal; + break; + case 0x0f: // speed 2 + song.speed2=effectVal; + break; + case 0x0b: // change order + changeOrd=effectVal; + changePos=0; + break; + case 0x0d: // next order + changeOrd=curOrder+1; + changePos=effectVal; + break; + } + } + } } void DivEngine::nextTick() { @@ -81,14 +122,15 @@ void DivEngine::nextTick() { } } if (--ticks<=0) { + nextRow(); if (speedAB) { ticks=song.speed2*(song.timeBase+1); } else { ticks=song.speed1*(song.timeBase+1); } speedAB=!speedAB; - nextRow(); } + dispatch->tick(); } void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size) { @@ -115,4 +157,4 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi out[0][i]=(float)bbOut[0][i]/32768.0; out[1][i]=(float)bbOut[1][i]/32768.0; } -} \ No newline at end of file +}