X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fmidi%2B%2B2%2Fmtc.cc;h=7f7506c344ba5cc593e60401f78a244e1c23af93;hb=e9752ff93ea44098fd8c02b21a3a787ef1cbf3ab;hp=37163da4e6a72bce2ad5569694ac058adf012e63;hpb=03c74e45a871f2e09fb1ee855f830c94d1cdb163;p=ardour.git diff --git a/libs/midi++2/mtc.cc b/libs/midi++2/mtc.cc index 37163da4e6..7f7506c344 100644 --- a/libs/midi++2/mtc.cc +++ b/libs/midi++2/mtc.cc @@ -33,8 +33,10 @@ using namespace std; using namespace sigc; using namespace MIDI; +#undef DEBUG_MTC + bool -Parser::possible_mtc (byte *sysex_buf, size_t msglen) +Parser::possible_mtc (MIDI::byte *sysex_buf, size_t msglen) { byte fake_mtc_time[5]; @@ -43,12 +45,12 @@ Parser::possible_mtc (byte *sysex_buf, size_t msglen) } /* full MTC */ - + fake_mtc_time[0] = sysex_buf[8]; // frames fake_mtc_time[1] = sysex_buf[7]; // minutes fake_mtc_time[2] = sysex_buf[6]; // seconds fake_mtc_time[3] = (sysex_buf[5] & 0x1f); // hours - + _mtc_fps = MTC_FPS ((sysex_buf[5] & 0x60) >> 5); // fps fake_mtc_time[4] = (byte) _mtc_fps; @@ -62,6 +64,9 @@ Parser::possible_mtc (byte *sysex_buf, size_t msglen) mtc (*this, &sysex_buf[1], msglen - 1); mtc_time (fake_mtc_time, true, _timestamp); +#ifdef DEBUG_MTC + cerr << "New full-MTC message marks state stopped" << endl; +#endif mtc_status (MTC_Stopped); return true; @@ -70,6 +75,9 @@ Parser::possible_mtc (byte *sysex_buf, size_t msglen) void Parser::reset_mtc_state () { +#ifdef DEBUG_MTC + cerr << "MTC state reset" << endl; +#endif /* MUST REMAIN RT-SAFE */ _mtc_forward = false; @@ -83,24 +91,24 @@ Parser::reset_mtc_state () } void -Parser::process_mtc_quarter_frame (byte *msg) +Parser::process_mtc_quarter_frame (MIDI::byte *msg) { int which_quarter_frame = (msg[1] & 0xf0) >> 4; - /* Is it an expected frame? - Remember, the first can be frame 7 or frame 0, + /* Is it an expected frame? + Remember, the first can be frame 7 or frame 0, depending on the direction of the MTC generator ... */ #ifdef DEBUG_MTC - cerr << "MTC: (state = " << _mtc_running << ") " + cerr << "MTC: (state = " << _mtc_running << ") " << which_quarter_frame << " vs. " << expected_mtc_quarter_frame_code << " consecutive ? " << consecutive_qtr_frame_cnt << endl; #endif if (_mtc_running == MTC_Stopped) { - + /* we are stopped but are seeing qtr frame messages */ if (consecutive_qtr_frame_cnt == 0) { @@ -108,11 +116,11 @@ Parser::process_mtc_quarter_frame (byte *msg) /* first quarter frame */ if (which_quarter_frame != 0 && which_quarter_frame != 7) { - + last_qtr_frame = which_quarter_frame; consecutive_qtr_frame_cnt++; } - + // cerr << "first seen qframe = " << (int) last_qtr_frame << endl; return; @@ -120,17 +128,20 @@ Parser::process_mtc_quarter_frame (byte *msg) } else if (consecutive_qtr_frame_cnt == 1) { /* third quarter frame */ - - // cerr << "second seen qframe = " << (int) which_quarter_frame << endl; +#ifdef DEBUG_MTC + cerr << "second seen qframe = " << (int) which_quarter_frame << endl; +#endif if (last_qtr_frame < which_quarter_frame) { _mtc_running = MTC_Forward; } else if (last_qtr_frame > which_quarter_frame) { _mtc_running = MTC_Backward; } - +#ifdef DEBUG_MTC + cerr << "Send MTC status as " << _mtc_running << endl; +#endif mtc_status (_mtc_running); - } + } switch (_mtc_running) { case MTC_Forward: @@ -144,7 +155,7 @@ Parser::process_mtc_quarter_frame (byte *msg) case MTC_Backward: if (which_quarter_frame == 0) { expected_mtc_quarter_frame_code = 7; - + } else { expected_mtc_quarter_frame_code = which_quarter_frame - 1; } @@ -153,9 +164,9 @@ Parser::process_mtc_quarter_frame (byte *msg) case MTC_Stopped: break; } - + } else { - + /* already running */ // for testing bad MIDI connections etc. @@ -166,7 +177,7 @@ Parser::process_mtc_quarter_frame (byte *msg) consecutive_qtr_frame_cnt = 0; #ifdef DEBUG_MTC - cerr << "MTC: (state = " << _mtc_running << ") " + cerr << "MTC: (state = " << _mtc_running << ") " << which_quarter_frame << " vs. " << expected_mtc_quarter_frame_code << endl; #endif @@ -174,7 +185,9 @@ Parser::process_mtc_quarter_frame (byte *msg) true, just ignore this in terms of it being an error. */ - if (1) { /* mtc_skipped () */ + boost::optional res = mtc_skipped (); + + if (res.get_value_or (false)) { /* no error, reset next expected frame */ @@ -190,7 +203,7 @@ Parser::process_mtc_quarter_frame (byte *msg) case MTC_Backward: if (which_quarter_frame == 0) { expected_mtc_quarter_frame_code = 7; - + } else { expected_mtc_quarter_frame_code = which_quarter_frame - 1; } @@ -202,19 +215,18 @@ Parser::process_mtc_quarter_frame (byte *msg) #ifdef DEBUG_MTC cerr << "SKIPPED, next expected = " << expected_mtc_quarter_frame_code << endl; -#endif +#endif return; } - /* go back to waiting for the first frame */ - - expected_mtc_quarter_frame_code = 0; - memset (_qtr_mtc_time, 0, sizeof (_qtr_mtc_time)); + /* skip counts as an error ... go back to waiting for the first frame */ - _mtc_running = MTC_Stopped; - _mtc_locked = false; +#ifdef DEBUG_MTC + cerr << "Skipped MTC qtr frame, return to stopped state" << endl; +#endif + reset_mtc_state (); mtc_status (MTC_Stopped); - + return; } else { @@ -228,7 +240,7 @@ Parser::process_mtc_quarter_frame (byte *msg) /* time code is looking good */ #ifdef DEBUG_MTC - // cerr << "for quarter frame " << which_quarter_frame << " byte = " << hex << (int) msg[1] << dec << endl; + cerr << "for quarter frame " << which_quarter_frame << " byte = " << hex << (int) msg[1] << dec << endl; #endif switch (which_quarter_frame) { @@ -255,29 +267,29 @@ Parser::process_mtc_quarter_frame (byte *msg) case 5: // minutes MS nibble _qtr_mtc_time[2] |= (msg[1] & 0xf)<<4; break; - + case 6: // hours LS nibble _qtr_mtc_time[3] |= msg[1] & 0xf; break; - case 7: - + case 7: + /* last quarter frame msg has the MS bit of the hour in bit 0, and the SMPTE FPS type - in bits 5 and 6 + in bits 5 and 6 */ - + _qtr_mtc_time[3] |= ((msg[1] & 0x1) << 4); _mtc_fps = MTC_FPS ((msg[1] & 0x6) >> 1); _qtr_mtc_time[4] = _mtc_fps; break; default: - /*NOTREACHED*/ + abort(); /*NOTREACHED*/ break; - } - + } + #ifdef DEBUG_MTC cerr << "Emit MTC Qtr\n"; #endif @@ -288,13 +300,13 @@ Parser::process_mtc_quarter_frame (byte *msg) switch (_mtc_running) { case MTC_Forward: - if ((which_quarter_frame == 7)) { - + if (which_quarter_frame == 7) { + /* we've reached the final of 8 quarter frame messages. store the time, reset the pending time holder, and signal anyone who wants to know the time. */ - + if (consecutive_qtr_frame_cnt >= 8) { memcpy (_mtc_time, _qtr_mtc_time, sizeof (_mtc_time)); memset (_qtr_mtc_time, 0, sizeof (_qtr_mtc_time)); @@ -305,15 +317,15 @@ Parser::process_mtc_quarter_frame (byte *msg) mtc_time (_mtc_time, false, _timestamp); } expected_mtc_quarter_frame_code = 0; - + } else { expected_mtc_quarter_frame_code = which_quarter_frame + 1; } break; - + case MTC_Backward: if (which_quarter_frame == 0) { - + /* we've reached the final of 8 quarter frame messages. store the time, reset the pending time holder, and signal anyone who wants to know the time.