prepare to fix MIDI clock

This commit is contained in:
tildearrow 2023-05-09 05:05:53 -05:00
parent 3b10cd9ce1
commit bdcbab0921
4 changed files with 66 additions and 9 deletions

View File

@ -2034,6 +2034,10 @@ String DivEngine::getPlaybackDebugInfo() {
"divider: %f\n"
"cycles: %d\n"
"clockDrift: %f\n"
"midiClockCycles: %d\n"
"midiClockDrift: %f\n"
"midiTimeCycles: %d\n"
"midiTimeDrift: %d\n"
"changeOrd: %d\n"
"changePos: %d\n"
"totalSeconds: %d\n"
@ -2048,8 +2052,9 @@ String DivEngine::getPlaybackDebugInfo() {
"totalProcessed: %d\n"
"bufferPos: %d\n",
curOrder,prevOrder,curRow,prevRow,ticks,subticks,totalLoops,lastLoopPos,nextSpeed,divider,cycles,clockDrift,
changeOrd,changePos,totalSeconds,totalTicks,totalTicksR,totalCmds,lastCmds,cmdsPerSecond,globalPitch,
(int)extValue,(int)tempoAccum,(int)totalProcessed,(int)bufferPos
midiClockCycles,midiClockDrift,midiTimeCycles,midiTimeDrift,changeOrd,changePos,totalSeconds,totalTicks,
totalTicksR,totalCmds,lastCmds,cmdsPerSecond,globalPitch,(int)extValue,(int)tempoAccum,(int)totalProcessed,
(int)bufferPos
);
}
@ -2165,10 +2170,16 @@ void DivEngine::playSub(bool preserveDrift, int goalRow) {
prevOrder=0;
prevRow=0;
stepPlay=0;
int prevDrift;
int prevDrift, prevMidiClockDrift, prevMidiTimeDrift;
prevDrift=clockDrift;
prevMidiClockDrift=midiClockDrift;
prevMidiTimeDrift=midiTimeDrift;
clockDrift=0;
cycles=0;
midiClockCycles=0;
midiClockDrift=0;
midiTimeCycles=0;
midiTimeDrift=0;
if (!preserveDrift) {
ticks=1;
tempoAccum=0;
@ -2211,9 +2222,15 @@ void DivEngine::playSub(bool preserveDrift, int goalRow) {
repeatPattern=oldRepeatPattern;
if (preserveDrift) {
clockDrift=prevDrift;
midiClockDrift=prevMidiClockDrift;
midiTimeDrift=prevMidiTimeDrift;
} else {
clockDrift=0;
cycles=0;
midiClockCycles=0;
midiClockDrift=0;
midiTimeCycles=0;
midiTimeDrift=0;
}
if (!preserveDrift) {
ticks=1;
@ -4367,6 +4384,10 @@ void DivEngine::quitDispatch() {
}
cycles=0;
clockDrift=0;
midiClockCycles=0;
midiClockDrift=0;
midiTimeCycles=0;
midiTimeDrift=0;
chans=0;
playing=false;
curSpeed=0;

View File

@ -378,6 +378,10 @@ class DivEngine {
double divider;
int cycles;
double clockDrift;
int midiClockCycles;
double midiClockDrift;
int midiTimeCycles;
double midiTimeDrift;
int stepPlay;
int changeOrd, changePos, totalSeconds, totalTicks, totalTicksR, totalCmds, lastCmds, cmdsPerSecond, globalPitch;
unsigned char extValue, pendingMetroTick;
@ -1146,6 +1150,10 @@ class DivEngine {
divider(60),
cycles(0),
clockDrift(0),
midiClockCycles(0),
midiClockDrift(0),
midiTimeCycles(0),
midiTimeDrift(0),
stepPlay(0),
changeOrd(-1),
changePos(0),

View File

@ -202,6 +202,7 @@ void DivPlatformSNES::tick(bool sysTick) {
}
}
for (int i=0; i<8; i++) {
// TODO: if wavetable length is higher than 32, we lose precision!
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
DivSample* s=parent->getSample(chan[i].sample);
double off=(s->centerRate>=1)?((double)s->centerRate/8363.0):1.0;

View File

@ -1317,11 +1317,6 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
if (--subticks<=0) {
subticks=tickMult;
// MIDI clock
if (output) if (!skipping && output->midiOut!=NULL && midiOutClock) {
output->midiOut->send(TAMidiMessage(TA_MIDI_CLOCK,0,0));
}
if (stepPlay!=1) {
tempoAccum+=curSubSong->virtualTempoN;
while (tempoAccum>=curSubSong->virtualTempoD) {
@ -1835,7 +1830,39 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
pendingMetroTick=0;
}
} else {
// 3. tick the clock and fill buffers as needed
// 3. run MIDI clock
for (int i=0; i<runLeftG; i++) {
// TODO: TEMPO
if (--midiClockCycles<=0) {
if (output) if (!skipping && output->midiOut!=NULL && midiOutClock) {
output->midiOut->send(TAMidiMessage(TA_MIDI_CLOCK,0,0));
}
double hl=curSubSong->hilightA;
if (hl<=0.0) hl=4.0;
double timeBase=curSubSong->timeBase+1;
double speedSum=0;
double vD=curSubSong->virtualTempoD;
for (int i=0; i<MIN(16,speeds.len); i++) {
speedSum+=speeds.val[i];
}
speedSum/=MAX(1,speeds.len);
if (timeBase<1.0) timeBase=1.0;
if (speedSum<1.0) speedSum=1.0;
if (vD<1) vD=1;
double bpm=10.0*((divider)/(timeBase*hl*speedSum))*(double)curSubSong->virtualTempoN/vD;
logV("bpm: %f %f",bpm,divider);
midiClockCycles=got.rate*pow(2,MASTER_CLOCK_PREC)/(bpm);
midiClockDrift+=fmod(got.rate*pow(2,MASTER_CLOCK_PREC),(double)(bpm));
if (midiClockDrift>=(bpm)) {
midiClockDrift-=(bpm);
midiClockCycles++;
}
}
}
// 4. tick the clock and fill buffers as needed
if (cycles<runLeftG) {
for (int i=0; i<song.systemLen; i++) {
int total=(cycles*disCont[i].runtotal)/(size<<MASTER_CLOCK_PREC);