add Cxxx effect for mid-song Hz change
also add hang detection as I ran into one of them while test multi-chip
This commit is contained in:
parent
d19d37c561
commit
6245b3af31
|
@ -2236,6 +2236,8 @@ void DivEngine::playSub(bool preserveDrift) {
|
||||||
} else {
|
} else {
|
||||||
ticks=1;
|
ticks=1;
|
||||||
totalTicks=0;
|
totalTicks=0;
|
||||||
|
totalSeconds=0;
|
||||||
|
totalTicksR=0;
|
||||||
}
|
}
|
||||||
speedAB=false;
|
speedAB=false;
|
||||||
playing=true;
|
playing=true;
|
||||||
|
@ -2308,6 +2310,16 @@ void DivEngine::reset() {
|
||||||
speed1=song.speed1;
|
speed1=song.speed1;
|
||||||
speed2=song.speed2;
|
speed2=song.speed2;
|
||||||
nextSpeed=speed1;
|
nextSpeed=speed1;
|
||||||
|
divider=60;
|
||||||
|
if (song.customTempo) {
|
||||||
|
divider=song.hz;
|
||||||
|
} else {
|
||||||
|
if (song.pal) {
|
||||||
|
divider=60;
|
||||||
|
} else {
|
||||||
|
divider=50;
|
||||||
|
}
|
||||||
|
}
|
||||||
globalPitch=0;
|
globalPitch=0;
|
||||||
for (int i=0; i<song.systemLen; i++) {
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
disCont[i].clear();
|
disCont[i].clear();
|
||||||
|
@ -2418,6 +2430,14 @@ int DivEngine::getHz() {
|
||||||
return 60;
|
return 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DivEngine::getCurHz() {
|
||||||
|
return divider;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DivEngine::getTotalSeconds() {
|
||||||
|
return totalSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
int DivEngine::getTotalTicks() {
|
int DivEngine::getTotalTicks() {
|
||||||
return totalTicks;
|
return totalTicks;
|
||||||
}
|
}
|
||||||
|
@ -2826,6 +2846,17 @@ void DivEngine::setSongRate(int hz, bool pal) {
|
||||||
for (int i=0; i<song.systemLen; i++) {
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
disCont[i].dispatch->setPAL((!song.pal) || (song.customTempo!=0 && song.hz<53));
|
disCont[i].dispatch->setPAL((!song.pal) || (song.customTempo!=0 && song.hz<53));
|
||||||
disCont[i].setRates(got.rate);
|
disCont[i].setRates(got.rate);
|
||||||
|
disCont[i].clockDrift=0;
|
||||||
|
}
|
||||||
|
divider=60;
|
||||||
|
if (song.customTempo) {
|
||||||
|
divider=song.hz;
|
||||||
|
} else {
|
||||||
|
if (song.pal) {
|
||||||
|
divider=60;
|
||||||
|
} else {
|
||||||
|
divider=50;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
isBusy.unlock();
|
isBusy.unlock();
|
||||||
}
|
}
|
||||||
|
@ -2879,6 +2910,8 @@ void DivEngine::quitDispatch() {
|
||||||
changeOrd=-1;
|
changeOrd=-1;
|
||||||
changePos=0;
|
changePos=0;
|
||||||
totalTicks=0;
|
totalTicks=0;
|
||||||
|
totalSeconds=0;
|
||||||
|
totalTicksR=0;
|
||||||
totalCmds=0;
|
totalCmds=0;
|
||||||
lastCmds=0;
|
lastCmds=0;
|
||||||
cmdsPerSecond=0;
|
cmdsPerSecond=0;
|
||||||
|
|
|
@ -121,8 +121,8 @@ class DivEngine {
|
||||||
bool extValuePresent;
|
bool extValuePresent;
|
||||||
bool repeatPattern;
|
bool repeatPattern;
|
||||||
bool metronome;
|
bool metronome;
|
||||||
int ticks, curRow, curOrder, remainingLoops, nextSpeed;
|
int ticks, curRow, curOrder, remainingLoops, nextSpeed, divider;
|
||||||
int changeOrd, changePos, totalTicks, totalCmds, lastCmds, cmdsPerSecond, globalPitch;
|
int changeOrd, changePos, totalSeconds, totalTicks, totalTicksR, totalCmds, lastCmds, cmdsPerSecond, globalPitch;
|
||||||
unsigned char extValue;
|
unsigned char extValue;
|
||||||
unsigned char speed1, speed2;
|
unsigned char speed1, speed2;
|
||||||
DivStatusView view;
|
DivStatusView view;
|
||||||
|
@ -298,8 +298,12 @@ class DivEngine {
|
||||||
// get Hz
|
// get Hz
|
||||||
int getHz();
|
int getHz();
|
||||||
|
|
||||||
|
// get current Hz
|
||||||
|
int getCurHz();
|
||||||
|
|
||||||
// get time
|
// get time
|
||||||
int getTotalTicks();
|
int getTotalTicks(); // 1/1000000th of a second
|
||||||
|
int getTotalSeconds();
|
||||||
|
|
||||||
// get repeat pattern
|
// get repeat pattern
|
||||||
bool getRepeatPattern();
|
bool getRepeatPattern();
|
||||||
|
@ -437,9 +441,12 @@ class DivEngine {
|
||||||
curOrder(0),
|
curOrder(0),
|
||||||
remainingLoops(-1),
|
remainingLoops(-1),
|
||||||
nextSpeed(3),
|
nextSpeed(3),
|
||||||
|
divider(60),
|
||||||
changeOrd(-1),
|
changeOrd(-1),
|
||||||
changePos(0),
|
changePos(0),
|
||||||
|
totalSeconds(0),
|
||||||
totalTicks(0),
|
totalTicks(0),
|
||||||
|
totalTicksR(0),
|
||||||
totalCmds(0),
|
totalCmds(0),
|
||||||
lastCmds(0),
|
lastCmds(0),
|
||||||
cmdsPerSecond(0),
|
cmdsPerSecond(0),
|
||||||
|
|
|
@ -90,7 +90,7 @@ const char* formatNote(unsigned char note, unsigned char octave) {
|
||||||
|
|
||||||
int DivEngine::dispatchCmd(DivCommand c) {
|
int DivEngine::dispatchCmd(DivCommand c) {
|
||||||
if (view==DIV_STATUS_COMMANDS) {
|
if (view==DIV_STATUS_COMMANDS) {
|
||||||
printf("%8d | %d: %s(%d, %d)\n",totalTicks,c.chan,cmdName[c.cmd],c.value,c.value2);
|
printf("%8d | %d: %s(%d, %d)\n",totalTicksR,c.chan,cmdName[c.cmd],c.value,c.value2);
|
||||||
}
|
}
|
||||||
totalCmds++;
|
totalCmds++;
|
||||||
c.chan=dispatchChanOfChan[c.dis];
|
c.chan=dispatchChanOfChan[c.dis];
|
||||||
|
@ -506,6 +506,16 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
chan[i].delayRow=whatRow;
|
chan[i].delayRow=whatRow;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 0xc0: case 0xc1: case 0xc2: case 0xc3: // set Hz
|
||||||
|
divider=((effect&0x3)<<8)|effectVal;
|
||||||
|
if (divider<10) divider=10;
|
||||||
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
|
disCont[i].clockDrift=0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xc4: // set Hz by tempo
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
case 0xe0: // arp speed
|
case 0xe0: // arp speed
|
||||||
song.arpLen=effectVal;
|
song.arpLen=effectVal;
|
||||||
break;
|
break;
|
||||||
|
@ -688,16 +698,7 @@ void DivEngine::nextRow() {
|
||||||
|
|
||||||
bool DivEngine::nextTick(bool noAccum) {
|
bool DivEngine::nextTick(bool noAccum) {
|
||||||
bool ret=false;
|
bool ret=false;
|
||||||
int divider=60;
|
if (divider<10) divider=10;
|
||||||
if (song.customTempo) {
|
|
||||||
divider=song.hz;
|
|
||||||
} else {
|
|
||||||
if (song.pal) {
|
|
||||||
divider=60;
|
|
||||||
} else {
|
|
||||||
divider=50;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0; i<song.systemLen; i++) {
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
DivDispatchContainer& dc=disCont[i];
|
DivDispatchContainer& dc=disCont[i];
|
||||||
|
@ -810,22 +811,18 @@ bool DivEngine::nextTick(bool noAccum) {
|
||||||
for (int i=0; i<song.systemLen; i++) disCont[i].dispatch->tick();
|
for (int i=0; i<song.systemLen; i++) disCont[i].dispatch->tick();
|
||||||
|
|
||||||
if (!freelance) {
|
if (!freelance) {
|
||||||
if (!noAccum) totalTicks++;
|
if (!noAccum) {
|
||||||
|
totalTicksR++;
|
||||||
int hz;
|
totalTicks+=1000000/divider;
|
||||||
if (song.customTempo) {
|
|
||||||
hz=song.hz;
|
|
||||||
} else if (song.pal) {
|
|
||||||
hz=60;
|
|
||||||
} else {
|
|
||||||
hz=50;
|
|
||||||
}
|
}
|
||||||
if (consoleMode) fprintf(stderr,"\x1b[2K> %d:%.2d:%.2d.%.2d %.2x/%.2x:%.3d/%.3d %4dcmd/s\x1b[G",totalTicks/(hz*3600),(totalTicks/(hz*60))%60,(totalTicks/hz)%60,totalTicks%hz,curOrder,song.ordersLen,curRow,song.patLen,cmdsPerSecond);
|
if (totalTicks>=1000000) {
|
||||||
|
totalTicks-=1000000;
|
||||||
if ((totalTicks%hz)==0) {
|
totalSeconds++;
|
||||||
cmdsPerSecond=totalCmds-lastCmds;
|
cmdsPerSecond=totalCmds-lastCmds;
|
||||||
lastCmds=totalCmds;
|
lastCmds=totalCmds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (consoleMode) fprintf(stderr,"\x1b[2K> %d:%.2d:%.2d.%.2d %.2x/%.2x:%.3d/%.3d %4dcmd/s\x1b[G",totalSeconds/3600,(totalSeconds/60)%60,totalSeconds%60,totalTicks/10000,curOrder,song.ordersLen,curRow,song.patLen,cmdsPerSecond);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -900,7 +897,8 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
||||||
|
|
||||||
memset(metroTick,0,size);
|
memset(metroTick,0,size);
|
||||||
|
|
||||||
while (true) {
|
int attempts=0;
|
||||||
|
while (++attempts<1000) {
|
||||||
bool allDone=true;
|
bool allDone=true;
|
||||||
bool getOut=true;
|
bool getOut=true;
|
||||||
// 1. check whether we are done with all buffers
|
// 1. check whether we are done with all buffers
|
||||||
|
@ -948,6 +946,13 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
||||||
runPos[i]+=total;
|
runPos[i]+=total;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
logD("attempts: %d\n",attempts);
|
||||||
|
if (attempts>=1000) {
|
||||||
|
logE("hang detected! stopping!\n");
|
||||||
|
freelance=false;
|
||||||
|
playing=false;
|
||||||
|
extValuePresent=false;
|
||||||
|
}
|
||||||
totalProcessed=(1+runPos[0])*got.rate/disCont[0].dispatch->rate;
|
totalProcessed=(1+runPos[0])*got.rate/disCont[0].dispatch->rate;
|
||||||
|
|
||||||
for (int i=0; i<song.systemLen; i++) {
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
|
|
|
@ -1436,6 +1436,10 @@ void FurnaceGUI::drawPattern() {
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_SYS_SECONDARY]);
|
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_SYS_SECONDARY]);
|
||||||
} else if (pat->data[i][index]<0x48) {
|
} else if (pat->data[i][index]<0x48) {
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY]);
|
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY]);
|
||||||
|
} else if (pat->data[i][index]<0xc0) {
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_INVALID]);
|
||||||
|
} else if (pat->data[i][index]<0xd0) {
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_SPEED]);
|
||||||
} else if (pat->data[i][index]<0xe0) {
|
} else if (pat->data[i][index]<0xe0) {
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_INVALID]);
|
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_INVALID]);
|
||||||
} else if (pat->data[i][index]<0xf0) {
|
} else if (pat->data[i][index]<0xf0) {
|
||||||
|
@ -2948,8 +2952,8 @@ bool FurnaceGUI::loop() {
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PLAYBACK_STAT]);
|
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PLAYBACK_STAT]);
|
||||||
if (e->isPlaying()) {
|
if (e->isPlaying()) {
|
||||||
int totalTicks=e->getTotalTicks();
|
int totalTicks=e->getTotalTicks();
|
||||||
int hz=e->getHz();
|
int totalSeconds=e->getTotalSeconds();
|
||||||
ImGui::Text("| Speed %d:%d | Order %d/%d | Row %d/%d | %d:%.2d:%.2d.%.2d",e->getSpeed1(),e->getSpeed2(),e->getOrder(),e->song.ordersLen,e->getRow(),e->song.patLen,totalTicks/(hz*3600),(totalTicks/(hz*60))%60,(totalTicks/hz)%60,(totalTicks%hz)*100/hz);
|
ImGui::Text("| Speed %d:%d @ %dHz | Order %d/%d | Row %d/%d | %d:%.2d:%.2d.%.2d",e->getSpeed1(),e->getSpeed2(),e->getCurHz(),e->getOrder(),e->song.ordersLen,e->getRow(),e->song.patLen,totalSeconds/3600,(totalSeconds/60)%60,totalSeconds%60,totalTicks/10000);
|
||||||
} else {
|
} else {
|
||||||
if (curFileName!="") ImGui::Text("| %s",curFileName.c_str());
|
if (curFileName!="") ImGui::Text("| %s",curFileName.c_str());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue