44
47
static int mtcLost;
45
48
static bool mtcSync; // receive complete mtc frame?
51
static bool playPendingFirstClock = false;
52
unsigned int syncSendFirstClockDelay = 1; // In milliseconds.
53
//static int lastStoppedBeat = 0;
54
static unsigned int curExtMidiSyncTick = 0;
55
unsigned int volatile lastExtMidiSyncTick = 0;
56
double volatile curExtMidiSyncTime = 0.0;
57
double volatile lastExtMidiSyncTime = 0.0;
48
60
// static bool mcStart = false;
49
61
// static int mcStartTick;
64
// From the "Introduction to the Volatile Keyword" at Embedded dot com
65
/* A variable should be declared volatile whenever its value could change unexpectedly.
66
... <such as> global variables within a multi-threaded application
67
... So all shared global variables should be declared volatile */
68
unsigned int volatile midiExtSyncTicks = 0;
51
70
//---------------------------------------------------------
53
72
//---------------------------------------------------------
92
125
_lastClkTime = sp._lastClkTime;
93
126
_lastTickTime = sp._lastTickTime;
127
_lastMRTTime = sp._lastMRTTime;
128
_lastMMCTime = sp._lastMMCTime;
129
_lastMTCTime = sp._lastMTCTime;
94
130
_clockTrig = sp._clockTrig;
95
131
_tickTrig = sp._tickTrig;
132
_MRTTrig = sp._MRTTrig;
133
_MMCTrig = sp._MMCTrig;
134
_MTCTrig = sp._MTCTrig;
96
135
_clockDetect = sp._clockDetect;
97
136
_tickDetect = sp._tickDetect;
98
_actDetectBits = sp._actDetectBits;
137
_MRTDetect = sp._MRTDetect;
138
_MMCDetect = sp._MMCDetect;
139
_MTCDetect = sp._MTCDetect;
140
_recMTCtype = sp._recMTCtype;
99
141
for(int i = 0; i < MIDI_CHANNELS; ++i)
101
143
_lastActTime[i] = sp._lastActTime[i];
188
277
//---------------------------------------------------------
279
//---------------------------------------------------------
281
void MidiSyncInfo::setMRTIn(const bool v)
284
// If sync receive was turned off, clear the current midi sync in port number so another port can grab it.
285
//if(!_recMRT && _port != -1 && curMidiSyncInPort == _port)
286
// curMidiSyncInPort = -1;
289
//---------------------------------------------------------
291
//---------------------------------------------------------
293
void MidiSyncInfo::setMMCIn(const bool v)
296
// If sync receive was turned off, clear the current midi sync in port number so another port can grab it.
297
//if(!_recMMC && _port != -1 && curMidiSyncInPort == _port)
298
// curMidiSyncInPort = -1;
301
//---------------------------------------------------------
303
//---------------------------------------------------------
305
void MidiSyncInfo::setMTCIn(const bool v)
308
// If sync receive was turned off, clear the current midi sync in port number so another port can grab it.
309
if(!_recMTC && _port != -1 && curMidiSyncInPort == _port)
310
curMidiSyncInPort = -1;
313
//---------------------------------------------------------
189
314
// trigMCSyncDetect
190
315
//---------------------------------------------------------
211
336
//---------------------------------------------------------
338
//---------------------------------------------------------
340
void MidiSyncInfo::trigMRTDetect()
344
// Set the current midi sync in port number if it's not taken...
345
//if(_recMRT && curMidiSyncInPort == -1)
346
// curMidiSyncInPort = _port;
349
//---------------------------------------------------------
351
//---------------------------------------------------------
353
void MidiSyncInfo::trigMMCDetect()
357
// Set the current midi sync in port number if it's not taken...
358
//if(_recMMC && curMidiSyncInPort == -1)
359
// curMidiSyncInPort = _port;
362
//---------------------------------------------------------
364
//---------------------------------------------------------
366
void MidiSyncInfo::trigMTCDetect()
370
// Set the current midi sync in port number if it's not taken...
371
if(_recMTC && curMidiSyncInPort == -1)
372
curMidiSyncInPort = _port;
375
//---------------------------------------------------------
213
377
//---------------------------------------------------------
254
418
_idIn = xml.parseInt();
255
419
else if (tag == "sendMC")
256
420
_sendMC = xml.parseInt();
421
else if (tag == "sendMRT")
422
_sendMRT = xml.parseInt();
257
423
else if (tag == "sendMMC")
258
424
_sendMMC = xml.parseInt();
259
425
else if (tag == "sendMTC")
260
426
_sendMTC = xml.parseInt();
427
//else if (tag == "sendContNotStart")
428
// _sendContNotStart = xml.parseInt();
261
429
else if (tag == "recMC")
262
430
_recMC = xml.parseInt();
431
else if (tag == "recMRT")
432
_recMRT = xml.parseInt();
263
433
else if (tag == "recMMC")
264
434
_recMMC = xml.parseInt();
265
435
else if (tag == "recMTC")
266
436
_recMTC = xml.parseInt();
437
else if (tag == "recRewStart")
438
_recRewOnStart = xml.parseInt();
268
440
xml.unknown("midiSyncInfo");
306
479
xml.intTag(level, "sendMC", true);
481
xml.intTag(level, "sendMRT", true);
308
483
xml.intTag(level, "sendMMC", true);
310
485
xml.intTag(level, "sendMTC", true);
486
//if(_sendContNotStart)
487
// xml.intTag(level, "sendContNotStart", true);
313
490
xml.intTag(level, "recMC", true);
492
xml.intTag(level, "recMRT", true);
315
494
xml.intTag(level, "recMMC", true);
317
496
xml.intTag(level, "recMTC", true);
498
xml.intTag(level, "recRewStart", false);
319
500
xml.etag(level, "midiSyncInfo");
324
505
// Midi Machine Control Input received
325
506
//---------------------------------------------------------
327
void MidiSeq::mmcInput(const unsigned char* p, int n)
508
//void MidiSeq::mmcInput(const unsigned char* p, int n)
509
void MidiSeq::mmcInput(int port, const unsigned char* p, int n)
330
512
printf("mmcInput: n:%d %02x %02x %02x %02x\n",
331
513
n, p[2], p[3], p[4], p[5]);
515
MidiPort* mp = &midiPorts[port];
516
MidiSyncInfo& msync = mp->syncInfo();
517
// Trigger MMC detect in.
518
msync.trigMMCDetect();
519
// MMC locate SMPTE time code may contain format type bits. Grab them.
520
if(p[3] == 0x44 && p[4] == 6 && p[5] == 1)
521
msync.setRecMTCtype((p[6] >> 5) & 3);
523
// MMC in not turned on? Forget it.
332
527
//if (!(extSyncFlag.value() && acceptMMC))
333
if(!extSyncFlag.value())
528
//if(!extSyncFlag.value())
339
534
printf(" MMC: STOP\n");
536
playPendingFirstClock = false;
340
538
//if ((state == PLAY || state == PRECOUNT))
341
539
if (audio->isPlaying())
342
540
audio->msgPlay(false);
383
586
else if (p[5] == 1) {
587
if (!checkAudioDevice()) return;
384
588
MTC mtc(p[6] & 0x1f, p[7], p[8], p[9], p[10]);
385
int mmcPos = tempomap.frame2tick(lrint(mtc.time()*sampleRate));
589
int type = (p[6] >> 5) & 3;
590
//int mmcPos = tempomap.frame2tick(lrint(mtc.time()*sampleRate));
591
//int mmcPos = lrint(mtc.time()*sampleRate);
592
int mmcPos = lrint(mtc.time(type) * sampleRate);
387
Pos tp(mmcPos, true);
388
if (!checkAudioDevice()) return;
594
//Pos tp(mmcPos, true);
595
Pos tp(mmcPos, false);
389
596
//audioDevice->seekTransport(tp.frame());
390
597
audioDevice->seekTransport(tp);
394
printf("MMC: %f %d seek ",
601
//printf("MMC: %f %d seek ", mtc.time(), mmcPos);
602
printf("MMC: LOCATE mtc type:%d time:%lf frame:%d mtc: ", type, mtc.time(), mmcPos);
453
661
frame &= 0x1f; // 0-29
454
662
sec &= 0x3f; // 0-59
455
663
min &= 0x3f; // 0-59
665
int type = (hour >> 5) & 3;
459
670
mtcValid = (mtcLost == 0);
463
675
mtcCurTime.set(hour, min, sec, frame);
464
mtcSyncMsg(mtcCurTime, !mtcSync);
678
MidiPort* mp = &midiPorts[port];
679
MidiSyncInfo& msync = mp->syncInfo();
680
msync.setRecMTCtype(type);
681
msync.trigMTCDetect();
682
// Not for the current in port? External sync not turned on? MTC in not turned on? Forget it.
683
if(port == curMidiSyncInPort && extSyncFlag.value() && msync.MTCIn())
686
printf("MidiSeq::mtcInputQuarter hour byte:%hx\n", tmphour);
687
mtcSyncMsg(mtcCurTime, type, !mtcSync);
468
else if (mtcValid && (mtcLost == 0)) {
469
mtcCurTime.incQuarter();
470
mtcSyncMsg(mtcCurTime, false);
693
else if (mtcValid && (mtcLost == 0))
695
//mtcCurTime.incQuarter();
696
mtcCurTime.incQuarter(type);
697
//mtcSyncMsg(mtcCurTime, type, false);
474
701
//---------------------------------------------------------
476
703
// process Frame Message
477
704
//---------------------------------------------------------
479
void MidiSeq::mtcInputFull(const unsigned char* p, int n)
706
//void MidiSeq::mtcInputFull(const unsigned char* p, int n)
707
void MidiSeq::mtcInputFull(int port, const unsigned char* p, int n)
482
710
printf("mtcInputFull\n");
483
if (!extSyncFlag.value())
711
//if (!extSyncFlag.value())
487
715
if (p[3] != 2) { // silently ignore user bits
498
726
frame &= 0x1f; // 0-29
499
727
sec &= 0x3f; // 0-59
500
728
min &= 0x3f; // 0-59
501
// int type = (hour >> 5) & 3;
729
int type = (hour >> 5) & 3;
504
732
mtcCurTime.set(hour, min, sec, frame);
739
printf("mtcInputFull: time:%lf stime:%lf hour byte (all bits):%hx\n", mtcCurTime.time(), mtcCurTime.time(type), p[4]);
742
MidiPort* mp = &midiPorts[port];
743
MidiSyncInfo& msync = mp->syncInfo();
744
msync.setRecMTCtype(type);
745
msync.trigMTCDetect();
746
// MTC in not turned on? Forget it.
747
//if(extSyncFlag.value() && msync.MTCIn())
750
//Pos tp(lrint(mtcCurTime.time() * sampleRate), false);
751
Pos tp(lrint(mtcCurTime.time(type) * sampleRate), false);
752
audioDevice->seekTransport(tp);
510
758
//---------------------------------------------------------
511
759
// nonRealtimeSystemSysex
512
760
//---------------------------------------------------------
514
void MidiSeq::nonRealtimeSystemSysex(const unsigned char* p, int n)
762
//void MidiSeq::nonRealtimeSystemSysex(const unsigned char* p, int n)
763
void MidiSeq::nonRealtimeSystemSysex(int /*port*/, const unsigned char* p, int n)
516
765
// int chan = p[2];
538
787
if (midiInputTrace)
539
788
printf("set song position port:%d %d\n", port, midiBeat);
541
midiPorts[port].syncInfo().trigMCSyncDetect();
790
//midiPorts[port].syncInfo().trigMCSyncDetect();
791
midiPorts[port].syncInfo().trigMRTDetect();
543
793
//if (!extSyncFlag.value())
544
794
// External sync not on? Clock in not turned on?
545
if(!extSyncFlag.value() || !midiPorts[port].syncInfo().MCIn())
795
//if(!extSyncFlag.value() || !midiPorts[port].syncInfo().MCIn())
796
if(!extSyncFlag.value() || !midiPorts[port].syncInfo().MRTIn())
548
Pos pos((config.division * midiBeat) / 4, true);
550
799
// Re-transmit song position to other devices if clock out turned on.
551
800
for(int p = 0; p < MIDI_PORTS; ++p)
552
if(p != port && midiPorts[p].syncInfo().MCOut())
801
//if(p != port && midiPorts[p].syncInfo().MCOut())
802
if(p != port && midiPorts[p].syncInfo().MRTOut())
553
803
midiPorts[p].sendSongpos(midiBeat);
805
curExtMidiSyncTick = (config.division * midiBeat) / 4;
806
lastExtMidiSyncTick = curExtMidiSyncTick;
808
//Pos pos((config.division * midiBeat) / 4, true);
809
Pos pos(curExtMidiSyncTick, true);
555
811
if (!checkAudioDevice()) return;
557
813
//audioDevice->seekTransport(pos.frame());
625
881
MidiPort* mp = &midiPorts[port];
627
883
// Trigger on any tick, clock, or realtime command.
884
if(c == ME_TICK) // Tick
629
885
mp->syncInfo().trigTickDetect();
887
if(c == ME_CLOCK) // Clock
631
888
mp->syncInfo().trigMCSyncDetect();
890
mp->syncInfo().trigMRTDetect(); // Other
633
// External sync not on? Clock in not turned on?
634
if(!extSyncFlag.value() || !mp->syncInfo().MCIn())
892
// External sync not on? Clock in not turned on? Otherwise realtime in not turned on?
893
if(!extSyncFlag.value())
897
if(!mp->syncInfo().MCIn())
901
if(!mp->syncInfo().MRTIn())
638
case 0xf8: // midi clock (24 ticks / quarter note)
906
case ME_CLOCK: // midi clock (24 ticks / quarter note)
640
908
// Not for the current in port? Forget it.
641
909
if(port != curMidiSyncInPort)
913
//printf("midi clock:%f\n", curTime());
644
915
// Re-transmit clock to other devices if clock out turned on.
645
916
// Must be careful not to allow more than one clock input at a time.
646
917
// Would re-transmit mixture of multiple clocks - confusing receivers.
650
921
if(p != port && midiPorts[p].syncInfo().MCOut())
651
922
midiPorts[p].sendClock();
925
if(playPendingFirstClock)
927
playPendingFirstClock = false;
928
// Hopefully the transport will be ready by now, the seek upon start should mean the
929
// audio prefetch has already finished or at least started...
930
// Must comfirm that play does not force a complete prefetch again, but don't think so...
931
if(!audio->isPlaying())
932
audioDevice->startTransport();
935
// This part will be run on the second and subsequent clocks, after start.
936
// Can't check audio state, might not be playing yet, we might miss some increments.
937
//if(audio->isPlaying())
940
lastExtMidiSyncTime = curExtMidiSyncTime;
941
curExtMidiSyncTime = curTime();
942
int div = config.division/24;
943
midiExtSyncTicks += div;
944
lastExtMidiSyncTick = curExtMidiSyncTick;
945
curExtMidiSyncTick += div;
948
//BEGIN : Original code:
653
950
double mclock0 = curTime();
654
951
// Difference in time last 2 rounds:
655
952
double tdiff0 = mclock0 - mclock1;
697
994
songtick, recTick, tickdiff, song_beat, sync_beat, scale, curFrame);
700
if ((mclock2 !=0.0) && (tdiff1 > 0.0) /*&& fabs(tickdiff) > 0.5*/ && lastTempo != 0) {
997
//if ((mclock2 !=0.0) && (tdiff1 > 0.0) && fabs(tickdiff) > 0.5 && lastTempo != 0) {
998
if ((mclock2 !=0.0) && (tdiff1 > 0.0) && lastTempo != 0) {
702
1000
double tickdiff1 = songtick1 - recTick1;
703
1001
double tickdiff2 = songtick2 - recTick2;
704
double newtickdiff = (tickdiff1+tickdiff2)/250; /*tickdiff/5.0 +
1002
double newtickdiff = (tickdiff1+tickdiff2)/250;
705
1004
tickdiff1/16.0 +
706
tickdiff2/24.0;*/ //5 mins 30 secs on 116BPM, -p 512 jackd
1005
tickdiff2/24.0; //5 mins 30 secs on 116BPM, -p 512 jackd
708
1007
if (newtickdiff != 0.0) {
709
1008
int newTempo = tempomap.tempo(0);
758
1057
mclock2 = mclock1;
759
1058
mclock1 = mclock0;
1060
//END : Original Code
1062
//BEGIN : Using external tempo map:
1064
double mclock0 = curTime();
1065
// Difference in time last 2 rounds:
1066
double tdiff0 = mclock0 - mclock1;
1067
double tdiff1 = mclock1 - mclock2;
1068
double averagetimediff = 0.0;
1070
if (mclock1 != 0.0) {
1071
if (storedtimediffs < 24)
1073
timediff[storedtimediffs] = mclock0 - mclock1;
1077
for (int i=0; i<23; i++) {
1078
timediff[i] = timediff[i+1];
1080
timediff[23] = mclock0 - mclock1;
1082
// Calculate average timediff:
1083
for (int i=0; i < storedtimediffs; i++) {
1084
averagetimediff += timediff[i]/storedtimediffs;
1088
// Compare w audio if playing:
1089
//if (playStateExt == true ) { //audio->isPlaying() state == PLAY
1091
//BEGIN standard setup:
1092
recTick += config.division / 24; // The one we're syncing to
1093
int tempo = tempomap.tempo(0);
1094
//unsigned curFrame = audio->pos().frame();
1095
//double songtick = (double(curFrame)/double(sampleRate)) *
1096
// double(config.division * 1000000.0) / double(tempo);
1097
double songtick = tempomap.curTickExt(mclock0);
1099
double scale = double(tdiff0/averagetimediff);
1100
double tickdiff = songtick - ((double) recTick - 24 + scale*24.0);
1102
//END standard setup
1105
audio->pos().mbt(&m, &b, &t);
1107
int song_beat = b + m*4; // if the time-signature is different than 4/4, this will be wrong.
1108
int sync_beat = recTick/config.division;
1109
printf("pT=%.3f rT=%d diff=%.3f songB=%d syncB=%d scale=%.3f, curFrame=%d averagetimediff:%.3lf",
1110
songtick, recTick, tickdiff, song_beat, sync_beat, scale, audio->pos().frame(), averagetimediff);
1113
//if ((mclock2 !=0.0) && (tdiff1 > 0.0) && fabs(tickdiff) > 0.5 && lastTempo != 0) {
1114
if ((mclock2 !=0.0) && (tdiff1 > 0.0) && lastTempo != 0) {
1116
double tickdiff1 = songtick1 - recTick1;
1117
double tickdiff2 = songtick2 - recTick2;
1118
double newtickdiff = (tickdiff1+tickdiff2)/250;
1119
////double newtickdiff = (tickdiff1+tickdiff2) / 10.0;
1120
//double newtickdiff = tickdiff/5.0 +
1122
// tickdiff2/24.0; //5 mins 30 secs on 116BPM, -p 512 jackd
1124
if (newtickdiff != 0.0) {
1125
//int newTempo = tempomap.tempo(0);
1126
int newTempo = tempo;
1127
//newTempo += int(24.0 * newtickdiff * scale);
1128
newTempo += int(24.0 * newtickdiff);
1130
printf(" tdiff=%f ntd=%f lt=%d tmpo=%.3f",
1131
tdiff0, newtickdiff, lastTempo, (float)((1000000.0 * 60.0)/newTempo));
1132
//syncTempo = newTempo;
1133
//tempomap.setTempo(0,newTempo);
1134
// Don't set the last stable tempo.
1135
//tempomap.setTempo(0, newTempo, false);
1136
tempomap.setExtTempo(newTempo);
1146
recTick2 = recTick1;
1150
songtick2 = songtick1;
1151
songtick1 = songtick;
1156
// Pre-sync (when audio is not running)
1157
// Calculate tempo depending on time per pulse
1159
if (mclock1 == 0.0) {
1160
mp->device()->discardInput();
1162
printf("Discarding input from port %d\n", port);
1164
if ((mclock2 != 0.0) && (tdiff0 > 0.0)) {
1166
//int tempo0 = int(24000000.0 * tdiff0 + .5);
1167
//int tempo1 = int(24000000.0 * tdiff1 + .5);
1168
//int tempo = tempomap.tempo(0);
1169
//int diff0 = tempo0 - tempo;
1170
//int diff1 = tempo1 - tempo0;
1173
// int newTempo = tempo + diff0/8 + diff1/16;
1175
// printf("setting new tempo %d = %f\n", newTempo, (float)((1000000.0 * 60.0)/newTempo));
1176
//tempomap.setTempo(0, newTempo);
1177
// Don't set the last stable tempo.
1178
//tempomap.setTempo(0, newTempo, false);
1179
// tempomap.setExtTempo(newTempo);
1182
//double tempo0 = 24000000.0 * tdiff0;
1183
//double tempo1 = 24000000.0 * tdiff1;
1184
//int newTempo = int((tempo0 + tempo1) / 2.0);
1185
int newTempo = int(averagetimediff * 24000000.0);
1187
printf("setting new tempo %d = %f\n", newTempo, (float)((1000000.0 * 60.0)/newTempo));
1188
tempomap.setExtTempo(newTempo);
1194
//END : Using external tempo map
762
case 0xf9: // midi tick (every 10 msec)
1198
case ME_TICK: // midi tick (every 10 msec)
763
1199
// FIXME: Unfinished? mcStartTick is uninitialized and Song::setPos doesn't set it either. Dangerous to allow this.
764
1200
//if (mcStart) {
765
1201
// song->setPos(0, mcStartTick);
1206
case ME_START: // start
771
1207
// Re-transmit start to other devices if clock out turned on.
772
1208
for(int p = 0; p < MIDI_PORTS; ++p)
773
if(p != port && midiPorts[p].syncInfo().MCOut())
774
midiPorts[p].sendStart();
1209
//if(p != port && midiPorts[p].syncInfo().MCOut())
1210
if(p != port && midiPorts[p].syncInfo().MRTOut())
1213
// If we aren't rewinding on start, there's no point in re-sending start.
1214
// Re-send continue instead, for consistency.
1215
if(midiPorts[port].syncInfo().recRewOnStart())
1216
midiPorts[p].sendStart();
1218
midiPorts[p].sendContinue();
777
1221
printf(" start\n");
1224
//printf("midi start:%f\n", curTime());
778
1226
if (1 /* !audio->isPlaying()*/ /*state == IDLE*/) {
779
1227
if (!checkAudioDevice()) return;
780
//audioDevice->seekTransport(0);
781
audioDevice->seekTransport(Pos(0, false));
782
unsigned curFrame = audio->curFrame();
784
printf(" curFrame=%d\n", curFrame);
1230
// Rew on start option.
1231
if(midiPorts[port].syncInfo().recRewOnStart())
1233
curExtMidiSyncTick = 0;
1234
lastExtMidiSyncTick = curExtMidiSyncTick;
1235
//audioDevice->seekTransport(0);
1236
audioDevice->seekTransport(Pos(0, false));
1239
//unsigned curFrame = audio->curFrame();
1241
// printf(" curFrame=%d\n", curFrame);
786
1243
alignAllTicks();
788
printf(" curFrame: %d curTick: %d tempo: %d\n", curFrame, recTick, tempomap.tempo(0));
1245
// printf(" curFrame: %d curTick: %d tempo: %d\n", curFrame, recTick, tempomap.tempo(0));
790
1247
storedtimediffs = 0;
791
1248
for (int i=0; i<24; i++)
792
1249
timediff[i] = 0.0;
793
audio->msgPlay(true);
1252
// Changed because msgPlay calls audioDevice->seekTransport(song->cPos())
1253
// and song->cPos() may not be changed to 0 yet, causing tranport not to go to 0.
1254
//audio->msgPlay(true);
1255
//audioDevice->startTransport();
1257
playPendingFirstClock = true;
1259
midiExtSyncTicks = 0;
794
1260
playStateExt = true;
797
case 0xfb: // continue
1263
case ME_CONTINUE: // continue
798
1264
// Re-transmit continue to other devices if clock out turned on.
799
1265
for(int p = 0; p < MIDI_PORTS; ++p)
800
if(p != port && midiPorts[p].syncInfo().MCOut())
1266
//if(p != port && midiPorts[p].syncInfo().MCOut())
1267
if(p != port && midiPorts[p].syncInfo().MRTOut())
801
1268
midiPorts[p].sendContinue();
804
printf(" continue\n");
1271
printf("realtimeSystemInput continue\n");
1274
//printf("continue:%f\n", curTime());
805
1276
if (1 /* !audio->isPlaying() */ /*state == IDLE */) {
806
1277
//unsigned curFrame = audio->curFrame();
807
1278
//recTick = tempomap.frame2tick(curFrame); // don't think this will work... (ml)
808
1279
//alignAllTicks();
809
audio->msgPlay(true);
1282
//audio->msgPlay(true);
1284
// Begin incrementing immediately upon first clock reception.
1285
playPendingFirstClock = true;
810
1287
playStateExt = true;
814
// Re-transmit stop to other devices if clock out turned on.
815
for(int p = 0; p < MIDI_PORTS; ++p)
816
if(p != port && midiPorts[p].syncInfo().MCOut())
817
midiPorts[p].sendStop();
1290
case ME_STOP: // stop
1293
// Stop the increment right away.
1294
midiExtSyncTicks = 0;
1295
playStateExt = false;
1296
playPendingFirstClock = false;
1298
// Re-transmit stop to other devices if clock out turned on.
1299
for(int p = 0; p < MIDI_PORTS; ++p)
1300
//if(p != port && midiPorts[p].syncInfo().MCOut())
1301
if(p != port && midiPorts[p].syncInfo().MRTOut())
1302
midiPorts[p].sendStop();
1304
//playPendingFirstClock = false;
1306
//lastStoppedBeat = (audio->tickPos() * 4) / config.division;
1307
//curExtMidiSyncTick = (config.division * lastStoppedBeat) / 4;
1310
//printf("stop:%f\n", curTime());
1312
if (audio->isPlaying() /*state == PLAY*/) {
1313
audio->msgPlay(false);
1314
//playStateExt = false;
1318
printf("realtimeSystemInput stop\n");
1320
// Just in case the process still runs a cycle or two and causes the
1321
// audio tick position to increment, reset the incrementer and force
1322
// the transport position to what the hardware thinks is the current position.
1323
//midiExtSyncTicks = 0;
1324
//Pos pos((config.division * lastStoppedBeat) / 4, true);
1325
//Pos pos(curExtMidiSyncTick, true);
1326
//audioDevice->seekTransport(pos);
821
if (audio->isPlaying() /*state == PLAY*/) {
822
audio->msgPlay(false);
823
playStateExt = false;
826
case 0xfd: // unknown
827
case 0xfe: // active sensing
828
case 0xff: // system reset
1330
//case 0xfd: // unknown
1331
//case ME_SENSE: // active sensing
1332
//case ME_META: // system reset (reset is 0xff same enumeration as file meta event)
839
1344
//---------------------------------------------------------
841
void MidiSeq::mtcSyncMsg(const MTC& mtc, bool seekFlag)
1346
void MidiSeq::mtcSyncMsg(const MTC& mtc, int type, bool seekFlag)
843
1348
double time = mtc.time();
1349
double stime = mtc.time(type);
845
printf("mtcSyncMsg: time %f\n", time);
1351
printf("MidiSeq::mtcSyncMsg time:%lf stime:%lf seekFlag:%d\n", time, stime, seekFlag);
847
1353
if (seekFlag && audio->isRunning() /*state == START_PLAY*/) {
848
1354
// int tick = tempomap.time2tick(time);
850
1356
//write(sigFd, "1", 1); // say PLAY to gui
851
1357
if (!checkAudioDevice()) return;
1359
printf("MidiSeq::mtcSyncMsg starting transport.\n");
852
1360
audioDevice->startTransport();