change master clock to sampleRate*256

this hopefully fixes the hang by doing all clock ops on a master clock
rather than one clock per system
This commit is contained in:
tildearrow 2022-01-12 17:45:07 -05:00
parent fa5b99b46a
commit cd739f5fde
3 changed files with 42 additions and 78 deletions

View file

@ -2225,12 +2225,10 @@ void DivEngine::playSub(bool preserveDrift) {
int goal=curOrder; int goal=curOrder;
curOrder=0; curOrder=0;
curRow=0; curRow=0;
int prevDrift[32]; int prevDrift;
for (int i=0; i<song.systemLen; i++) { prevDrift=clockDrift;
prevDrift[i]=disCont[i].clockDrift; clockDrift=0;
disCont[i].clockDrift=0; cycles=0;
disCont[i].cycles=0;
}
if (preserveDrift) { if (preserveDrift) {
endOfSong=false; endOfSong=false;
} else { } else {
@ -2250,13 +2248,11 @@ void DivEngine::playSub(bool preserveDrift) {
for (int i=0; i<song.systemLen; i++) disCont[i].dispatch->forceIns(); for (int i=0; i<song.systemLen; i++) disCont[i].dispatch->forceIns();
} }
repeatPattern=oldRepeatPattern; repeatPattern=oldRepeatPattern;
for (int i=0; i<song.systemLen; i++) { if (preserveDrift) {
if (preserveDrift) { clockDrift=prevDrift;
disCont[i].clockDrift=prevDrift[i]; } else {
} else { clockDrift=0;
disCont[i].clockDrift=0; cycles=0;
disCont[i].cycles=0;
}
} }
if (!preserveDrift) { if (!preserveDrift) {
ticks=1; ticks=1;
@ -2846,7 +2842,6 @@ 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; divider=60;
if (song.customTempo) { if (song.customTempo) {
@ -2896,9 +2891,9 @@ void DivEngine::quitDispatch() {
isBusy.lock(); isBusy.lock();
for (int i=0; i<song.systemLen; i++) { for (int i=0; i<song.systemLen; i++) {
disCont[i].quit(); disCont[i].quit();
disCont[i].cycles=0;
disCont[i].clockDrift=0;
} }
cycles=0;
clockDrift=0;
chans=0; chans=0;
playing=false; playing=false;
speedAB=false; speedAB=false;

View file

@ -87,8 +87,6 @@ struct DivDispatchContainer {
short* bbIn[2]; short* bbIn[2];
short* bbOut[2]; short* bbOut[2];
int cycles, clockDrift;
void setRates(double gotRate); void setRates(double gotRate);
void acquire(size_t offset, size_t count); void acquire(size_t offset, size_t count);
void fillBuf(size_t runtotal, size_t size); void fillBuf(size_t runtotal, size_t size);
@ -102,9 +100,7 @@ struct DivDispatchContainer {
temp{0,0}, temp{0,0},
prevSample{0,0}, prevSample{0,0},
bbIn{NULL,NULL}, bbIn{NULL,NULL},
bbOut{NULL,NULL}, bbOut{NULL,NULL} {}
cycles(0),
clockDrift(0) {}
}; };
class DivEngine { class DivEngine {
@ -122,6 +118,7 @@ class DivEngine {
bool repeatPattern; bool repeatPattern;
bool metronome; bool metronome;
int ticks, curRow, curOrder, remainingLoops, nextSpeed, divider; int ticks, curRow, curOrder, remainingLoops, nextSpeed, divider;
int cycles, clockDrift;
int changeOrd, changePos, totalSeconds, totalTicks, totalTicksR, 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;
@ -442,6 +439,8 @@ class DivEngine {
remainingLoops(-1), remainingLoops(-1),
nextSpeed(3), nextSpeed(3),
divider(60), divider(60),
cycles(0),
clockDrift(0),
changeOrd(-1), changeOrd(-1),
changePos(0), changePos(0),
totalSeconds(0), totalSeconds(0),

View file

@ -509,10 +509,8 @@ void DivEngine::processRow(int i, bool afterDelay) {
case 0xc0: case 0xc1: case 0xc2: case 0xc3: // set Hz case 0xc0: case 0xc1: case 0xc2: case 0xc3: // set Hz
divider=((effect&0x3)<<8)|effectVal; divider=((effect&0x3)<<8)|effectVal;
if (divider<10) divider=10; if (divider<10) divider=10;
for (int i=0; i<song.systemLen; i++) { cycles=((int)(got.rate)<<8)/divider;
disCont[i].cycles=disCont[i].dispatch->rate/divider; clockDrift=0;
disCont[i].clockDrift=0;
}
break; break;
case 0xc4: // set Hz by tempo case 0xc4: // set Hz by tempo
// TODO // TODO
@ -701,14 +699,11 @@ bool DivEngine::nextTick(bool noAccum) {
bool ret=false; bool ret=false;
if (divider<10) divider=10; if (divider<10) divider=10;
for (int i=0; i<song.systemLen; i++) { cycles=((int)(got.rate)<<8)/divider;
DivDispatchContainer& dc=disCont[i]; clockDrift+=((int)(got.rate)<<8)%divider;
dc.cycles=dc.dispatch->rate/divider; if (clockDrift>=divider) {
dc.clockDrift+=dc.dispatch->rate%divider; clockDrift-=divider;
if (dc.clockDrift>=divider) { cycles++;
dc.clockDrift-=divider;
dc.cycles++;
}
} }
while (!pendingNotes.empty()) { while (!pendingNotes.empty()) {
@ -899,37 +894,14 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
memset(metroTick,0,size); memset(metroTick,0,size);
int attempts=0; int attempts=0;
logI("--------\n"); int runLeftG=size<<8;
while (++attempts<100) { while (++attempts<100) {
logI("ATTEMPT %d\n",attempts);
bool allDone=true;
bool getOut=true;
// 1. check whether we are done with all buffers // 1. check whether we are done with all buffers
for (int i=0; i<song.systemLen; i++) { if (runLeftG<=0) break;
logD("runLeft[%d]=%d\n",i,runLeft[i]);
if (runLeft[i]>0) {
getOut=false;
logD("no getOut because runLeft[%d]=%d\n",i,runLeft[i]);
break;
}
}
if (getOut) {
logD("GETTING OUT\n");
break;
}
// 2. check whether we gonna tick // 2. check whether we gonna tick
for (int i=0; i<song.systemLen; i++) { if (cycles<=0) {
logD("disCont[%d].cycles=%d\n",i,disCont[i].cycles);
if (disCont[i].cycles>0) {
allDone=false;
logD("not allDone because disCont[%d].cycles=%d\n",i,disCont[i].cycles);
break;
}
}
if (allDone) {
// we have to tick // we have to tick
logD("ticking\n");
unsigned int realPos=(runPos[0]*size)/runtotal[0]; unsigned int realPos=(runPos[0]*size)/runtotal[0];
if (realPos>=size) realPos=size-1; if (realPos>=size) realPos=size-1;
if (song.hilightA>0) { if (song.hilightA>0) {
@ -944,27 +916,25 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
if (!remainingLoops) logI("end of song!\n"); if (!remainingLoops) logI("end of song!\n");
} }
} }
} } else {
// 3. tick the clock and fill buffers as needed
// 3. fill buffers as needed if (cycles<runLeftG) {
for (int i=0; i<song.systemLen; i++) { for (int i=0; i<song.systemLen; i++) {
logD("filling buf %d...\n",i); int total=cycles*runtotal[i]/(size<<8);
if (runLeft[i]<=0) { disCont[i].acquire(runPos[i],total);
logD("runLeft[%d]<=0\n",i,runLeft[i]); runLeft[i]-=total;
continue; runPos[i]+=total;
} }
int total=runLeft[i]; runLeftG-=cycles;
if (total>disCont[i].cycles) { cycles=0;
logD("total set to cycles: %d\n",disCont[i].cycles);
total=disCont[i].cycles;
} else { } else {
logD("total is %d\n",total); cycles-=runLeftG;
runLeftG=0;
for (int i=0; i<song.systemLen; i++) {
disCont[i].acquire(runPos[i],runLeft[i]);
runLeft[i]=0;
}
} }
runLeft[i]-=total;
disCont[i].cycles-=total;
disCont[i].acquire(runPos[i],total);
runPos[i]+=total;
logD("runPos is %d\n",runPos[i]);
} }
} }
logD("attempts: %d\n",attempts); logD("attempts: %d\n",attempts);