From 6245b3af31080934fc45613b5b7072263cf90afd Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 12 Jan 2022 02:45:26 -0500 Subject: [PATCH] add Cxxx effect for mid-song Hz change also add hang detection as I ran into one of them while test multi-chip --- src/engine/engine.cpp | 33 +++++++++++++++++++++++++ src/engine/engine.h | 13 +++++++--- src/engine/playback.cpp | 53 ++++++++++++++++++++++------------------- src/gui/gui.cpp | 8 +++++-- 4 files changed, 78 insertions(+), 29 deletions(-) diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 5be4fc91..ecfa1bcf 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -2236,6 +2236,8 @@ void DivEngine::playSub(bool preserveDrift) { } else { ticks=1; totalTicks=0; + totalSeconds=0; + totalTicksR=0; } speedAB=false; playing=true; @@ -2308,6 +2310,16 @@ void DivEngine::reset() { speed1=song.speed1; speed2=song.speed2; nextSpeed=speed1; + divider=60; + if (song.customTempo) { + divider=song.hz; + } else { + if (song.pal) { + divider=60; + } else { + divider=50; + } + } globalPitch=0; for (int i=0; isetPAL((!song.pal) || (song.customTempo!=0 && song.hz<53)); 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(); } @@ -2879,6 +2910,8 @@ void DivEngine::quitDispatch() { changeOrd=-1; changePos=0; totalTicks=0; + totalSeconds=0; + totalTicksR=0; totalCmds=0; lastCmds=0; cmdsPerSecond=0; diff --git a/src/engine/engine.h b/src/engine/engine.h index 2ab000e3..4114d968 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -121,8 +121,8 @@ class DivEngine { bool extValuePresent; bool repeatPattern; bool metronome; - int ticks, curRow, curOrder, remainingLoops, nextSpeed; - int changeOrd, changePos, totalTicks, totalCmds, lastCmds, cmdsPerSecond, globalPitch; + int ticks, curRow, curOrder, remainingLoops, nextSpeed, divider; + int changeOrd, changePos, totalSeconds, totalTicks, totalTicksR, totalCmds, lastCmds, cmdsPerSecond, globalPitch; unsigned char extValue; unsigned char speed1, speed2; DivStatusView view; @@ -298,8 +298,12 @@ class DivEngine { // get Hz int getHz(); + // get current Hz + int getCurHz(); + // get time - int getTotalTicks(); + int getTotalTicks(); // 1/1000000th of a second + int getTotalSeconds(); // get repeat pattern bool getRepeatPattern(); @@ -437,9 +441,12 @@ class DivEngine { curOrder(0), remainingLoops(-1), nextSpeed(3), + divider(60), changeOrd(-1), changePos(0), + totalSeconds(0), totalTicks(0), + totalTicksR(0), totalCmds(0), lastCmds(0), cmdsPerSecond(0), diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 8db32ee0..ec623fb5 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -90,7 +90,7 @@ const char* formatNote(unsigned char note, unsigned char octave) { int DivEngine::dispatchCmd(DivCommand c) { 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++; c.chan=dispatchChanOfChan[c.dis]; @@ -506,6 +506,16 @@ void DivEngine::processRow(int i, bool afterDelay) { chan[i].delayRow=whatRow; } 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; itick(); if (!freelance) { - if (!noAccum) totalTicks++; - - int hz; - if (song.customTempo) { - hz=song.hz; - } else if (song.pal) { - hz=60; - } else { - hz=50; + if (!noAccum) { + totalTicksR++; + totalTicks+=1000000/divider; } - 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%hz)==0) { + if (totalTicks>=1000000) { + totalTicks-=1000000; + totalSeconds++; cmdsPerSecond=totalCmds-lastCmds; 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; @@ -900,7 +897,8 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi memset(metroTick,0,size); - while (true) { + int attempts=0; + while (++attempts<1000) { bool allDone=true; bool getOut=true; // 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; } } + 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; for (int i=0; idata[i][index]<0x48) { 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) { ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_INVALID]); } else if (pat->data[i][index]<0xf0) { @@ -2948,8 +2952,8 @@ bool FurnaceGUI::loop() { ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PLAYBACK_STAT]); if (e->isPlaying()) { int totalTicks=e->getTotalTicks(); - int hz=e->getHz(); - 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); + int totalSeconds=e->getTotalSeconds(); + 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 { if (curFileName!="") ImGui::Text("| %s",curFileName.c_str()); }