prepare to fix MIDI clock
This commit is contained in:
parent
3b10cd9ce1
commit
bdcbab0921
|
@ -2034,6 +2034,10 @@ String DivEngine::getPlaybackDebugInfo() {
|
||||||
"divider: %f\n"
|
"divider: %f\n"
|
||||||
"cycles: %d\n"
|
"cycles: %d\n"
|
||||||
"clockDrift: %f\n"
|
"clockDrift: %f\n"
|
||||||
|
"midiClockCycles: %d\n"
|
||||||
|
"midiClockDrift: %f\n"
|
||||||
|
"midiTimeCycles: %d\n"
|
||||||
|
"midiTimeDrift: %d\n"
|
||||||
"changeOrd: %d\n"
|
"changeOrd: %d\n"
|
||||||
"changePos: %d\n"
|
"changePos: %d\n"
|
||||||
"totalSeconds: %d\n"
|
"totalSeconds: %d\n"
|
||||||
|
@ -2048,8 +2052,9 @@ String DivEngine::getPlaybackDebugInfo() {
|
||||||
"totalProcessed: %d\n"
|
"totalProcessed: %d\n"
|
||||||
"bufferPos: %d\n",
|
"bufferPos: %d\n",
|
||||||
curOrder,prevOrder,curRow,prevRow,ticks,subticks,totalLoops,lastLoopPos,nextSpeed,divider,cycles,clockDrift,
|
curOrder,prevOrder,curRow,prevRow,ticks,subticks,totalLoops,lastLoopPos,nextSpeed,divider,cycles,clockDrift,
|
||||||
changeOrd,changePos,totalSeconds,totalTicks,totalTicksR,totalCmds,lastCmds,cmdsPerSecond,globalPitch,
|
midiClockCycles,midiClockDrift,midiTimeCycles,midiTimeDrift,changeOrd,changePos,totalSeconds,totalTicks,
|
||||||
(int)extValue,(int)tempoAccum,(int)totalProcessed,(int)bufferPos
|
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;
|
prevOrder=0;
|
||||||
prevRow=0;
|
prevRow=0;
|
||||||
stepPlay=0;
|
stepPlay=0;
|
||||||
int prevDrift;
|
int prevDrift, prevMidiClockDrift, prevMidiTimeDrift;
|
||||||
prevDrift=clockDrift;
|
prevDrift=clockDrift;
|
||||||
|
prevMidiClockDrift=midiClockDrift;
|
||||||
|
prevMidiTimeDrift=midiTimeDrift;
|
||||||
clockDrift=0;
|
clockDrift=0;
|
||||||
cycles=0;
|
cycles=0;
|
||||||
|
midiClockCycles=0;
|
||||||
|
midiClockDrift=0;
|
||||||
|
midiTimeCycles=0;
|
||||||
|
midiTimeDrift=0;
|
||||||
if (!preserveDrift) {
|
if (!preserveDrift) {
|
||||||
ticks=1;
|
ticks=1;
|
||||||
tempoAccum=0;
|
tempoAccum=0;
|
||||||
|
@ -2211,9 +2222,15 @@ void DivEngine::playSub(bool preserveDrift, int goalRow) {
|
||||||
repeatPattern=oldRepeatPattern;
|
repeatPattern=oldRepeatPattern;
|
||||||
if (preserveDrift) {
|
if (preserveDrift) {
|
||||||
clockDrift=prevDrift;
|
clockDrift=prevDrift;
|
||||||
|
midiClockDrift=prevMidiClockDrift;
|
||||||
|
midiTimeDrift=prevMidiTimeDrift;
|
||||||
} else {
|
} else {
|
||||||
clockDrift=0;
|
clockDrift=0;
|
||||||
cycles=0;
|
cycles=0;
|
||||||
|
midiClockCycles=0;
|
||||||
|
midiClockDrift=0;
|
||||||
|
midiTimeCycles=0;
|
||||||
|
midiTimeDrift=0;
|
||||||
}
|
}
|
||||||
if (!preserveDrift) {
|
if (!preserveDrift) {
|
||||||
ticks=1;
|
ticks=1;
|
||||||
|
@ -4367,6 +4384,10 @@ void DivEngine::quitDispatch() {
|
||||||
}
|
}
|
||||||
cycles=0;
|
cycles=0;
|
||||||
clockDrift=0;
|
clockDrift=0;
|
||||||
|
midiClockCycles=0;
|
||||||
|
midiClockDrift=0;
|
||||||
|
midiTimeCycles=0;
|
||||||
|
midiTimeDrift=0;
|
||||||
chans=0;
|
chans=0;
|
||||||
playing=false;
|
playing=false;
|
||||||
curSpeed=0;
|
curSpeed=0;
|
||||||
|
|
|
@ -378,6 +378,10 @@ class DivEngine {
|
||||||
double divider;
|
double divider;
|
||||||
int cycles;
|
int cycles;
|
||||||
double clockDrift;
|
double clockDrift;
|
||||||
|
int midiClockCycles;
|
||||||
|
double midiClockDrift;
|
||||||
|
int midiTimeCycles;
|
||||||
|
double midiTimeDrift;
|
||||||
int stepPlay;
|
int stepPlay;
|
||||||
int changeOrd, changePos, totalSeconds, totalTicks, totalTicksR, totalCmds, lastCmds, cmdsPerSecond, globalPitch;
|
int changeOrd, changePos, totalSeconds, totalTicks, totalTicksR, totalCmds, lastCmds, cmdsPerSecond, globalPitch;
|
||||||
unsigned char extValue, pendingMetroTick;
|
unsigned char extValue, pendingMetroTick;
|
||||||
|
@ -1146,6 +1150,10 @@ class DivEngine {
|
||||||
divider(60),
|
divider(60),
|
||||||
cycles(0),
|
cycles(0),
|
||||||
clockDrift(0),
|
clockDrift(0),
|
||||||
|
midiClockCycles(0),
|
||||||
|
midiClockDrift(0),
|
||||||
|
midiTimeCycles(0),
|
||||||
|
midiTimeDrift(0),
|
||||||
stepPlay(0),
|
stepPlay(0),
|
||||||
changeOrd(-1),
|
changeOrd(-1),
|
||||||
changePos(0),
|
changePos(0),
|
||||||
|
|
|
@ -202,6 +202,7 @@ void DivPlatformSNES::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i=0; i<8; i++) {
|
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) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
DivSample* s=parent->getSample(chan[i].sample);
|
DivSample* s=parent->getSample(chan[i].sample);
|
||||||
double off=(s->centerRate>=1)?((double)s->centerRate/8363.0):1.0;
|
double off=(s->centerRate>=1)?((double)s->centerRate/8363.0):1.0;
|
||||||
|
|
|
@ -1317,11 +1317,6 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
|
||||||
if (--subticks<=0) {
|
if (--subticks<=0) {
|
||||||
subticks=tickMult;
|
subticks=tickMult;
|
||||||
|
|
||||||
// MIDI clock
|
|
||||||
if (output) if (!skipping && output->midiOut!=NULL && midiOutClock) {
|
|
||||||
output->midiOut->send(TAMidiMessage(TA_MIDI_CLOCK,0,0));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stepPlay!=1) {
|
if (stepPlay!=1) {
|
||||||
tempoAccum+=curSubSong->virtualTempoN;
|
tempoAccum+=curSubSong->virtualTempoN;
|
||||||
while (tempoAccum>=curSubSong->virtualTempoD) {
|
while (tempoAccum>=curSubSong->virtualTempoD) {
|
||||||
|
@ -1835,7 +1830,39 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
||||||
pendingMetroTick=0;
|
pendingMetroTick=0;
|
||||||
}
|
}
|
||||||
} else {
|
} 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) {
|
if (cycles<runLeftG) {
|
||||||
for (int i=0; i<song.systemLen; i++) {
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
int total=(cycles*disCont[i].runtotal)/(size<<MASTER_CLOCK_PREC);
|
int total=(cycles*disCont[i].runtotal)/(size<<MASTER_CLOCK_PREC);
|
||||||
|
|
Loading…
Reference in a new issue