1 /*
2  * Copyright (C) 2000-2017 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2009-2010 David Robillard <d@drobilla.net>
4  * Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net>
5  * Copyright (C) 2014-2015 Robin Gareus <robin@gareus.org>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21 
22 #include <fcntl.h>
23 #include <map>
24 
25 #include "temporal/time.h"
26 #include "temporal/bbt_time.h"
27 
28 #include "pbd/error.h"
29 
30 #include "midi++/mmc.h"
31 #include "midi++/port.h"
32 #include "midi++/parser.h"
33 
34 #ifndef __INT_MAX__   // 'ssize_t' won't be defined yet
35                       // (except in later versions of MSVC)
36 #if !defined (_MSC_VER) || (_MSC_VER < 1800)
37 typedef long ssize_t;
38 #endif
39 #endif
40 
41 using namespace std;
42 using namespace MIDI;
43 using namespace PBD;
44 
45 /**
46  * As libtimecode is linked statically to libmidi++ this
47  * is necessary to pull in all the symbols from libtimecode
48  * so they are exported for other users of libtimecode.
49  */
50 double tmp = Timecode::BBT_Time::ticks_per_beat;
51 
52 static std::map<int,string> mmc_cmd_map;
build_mmc_cmd_map()53 static void build_mmc_cmd_map ()
54 {
55 	pair<int,string> newpair;
56 
57 	newpair.first = 0x1;
58 	newpair.second = "Stop";
59 	mmc_cmd_map.insert (newpair);
60 
61 	newpair.first = 0x2;
62 	newpair.second = "Play";
63 	mmc_cmd_map.insert (newpair);
64 
65 	newpair.first = 0x3;
66 	newpair.second = "DeferredPlay";
67 	mmc_cmd_map.insert (newpair);
68 
69 	newpair.first = 0x4;
70 	newpair.second = "FastForward";
71 	mmc_cmd_map.insert (newpair);
72 
73 	newpair.first = 0x5;
74 	newpair.second = "Rewind";
75 	mmc_cmd_map.insert (newpair);
76 
77 	newpair.first = 0x6;
78 	newpair.second = "RecordStrobe";
79 	mmc_cmd_map.insert (newpair);
80 
81 	newpair.first = 0x7;
82 	newpair.second = "RecordExit";
83 	mmc_cmd_map.insert (newpair);
84 
85 	newpair.first = 0x8;
86 	newpair.second = "RecordPause";
87 	mmc_cmd_map.insert (newpair);
88 
89 	newpair.first = 0x9;
90 	newpair.second = "Pause";
91 	mmc_cmd_map.insert (newpair);
92 
93 	newpair.first = 0xA;
94 	newpair.second = "Eject";
95 	mmc_cmd_map.insert (newpair);
96 
97 	newpair.first = 0xB;
98 	newpair.second = "Chase";
99 	mmc_cmd_map.insert (newpair);
100 
101 	newpair.first = 0xC;
102 	newpair.second = "CommandErrorReset";
103 	mmc_cmd_map.insert (newpair);
104 
105 	newpair.first = 0xD;
106 	newpair.second = "MmcReset";
107 	mmc_cmd_map.insert (newpair);
108 
109 	newpair.first = 0x20;
110 	newpair.second = "Illegal Mackie Jog Start";
111 	mmc_cmd_map.insert (newpair);
112 
113 	newpair.first = 0x21;
114 	newpair.second = "Illegal Mackie Jog Stop";
115 	mmc_cmd_map.insert (newpair);
116 
117 	newpair.first = 0x40;
118 	newpair.second = "Write";
119 	mmc_cmd_map.insert (newpair);
120 
121 	newpair.first = 0x41;
122 	newpair.second = "MaskedWrite";
123 	mmc_cmd_map.insert (newpair);
124 
125 	newpair.first = 0x42;
126 	newpair.second = "Read";
127 	mmc_cmd_map.insert (newpair);
128 
129 	newpair.first = 0x43;
130 	newpair.second = "Update";
131 	mmc_cmd_map.insert (newpair);
132 
133 	newpair.first = 0x44;
134 	newpair.second = "Locate";
135 	mmc_cmd_map.insert (newpair);
136 
137 	newpair.first = 0x45;
138 	newpair.second = "VariablePlay";
139 	mmc_cmd_map.insert (newpair);
140 
141 	newpair.first = 0x46;
142 	newpair.second = "Search";
143 	mmc_cmd_map.insert (newpair);
144 
145 	newpair.first = 0x47;
146 	newpair.second = "Shuttle";
147 	mmc_cmd_map.insert (newpair);
148 
149 	newpair.first = 0x48;
150 	newpair.second = "Step";
151 	mmc_cmd_map.insert (newpair);
152 
153 	newpair.first = 0x49;
154 	newpair.second = "AssignSystemMaster";
155 	mmc_cmd_map.insert (newpair);
156 
157 	newpair.first = 0x4A;
158 	newpair.second = "GeneratorCommand";
159 	mmc_cmd_map.insert (newpair);
160 
161 	newpair.first = 0x4B;
162 	newpair.second = "MtcCommand";
163 	mmc_cmd_map.insert (newpair);
164 
165 	newpair.first = 0x4C;
166 	newpair.second = "Move";
167 	mmc_cmd_map.insert (newpair);
168 
169 	newpair.first = 0x4D;
170 	newpair.second = "Add";
171 	mmc_cmd_map.insert (newpair);
172 
173 	newpair.first = 0x4E;
174 	newpair.second = "Subtract";
175 	mmc_cmd_map.insert (newpair);
176 
177 	newpair.first = 0x4F;
178 	newpair.second = "DropFrameAdjust";
179 	mmc_cmd_map.insert (newpair);
180 
181 	newpair.first = 0x50;
182 	newpair.second = "Procedure";
183 	mmc_cmd_map.insert (newpair);
184 
185 	newpair.first = 0x51;
186 	newpair.second = "Event";
187 	mmc_cmd_map.insert (newpair);
188 
189 	newpair.first = 0x52;
190 	newpair.second = "Group";
191 	mmc_cmd_map.insert (newpair);
192 
193 	newpair.first = 0x53;
194 	newpair.second = "CommandSegment";
195 	mmc_cmd_map.insert (newpair);
196 
197 	newpair.first = 0x54;
198 	newpair.second = "DeferredVariablePlay";
199 	mmc_cmd_map.insert (newpair);
200 
201 	newpair.first = 0x55;
202 	newpair.second = "RecordStrobeVariable";
203 	mmc_cmd_map.insert (newpair);
204 
205 	newpair.first = 0x7C;
206 	newpair.second = "Wait";
207 	mmc_cmd_map.insert (newpair);
208 
209 	newpair.first = 0x7F;
210 	newpair.second = "Resume";
211 	mmc_cmd_map.insert (newpair);
212 }
213 
MachineControl()214 MachineControl::MachineControl ()
215 {
216 	build_mmc_cmd_map ();
217 
218 	_receive_device_id = 0x7f;
219 	_send_device_id = 0x7f;
220 }
221 
222 void
set_ports(MIDI::Port * ip,MIDI::Port * op)223 MachineControl::set_ports (MIDI::Port* ip, MIDI::Port* op)
224 {
225 	port_connections.drop_connections ();
226 
227 	_input_port = ip;
228 	_output_port = op;
229 
230 	_input_port->parser()->mmc.connect_same_thread (port_connections, boost::bind (&MachineControl::process_mmc_message, this, _1, _2, _3));
231 	_input_port->parser()->start.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_start, this));
232 	_input_port->parser()->contineu.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_continue, this));
233 	_input_port->parser()->stop.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_stop, this));
234 }
235 
236 void
set_receive_device_id(MIDI::byte id)237 MachineControl::set_receive_device_id (MIDI::byte id)
238 {
239 	_receive_device_id = id & 0x7f;
240 }
241 
242 void
set_send_device_id(MIDI::byte id)243 MachineControl::set_send_device_id (MIDI::byte id)
244 {
245 	_send_device_id = id & 0x7f;
246 }
247 
248 bool
is_mmc(MIDI::byte * sysex_buf,size_t len)249 MachineControl::is_mmc (MIDI::byte *sysex_buf, size_t len)
250 {
251 	if (len < 4 || len > 48) {
252 		return false;
253 	}
254 
255 	if (sysex_buf[1] != 0x7f) {
256 		return false;
257 	}
258 
259 	if (sysex_buf[3] != 0x6 && /* MMC Command */
260 	    sysex_buf[3] != 0x7) { /* MMC Response */
261 		return false;
262 	}
263 
264 	return true;
265 }
266 
267 void
process_mmc_message(Parser &,MIDI::byte * msg,size_t len)268 MachineControl::process_mmc_message (Parser &, MIDI::byte *msg, size_t len)
269 {
270 	size_t skiplen;
271 	byte *mmc_msg;
272 	bool single_byte;
273 
274 	/* Reject if its not for us. 0x7f is the "all-call" device ID */
275 
276 	/* msg[0] = 0x7f (MMC sysex ID(
277 	   msg[1] = device ID
278 	   msg[2] = 0x6 (MMC command) or 0x7 (MMC response)
279 	   msg[3] = MMC command code
280 	   msg[4] = (typically) byte count for following part of command
281 	*/
282 
283 #if 0
284 	cerr << "*** me = " << (int) _receive_device_id << " MMC message: len = " << len << "\n\t";
285 	for (size_t i = 0; i < len; i++) {
286 		cerr << hex << (int) msg[i] << dec << ' ';
287 	}
288 	cerr << endl;
289 #endif
290 
291 	if (_receive_device_id != 0x7f && msg[1] != 0x7f && msg[1] != _receive_device_id) {
292 		return;
293 	}
294 
295 	mmc_msg = &msg[3];
296 	len -= 3;
297 
298 	do {
299 
300 		single_byte = false;
301 
302 		/* this works for all non-single-byte "counted"
303 		   commands. we set it to 1 for the exceptions.
304 		*/
305 
306 		std::map<int,string>::iterator x = mmc_cmd_map.find ((int)mmc_msg[0]);
307 		string cmdname = "unknown";
308 
309 		if (x != mmc_cmd_map.end()) {
310 			cmdname = (*x).second;
311 		}
312 
313 #if 0
314 		cerr << "+++ MMC type "
315 		     << hex
316 		     << ((int) *mmc_msg)
317 		     << dec
318 		     << " \"" << cmdname << "\" "
319 		     << " len = " << len
320 		     << endl;
321 #endif
322 
323 		switch (*mmc_msg) {
324 
325 		/* SINGLE-BYTE, UNCOUNTED COMMANDS */
326 
327 		case cmdStop:
328 			Stop (*this);
329 			single_byte = true;
330 			break;
331 
332 		case cmdPlay:
333 			Play (*this);
334 			single_byte = true;
335 			break;
336 
337 		case cmdDeferredPlay:
338 			DeferredPlay (*this);
339 			single_byte = true;
340 			break;
341 
342 		case cmdFastForward:
343 			FastForward (*this);
344 			single_byte = true;
345 			break;
346 
347 		case cmdRewind:
348 			Rewind (*this);
349 			single_byte = true;
350 			break;
351 
352 		case cmdRecordStrobe:
353 			RecordStrobe (*this);
354 			single_byte = true;
355 			break;
356 
357 		case cmdRecordExit:
358 			RecordExit (*this);
359 			single_byte = true;
360 			break;
361 
362 		case cmdRecordPause:
363 			RecordPause (*this);
364 			single_byte = true;
365 			break;
366 
367 		case cmdPause:
368 			Pause (*this);
369 			single_byte = true;
370 			break;
371 
372 		case cmdEject:
373 			Eject (*this);
374 			single_byte = true;
375 			break;
376 
377 		case cmdChase:
378 			Chase (*this);
379 			single_byte = true;
380 			break;
381 
382 		case cmdCommandErrorReset:
383 			CommandErrorReset (*this);
384 			single_byte = true;
385 			break;
386 
387 		case cmdMmcReset:
388 			MmcReset (*this);
389 			single_byte = true;
390 			break;
391 
392 		case cmdIllegalMackieJogStart:
393 			JogStart (*this);
394 			single_byte = true;
395 			break;
396 
397 		case cmdIllegalMackieJogStop:
398 			JogStop (*this);
399 			single_byte = true;
400 			break;
401 
402 		/* END OF SINGLE-BYTE, UNCOUNTED COMMANDS */
403 
404 		case cmdMaskedWrite:
405 			do_masked_write (mmc_msg, len);
406 			break;
407 
408 		case cmdLocate:
409 			do_locate (mmc_msg, len);
410 			break;
411 
412 		case cmdShuttle:
413 			do_shuttle (mmc_msg, len);
414 			break;
415 
416 		case cmdStep:
417 			do_step (mmc_msg, len);
418 			break;
419 
420 		case cmdWrite:
421 		case cmdRead:
422 		case cmdUpdate:
423 		case cmdVariablePlay:
424 		case cmdSearch:
425 		case cmdAssignSystemMaster:
426 		case cmdGeneratorCommand:
427 		case cmdMtcCommand:
428 		case cmdMove:
429 		case cmdAdd:
430 		case cmdSubtract:
431 		case cmdDropFrameAdjust:
432 		case cmdProcedure:
433 		case cmdEvent:
434 		case cmdGroup:
435 		case cmdCommandSegment:
436 		case cmdDeferredVariablePlay:
437 		case cmdRecordStrobeVariable:
438 		case cmdWait:
439 		case cmdResume:
440 			error << "MIDI::MachineControl: unimplemented MMC command "
441 			      << hex << (int) *mmc_msg << dec
442 			      << endmsg;
443 
444 			break;
445 
446 		default:
447 			error << "MIDI::MachineControl: unknown MMC command "
448 			      << hex << (int) *mmc_msg << dec
449 			      << endmsg;
450 
451 			break;
452 		}
453 
454 		/* increase skiplen to cover the command byte and
455 		   count byte (if it existed).
456 		*/
457 
458 		if (!single_byte) {
459 			skiplen = mmc_msg[1] + 2;
460 		} else {
461 			skiplen = 1;
462 		}
463 
464 		if (len <= skiplen) {
465 			break;
466 		}
467 
468 		mmc_msg += skiplen;
469 		len -= skiplen;
470 
471 	} while (len > 1); /* skip terminating EOX byte */
472 }
473 
474 int
do_masked_write(MIDI::byte * msg,size_t len)475 MachineControl::do_masked_write (MIDI::byte *msg, size_t len)
476 {
477 	/* return the number of bytes "consumed" */
478 
479 	int retval = msg[1] + 2; /* bytes following + 2 */
480 
481 	switch (msg[2]) {
482 	case 0x4f:  /* Track Record Ready Status */
483 		write_track_status (&msg[3], len - 3, msg[2]);
484 		break;
485 
486 	case 0x62: /* track mute */
487 		write_track_status (&msg[3], len - 3, msg[2]);
488 		break;
489 
490 	default:
491 		warning << "MIDI::MachineControl: masked write to "
492 			<< hex << (int) msg[2] << dec
493 			<< " not implemented"
494 			<< endmsg;
495 	}
496 
497 	return retval;
498 }
499 
500 void
write_track_status(MIDI::byte * msg,size_t,MIDI::byte reg)501 MachineControl::write_track_status (MIDI::byte *msg, size_t /*len*/, MIDI::byte reg)
502 {
503 	size_t n;
504 	ssize_t base_track;
505 
506 	/* Bits 0-4 of the first byte are for special tracks:
507 
508 	   bit 0: video
509 	   bit 1: reserved
510 	   bit 2: time code
511 	   bit 3: aux track a
512 	   bit 4: aux track b
513 
514 	   the format of the message (its an MMC Masked Write) is:
515 
516 	   0x41      Command Code
517 	   <count>   byte count of following data
518 	   <name>    byte value of the field being written
519 	   <byte #>  byte number of target byte in the
520 	   bitmap being written to
521 	   <mask>    ones in the mask indicate which bits will be changed
522 	   <data>    new data for the byte being written
523 
524 	   by the time this code is executing, msg[0] is the
525 	   byte number of the target byte. if its zero, we
526 	   are writing to a special byte in the standard
527 	   track bitmap, in which the first 5 bits are
528 	   special. hence the bits for tracks 1 + 2 are bits
529 	   5 and 6 of the first byte of the track
530 	   bitmap. so:
531 
532 	   change track 1:  msg[0] = 0;       << first byte of track bitmap
533 	                    msg[1] = 0100000; << binary: bit 5 set
534 
535 	   change track 2:  msg[0] = 0;       << first byte of track bitmap
536 	                    msg[1] = 1000000; << binary: bit 6 set
537 
538 	   change track 3:  msg[0] = 1;       << second byte of track bitmap
539 	                    msg[1] = 0000001; << binary: bit 0 set
540 
541 	   the (msg[0] * 8) - 6 computation is an attempt to
542 	   extract the value of the first track: ie. the one
543 	   that would be indicated by bit 0 being set.
544 
545            so, if msg[0] = 0, msg[1] = 0100000 (binary),
546 	   what happens is that base_track = -5, but by the
547 	   time we check the correct bit, n = 5, and so the
548 	   computed track for the status change is 0 (first
549 	   track).
550 
551            if msg[0] = 1, then the base track for any change is 2 (the third track), and so on.
552 	*/
553 
554 	/* XXX check needed to make sure we don't go outside the
555 	   supported number of tracks.
556 	*/
557 
558 	if (msg[0] == 0) {
559 		base_track = -5;
560 	} else {
561 		base_track = (msg[0] * 8) - 6;
562 	}
563 
564 	for (n = 0; n < 7; n++) {
565 		if (msg[1] & (1<<n)) {
566 
567 			/* Only touch tracks that have the "mask"
568 			   bit set.
569 			*/
570 
571 			bool val = (msg[2] & (1<<n));
572 
573 			switch (reg) {
574 			case 0x4f:
575 				trackRecordStatus[base_track+n] = val;
576 				TrackRecordStatusChange (*this, base_track+n, val);
577 				break;
578 
579 			case 0x62:
580 				trackMute[base_track+n] = val;
581 				TrackMuteChange (*this, base_track+n, val);
582 				break;
583 			}
584 		}
585 
586 	}
587 }
588 
589 int
do_locate(MIDI::byte * msg,size_t)590 MachineControl::do_locate (MIDI::byte *msg, size_t /*msglen*/)
591 {
592 	if (msg[2] == 0) {
593 		warning << "MIDI::MMC: locate [I/F] command not supported"
594 			<< endmsg;
595 		return 0;
596 	}
597 
598 	/* regular "target" locate command */
599 
600 	Locate (*this, &msg[3]);
601 	return 0;
602 }
603 
604 int
do_step(MIDI::byte * msg,size_t)605 MachineControl::do_step (MIDI::byte *msg, size_t /*msglen*/)
606 {
607 	int steps = msg[2] & 0x3f;
608 
609 	if (msg[2] & 0x40) {
610 		steps = -steps;
611 	}
612 
613 	Step (*this, steps);
614 	return 0;
615 }
616 
617 int
do_shuttle(MIDI::byte * msg,size_t)618 MachineControl::do_shuttle (MIDI::byte *msg, size_t /*msglen*/)
619 {
620 	size_t forward;
621 	byte sh = msg[2];
622 	byte sm = msg[3];
623 	byte sl = msg[4];
624 	size_t left_shift;
625 	size_t integral;
626 	size_t fractional;
627 	float shuttle_speed;
628 
629 	if (sh & (1<<6)) {
630 		forward = false;
631 	} else {
632 		forward = true;
633 	}
634 
635 	left_shift = (sh & 0x38);
636 
637 	integral = ((sh & 0x7) << left_shift) | (sm >> (7 - left_shift));
638 	fractional = ((sm << left_shift) << 7) | sl;
639 
640 	shuttle_speed = integral +
641 		((float)fractional / (1 << (14 - left_shift)));
642 
643 	Shuttle (*this, shuttle_speed, forward);
644 
645 	return 0;
646 }
647 
648 void
enable_send(bool yn)649 MachineControl::enable_send (bool yn)
650 {
651 	_enable_send = yn;
652 }
653 
654 /** Send a MMC command to a the MMC port.
655  *  @param c command.
656  */
657 void
send(MachineControlCommand const & c,timestamp_t when)658 MachineControl::send (MachineControlCommand const & c, timestamp_t when)
659 {
660 	if (_output_port == 0 || !_enable_send) {
661 		// cerr << "Not delivering MMC " << _mmc->port() << " - " << session_send_mmc << endl;
662 		return;
663 	}
664 
665 	MIDI::byte buffer[32];
666 	MIDI::byte* b = c.fill_buffer (this, buffer);
667 
668 	if (_output_port->midimsg (buffer, b - buffer, when)) {
669 		error << "MMC: cannot send command" << endmsg;
670 	}
671 }
672 
673 void
spp_start()674 MachineControl::spp_start ()
675 {
676 	SPPStart (); /* EMIT SIGNAL */
677 }
678 
679 void
spp_continue()680 MachineControl::spp_continue ()
681 {
682 	SPPContinue (); /* EMIT SIGNAL */
683 }
684 
685 void
spp_stop()686 MachineControl::spp_stop ()
687 {
688 	SPPStop (); /* EMIT SIGNAL */
689 }
690 
MachineControlCommand(MachineControl::Command c)691 MachineControlCommand::MachineControlCommand (MachineControl::Command c)
692 	: _command (c)
693 {
694 
695 }
696 
MachineControlCommand(Timecode::Time t)697 MachineControlCommand::MachineControlCommand (Timecode::Time t)
698 	: _command (MachineControl::cmdLocate)
699 	, _time (t)
700 {
701 
702 }
703 
704 MIDI::byte *
fill_buffer(MachineControl * mmc,MIDI::byte * b) const705 MachineControlCommand::fill_buffer (MachineControl* mmc, MIDI::byte* b) const
706 {
707 	*b++ = 0xf0; // SysEx
708 	*b++ = 0x7f; // Real-time SysEx ID for MMC
709 	*b++ = mmc->send_device_id();
710 	*b++ = 0x6; // MMC command
711 
712 	*b++ = _command;
713 
714 	if (_command == MachineControl::cmdLocate) {
715 		*b++ = 0x6; // byte count
716 		*b++ = 0x1; // "TARGET" subcommand
717 		*b++ = _time.hours % 24;
718 		*b++ = _time.minutes;
719 		*b++ = _time.seconds;
720 		*b++ = _time.frames;
721 		*b++ = _time.subframes;
722 	}
723 
724 	*b++ = 0xf7;
725 
726 	return b;
727 }
728 
729