command stream preset instruments/volumes
This commit is contained in:
parent
d3ce1a0b84
commit
92ad27f87e
5 changed files with 200 additions and 38 deletions
|
|
@ -59,6 +59,14 @@ unsigned char* DivCSPlayer::getFastDelays() {
|
|||
return fastDelays;
|
||||
}
|
||||
|
||||
unsigned char* DivCSPlayer::getFastIns() {
|
||||
return fastIns;
|
||||
}
|
||||
|
||||
unsigned char* DivCSPlayer::getFastVols() {
|
||||
return fastVols;
|
||||
}
|
||||
|
||||
unsigned char* DivCSPlayer::getFastCmds() {
|
||||
return fastCmds;
|
||||
}
|
||||
|
|
@ -110,9 +118,6 @@ bool DivCSPlayer::tick() {
|
|||
e->dispatchCmd(DivCommand(DIV_CMD_NOTE_ON,i,(int)next-60));
|
||||
chan[i].note=(int)next-60;
|
||||
chan[i].vibratoPos=0;
|
||||
} else if (next>=0xe0 && next<=0xef) {
|
||||
command=fastCmds[next&15];
|
||||
bAccessTS[fastCmdsOff+(next&15)]=curTick;
|
||||
} else if (next>=0xf0) { // preset delay
|
||||
chan[i].waitTicks=fastDelays[next&15];
|
||||
chan[i].lastWaitLen=chan[i].waitTicks;
|
||||
|
|
@ -205,13 +210,18 @@ bool DivCSPlayer::tick() {
|
|||
e->dispatchCmd(DivCommand(DIV_CMD_PANNING,i,panL,panR));
|
||||
break;
|
||||
}
|
||||
case 0xe0: case 0xe1: case 0xe2: case 0xe3:
|
||||
case 0xe4: case 0xe5: case 0xe6: case 0xe7:
|
||||
case 0xe8: case 0xe9: case 0xea: case 0xeb:
|
||||
case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5:
|
||||
e->dispatchCmd(DivCommand(DIV_CMD_INSTRUMENT,i,fastIns[next-0xe0]));
|
||||
bAccessTS[fastInsOff+(next-0xe0)]=curTick;
|
||||
break;
|
||||
case 0xe6: case 0xe7: case 0xe8: case 0xe9: case 0xea: case 0xeb:
|
||||
chan[i].volume=fastVols[next-0xe6]<<8;
|
||||
bAccessTS[fastVolsOff+(next-0xe6)]=curTick;
|
||||
sendVolume=true;
|
||||
break;
|
||||
case 0xec: case 0xed: case 0xee: case 0xef:
|
||||
// TODO: remove as it has no effect
|
||||
command=fastCmds[next&15];
|
||||
|
||||
command=fastCmds[next&3];
|
||||
bAccessTS[fastCmdsOff+(next&3)]=curTick;
|
||||
break;
|
||||
case 0xd0: // placeholder
|
||||
stream.readC();
|
||||
|
|
@ -644,8 +654,12 @@ bool DivCSPlayer::init() {
|
|||
|
||||
fastDelaysOff=stream.tell();
|
||||
stream.read(fastDelays,16);
|
||||
fastInsOff=stream.tell();
|
||||
stream.read(fastIns,6);
|
||||
fastVolsOff=stream.tell();
|
||||
stream.read(fastVols,6);
|
||||
fastCmdsOff=stream.tell();
|
||||
stream.read(fastCmds,16);
|
||||
stream.read(fastCmds,4);
|
||||
|
||||
if (longPointers) {
|
||||
for (unsigned int i=0; i<fileChans; i++) {
|
||||
|
|
|
|||
|
|
@ -83,10 +83,12 @@ class DivCSPlayer {
|
|||
SafeReader stream;
|
||||
DivCSChannelState chan[DIV_MAX_CHANS];
|
||||
unsigned char fastDelays[16];
|
||||
unsigned char fastCmds[16];
|
||||
unsigned char fastIns[6];
|
||||
unsigned char fastVols[6];
|
||||
unsigned char fastCmds[4];
|
||||
unsigned char arpSpeed;
|
||||
unsigned int fileChans;
|
||||
unsigned int curTick, fastDelaysOff, fastCmdsOff, deltaCyclePos;
|
||||
unsigned int curTick, fastDelaysOff, fastInsOff, fastVolsOff, fastCmdsOff, deltaCyclePos;
|
||||
bool longPointers;
|
||||
bool bigEndian;
|
||||
|
||||
|
|
@ -98,6 +100,8 @@ class DivCSPlayer {
|
|||
DivCSChannelState* getChanState(int ch);
|
||||
unsigned int getFileChans();
|
||||
unsigned char* getFastDelays();
|
||||
unsigned char* getFastIns();
|
||||
unsigned char* getFastVols();
|
||||
unsigned char* getFastCmds();
|
||||
unsigned int getCurTick();
|
||||
void cleanup();
|
||||
|
|
|
|||
|
|
@ -256,13 +256,14 @@ int DivCS::getInsLength(unsigned char ins, unsigned char ext, unsigned char* spe
|
|||
case 0xc8: // vol slide
|
||||
case 0xc9: // porta
|
||||
return 3;
|
||||
// speed dial commands
|
||||
case 0xe0: case 0xe1: case 0xe2: case 0xe3:
|
||||
case 0xe4: case 0xe5: case 0xe6: case 0xe7:
|
||||
case 0xe8: case 0xe9: case 0xea: case 0xeb:
|
||||
return 1;
|
||||
// speed dial commands
|
||||
case 0xec: case 0xed: case 0xee: case 0xef:
|
||||
if (speedDial==NULL) return 0;
|
||||
return 1+getCmdLength(speedDial[ins&15]);
|
||||
return 1+getCmdLength(speedDial[ins&3]);
|
||||
case 0xd0: // opt
|
||||
return 4;
|
||||
case 0xd7: // cmd
|
||||
|
|
@ -1257,12 +1258,18 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
int loopRow=curSubSong->ts.loopStart.row;
|
||||
logI("loop point: %d %d",loopOrder,loopRow);
|
||||
|
||||
int insPopularity[256];
|
||||
int volPopularity[256];
|
||||
int cmdPopularity[256];
|
||||
int delayPopularity[256];
|
||||
|
||||
int sortedCmdPopularity[16];
|
||||
int sortedInsPopularity[6];
|
||||
int sortedVolPopularity[6];
|
||||
int sortedCmdPopularity[4];
|
||||
int sortedDelayPopularity[16];
|
||||
unsigned char sortedCmd[16];
|
||||
unsigned char sortedIns[6];
|
||||
unsigned char sortedVol[6];
|
||||
unsigned char sortedCmd[4];
|
||||
unsigned char sortedDelay[16];
|
||||
|
||||
SafeWriter* globalStream;
|
||||
|
|
@ -1272,14 +1279,20 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
std::vector<size_t> tickPos[DIV_MAX_CHANS];
|
||||
int loopTick=-1;
|
||||
|
||||
memset(insPopularity,0,256*sizeof(int));
|
||||
memset(volPopularity,0,256*sizeof(int));
|
||||
memset(cmdPopularity,0,256*sizeof(int));
|
||||
memset(delayPopularity,0,256*sizeof(int));
|
||||
memset(chanStream,0,DIV_MAX_CHANS*sizeof(void*));
|
||||
memset(chanStreamOff,0,DIV_MAX_CHANS*sizeof(unsigned int));
|
||||
memset(chanStackSize,0,DIV_MAX_CHANS*sizeof(unsigned int));
|
||||
memset(sortedCmdPopularity,0,16*sizeof(int));
|
||||
memset(sortedInsPopularity,0,6*sizeof(int));
|
||||
memset(sortedVolPopularity,0,6*sizeof(int));
|
||||
memset(sortedCmdPopularity,0,4*sizeof(int));
|
||||
memset(sortedDelayPopularity,0,16*sizeof(int));
|
||||
memset(sortedCmd,0,16);
|
||||
memset(sortedIns,0,6);
|
||||
memset(sortedVol,0,6);
|
||||
memset(sortedCmd,0,4);
|
||||
memset(sortedDelay,0,16);
|
||||
|
||||
SafeWriter* w=new SafeWriter;
|
||||
|
|
@ -1386,6 +1399,11 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
case DIV_CMD_PRE_NOTE:
|
||||
break;
|
||||
default:
|
||||
if (i.cmd==DIV_CMD_HINT_VOLUME) {
|
||||
volPopularity[i.value&0xff]++;
|
||||
} else if (i.cmd==DIV_CMD_INSTRUMENT) {
|
||||
insPopularity[i.value&0xff]++;
|
||||
}
|
||||
cmdPopularity[i.cmd]++;
|
||||
writeCommandValues(chanStream[i.chan],i,options.bigEndian);
|
||||
break;
|
||||
|
|
@ -1450,12 +1468,97 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
extValuePresent=false;
|
||||
BUSY_END;
|
||||
|
||||
// PASS 1: optimize command calls
|
||||
// PASS 1: optimize command calls and volume/instrument changes
|
||||
if (!options.noCmdCallOpt) {
|
||||
// calculate command usage
|
||||
/// 1. instruments
|
||||
// calculate instrument usage
|
||||
int sortCand=-1;
|
||||
int sortPos=0;
|
||||
while (sortPos<16) {
|
||||
while (sortPos<6) {
|
||||
sortCand=-1;
|
||||
for (int i=0; i<256; i++) {
|
||||
if (insPopularity[i]) {
|
||||
if (sortCand==-1) {
|
||||
sortCand=i;
|
||||
} else if (insPopularity[sortCand]<insPopularity[i]) {
|
||||
sortCand=i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sortCand==-1) break;
|
||||
|
||||
sortedInsPopularity[sortPos]=insPopularity[sortCand];
|
||||
sortedIns[sortPos]=sortCand;
|
||||
insPopularity[sortCand]=0;
|
||||
sortPos++;
|
||||
}
|
||||
|
||||
// set preset instruments
|
||||
for (int h=0; h<chans; h++) {
|
||||
unsigned char* buf=chanStream[h]->getFinalBuf();
|
||||
for (size_t i=0; i<chanStream[h]->size(); i+=8) {
|
||||
if (buf[i]==0xb8) {
|
||||
// find whether this instrument is preset
|
||||
for (int j=0; j<6; j++) {
|
||||
if (buf[i+1]==sortedIns[j]) {
|
||||
buf[i]=0xe0+j;
|
||||
for (int k=i+1; k<(int)i+8; k++) {
|
||||
buf[k]=0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 2. volumes
|
||||
// calculate volume usage
|
||||
sortCand=-1;
|
||||
sortPos=0;
|
||||
while (sortPos<6) {
|
||||
sortCand=-1;
|
||||
for (int i=0; i<256; i++) {
|
||||
if (volPopularity[i]) {
|
||||
if (sortCand==-1) {
|
||||
sortCand=i;
|
||||
} else if (volPopularity[sortCand]<volPopularity[i]) {
|
||||
sortCand=i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sortCand==-1) break;
|
||||
|
||||
sortedVolPopularity[sortPos]=volPopularity[sortCand];
|
||||
sortedVol[sortPos]=sortCand;
|
||||
volPopularity[sortCand]=0;
|
||||
sortPos++;
|
||||
}
|
||||
|
||||
// set preset volumes
|
||||
for (int h=0; h<chans; h++) {
|
||||
unsigned char* buf=chanStream[h]->getFinalBuf();
|
||||
for (size_t i=0; i<chanStream[h]->size(); i+=8) {
|
||||
if (buf[i]==0xc7) {
|
||||
// find whether this volume is preset
|
||||
for (int j=0; j<6; j++) {
|
||||
if (buf[i+1]==sortedVol[j]) {
|
||||
buf[i]=0xe6+j;
|
||||
for (int k=i+1; k<(int)i+8; k++) {
|
||||
buf[k]=0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 3. commands
|
||||
// calculate command usage
|
||||
sortCand=-1;
|
||||
sortPos=0;
|
||||
while (sortPos<4) {
|
||||
sortCand=-1;
|
||||
for (int i=DIV_CMD_SAMPLE_MODE; i<256; i++) {
|
||||
if (cmdPopularity[i]) {
|
||||
|
|
@ -1480,9 +1583,9 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
for (size_t i=0; i<chanStream[h]->size(); i+=8) {
|
||||
if (buf[i]==0xd7) {
|
||||
// find whether this command is in speed dial
|
||||
for (int j=0; j<16; j++) {
|
||||
for (int j=0; j<4; j++) {
|
||||
if (buf[i+1]==sortedCmd[j]) {
|
||||
buf[i]=0xe0+j;
|
||||
buf[i]=0xec+j;
|
||||
// move everything to the left
|
||||
for (int k=i+2; k<(int)i+8; k++) {
|
||||
buf[k-1]=buf[k];
|
||||
|
|
@ -1795,8 +1898,20 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
if (sortedDelayPopularity[i]) logD("- %d: %d",sortedDelay[i],sortedDelayPopularity[i]);
|
||||
}
|
||||
|
||||
logD("instrument popularity:");
|
||||
for (int i=0; i<6; i++) {
|
||||
w->writeC(sortedIns[i]);
|
||||
logD("- $%.2x: %d",sortedIns[i],sortedInsPopularity[i]);
|
||||
}
|
||||
|
||||
logD("volume popularity:");
|
||||
for (int i=0; i<6; i++) {
|
||||
w->writeC(sortedVol[i]);
|
||||
logD("- $%.2x: %d",sortedVol[i],sortedVolPopularity[i]);
|
||||
}
|
||||
|
||||
logD("command popularity:");
|
||||
for (int i=0; i<16; i++) {
|
||||
for (int i=0; i<4; i++) {
|
||||
w->writeC(sortedCmd[i]);
|
||||
if (sortedCmdPopularity[i]) logD("- %s ($%.2x): %d",cmdName[sortedCmd[i]],sortedCmd[i],sortedCmdPopularity[i]);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue