experimental split command stream

This commit is contained in:
tildearrow 2022-10-04 18:57:04 -05:00
parent 1fbf592994
commit 16b752dc8a
1 changed files with 54 additions and 22 deletions

View File

@ -274,23 +274,26 @@ double DivEngine::benchmarkSeek() {
return tAvg; return tAvg;
} }
#define WRITE_TICK \ #define WRITE_TICK(x) \
if (!wroteTick) { \ if (binary) { \
wroteTick=true; \ if (!wroteTick[x]) { \
if (binary) { \ wroteTick[x]=true; \
if (tick-lastTick>255) { \ if (tick-lastTick[x]>255) { \
w->writeC(0xfc); \ chanStream[x]->writeC(0xfc); \
w->writeS(tick-lastTick); \ chanStream[x]->writeS(tick-lastTick[x]); \
} else if (tick-lastTick>1) { \ } else if (tick-lastTick[x]>1) { \
w->writeC(0xfd); \ chanStream[x]->writeC(0xfd); \
w->writeC(tick-lastTick); \ chanStream[x]->writeC(tick-lastTick[x]); \
} else { \ } else { \
w->writeC(0xfe); \ chanStream[x]->writeC(0xfe); \
} \ } \
} else { \ lastTick[x]=tick; \
} \
} else { \
if (!wroteTickGlobal) { \
wroteTickGlobal=true; \
w->writeText(fmt::sprintf(">> TICK %d\n",tick)); \ w->writeText(fmt::sprintf(">> TICK %d\n",tick)); \
} \ } \
lastTick=tick; \
} }
void writePackedCommandValues(SafeWriter* w, const DivCommand& c) { void writePackedCommandValues(SafeWriter* w, const DivCommand& c) {
@ -411,12 +414,26 @@ SafeWriter* DivEngine::saveCommand(bool binary) {
walkSong(loopOrder,loopRow,loopEnd); walkSong(loopOrder,loopRow,loopEnd);
logI("loop point: %d %d",loopOrder,loopRow); logI("loop point: %d %d",loopOrder,loopRow);
SafeWriter* chanStream[DIV_MAX_CHANS];
unsigned int chanStreamOff[DIV_MAX_CHANS];
bool wroteTick[DIV_MAX_CHANS];
memset(chanStream,0,DIV_MAX_CHANS*sizeof(void*));
memset(chanStreamOff,0,DIV_MAX_CHANS*sizeof(unsigned int));
SafeWriter* w=new SafeWriter; SafeWriter* w=new SafeWriter;
w->init(); w->init();
// write header // write header
if (binary) { if (binary) {
w->write("FCS",4); w->write("FCS",4);
w->writeI(chans);
// offsets
for (int i=0; i<chans; i++) {
chanStream[i]=new SafeWriter;
chanStream[i]->init();
w->writeI(0);
}
} else { } else {
w->writeText("# Furnace Command Stream\n\n"); w->writeText("# Furnace Command Stream\n\n");
@ -451,19 +468,22 @@ SafeWriter* DivEngine::saveCommand(bool binary) {
bool oldCmdStreamEnabled=cmdStreamEnabled; bool oldCmdStreamEnabled=cmdStreamEnabled;
cmdStreamEnabled=true; cmdStreamEnabled=true;
double curDivider=divider; double curDivider=divider;
int lastTick=0; int lastTick[DIV_MAX_CHANS];
memset(lastTick,0,DIV_MAX_CHANS*sizeof(int));
while (!done) { while (!done) {
if (nextTick(false,true) || !playing) { if (nextTick(false,true) || !playing) {
done=true; done=true;
} }
// get command stream // get command stream
bool wroteTick=false; bool wroteTickGlobal=false;
memset(wroteTick,0,DIV_MAX_CHANS*sizeof(bool));
if (curDivider!=divider) { if (curDivider!=divider) {
curDivider=divider; curDivider=divider;
WRITE_TICK; WRITE_TICK(0);
if (binary) { if (binary) {
w->writeC(0xfb); chanStream[0]->writeC(0xfb);
w->writeI((int)(curDivider*65536)); chanStream[0]->writeI((int)(curDivider*65536));
} else { } else {
w->writeText(fmt::sprintf(">> SET_RATE %f\n",curDivider)); w->writeText(fmt::sprintf(">> SET_RATE %f\n",curDivider));
} }
@ -486,10 +506,9 @@ SafeWriter* DivEngine::saveCommand(bool binary) {
case DIV_CMD_PRE_NOTE: case DIV_CMD_PRE_NOTE:
break; break;
default: default:
WRITE_TICK; WRITE_TICK(i.chan);
if (binary) { if (binary) {
w->writeC(i.chan); writePackedCommandValues(chanStream[i.chan],i);
writePackedCommandValues(w,i);
} else { } else {
w->writeText(fmt::sprintf(" %d: %s %d %d\n",i.chan,cmdName[i.cmd],i.value,i.value2)); w->writeText(fmt::sprintf(" %d: %s %d %d\n",i.chan,cmdName[i.cmd],i.value,i.value2));
} }
@ -502,7 +521,20 @@ SafeWriter* DivEngine::saveCommand(bool binary) {
cmdStreamEnabled=oldCmdStreamEnabled; cmdStreamEnabled=oldCmdStreamEnabled;
if (binary) { if (binary) {
w->writeC(0xff); for (int i=0; i<chans; i++) {
chanStream[i]->writeC(0xff);
chanStreamOff[i]=w->tell();
logI("- %d: off %x size %ld",i,chanStreamOff[i],chanStream[i]->size());
w->write(chanStream[i]->getFinalBuf(),chanStream[i]->size());
chanStream[i]->finish();
delete chanStream[i];
}
w->seek(8,SEEK_SET);
for (int i=0; i<chans; i++) {
w->writeI(chanStreamOff[i]);
}
} else { } else {
if (!playing) { if (!playing) {
w->writeText(">> END\n"); w->writeText(">> END\n");