implement MIDI timecode output

This commit is contained in:
tildearrow 2023-05-10 02:57:59 -05:00
parent eb521a6dac
commit 826538e41b
5 changed files with 227 additions and 8 deletions

View file

@ -1852,7 +1852,6 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
if (speedSum<1.0) speedSum=1.0;
if (vD<1) vD=1;
double bpm=((24.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));
@ -1863,7 +1862,115 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
}
}
// 4. tick the clock and fill buffers as needed
// 4. run MIDI timecode
for (int i=0; i<midiTotal; i++) {
if (--midiTimeCycles<=0) {
if (curMidiTimePiece==0) {
curMidiTimeCode=curMidiTime;
}
if (!(curMidiTimePiece&3)) curMidiTime++;
double frameRate=96.0;
int timeRate=midiOutTimeRate;
if (timeRate<1 || timeRate>4) {
if (curSubSong->hz>=47.98 && curSubSong->hz<=48.02) {
timeRate=1;
} else if (curSubSong->hz>=49.98 && curSubSong->hz<=50.02) {
timeRate=2;
} else if (curSubSong->hz>=59.9 && curSubSong->hz<=60.11) {
timeRate=4;
} else {
timeRate=4;
}
}
int hour=0;
int minute=0;
int second=0;
int frame=0;
int drop=0;
int actualTime=curMidiTimeCode;
switch (timeRate) {
case 1: // 24
frameRate=96.0;
hour=(actualTime/(60*60*24))%24;
minute=(actualTime/(60*24))%60;
second=(actualTime/24)%60;
frame=actualTime%24;
break;
case 2: // 25
frameRate=100.0;
hour=(actualTime/(60*60*25))%24;
minute=(actualTime/(60*25))%60;
second=(actualTime/25)%60;
frame=actualTime%25;
break;
case 3: // 29.97 (NTSC drop)
frameRate=120.0*(1000.0/1001.0);
// drop
drop=((actualTime/(30*60))-(actualTime/(30*600)))*2;
actualTime+=drop;
hour=(actualTime/(60*60*30))%24;
minute=(actualTime/(60*30))%60;
second=(actualTime/30)%60;
frame=actualTime%30;
break;
case 4: // 30 (NTSC non-drop)
default:
frameRate=120.0;
hour=(actualTime/(60*60*30))%24;
minute=(actualTime/(60*30))%60;
second=(actualTime/30)%60;
frame=actualTime%30;
break;
}
if (output) if (!skipping && output->midiOut!=NULL && midiOutTime) {
unsigned char val=0;
switch (curMidiTimePiece) {
case 0:
val=frame&15;
break;
case 1:
val=frame>>4;
break;
case 2:
val=second&15;
break;
case 3:
val=second>>4;
break;
case 4:
val=minute&15;
break;
case 5:
val=minute>>4;
break;
case 6:
val=hour&15;
break;
case 7:
val=(hour>>4)|((timeRate-1)<<1);
break;
}
val|=curMidiTimePiece<<4;
output->midiOut->send(TAMidiMessage(TA_MIDI_MTC_FRAME,val,0));
}
curMidiTimePiece=(curMidiTimePiece+1)&7;
midiTimeCycles=got.rate*pow(2,MASTER_CLOCK_PREC)/(frameRate);
midiTimeDrift+=fmod(got.rate*pow(2,MASTER_CLOCK_PREC),(double)(frameRate));
if (midiTimeDrift>=(frameRate)) {
midiTimeDrift-=(frameRate);
midiTimeCycles++;
}
}
}
// 5. 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);