#include <cstdlib>
#include <unistd.h>
-#include <string>
+#include <cstring>
#include <iostream>
-#include <midi++/types.h>
-#include <midi++/parser.h>
-#include <midi++/port.h>
-#include <midi++/mmc.h>
-#include <pbd/transmitter.h>
+#include "midi++/types.h"
+#include "midi++/parser.h"
+#include "midi++/port.h"
+#include "midi++/mmc.h"
+#include "pbd/transmitter.h"
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];
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;
/* wait for first quarter frame, which could indicate forwards
/* emit signals */
mtc (*this, &sysex_buf[1], msglen - 1);
- mtc_time (fake_mtc_time, true);
+ 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;
void
Parser::reset_mtc_state ()
{
+#ifdef DEBUG_MTC
+ cerr << "MTC state reset" << endl;
+#endif
+ /* MUST REMAIN RT-SAFE */
+
_mtc_forward = false;
_mtc_running = MTC_Stopped;
_mtc_locked = false;
}
void
-Parser::process_mtc_quarter_frame (byte *msg)
+Parser::process_mtc_quarter_frame (MIDI::byte *msg)
{
int which_quarter_frame = (msg[1] & 0xf0) >> 4;
depending on the direction of the MTC generator ...
*/
-#if 0
+#ifdef DEBUG_MTC
cerr << "MTC: (state = " << _mtc_running << ") "
<< which_quarter_frame << " vs. " << expected_mtc_quarter_frame_code
<< " consecutive ? " << consecutive_qtr_frame_cnt
last_qtr_frame = which_quarter_frame;
consecutive_qtr_frame_cnt++;
}
-
+
// cerr << "first seen qframe = " << (int) last_qtr_frame << endl;
return;
} 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);
}
true, just ignore this in terms of it being an error.
*/
- if (1) { /* mtc_skipped () */
+ boost::optional<bool> res = mtc_skipped ();
+
+ if (res.get_value_or (false)) {
/* no error, reset next expected frame */
return;
}
- /* go back to waiting for the first frame */
+ /* skip counts as an error ... go back to waiting for the first frame */
- expected_mtc_quarter_frame_code = 0;
- memset (_qtr_mtc_time, 0, sizeof (_qtr_mtc_time));
-
- _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;
/* time code is looking good */
+#ifdef DEBUG_MTC
+ cerr << "for quarter frame " << which_quarter_frame << " byte = " << hex << (int) msg[1] << dec << endl;
+#endif
+
switch (which_quarter_frame) {
case 0: // frames LS nibble
_qtr_mtc_time[0] |= msg[1] & 0xf;
break;
default:
- /*NOTREACHED*/
+ abort(); /*NOTREACHED*/
break;
}
- mtc_qtr (*this); /* EMIT_SIGNAL */
+#ifdef DEBUG_MTC
+ cerr << "Emit MTC Qtr\n";
+#endif
+
+ mtc_qtr (*this, which_quarter_frame, _timestamp); /* EMIT_SIGNAL */
// mtc (*this, &msg[1], msglen - 1);
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,
if (!_mtc_locked) {
_mtc_locked = true;
}
- mtc_time (_mtc_time, false);
+
+ mtc_time (_mtc_time, false, _timestamp);
}
expected_mtc_quarter_frame_code = 0;
if (!_mtc_locked) {
_mtc_locked = true;
}
- mtc_time (_mtc_time, false);
+ mtc_time (_mtc_time, false, _timestamp);
}
expected_mtc_quarter_frame_code = 7;