mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-24 05:25:12 +00:00
experimental split command stream
This commit is contained in:
parent
1fbf592994
commit
16b752dc8a
1 changed files with 54 additions and 22 deletions
|
@ -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");
|
||||||
|
|
Loading…
Reference in a new issue