Fix broken whitespace. I'd apologize for the compile times if it was my fault :D
[ardour.git] / libs / ardour / session_transport.cc
1 /*
2     Copyright (C) 1999-2003 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <cmath>
21 #include <cerrno>
22 #include <unistd.h>
23
24 #ifdef WAF_BUILD
25 #include "libardour-config.h"
26 #endif
27
28
29 #include "pbd/undo.h"
30 #include "pbd/error.h"
31 #include "pbd/enumwriter.h"
32 #include "pbd/pthread_utils.h"
33 #include "pbd/memento_command.h"
34
35 #include "midi++/mmc.h"
36 #include "midi++/port.h"
37 #include "midi++/manager.h"
38
39 #include "ardour/ardour.h"
40 #include "ardour/audioengine.h"
41 #include "ardour/auditioner.h"
42 #include "ardour/butler.h"
43 #include "ardour/debug.h"
44 #include "ardour/location.h"
45 #include "ardour/session.h"
46 #include "ardour/slave.h"
47 #include "ardour/operations.h"
48
49 #include "i18n.h"
50
51 using namespace std;
52 using namespace ARDOUR;
53 using namespace PBD;
54
55 void
56 Session::add_post_transport_work (PostTransportWork ptw)
57 {
58         PostTransportWork oldval;
59         PostTransportWork newval;
60         int tries = 0;
61
62         while (tries < 8) {
63                 oldval = (PostTransportWork) g_atomic_int_get (&_post_transport_work);
64                 newval = PostTransportWork (oldval | ptw);
65                 if (g_atomic_int_compare_and_exchange (&_post_transport_work, oldval, newval)) {
66                         /* success */
67                         return;
68                 }
69         }
70
71         error << "Could not set post transport work! Crazy thread madness, call the programmers" << endmsg;
72 }
73
74 void
75 Session::request_input_change_handling ()
76 {
77         if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
78                 SessionEvent* ev = new SessionEvent (SessionEvent::InputConfigurationChange, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
79                 queue_event (ev);
80         }
81 }
82
83 void
84 Session::request_sync_source (Slave* new_slave)
85 {
86         SessionEvent* ev = new SessionEvent (SessionEvent::SetSyncSource, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
87         bool seamless;
88
89         seamless = Config->get_seamless_loop ();
90
91         if (dynamic_cast<JACK_Slave*>(new_slave)) {
92                 /* JACK cannot support seamless looping at present */
93                 Config->set_seamless_loop (false);
94         } else {
95                 /* reset to whatever the value was before we last switched slaves */
96                 Config->set_seamless_loop (_was_seamless);
97         }
98
99         /* save value of seamless from before the switch */
100         _was_seamless = seamless;
101
102         ev->slave = new_slave;
103         queue_event (ev);
104 }
105
106 void
107 Session::request_transport_speed (double speed)
108 {
109         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
110         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport speed = %1\n", speed));
111         queue_event (ev);
112 }
113
114 /** Request a new transport speed, but if the speed parameter is exactly zero then use
115  *  a very small +ve value to prevent the transport actually stopping.  This method should
116  *  be used by callers who are varying transport speed but don't ever want to stop it.
117  */
118 void
119 Session::request_transport_speed_nonzero (double speed)
120 {
121         if (speed == 0) {
122                 speed = DBL_EPSILON;
123         }
124
125         request_transport_speed (speed);
126 }
127
128 void
129 Session::request_track_speed (Track* tr, double speed)
130 {
131         SessionEvent* ev = new SessionEvent (SessionEvent::SetTrackSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
132         ev->set_ptr (tr);
133         queue_event (ev);
134 }
135
136 void
137 Session::request_stop (bool abort, bool clear_state)
138 {
139         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0, abort, clear_state);
140         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport stop, abort = %1, clear state = %2\n", abort, clear_state));
141         queue_event (ev);
142 }
143
144 void
145 Session::request_locate (framepos_t target_frame, bool with_roll)
146 {
147         SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, false);
148         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request locate to %1\n", target_frame));
149         queue_event (ev);
150 }
151
152 void
153 Session::force_locate (framepos_t target_frame, bool with_roll)
154 {
155         SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, true);
156         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request forced locate to %1\n", target_frame));
157         queue_event (ev);
158 }
159
160 void
161 Session::request_play_loop (bool yn, bool leave_rolling)
162 {
163         SessionEvent* ev;
164         Location *location = _locations->auto_loop_location();
165
166         if (location == 0 && yn) {
167                 error << _("Cannot loop - no loop range defined")
168                       << endmsg;
169                 return;
170         }
171
172         ev = new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn);
173         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request set loop = %1, leave rolling ? %2\n", yn, leave_rolling));
174         queue_event (ev);
175
176         if (!leave_rolling && !yn && Config->get_seamless_loop() && transport_rolling()) {
177                 // request an immediate locate to refresh the tracks
178                 // after disabling looping
179                 request_locate (_transport_frame-1, false);
180         }
181 }
182
183 void
184 Session::request_play_range (list<AudioRange>* range, bool leave_rolling)
185 {
186         SessionEvent* ev = new SessionEvent (SessionEvent::SetPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0));
187         if (range) {
188                 ev->audio_range = *range;
189         } else {
190                 ev->audio_range.clear ();
191         }
192         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request play range, leave rolling ? %1\n", leave_rolling));
193         queue_event (ev);
194 }
195
196 void
197 Session::realtime_stop (bool abort, bool clear_state)
198 {
199         DEBUG_TRACE (DEBUG::Transport, "realtime stop\n");
200         PostTransportWork todo = PostTransportWork (0);
201
202         /* assume that when we start, we'll be moving forwards */
203
204         if (_transport_speed < 0.0f) {
205                 todo = (PostTransportWork (todo | PostTransportStop | PostTransportReverse));
206         } else {
207                 todo = PostTransportWork (todo | PostTransportStop);
208         }
209
210         /* call routes */
211
212         boost::shared_ptr<RouteList> r = routes.reader ();
213
214         for (RouteList::iterator i = r->begin (); i != r->end(); ++i) {
215                 (*i)->realtime_handle_transport_stopped ();
216         }
217
218         if (actively_recording()) {
219
220                 /* move the transport position back to where the
221                    request for a stop was noticed. we rolled
222                    past that point to pick up delayed input (and/or to delick)
223                 */
224
225                 if (worst_playback_latency() > current_block_size) {
226                         /* we rolled past the stop point to pick up data that had
227                            not yet arrived. move back to where the stop occured.
228                         */
229                         decrement_transport_position (current_block_size + (worst_input_latency() - current_block_size));
230                 } else {
231                         decrement_transport_position (current_block_size);
232                 }
233
234                 /* the duration change is not guaranteed to have happened, but is likely */
235
236                 todo = PostTransportWork (todo | PostTransportDuration);
237         }
238
239         if (abort) {
240                 todo = PostTransportWork (todo | PostTransportAbort);
241         }
242
243         if (clear_state) {
244                 todo = PostTransportWork (todo | PostTransportClearSubstate);
245         }
246
247         if (todo) {
248                 add_post_transport_work (todo);
249         }
250
251         _clear_event_type (SessionEvent::StopOnce);
252         _clear_event_type (SessionEvent::RangeStop);
253         _clear_event_type (SessionEvent::RangeLocate);
254
255         /* if we're going to clear loop state, then force disabling record BUT only if we're not doing latched rec-enable */
256         disable_record (true, (!Config->get_latched_record_enable() && clear_state));
257
258         reset_slave_state ();
259
260         _transport_speed = 0;
261         _target_transport_speed = 0;
262
263         g_atomic_int_set (&_playback_load, 100);
264         g_atomic_int_set (&_capture_load, 100);
265
266         if (config.get_use_video_sync()) {
267                 waiting_for_sync_offset = true;
268         }
269
270         transport_sub_state = 0;
271 }
272
273 void
274 Session::realtime_locate ()
275 {
276         boost::shared_ptr<RouteList> r = routes.reader ();
277         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
278                 (*i)->realtime_locate ();
279         }
280 }
281
282 void
283 Session::butler_transport_work ()
284 {
285   restart:
286         bool finished;
287         PostTransportWork ptw;
288         boost::shared_ptr<RouteList> r = routes.reader ();
289
290         int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
291         finished = true;
292         ptw = post_transport_work();
293
294         DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler transport work, todo = %1\n", enum_2_string (ptw)));
295
296         if (ptw & PostTransportAdjustPlaybackBuffering) {
297                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
298                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
299                         if (tr) {
300                                 tr->adjust_playback_buffering ();
301                                 /* and refill those buffers ... */
302                                 tr->non_realtime_locate (_transport_frame);
303                         }
304                 }
305
306         }
307
308         if (ptw & PostTransportAdjustCaptureBuffering) {
309                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
310                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
311                         if (tr) {
312                                 tr->adjust_capture_buffering ();
313                         }
314                 }
315         }
316
317         if (ptw & PostTransportCurveRealloc) {
318                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
319                         (*i)->curve_reallocate();
320                 }
321         }
322
323         if (ptw & PostTransportInputChange) {
324                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
325                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
326                         if (tr) {
327                                 tr->non_realtime_input_change ();
328                         }
329                 }
330         }
331
332         if (ptw & PostTransportSpeed) {
333                 non_realtime_set_speed ();
334         }
335
336         if (ptw & PostTransportReverse) {
337
338                 clear_clicks();
339                 cumulative_rf_motion = 0;
340                 reset_rf_scale (0);
341
342                 /* don't seek if locate will take care of that in non_realtime_stop() */
343
344                 if (!(ptw & PostTransportLocate)) {
345
346                         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
347                                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
348                                 if (tr && !tr->hidden()) {
349                                         tr->non_realtime_locate (_transport_frame);
350                                 }
351                                 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
352                                         /* new request, stop seeking, and start again */
353                                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
354                                         goto restart;
355                                 }
356                         }
357                 }
358         }
359
360         if (ptw & PostTransportLocate) {
361                 non_realtime_locate ();
362         }
363
364         if (ptw & PostTransportStop) {
365                 non_realtime_stop (ptw & PostTransportAbort, on_entry, finished);
366                 if (!finished) {
367                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
368                         goto restart;
369                 }
370         }
371
372         if (ptw & PostTransportOverWrite) {
373                 non_realtime_overwrite (on_entry, finished);
374                 if (!finished) {
375                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
376                         goto restart;
377                 }
378         }
379
380         if (ptw & PostTransportAudition) {
381                 non_realtime_set_audition ();
382         }
383
384         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
385
386         DEBUG_TRACE (DEBUG::Transport, X_("Butler transport work all done\n"));
387 }
388
389 void
390 Session::non_realtime_set_speed ()
391 {
392         boost::shared_ptr<RouteList> rl = routes.reader();
393         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
394                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
395                 if (tr) {
396                         tr->non_realtime_set_speed ();
397                 }
398         }
399 }
400
401 void
402 Session::non_realtime_overwrite (int on_entry, bool& finished)
403 {
404         boost::shared_ptr<RouteList> rl = routes.reader();
405         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
406                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
407                 if (tr && tr->pending_overwrite ()) {
408                         tr->overwrite_existing_buffers ();
409                 }
410                 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
411                         finished = false;
412                         return;
413                 }
414         }
415 }
416
417
418 void
419 Session::non_realtime_locate ()
420 {
421         boost::shared_ptr<RouteList> rl = routes.reader();
422         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
423                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
424                 if (tr) {
425                         tr->non_realtime_locate (_transport_frame);
426                 }
427         }
428 }
429
430
431 void
432 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
433 {
434         struct tm* now;
435         time_t     xnow;
436         bool       did_record;
437         bool       saved;
438         PostTransportWork ptw = post_transport_work();
439
440         did_record = false;
441         saved = false;
442
443         boost::shared_ptr<RouteList> rl = routes.reader();
444         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
445                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
446                 if (tr && tr->get_captured_frames () != 0) {
447                         did_record = true;
448                         break;
449                 }
450         }
451
452         /* stop and locate are merged here because they share a lot of common stuff */
453
454         time (&xnow);
455         now = localtime (&xnow);
456
457         if (auditioner) {
458                 auditioner->cancel_audition ();
459         }
460
461         clear_clicks();
462         cumulative_rf_motion = 0;
463         reset_rf_scale (0);
464
465         if (did_record) {
466                 begin_reversible_command (Operations::capture);
467                 _have_captured = true;
468         }
469
470         DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: DS stop\n"));
471
472         if (abort && did_record) {
473                 /* no reason to save the session file when we remove sources
474                  */
475                 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
476         }
477
478         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
479                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
480                 if (tr) {
481                         tr->transport_stopped_wallclock (*now, xnow, abort);
482                 }
483         }
484
485         if (abort && did_record) {
486                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
487         }
488
489         boost::shared_ptr<RouteList> r = routes.reader ();
490
491         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
492                 if (!(*i)->is_hidden()) {
493                         (*i)->set_pending_declick (0);
494                 }
495         }
496
497         if (did_record) {
498                 commit_reversible_command ();
499         }
500
501         if (_engine.running()) {
502                 PostTransportWork ptw = post_transport_work ();
503                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
504                         (*i)->nonrealtime_handle_transport_stopped (abort, (ptw & PostTransportLocate), (!(ptw & PostTransportLocate) || pending_locate_flush));
505                 }
506                 update_latency_compensation ();
507         }
508
509         bool const auto_return_enabled =
510                 (!config.get_external_sync() && config.get_auto_return());
511
512         if (auto_return_enabled ||
513             (ptw & PostTransportLocate) ||
514             (_requested_return_frame >= 0) ||
515             synced_to_jack()) {
516
517                 if (pending_locate_flush) {
518                         flush_all_inserts ();
519                 }
520
521                 if ((auto_return_enabled || synced_to_jack() || _requested_return_frame >= 0) &&
522                     !(ptw & PostTransportLocate)) {
523
524                         /* no explicit locate queued */
525
526                         bool do_locate = false;
527
528                         if (_requested_return_frame >= 0) {
529
530                                 /* explicit return request pre-queued in event list. overrides everything else */
531
532                                 cerr << "explicit auto-return to " << _requested_return_frame << endl;
533
534                                 _transport_frame = _requested_return_frame;
535                                 do_locate = true;
536
537                         } else {
538                                 if (config.get_auto_return()) {
539
540                                         if (play_loop) {
541
542                                                 /* don't try to handle loop play when synced to JACK */
543
544                                                 if (!synced_to_jack()) {
545
546                                                         Location *location = _locations->auto_loop_location();
547
548                                                         if (location != 0) {
549                                                                 _transport_frame = location->start();
550                                                         } else {
551                                                                 _transport_frame = _last_roll_location;
552                                                         }
553                                                         do_locate = true;
554                                                 }
555
556                                         } else if (_play_range) {
557
558                                                 /* return to start of range */
559
560                                                 if (!current_audio_range.empty()) {
561                                                         _transport_frame = current_audio_range.front().start;
562                                                         do_locate = true;
563                                                 }
564
565                                         } else {
566
567                                                 /* regular auto-return */
568
569                                                 _transport_frame = _last_roll_location;
570                                                 do_locate = true;
571                                         }
572                                 }
573                         }
574
575                         _requested_return_frame = -1;
576
577                         if (do_locate) {
578                                 _engine.transport_locate (_transport_frame);
579                         }
580                 }
581
582         }
583
584         /* do this before seeking, because otherwise the tracks will do the wrong thing in seamless loop mode.
585         */
586
587         if (ptw & PostTransportClearSubstate) {
588                 _play_range = false;
589                 unset_play_loop ();
590         }
591
592         /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
593
594         DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: locate\n"));
595         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
596                 DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler PTW: locate on %1\n", (*i)->name()));
597                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
598                 if (tr && !tr->hidden()) {
599                         tr->non_realtime_locate (_transport_frame);
600                 }
601
602                 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
603                         finished = false;
604                         /* we will be back */
605                         return;
606                 }
607         }
608
609         have_looped = false;
610
611         send_full_time_code (_transport_frame);
612
613         if (!dynamic_cast<MTC_Slave*>(_slave)) {
614                 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
615                 send_mmc_locate (_transport_frame);
616         }
617
618         if ((ptw & PostTransportLocate) && get_record_enabled()) {
619                 /* capture start has been changed, so save pending state */
620                 save_state ("", true);
621                 saved = true;
622         }
623
624         /* always try to get rid of this */
625
626         remove_pending_capture_state ();
627
628         /* save the current state of things if appropriate */
629
630         if (did_record && !saved) {
631                 save_state (_current_snapshot_name);
632         }
633
634         if (ptw & PostTransportStop) {
635                 _play_range = false;
636                 play_loop = false;
637         }
638
639         PositionChanged (_transport_frame); /* EMIT SIGNAL */
640         TransportStateChange (); /* EMIT SIGNAL */
641
642         /* and start it up again if relevant */
643
644         if ((ptw & PostTransportLocate) && !config.get_external_sync() && pending_locate_roll) {
645                 request_transport_speed (1.0);
646                 pending_locate_roll = false;
647         }
648 }
649
650 void
651 Session::check_declick_out ()
652 {
653         bool locate_required = transport_sub_state & PendingLocate;
654
655         /* this is called after a process() iteration. if PendingDeclickOut was set,
656            it means that we were waiting to declick the output (which has just been
657            done) before doing something else. this is where we do that "something else".
658
659            note: called from the audio thread.
660         */
661
662         if (transport_sub_state & PendingDeclickOut) {
663
664                 if (locate_required) {
665                         start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
666                         transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
667                 } else {
668                         stop_transport (pending_abort);
669                         transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
670                 }
671         }
672 }
673
674 void
675 Session::unset_play_loop ()
676 {
677         play_loop = false;
678         clear_events (SessionEvent::AutoLoop);
679
680         // set all tracks to NOT use internal looping
681         boost::shared_ptr<RouteList> rl = routes.reader ();
682         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
683                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
684                 if (tr && !tr->hidden()) {
685                         tr->set_loop (0);
686                 }
687         }
688 }
689
690 void
691 Session::set_play_loop (bool yn)
692 {
693         /* Called from event-handling context */
694
695         Location *loc;
696
697         if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) {
698                 /* nothing to do, or can't change loop status while recording */
699                 return;
700         }
701
702         if (yn && Config->get_seamless_loop() && synced_to_jack()) {
703                 warning << string_compose (
704                         _("Seamless looping cannot be supported while %1 is using JACK transport.\n"
705                           "Recommend changing the configured options"), PROGRAM_NAME)
706                         << endmsg;
707                 return;
708         }
709
710         if (yn) {
711
712                 play_loop = true;
713
714                 if (loc) {
715
716                         unset_play_range ();
717
718                         if (Config->get_seamless_loop()) {
719                                 // set all tracks to use internal looping
720                                 boost::shared_ptr<RouteList> rl = routes.reader ();
721                                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
722                                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
723                                         if (tr && !tr->hidden()) {
724                                                 tr->set_loop (loc);
725                                         }
726                                 }
727                         }
728                         else {
729                                 // set all tracks to NOT use internal looping
730                                 boost::shared_ptr<RouteList> rl = routes.reader ();
731                                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
732                                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
733                                         if (tr && !tr->hidden()) {
734                                                 tr->set_loop (0);
735                                         }
736                                 }
737                         }
738
739                         /* put the loop event into the event list */
740
741                         SessionEvent* event = new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f);
742                         merge_event (event);
743
744                         /* locate to start of loop and roll. If doing seamless loop, force a
745                            locate+buffer refill even if we are positioned there already.
746                         */
747
748                         start_locate (loc->start(), true, true, false, Config->get_seamless_loop());
749                 }
750
751         } else {
752
753                 unset_play_loop ();
754         }
755
756         TransportStateChange ();
757 }
758 void
759 Session::flush_all_inserts ()
760 {
761         boost::shared_ptr<RouteList> r = routes.reader ();
762
763         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
764                 (*i)->flush_processors ();
765         }
766 }
767
768 void
769 Session::start_locate (framepos_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
770 {
771         if (synced_to_jack()) {
772
773                 double sp;
774                 framepos_t pos;
775
776                 _slave->speed_and_position (sp, pos);
777
778                 if (target_frame != pos) {
779
780                         /* tell JACK to change transport position, and we will
781                            follow along later in ::follow_slave()
782                         */
783
784                         _engine.transport_locate (target_frame);
785
786                         if (sp != 1.0f && with_roll) {
787                                 _engine.transport_start ();
788                         }
789
790                 }
791
792         } else {
793                 locate (target_frame, with_roll, with_flush, with_loop, force);
794         }
795 }
796
797 int
798 Session::micro_locate (framecnt_t distance)
799 {
800         boost::shared_ptr<RouteList> rl = routes.reader();
801         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
802                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
803                 if (tr && !tr->can_internal_playback_seek (distance)) {
804                         return -1;
805                 }
806         }
807
808         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
809                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
810                 if (tr) {
811                         tr->internal_playback_seek (distance);
812                 }
813         }
814
815         _transport_frame += distance;
816         return 0;
817 }
818
819 /** @param with_mmc true to send a MMC locate command when the locate is done */
820 void
821 Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force, bool with_mmc)
822 {
823         if (actively_recording() && !with_loop) {
824                 return;
825         }
826
827         if (!force && _transport_frame == target_frame && !loop_changing && !with_loop) {
828                 if (with_roll) {
829                         set_transport_speed (1.0, false);
830                 }
831                 loop_changing = false;
832                 Located (); /* EMIT SIGNAL */
833                 return;
834         }
835
836         if (_transport_speed) {
837                 /* schedule a declick. we'll be called again when its done */
838
839                 if (!(transport_sub_state & PendingDeclickOut)) {
840                         transport_sub_state |= (PendingDeclickOut|PendingLocate);
841                         pending_locate_frame = target_frame;
842                         pending_locate_roll = with_roll;
843                         pending_locate_flush = with_flush;
844                         return;
845                 }
846         }
847
848         // Update Timecode time
849         // [DR] FIXME: find out exactly where this should go below
850         _transport_frame = target_frame;
851         timecode_time(_transport_frame, transmitting_timecode_time);
852         outbound_mtc_timecode_frame = _transport_frame;
853         next_quarter_frame_to_send = 0;
854
855         /* do "stopped" stuff if:
856          *
857          * we are rolling AND
858          *    no autoplay in effect AND
859          *       we're not going to keep rolling after the locate AND
860          *           !(playing a loop with JACK sync)
861          *
862          */
863
864         if (transport_rolling() && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
865                 realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
866         } else {
867                 /* otherwise tell the world that we located */
868                 realtime_locate ();
869         }
870
871         if (force || !with_loop || loop_changing) {
872
873                 PostTransportWork todo = PostTransportLocate;
874
875                 if (with_roll) {
876                         todo = PostTransportWork (todo | PostTransportRoll);
877                 }
878
879                 add_post_transport_work (todo);
880                 _butler->schedule_transport_work ();
881
882         } else {
883
884                 /* this is functionally what clear_clicks() does but with a tentative lock */
885
886                 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
887
888                 if (clickm.locked()) {
889
890                         for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
891                                 delete *i;
892                         }
893
894                         clicks.clear ();
895                 }
896         }
897
898         if (with_roll) {
899                 /* switch from input if we're going to roll */
900                 if (Config->get_monitoring_model() == HardwareMonitoring) {
901                         set_track_monitor_input_status (!config.get_auto_input());
902                 }
903         } else {
904                 /* otherwise we're going to stop, so do the opposite */
905                 if (Config->get_monitoring_model() == HardwareMonitoring) {
906                         set_track_monitor_input_status (true);
907                 }
908         }
909
910         /* cancel looped playback if transport pos outside of loop range */
911         if (play_loop) {
912                 Location* al = _locations->auto_loop_location();
913
914                 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
915                         // cancel looping directly, this is called from event handling context
916                         set_play_loop (false);
917                 }
918                 else if (al && _transport_frame == al->start()) {
919                         if (with_loop) {
920                                 // this is only necessary for seamless looping
921
922                                 boost::shared_ptr<RouteList> rl = routes.reader();
923                                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
924                                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
925                                         if (tr && tr->record_enabled ()) {
926                                                 // tell it we've looped, so it can deal with the record state
927                                                 tr->transport_looped(_transport_frame);
928                                         }
929                                 }
930                         }
931                         have_looped = true;
932                         TransportLooped(); // EMIT SIGNAL
933                 }
934         }
935
936         loop_changing = false;
937
938         _send_timecode_update = true;
939
940         if (with_mmc) {
941                 send_mmc_locate (_transport_frame);
942         }
943
944         Located (); /* EMIT SIGNAL */
945 }
946
947 /** Set the transport speed.
948  *  Called from the process thread.
949  *  @param speed New speed
950  */
951 void
952 Session::set_transport_speed (double speed, bool abort, bool clear_state)
953 {
954         DEBUG_TRACE (DEBUG::Transport, string_compose ("Set transport speed to %1, abort = %2 clear_state = %3, current = %4\n", speed, abort, clear_state, _transport_speed));
955
956         if (_transport_speed == speed) {
957                 return;
958         }
959
960         _target_transport_speed = fabs(speed);
961
962         /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
963            and user needs. We really need CD-style "skip" playback for ffwd and rewind.
964         */
965
966         if (speed > 0) {
967                 speed = min (8.0, speed);
968         } else if (speed < 0) {
969                 speed = max (-8.0, speed);
970         }
971
972         if (transport_rolling() && speed == 0.0) {
973
974                 /* we are rolling and we want to stop */
975
976                 if (Config->get_monitoring_model() == HardwareMonitoring) {
977                         set_track_monitor_input_status (true);
978                 }
979
980                 if (synced_to_jack ()) {
981                         if (clear_state) {
982                                 /* do this here because our response to the slave won't
983                                    take care of it.
984                                 */
985                                 _play_range = false;
986                                 unset_play_loop ();
987                         }
988                         _engine.transport_stop ();
989                 } else {
990                         stop_transport (abort);
991                 }
992
993                 unset_play_loop ();
994
995         } else if (transport_stopped() && speed == 1.0) {
996
997                 /* we are stopped and we want to start rolling at speed 1 */
998
999                 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1000                         set_track_monitor_input_status (false);
1001                 }
1002
1003                 if (synced_to_jack()) {
1004                         _engine.transport_start ();
1005                 } else {
1006                         start_transport ();
1007                 }
1008
1009         } else {
1010
1011                 /* not zero, not 1.0 ... varispeed */
1012
1013                 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
1014                         warning << string_compose (
1015                                 _("Global varispeed cannot be supported while %1 is connected to JACK transport control"),
1016                                 PROGRAM_NAME)
1017                                 << endmsg;
1018                         return;
1019                 }
1020
1021                 if (actively_recording()) {
1022                         return;
1023                 }
1024
1025                 if (speed > 0.0 && _transport_frame == current_end_frame()) {
1026                         return;
1027                 }
1028
1029                 if (speed < 0.0 && _transport_frame == 0) {
1030                         return;
1031                 }
1032
1033                 clear_clicks ();
1034
1035                 /* if we are reversing relative to the current speed, or relative to the speed
1036                    before the last stop, then we have to do extra work.
1037                 */
1038
1039                 PostTransportWork todo = PostTransportWork (0);
1040
1041                 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
1042                         todo = PostTransportWork (todo | PostTransportReverse);
1043                         _last_roll_or_reversal_location = _transport_frame;
1044                 }
1045
1046                 _last_transport_speed = _transport_speed;
1047                 _transport_speed = speed;
1048
1049                 boost::shared_ptr<RouteList> rl = routes.reader();
1050                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1051                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1052                         if (tr && tr->realtime_set_speed (tr->speed(), true)) {
1053                                 todo = PostTransportWork (todo | PostTransportSpeed);
1054                         }
1055                 }
1056
1057                 if (todo) {
1058                         add_post_transport_work (todo);
1059                         _butler->schedule_transport_work ();
1060                 }
1061
1062                 TransportStateChange (); /* EMIT SIGNAL */
1063         }
1064 }
1065
1066
1067 /** Stop the transport.  */
1068 void
1069 Session::stop_transport (bool abort, bool clear_state)
1070 {
1071         if (_transport_speed == 0.0f) {
1072                 return;
1073         }
1074
1075         if (actively_recording() && !(transport_sub_state & StopPendingCapture) && worst_input_latency() > current_block_size) {
1076
1077                 boost::shared_ptr<RouteList> rl = routes.reader();
1078                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1079                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1080                         if (tr) {
1081                                 tr->prepare_to_stop (_transport_frame);
1082                         }
1083                 }
1084
1085                 /* we need to capture the audio that has still not yet been received by the system
1086                    at the time the stop is requested, so we have to roll past that time.
1087
1088                    we want to declick before stopping, so schedule the autostop for one
1089                    block before the actual end. we'll declick in the subsequent block,
1090                    and then we'll really be stopped.
1091                 */
1092
1093                 SessionEvent *ev = new SessionEvent (SessionEvent::StopOnce, SessionEvent::Replace,
1094                                                      _transport_frame + _worst_input_latency - current_block_size,
1095                                                      0, 0, abort);
1096
1097                 merge_event (ev);
1098                 transport_sub_state |= StopPendingCapture;
1099                 pending_abort = abort;
1100                 return;
1101         }
1102
1103         if ((transport_sub_state & PendingDeclickOut) == 0) {
1104
1105                 if (!(transport_sub_state & StopPendingCapture)) {
1106                         boost::shared_ptr<RouteList> rl = routes.reader();
1107                         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1108                                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1109                                 if (tr) {
1110                                         tr->prepare_to_stop (_transport_frame);
1111                                 }
1112                         }
1113                 }
1114
1115                 transport_sub_state |= PendingDeclickOut;
1116                 /* we'll be called again after the declick */
1117                 pending_abort = abort;
1118                 return;
1119         }
1120
1121         realtime_stop (abort, clear_state);
1122         _butler->schedule_transport_work ();
1123 }
1124
1125 /** Called from the process thread */
1126 void
1127 Session::start_transport ()
1128 {
1129         DEBUG_TRACE (DEBUG::Transport, "start_transport\n");
1130
1131         _last_roll_location = _transport_frame;
1132         _last_roll_or_reversal_location = _transport_frame;
1133
1134         have_looped = false;
1135
1136         /* if record status is Enabled, move it to Recording. if its
1137            already Recording, move it to Disabled.
1138         */
1139
1140         switch (record_status()) {
1141         case Enabled:
1142                 if (!config.get_punch_in()) {
1143                         enable_record ();
1144                 }
1145                 break;
1146
1147         case Recording:
1148                 if (!play_loop) {
1149                         disable_record (false);
1150                 }
1151                 break;
1152
1153         default:
1154                 break;
1155         }
1156
1157         transport_sub_state |= PendingDeclickIn;
1158
1159         _transport_speed = 1.0;
1160         _target_transport_speed = 1.0;
1161
1162         boost::shared_ptr<RouteList> rl = routes.reader();
1163         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1164                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1165                 if (tr) {
1166                         tr->realtime_set_speed (tr->speed(), true);
1167                 }
1168                 (*i)->automation_snapshot (_transport_frame, true);
1169         }
1170
1171         Timecode::Time time;
1172         timecode_time_subframes (_transport_frame, time);
1173         if (!dynamic_cast<MTC_Slave*>(_slave)) {
1174                 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
1175         }
1176
1177         TransportStateChange (); /* EMIT SIGNAL */
1178 }
1179
1180 /** Do any transport work in the audio thread that needs to be done after the
1181  * transport thread is finished.  Audio thread, realtime safe.
1182  */
1183 void
1184 Session::post_transport ()
1185 {
1186         PostTransportWork ptw = post_transport_work ();
1187
1188         if (ptw & PostTransportAudition) {
1189                 if (auditioner && auditioner->auditioning()) {
1190                         process_function = &Session::process_audition;
1191                 } else {
1192                         process_function = &Session::process_with_events;
1193                 }
1194         }
1195
1196         if (ptw & PostTransportStop) {
1197
1198                 transport_sub_state = 0;
1199         }
1200
1201         if (ptw & PostTransportLocate) {
1202
1203                 if (((!config.get_external_sync() && (auto_play_legal && config.get_auto_play())) && !_exporting) || (ptw & PostTransportRoll)) {
1204                         start_transport ();
1205
1206                 } else {
1207                         transport_sub_state = 0;
1208                 }
1209         }
1210
1211         set_next_event ();
1212         /* XXX is this really safe? shouldn't we just be unsetting the bits that we actually
1213            know were handled ?
1214         */
1215         set_post_transport_work (PostTransportWork (0));
1216 }
1217
1218 void
1219 Session::reset_rf_scale (framecnt_t motion)
1220 {
1221         cumulative_rf_motion += motion;
1222
1223         if (cumulative_rf_motion < 4 * _current_frame_rate) {
1224                 rf_scale = 1;
1225         } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1226                 rf_scale = 4;
1227         } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1228                 rf_scale = 10;
1229         } else {
1230                 rf_scale = 100;
1231         }
1232
1233         if (motion != 0) {
1234                 set_dirty();
1235         }
1236 }
1237
1238 void
1239 Session::use_sync_source (Slave* new_slave)
1240 {
1241         /* Runs in process() context */
1242
1243         bool non_rt_required = false;
1244
1245         /* XXX this deletion is problematic because we're in RT context */
1246
1247         delete _slave;
1248         _slave = new_slave;
1249
1250         boost::shared_ptr<RouteList> rl = routes.reader();
1251         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1252                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1253                 if (tr && !tr->hidden()) {
1254                         if (tr->realtime_set_speed (tr->speed(), true)) {
1255                                 non_rt_required = true;
1256                         }
1257                         tr->set_slaved (_slave != 0);
1258                 }
1259         }
1260
1261         if (non_rt_required) {
1262                 add_post_transport_work (PostTransportSpeed);
1263                 _butler->schedule_transport_work ();
1264         }
1265
1266         set_dirty();
1267 }
1268
1269 void
1270 Session::drop_sync_source ()
1271 {
1272         request_sync_source (0);
1273 }
1274
1275 void
1276 Session::switch_to_sync_source (SyncSource src)
1277 {
1278         Slave* new_slave;
1279
1280         DEBUG_TRACE (DEBUG::Slave, string_compose ("Setting up sync source %1\n", enum_2_string (src)));
1281
1282         switch (src) {
1283         case MTC:
1284                 if (_slave && dynamic_cast<MTC_Slave*>(_slave)) {
1285                         return;
1286                 }
1287
1288                 try {
1289                         new_slave = new MTC_Slave (*this, *MIDI::Manager::instance()->mtc_input_port());
1290                 }
1291
1292                 catch (failed_constructor& err) {
1293                         return;
1294                 }
1295                 break;
1296
1297         case MIDIClock:
1298                 if (_slave && dynamic_cast<MIDIClock_Slave*>(_slave)) {
1299                         return;
1300                 }
1301
1302                 try {
1303                         new_slave = new MIDIClock_Slave (*this, *MIDI::Manager::instance()->midi_clock_input_port(), 24);
1304                 }
1305
1306                 catch (failed_constructor& err) {
1307                         return;
1308                 }
1309                 break;
1310
1311         case JACK:
1312                 if (_slave && dynamic_cast<JACK_Slave*>(_slave)) {
1313                         return;
1314                 }
1315
1316                 if (config.get_video_pullup() != 0.0f) {
1317                         return;
1318                 }
1319
1320                 new_slave = new JACK_Slave (_engine.jack());
1321                 break;
1322
1323         default:
1324                 new_slave = 0;
1325                 break;
1326         };
1327
1328         request_sync_source (new_slave);
1329 }
1330
1331 void
1332 Session::reverse_track_buffers ()
1333 {
1334         add_post_transport_work (PostTransportReverse);
1335         _butler->schedule_transport_work ();
1336 }
1337
1338 void
1339 Session::set_track_speed (Track* track, double speed)
1340 {
1341         if (track->realtime_set_speed (speed, false)) {
1342                 add_post_transport_work (PostTransportSpeed);
1343                 _butler->schedule_transport_work ();
1344                 set_dirty ();
1345         }
1346 }
1347
1348 void
1349 Session::unset_play_range ()
1350 {
1351         _play_range = false;
1352         _clear_event_type (SessionEvent::RangeStop);
1353         _clear_event_type (SessionEvent::RangeLocate);
1354 }
1355
1356 void
1357 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1358 {
1359         SessionEvent* ev;
1360
1361         /* Called from event-processing context */
1362
1363         unset_play_range ();
1364
1365         if (range.empty()) {
1366                 /* _play_range set to false in unset_play_range()
1367                  */
1368                 if (!leave_rolling) {
1369                         /* stop transport */
1370                         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false);
1371                         merge_event (ev);
1372                 }
1373                 return;
1374         }
1375
1376         _play_range = true;
1377
1378         /* cancel loop play */
1379         unset_play_loop ();
1380
1381         list<AudioRange>::size_type sz = range.size();
1382
1383         if (sz > 1) {
1384
1385                 list<AudioRange>::iterator i = range.begin();
1386                 list<AudioRange>::iterator next;
1387
1388                 while (i != range.end()) {
1389
1390                         next = i;
1391                         ++next;
1392
1393                         /* locating/stopping is subject to delays for declicking.
1394                          */
1395
1396                         framepos_t requested_frame = i->end;
1397
1398                         if (requested_frame > current_block_size) {
1399                                 requested_frame -= current_block_size;
1400                         } else {
1401                                 requested_frame = 0;
1402                         }
1403
1404                         if (next == range.end()) {
1405                                 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_frame, 0, 0.0f);
1406                         } else {
1407                                 ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_frame, (*next).start, 0.0f);
1408                         }
1409
1410                         merge_event (ev);
1411
1412                         i = next;
1413                 }
1414
1415         } else if (sz == 1) {
1416
1417                 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
1418                 merge_event (ev);
1419
1420         }
1421
1422         /* save range so we can do auto-return etc. */
1423
1424         current_audio_range = range;
1425
1426         /* now start rolling at the right place */
1427
1428         ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
1429         merge_event (ev);
1430
1431         TransportStateChange ();
1432 }
1433
1434 void
1435 Session::request_bounded_roll (framepos_t start, framepos_t end)
1436 {
1437         AudioRange ar (start, end, 0);
1438         list<AudioRange> lar;
1439
1440         lar.push_back (ar);
1441         request_play_range (&lar, true);
1442 }
1443 void
1444 Session::request_roll_at_and_return (framepos_t start, framepos_t return_to)
1445 {
1446         SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
1447         ev->target2_frame = start;
1448         queue_event (ev);
1449 }
1450
1451 void
1452 Session::engine_halted ()
1453 {
1454         bool ignored;
1455
1456         /* there will be no more calls to process(), so
1457            we'd better clean up for ourselves, right now.
1458
1459            but first, make sure the butler is out of
1460            the picture.
1461         */
1462
1463         g_atomic_int_set (&_butler->should_do_transport_work, 0);
1464         set_post_transport_work (PostTransportWork (0));
1465         _butler->stop ();
1466
1467         realtime_stop (false, true);
1468         non_realtime_stop (false, 0, ignored);
1469         transport_sub_state = 0;
1470
1471         TransportStateChange (); /* EMIT SIGNAL */
1472 }
1473
1474
1475 void
1476 Session::xrun_recovery ()
1477 {
1478         Xrun (_transport_frame); /* EMIT SIGNAL */
1479
1480         if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1481
1482                 /* it didn't actually halt, but we need
1483                    to handle things in the same way.
1484                 */
1485
1486                 engine_halted();
1487         }
1488 }
1489
1490 void
1491 Session::route_processors_changed (RouteProcessorChange c)
1492 {
1493         if (c.type == RouteProcessorChange::MeterPointChange) {
1494                 return;
1495         }
1496
1497         update_latency_compensation ();
1498         resort_routes ();
1499
1500         set_dirty ();
1501 }
1502
1503 void
1504 Session::allow_auto_play (bool yn)
1505 {
1506         auto_play_legal = yn;
1507 }
1508
1509 void
1510 Session::reset_jack_connection (jack_client_t* jack)
1511 {
1512         JACK_Slave* js;
1513
1514         if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1515                 js->reset_client (jack);
1516         }
1517 }
1518
1519 bool
1520 Session::maybe_stop (framepos_t limit)
1521 {
1522         if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
1523                 if (synced_to_jack () && config.get_jack_time_master ()) {
1524                         _engine.transport_stop ();
1525                 } else if (!synced_to_jack ()) {
1526                         stop_transport ();
1527                 }
1528                 return true;
1529         }
1530         return false;
1531 }
1532
1533 void
1534 Session::send_mmc_locate (framepos_t t)
1535 {
1536         Timecode::Time time;
1537         timecode_time_subframes (t, time);
1538         MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (time));
1539 }
1540
1541 /** Ask the transport to not send timecode until further notice.  The suspension
1542  *  will come into effect some finite time after this call, and timecode_transmission_suspended()
1543  *  should be checked by the caller to find out when.
1544  */
1545 void
1546 Session::request_suspend_timecode_transmission ()
1547 {
1548         SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, false);
1549         queue_event (ev);
1550 }
1551
1552 void
1553 Session::request_resume_timecode_transmission ()
1554 {
1555         SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, true);
1556         queue_event (ev);
1557 }
1558
1559 bool
1560 Session::timecode_transmission_suspended () const
1561 {
1562         return g_atomic_int_get (&_suspend_timecode_transmission) == 1;
1563 }