1 /*
2  * Copyright (C) 2005-2009 Taybin Rutkin <taybin@taybin.com>
3  * Copyright (C) 2005-2019 Paul Davis <paul@linuxaudiosystems.com>
4  * Copyright (C) 2006-2012 David Robillard <d@drobilla.net>
5  * Copyright (C) 2008 Hans Baier <hansfbaier@googlemail.com>
6  * Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net>
7  * Copyright (C) 2012-2019 Robin Gareus <robin@gareus.org>
8  * Copyright (C) 2013 John Emmas <john@creativepost.co.uk>
9  * Copyright (C) 2013 Michael Fisher <mfisher31@gmail.com>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 
26 #include <string>
27 #include <cmath>
28 #include <cerrno>
29 #include <cassert>
30 #include <unistd.h>
31 
32 #include <boost/shared_ptr.hpp>
33 
34 #include <glibmm/main.h>
35 
36 #include "midi++/mmc.h"
37 #include "midi++/port.h"
38 
39 #include "pbd/error.h"
40 #include "pbd/pthread_utils.h"
41 #include "pbd/timersub.h"
42 
43 #include "temporal/time.h"
44 
45 #include "ardour/audio_track.h"
46 #include "ardour/audioengine.h"
47 #include "ardour/debug.h"
48 #include "ardour/midi_port.h"
49 #include "ardour/midi_track.h"
50 #include "ardour/midi_ui.h"
51 #include "ardour/profile.h"
52 #include "ardour/session.h"
53 #include "ardour/transport_master.h"
54 #include "ardour/transport_fsm.h"
55 #include "ardour/ticker.h"
56 
57 #include "pbd/i18n.h"
58 
59 using namespace std;
60 using namespace ARDOUR;
61 using namespace PBD;
62 using namespace MIDI;
63 using namespace Glib;
64 
65 void
midi_panic()66 Session::midi_panic()
67 {
68 	{
69 		boost::shared_ptr<RouteList> r = routes.reader ();
70 
71 		for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
72 			MidiTrack *track = dynamic_cast<MidiTrack*>((*i).get());
73 			if (track != 0) {
74 				track->midi_panic();
75 			}
76 		}
77 	}
78 }
79 
80 void
setup_midi_control()81 Session::setup_midi_control ()
82 {
83 	outbound_mtc_timecode_frame = 0;
84 	next_quarter_frame_to_send = 0;
85 
86 	/* Set up the qtr frame message */
87 
88 	mtc_msg[0] = 0xf1;
89 	mtc_msg[2] = 0xf1;
90 	mtc_msg[4] = 0xf1;
91 	mtc_msg[6] = 0xf1;
92 	mtc_msg[8] = 0xf1;
93 	mtc_msg[10] = 0xf1;
94 	mtc_msg[12] = 0xf1;
95 	mtc_msg[14] = 0xf1;
96 }
97 
98 void
spp_start()99 Session::spp_start ()
100 {
101 	if (Config->get_mmc_control ()) {
102 		request_roll (TRS_MIDIClock);
103 	}
104 }
105 
106 void
spp_continue()107 Session::spp_continue ()
108 {
109 	spp_start ();
110 }
111 
112 void
spp_stop()113 Session::spp_stop ()
114 {
115 	if (Config->get_mmc_control ()) {
116 		request_stop ();
117 	}
118 }
119 
120 void
mmc_deferred_play(MIDI::MachineControl &)121 Session::mmc_deferred_play (MIDI::MachineControl &/*mmc*/)
122 {
123 	if (Config->get_mmc_control ()) {
124 		request_roll (TRS_MMC);
125 	}
126 }
127 
128 void
mmc_record_pause(MIDI::MachineControl &)129 Session::mmc_record_pause (MIDI::MachineControl &/*mmc*/)
130 {
131 	if (Config->get_mmc_control ()) {
132 		maybe_enable_record();
133 	}
134 }
135 
136 void
mmc_record_strobe(MIDI::MachineControl &)137 Session::mmc_record_strobe (MIDI::MachineControl &/*mmc*/)
138 {
139 	if (!Config->get_mmc_control() || (_step_editors > 0)) {
140 		return;
141 	}
142 
143 	/* record strobe does an implicit "Play" command */
144 
145 	if (_transport_fsm->transport_speed() != 1.0) {
146 
147 		/* start_transport() will move from Enabled->Recording, so we
148 		   don't need to do anything here except enable recording.
149 		   its not the same as maybe_enable_record() though, because
150 		   that *can* switch to Recording, which we do not want.
151 		*/
152 
153 		save_state ("", true);
154 		g_atomic_int_set (&_record_status, Enabled);
155 		RecordStateChanged (); /* EMIT SIGNAL */
156 
157 		request_roll (TRS_MMC);
158 
159 	} else {
160 
161 		enable_record ();
162 	}
163 }
164 
165 void
mmc_record_exit(MIDI::MachineControl &)166 Session::mmc_record_exit (MIDI::MachineControl &/*mmc*/)
167 {
168 	if (Config->get_mmc_control ()) {
169 		disable_record (false);
170 	}
171 }
172 
173 void
mmc_stop(MIDI::MachineControl &)174 Session::mmc_stop (MIDI::MachineControl &/*mmc*/)
175 {
176 	if (Config->get_mmc_control ()) {
177 		request_stop ();
178 	}
179 }
180 
181 void
mmc_pause(MIDI::MachineControl &)182 Session::mmc_pause (MIDI::MachineControl &/*mmc*/)
183 {
184 	if (Config->get_mmc_control ()) {
185 
186 		/* We support RECORD_PAUSE, so the spec says that
187 		   we must interpret PAUSE like RECORD_PAUSE if
188 		   recording.
189 		*/
190 
191 		if (actively_recording()) {
192 			maybe_enable_record ();
193 		} else {
194 			request_stop ();
195 		}
196 	}
197 }
198 
199 static bool step_queued = false;
200 
201 void
mmc_step(MIDI::MachineControl &,int steps)202 Session::mmc_step (MIDI::MachineControl &/*mmc*/, int steps)
203 {
204 	if (!Config->get_mmc_control ()) {
205 		return;
206 	}
207 
208 	struct timeval now;
209 	struct timeval diff = { 0, 0 };
210 
211 	gettimeofday (&now, 0);
212 
213 	timersub (&now, &last_mmc_step, &diff);
214 
215 	gettimeofday (&now, 0);
216 	timersub (&now, &last_mmc_step, &diff);
217 
218 	if (last_mmc_step.tv_sec != 0 && (diff.tv_usec + (diff.tv_sec * 1000000)) < _engine.usecs_per_cycle()) {
219 		return;
220 	}
221 
222 	double diff_secs = diff.tv_sec + (diff.tv_usec / 1000000.0);
223 	double cur_speed = (((steps * 0.5) * timecode_frames_per_second()) / diff_secs) / timecode_frames_per_second();
224 
225 	if (_transport_fsm->transport_speed() == 0 || cur_speed * _transport_fsm->transport_speed() < 0) {
226 		/* change direction */
227 		step_speed = cur_speed;
228 	} else {
229 		step_speed = (0.6 * step_speed) + (0.4 * cur_speed);
230 	}
231 
232 	step_speed *= 0.25;
233 
234 #if 0
235 	cerr << "delta = " << diff_secs
236 	     << " ct = " << _transport_fsm->transport_speed()
237 	     << " steps = " << steps
238 	     << " new speed = " << cur_speed
239 	     << " speed = " << step_speed
240 	     << endl;
241 #endif
242 
243 	request_transport_speed_nonzero (step_speed);
244 	last_mmc_step = now;
245 
246 	if (!step_queued) {
247 		if (midi_control_ui) {
248 			RefPtr<TimeoutSource> tsrc = TimeoutSource::create (100);
249 			tsrc->connect (sigc::mem_fun (*this, &Session::mmc_step_timeout));
250 			tsrc->attach (midi_control_ui->main_loop()->get_context());
251 			step_queued = true;
252 		}
253 	}
254 }
255 
256 void
mmc_rewind(MIDI::MachineControl &)257 Session::mmc_rewind (MIDI::MachineControl &/*mmc*/)
258 {
259 	if (Config->get_mmc_control ()) {
260 		request_transport_speed(-8.0f);
261 	}
262 }
263 
264 void
mmc_fast_forward(MIDI::MachineControl &)265 Session::mmc_fast_forward (MIDI::MachineControl &/*mmc*/)
266 {
267 	if (Config->get_mmc_control ()) {
268 		request_transport_speed(8.0f);
269 	}
270 }
271 
272 void
mmc_locate(MIDI::MachineControl &,const MIDI::byte * mmc_tc)273 Session::mmc_locate (MIDI::MachineControl &/*mmc*/, const MIDI::byte* mmc_tc)
274 {
275 	if (!Config->get_mmc_control ()) {
276 		return;
277 	}
278 
279 	samplepos_t target_sample;
280 	Timecode::Time timecode;
281 
282 	timecode.hours = mmc_tc[0] & 0xf;
283 	timecode.minutes = mmc_tc[1];
284 	timecode.seconds = mmc_tc[2];
285 	timecode.frames = mmc_tc[3];
286 	timecode.rate = timecode_frames_per_second();
287 	timecode.drop = timecode_drop_frames();
288 
289 	// Also takes timecode offset into account:
290 	timecode_to_sample( timecode, target_sample, true /* use_offset */, false /* use_subframes */ );
291 
292 	if (target_sample > max_samplepos) {
293 		target_sample = max_samplepos;
294 	}
295 
296 	/* Some (all?) MTC/MMC devices do not send a full MTC frame
297 	   at the end of a locate, instead sending only an MMC
298 	   locate command. This causes the current position
299 	   of an MTC slave to become out of date. Catch this.
300 	*/
301 
302 	boost::shared_ptr<MTC_TransportMaster> mtcs = boost::dynamic_pointer_cast<MTC_TransportMaster> (transport_master());
303 
304 	if (mtcs) {
305 		// cerr << "Locate *with* MTC slave\n";
306 		mtcs->handle_locate (mmc_tc);
307 	} else {
308 		// cerr << "Locate without MTC slave\n";
309 		request_locate (target_sample, MustStop);
310 	}
311 }
312 
313 void
mmc_shuttle(MIDI::MachineControl &,float speed,bool forw)314 Session::mmc_shuttle (MIDI::MachineControl &/*mmc*/, float speed, bool forw)
315 {
316 	if (!Config->get_mmc_control ()) {
317 		return;
318 	}
319 
320 	if (Config->get_shuttle_speed_threshold() >= 0 && speed > Config->get_shuttle_speed_threshold()) {
321 		speed *= Config->get_shuttle_speed_factor();
322 	}
323 
324 	if (forw) {
325 		request_transport_speed_nonzero (speed);
326 	} else {
327 		request_transport_speed_nonzero (-speed);
328 	}
329 }
330 
331 boost::shared_ptr<Route>
get_midi_nth_route_by_id(PresentationInfo::order_t n) const332 Session::get_midi_nth_route_by_id (PresentationInfo::order_t n) const
333 {
334 	PresentationInfo::Flag f;
335 
336 	/* These numbers are defined by the MMC specification.
337 	 */
338 
339 	if (n == 318) {
340 		f = PresentationInfo::MasterOut;
341 	} else if (n == 319) {
342 		f = PresentationInfo::MonitorOut;
343 	} else {
344 		f = PresentationInfo::Route;
345 	}
346 
347 	boost::shared_ptr<RouteList> r = routes.reader ();
348 	PresentationInfo::order_t match_cnt = 0;
349 
350 	for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
351 		if ((*i)->presentation_info().flag_match (f)) {
352 			if (match_cnt++ == n) {
353 				return *i;
354 			}
355 		}
356 	}
357 
358 	return boost::shared_ptr<Route>();
359 }
360 
361 void
mmc_record_enable(MIDI::MachineControl & mmc,size_t trk,bool enabled)362 Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
363 {
364 	if (!Config->get_mmc_control ()) {
365 		return;
366 	}
367 
368 	boost::shared_ptr<Route> r = get_midi_nth_route_by_id (trk);
369 
370 	if (r) {
371 		boost::shared_ptr<AudioTrack> at;
372 
373 		if ((at = boost::dynamic_pointer_cast<AudioTrack> (r))) {
374 			at->rec_enable_control()->set_value (enabled, Controllable::UseGroup);
375 		}
376 	}
377 }
378 
379 void
mtc_tx_resync_latency(bool playback)380 Session::mtc_tx_resync_latency (bool playback)
381 {
382 	if (deletion_in_progress() || !playback) {
383 		return;
384 	}
385 	boost::shared_ptr<Port> mtxport = _midi_ports->mtc_output_port ();
386 	if (mtxport) {
387 		mtxport->get_connected_latency_range(mtc_out_latency, true);
388 		DEBUG_TRACE (DEBUG::MTC, string_compose ("resync latency: %1\n", mtc_out_latency.max));
389 	}
390 }
391 
392 /** Send MTC Full Frame message (complete Timecode time) for the start of this cycle.
393  * This resets the MTC code, the next quarter frame message that is sent will be
394  * the first one with the beginning of this cycle as the new start point.
395  * @param t time to send.
396  */
397 int
send_full_time_code(samplepos_t const t,MIDI::pframes_t nframes)398 Session::send_full_time_code (samplepos_t const t, MIDI::pframes_t nframes)
399 {
400 	/* This function could easily send at a given sample offset, but would
401 	 * that be useful?  Does ardour do sub-block accurate locating? [DR] */
402 
403 	MIDI::byte msg[10];
404 	Timecode::Time timecode;
405 
406 	_send_timecode_update = false;
407 
408 	if (_engine.freewheeling() || !Config->get_send_mtc()) {
409 		return 0;
410 	}
411 
412 	if (transport_master_is_external() && !transport_master()->locked()) {
413 		return 0;
414 	}
415 
416 	// Get timecode time for the given time
417 	sample_to_timecode (t, timecode, true /* use_offset */, false /* no subframes */);
418 
419 	// sample-align outbound to rounded (no subframes) timecode
420 	samplepos_t mtc_tc;
421 	timecode_to_sample(timecode, mtc_tc, true, false);
422 	outbound_mtc_timecode_frame = mtc_tc;
423 	transmitting_timecode_time = timecode;
424 
425 	sampleoffset_t mtc_offset = mtc_out_latency.max;
426 
427 	// only if rolling.. ?
428 	outbound_mtc_timecode_frame += mtc_offset;
429 
430 	// outbound_mtc_timecode_frame needs to be >= _transport_sample
431 	// or a new full timecode will be queued next cycle.
432 	while (outbound_mtc_timecode_frame < t) {
433 		Timecode::increment (transmitting_timecode_time, config.get_subframes_per_frame());
434 		outbound_mtc_timecode_frame += _samples_per_timecode_frame;
435 	}
436 
437 	double const quarter_frame_duration = ((samplecnt_t) _samples_per_timecode_frame) / 4.0;
438 	if (ceil((t - mtc_tc) / quarter_frame_duration) > 0) {
439 		Timecode::increment (transmitting_timecode_time, config.get_subframes_per_frame());
440 		outbound_mtc_timecode_frame += _samples_per_timecode_frame;
441 	}
442 
443 	DEBUG_TRACE (DEBUG::MTC, string_compose ("Full MTC TC %1 (off %2)\n", outbound_mtc_timecode_frame, mtc_offset));
444 
445 	/* according to MTC spec 24, 30 drop and 30 non-drop TC, the frame-number represented by 8 quarter frames must be even. */
446 	if (((mtc_timecode_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_timecode_time.frames % 2)) {
447 		/* start MTC quarter frame transmission on an even frame */
448 		Timecode::increment (transmitting_timecode_time, config.get_subframes_per_frame());
449 		outbound_mtc_timecode_frame += _samples_per_timecode_frame;
450 	}
451 
452 	next_quarter_frame_to_send = 0;
453 
454 	// Sync slave to the same Timecode time as we are on
455 	msg[0] = 0xf0;
456 	msg[1] = 0x7f;
457 	msg[2] = 0x7f;
458 	msg[3] = 0x1;
459 	msg[4] = 0x1;
460 	msg[9] = 0xf7;
461 
462 	msg[5] = mtc_timecode_bits | (timecode.hours % 24);
463 	msg[6] = timecode.minutes;
464 	msg[7] = timecode.seconds;
465 	msg[8] = timecode.frames;
466 
467 	// Send message at offset 0, sent time is for the start of this cycle
468 
469 	MidiBuffer& mb (_midi_ports->mtc_output_port()->get_midi_buffer (nframes));
470 	mb.push_back (0, Evoral::MIDI_EVENT, sizeof (msg), msg);
471 
472 	_pframes_since_last_mtc = 0;
473 	return 0;
474 }
475 
476 /** Send MTC (quarter-frame) messages for this cycle.
477  * Must be called exactly once per cycle from the process thread.  Realtime safe.
478  * This function assumes the state of full Timecode is sane, eg. the slave is
479  * expecting quarter frame messages and has the right frame of reference (any
480  * full MTC Timecode time messages that needed to be sent should have been sent
481  * earlier already this cycle by send_full_time_code)
482  */
483 int
send_midi_time_code_for_cycle(samplepos_t start_sample,samplepos_t end_sample,ARDOUR::pframes_t nframes)484 Session::send_midi_time_code_for_cycle (samplepos_t start_sample, samplepos_t end_sample, ARDOUR::pframes_t nframes)
485 {
486 	// start_sample == start_sample  for normal cycles
487 	// start_sample > _transport_sample  for split cycles
488 	if (_engine.freewheeling() || !_send_qf_mtc || transmitting_timecode_time.negative || (next_quarter_frame_to_send < 0)) {
489 		// cerr << "(MTC) Not sending MTC\n";
490 		return 0;
491 	}
492 	if (transport_master_is_external() && !transport_master()->locked()) {
493 		return 0;
494 	}
495 
496 	if (_transport_fsm->transport_speed() < 0) {
497 		// we don't support rolling backwards
498 		return 0;
499 	}
500 
501 	/* MTC is max. 30 fps - assert() below will fail
502 	 * TODO actually limit it to 24,25,29df,30fps
503 	 * talk to oofus, first.
504 	 */
505 	if (Timecode::timecode_to_frames_per_second(config.get_timecode_format()) > 30) {
506 		return 0;
507 	}
508 
509 	assert (next_quarter_frame_to_send >= 0);
510 	assert (next_quarter_frame_to_send <= 7);
511 
512 	/* Duration of one quarter frame */
513 	double const quarter_frame_duration = _samples_per_timecode_frame / 4.0;
514 
515 	DEBUG_TRACE (DEBUG::MTC, string_compose ("TF %1 SF %2 MT %3 QF %4 QD %5\n",
516 	                                         _transport_sample, start_sample, outbound_mtc_timecode_frame,
517 	                                         next_quarter_frame_to_send, quarter_frame_duration));
518 
519 	if (rint(outbound_mtc_timecode_frame + (next_quarter_frame_to_send * quarter_frame_duration)) < _transport_sample) {
520 		// send full timecode and set outbound_mtc_timecode_frame, next_quarter_frame_to_send
521 		send_full_time_code (_transport_sample, nframes);
522 	}
523 
524 	if (rint(outbound_mtc_timecode_frame + (next_quarter_frame_to_send * quarter_frame_duration)) < start_sample) {
525 		// no QF for this cycle
526 		return 0;
527 	}
528 
529 	/* Send quarter frames for this cycle */
530 	while (end_sample > rint(outbound_mtc_timecode_frame + (next_quarter_frame_to_send * quarter_frame_duration))) {
531 
532 		DEBUG_TRACE (DEBUG::MTC, string_compose ("next sample to send: %1\n", next_quarter_frame_to_send));
533 
534 		switch (next_quarter_frame_to_send) {
535 		case 0:
536 			mtc_msg[1] = 0x00 | (transmitting_timecode_time.frames & 0xf);
537 			break;
538 		case 1:
539 			mtc_msg[1] = 0x10 | ((transmitting_timecode_time.frames & 0xf0) >> 4);
540 			break;
541 		case 2:
542 			mtc_msg[1] = 0x20 | (transmitting_timecode_time.seconds & 0xf);
543 			break;
544 		case 3:
545 			mtc_msg[1] = 0x30 | ((transmitting_timecode_time.seconds & 0xf0) >> 4);
546 			break;
547 		case 4:
548 			mtc_msg[1] = 0x40 | (transmitting_timecode_time.minutes & 0xf);
549 			break;
550 		case 5:
551 			mtc_msg[1] = 0x50 | ((transmitting_timecode_time.minutes & 0xf0) >> 4);
552 			break;
553 		case 6:
554 			mtc_msg[1] = 0x60 | ((mtc_timecode_bits | transmitting_timecode_time.hours) & 0xf);
555 			break;
556 		case 7:
557 			mtc_msg[1] = 0x70 | (((mtc_timecode_bits | transmitting_timecode_time.hours) & 0xf0) >> 4);
558 			break;
559 		}
560 
561 		const samplepos_t msg_time = rint (outbound_mtc_timecode_frame + (quarter_frame_duration * next_quarter_frame_to_send));
562 
563 		// This message must fall within this block or something is broken
564 		assert (msg_time >= start_sample);
565 		assert (msg_time < end_sample);
566 
567 		/* convert from session samples back to JACK samples using the transport speed */
568 		ARDOUR::pframes_t const out_stamp = (msg_time - start_sample) / _transport_fsm->transport_speed();
569 		assert (out_stamp < nframes);
570 
571 		MidiBuffer& mb (_midi_ports->mtc_output_port()->get_midi_buffer(nframes));
572 		if (!mb.push_back (out_stamp, Evoral::MIDI_EVENT, 2, mtc_msg)) {
573 			error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
574 			      << endmsg;
575 			return -1;
576 		}
577 
578 #ifndef NDEBUG
579 		if (DEBUG_ENABLED(DEBUG::MTC)) {
580 			DEBUG_STR_DECL(foo);
581 			DEBUG_STR_APPEND(foo,"sending ");
582 			DEBUG_STR_APPEND(foo, transmitting_timecode_time);
583 			DEBUG_TRACE (DEBUG::MTC, string_compose ("%1 qfm = %2, stamp = %3\n", DEBUG_STR(foo).str(), next_quarter_frame_to_send,
584 			                                         out_stamp));
585 		}
586 #endif
587 
588 		// Increment quarter frame counter
589 		next_quarter_frame_to_send++;
590 
591 		if (next_quarter_frame_to_send >= 8) {
592 			// Wrap quarter frame counter
593 			next_quarter_frame_to_send = 0;
594 			// Increment timecode time twice
595 			Timecode::increment (transmitting_timecode_time, config.get_subframes_per_frame());
596 			Timecode::increment (transmitting_timecode_time, config.get_subframes_per_frame());
597 			// Increment timing of first quarter frame
598 			outbound_mtc_timecode_frame += 2.0 * _samples_per_timecode_frame;
599 		}
600 	}
601 
602 	return 0;
603 }
604 
605 /***********************************************************************
606  OUTBOUND MMC STUFF
607 **********************************************************************/
608 
609 void
send_immediate_mmc(MachineControlCommand c)610 Session::send_immediate_mmc (MachineControlCommand c)
611 {
612 	_mmc->send (c, 0);
613 }
614 
615 bool
mmc_step_timeout()616 Session::mmc_step_timeout ()
617 {
618 	struct timeval now;
619 	struct timeval diff;
620 	double diff_usecs;
621 	gettimeofday (&now, 0);
622 
623 	timersub (&now, &last_mmc_step, &diff);
624 	diff_usecs = diff.tv_sec * 1000000 + diff.tv_usec;
625 
626 	if (diff_usecs > 1000000.0 || fabs (_transport_fsm->transport_speed()) < 0.0000001) {
627 		/* too long or too slow, stop transport */
628 		request_stop ();
629 		step_queued = false;
630 		return false;
631 	}
632 
633 	if (diff_usecs < 250000.0) {
634 		/* too short, just keep going */
635 		return true;
636 	}
637 
638 	/* slow it down */
639 
640 	request_transport_speed_nonzero (actual_speed() * 0.75);
641 	return true;
642 }
643 
644 /* *********************************************************************
645  * OUTBOUND SYSTEM COMMON STUFF
646  **********************************************************************/
647 
648 void
send_song_position_pointer(samplepos_t)649 Session::send_song_position_pointer (samplepos_t)
650 {
651 	if (midi_clock) {
652 		/* Do nothing for the moment */
653 	}
654 }
655 
656 int
start_midi_thread()657 Session::start_midi_thread ()
658 {
659 	if (midi_control_ui) { return 0; }
660 	midi_control_ui = new MidiControlUI (*this);
661 	midi_control_ui->run ();
662 	return 0;
663 }
664 
665 boost::shared_ptr<ARDOUR::Port>
mmc_output_port() const666 Session::mmc_output_port () const
667 {
668 	return _midi_ports->mmc_output_port ();
669 }
670 
671 boost::shared_ptr<ARDOUR::Port>
mmc_input_port() const672 Session::mmc_input_port () const
673 {
674 	return _midi_ports->mmc_input_port ();
675 }
676 
677 boost::shared_ptr<ARDOUR::Port>
scene_output_port() const678 Session::scene_output_port () const
679 {
680 	return _midi_ports->scene_output_port ();
681 }
682 
683 boost::shared_ptr<ARDOUR::Port>
scene_input_port() const684 Session::scene_input_port () const
685 {
686 	return _midi_ports->scene_input_port ();
687 }
688 
689 boost::shared_ptr<AsyncMIDIPort>
vkbd_output_port() const690 Session::vkbd_output_port () const
691 {
692 	return _midi_ports->vkbd_output_port ();
693 }
694 
695 boost::shared_ptr<MidiPort>
midi_clock_output_port() const696 Session::midi_clock_output_port () const
697 {
698 	return _midi_ports->midi_clock_output_port ();
699 }
700 
701 boost::shared_ptr<MidiPort>
mtc_output_port() const702 Session::mtc_output_port () const
703 {
704 	return _midi_ports->mtc_output_port ();
705 }
706 
707 void
midi_track_presentation_info_changed(PropertyChange const & what_changed,boost::weak_ptr<MidiTrack> mt)708 Session::midi_track_presentation_info_changed (PropertyChange const& what_changed, boost::weak_ptr<MidiTrack> mt)
709 {
710 	if (!Config->get_midi_input_follows_selection()) {
711 		return;
712 	}
713 
714 	if (!what_changed.contains (Properties::selected)) {
715 		return;
716 	}
717 
718 	boost::shared_ptr<MidiTrack> new_midi_target (mt.lock ());
719 
720 	if (new_midi_target->is_selected()) {
721 		rewire_selected_midi (new_midi_target);
722 	}
723 }
724 
725 void
rewire_selected_midi(boost::shared_ptr<MidiTrack> new_midi_target)726 Session::rewire_selected_midi (boost::shared_ptr<MidiTrack> new_midi_target)
727 {
728 	if (!new_midi_target) {
729 		return;
730 	}
731 
732 	boost::shared_ptr<MidiTrack> old_midi_target = current_midi_target.lock ();
733 
734 	if (new_midi_target == old_midi_target) {
735 		return;
736 	}
737 
738 	vector<string> msp;
739 	AudioEngine::instance()->get_midi_selection_ports (msp);
740 
741 	if (!msp.empty()) {
742 
743 		for (vector<string>::const_iterator p = msp.begin(); p != msp.end(); ++p) {
744 			MidiPortFlags mpf = AudioEngine::instance()->midi_port_metadata (*p);
745 
746 			/* if a port is marked for control data, do not
747 			 * disconnect it from everything since it may also be
748 			 * used via a control surface or some other
749 			 * functionality.
750 			 */
751 
752 			if (0 == (mpf & MidiPortControl)) {
753 				/* disconnect the port from everything */
754 				AudioEngine::instance()->disconnect (*p);
755 			} else {
756 				/* only disconnect from non-control ports */
757 				vector<string> port_connections;
758 				AudioEngine::instance()->get_connections (*p, port_connections);
759 				for (vector<string>::iterator i = port_connections.begin(); i != port_connections.end(); ++i) {
760 					/* test if (*i) is a control-surface input port */
761 					if (AudioEngine::instance()->port_is_control_only (*i)) {
762 						continue;
763 					}
764 					AudioEngine::instance()->disconnect (*p, *i);
765 				}
766 			}
767 			/* connect it to the new target */
768 			new_midi_target->input()->connect (new_midi_target->input()->nth(0), (*p), this);
769 		}
770 	}
771 
772 	current_midi_target = new_midi_target;
773 }
774 
775 void
rewire_midi_selection_ports()776 Session::rewire_midi_selection_ports ()
777 {
778 	if (!Config->get_midi_input_follows_selection()) {
779 		return;
780 	}
781 
782 	boost::shared_ptr<MidiTrack> target = current_midi_target.lock();
783 
784 	if (!target) {
785 		return;
786 	}
787 
788 	vector<string> msp;
789 	AudioEngine::instance()->get_midi_selection_ports (msp);
790 
791 	if (msp.empty()) {
792 		return;
793 	}
794 
795 	target->input()->disconnect (this);
796 
797 	for (vector<string>::const_iterator p = msp.begin(); p != msp.end(); ++p) {
798 		AudioEngine::instance()->disconnect (*p);
799 		target->input()->connect (target->input()->nth (0), (*p), this);
800 	}
801 }
802