sort of no-op ... remove debug output ... just basically put it in git so that i...
[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 #ifdef WAF_BUILD
21 #include "libardour-config.h"
22 #endif
23
24 #include <cmath>
25 #include <cerrno>
26 #include <unistd.h>
27
28 #include "pbd/undo.h"
29 #include "pbd/error.h"
30 #include "pbd/enumwriter.h"
31 #include "pbd/pthread_utils.h"
32 #include "pbd/memento_command.h"
33 #include "pbd/stacktrace.h"
34
35 #include "midi++/mmc.h"
36 #include "midi++/port.h"
37
38 #include "ardour/audioengine.h"
39 #include "ardour/auditioner.h"
40 #include "ardour/automation_watch.h"
41 #include "ardour/butler.h"
42 #include "ardour/click.h"
43 #include "ardour/debug.h"
44 #include "ardour/disk_reader.h"
45 #include "ardour/location.h"
46 #include "ardour/profile.h"
47 #include "ardour/scene_changer.h"
48 #include "ardour/session.h"
49 #include "ardour/slave.h"
50 #include "ardour/tempo.h"
51 #include "ardour/operations.h"
52 #include "ardour/vca.h"
53 #include "ardour/vca_manager.h"
54
55 #include "pbd/i18n.h"
56
57 using namespace std;
58 using namespace ARDOUR;
59 using namespace PBD;
60
61 void
62 Session::add_post_transport_work (PostTransportWork ptw)
63 {
64         PostTransportWork oldval;
65         PostTransportWork newval;
66         int tries = 0;
67
68         while (tries < 8) {
69                 oldval = (PostTransportWork) g_atomic_int_get (&_post_transport_work);
70                 newval = PostTransportWork (oldval | ptw);
71                 if (g_atomic_int_compare_and_exchange (&_post_transport_work, oldval, newval)) {
72                         /* success */
73                         return;
74                 }
75         }
76
77         error << "Could not set post transport work! Crazy thread madness, call the programmers" << endmsg;
78 }
79
80 void
81 Session::request_sync_source (Slave* new_slave)
82 {
83         SessionEvent* ev = new SessionEvent (SessionEvent::SetSyncSource, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
84         bool seamless;
85
86         seamless = Config->get_seamless_loop ();
87
88         if (dynamic_cast<Engine_Slave*>(new_slave)) {
89                 /* JACK cannot support seamless looping at present */
90                 Config->set_seamless_loop (false);
91         } else {
92                 /* reset to whatever the value was before we last switched slaves */
93                 Config->set_seamless_loop (_was_seamless);
94         }
95
96         /* save value of seamless from before the switch */
97         _was_seamless = seamless;
98
99         ev->slave = new_slave;
100         DEBUG_TRACE (DEBUG::Slave, "sent request for new slave\n");
101         queue_event (ev);
102 }
103
104 void
105 Session::request_transport_speed (double speed, bool as_default)
106 {
107         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
108         ev->third_yes_or_no = as_default; // as_default
109         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport speed = %1 as default = %2\n", speed, as_default));
110         queue_event (ev);
111 }
112
113 /** Request a new transport speed, but if the speed parameter is exactly zero then use
114  *  a very small +ve value to prevent the transport actually stopping.  This method should
115  *  be used by callers who are varying transport speed but don't ever want to stop it.
116  */
117 void
118 Session::request_transport_speed_nonzero (double speed, bool as_default)
119 {
120         if (speed == 0) {
121                 speed = DBL_EPSILON;
122         }
123
124         request_transport_speed (speed, as_default);
125 }
126
127 void
128 Session::request_stop (bool abort, bool clear_state)
129 {
130         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, audible_frame(), 0.0, abort, clear_state);
131         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport stop, audible %3 transport %4 abort = %1, clear state = %2\n", abort, clear_state, audible_frame(), _transport_frame));
132         queue_event (ev);
133 }
134
135 void
136 Session::request_locate (framepos_t target_frame, bool with_roll)
137 {
138         SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, false);
139         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request locate to %1\n", target_frame));
140         queue_event (ev);
141 }
142
143 void
144 Session::force_locate (framepos_t target_frame, bool with_roll)
145 {
146         SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, true);
147         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request forced locate to %1\n", target_frame));
148         queue_event (ev);
149 }
150
151 void
152 Session::unset_preroll_record_punch ()
153 {
154         if (_preroll_record_punch_pos >= 0) {
155                 remove_event (_preroll_record_punch_pos, SessionEvent::RecordStart);
156         }
157         _preroll_record_punch_pos = -1;
158 }
159
160 void
161 Session::unset_preroll_record_trim ()
162 {
163         _preroll_record_trim_len = 0;
164 }
165
166 void
167 Session::request_preroll_record_punch (framepos_t rec_in, framecnt_t preroll)
168 {
169         if (actively_recording ()) {
170                 return;
171         }
172         unset_preroll_record_punch ();
173         unset_preroll_record_trim ();
174         framepos_t start = std::max ((framepos_t)0, rec_in - preroll);
175
176         _preroll_record_punch_pos = rec_in;
177         if (_preroll_record_punch_pos >= 0) {
178                 replace_event (SessionEvent::RecordStart, _preroll_record_punch_pos);
179                 config.set_punch_in (false);
180                 config.set_punch_out (false);
181         }
182         maybe_enable_record ();
183         request_locate (start, true);
184         set_requested_return_frame (rec_in);
185 }
186
187 void
188 Session::request_preroll_record_trim (framepos_t rec_in, framecnt_t preroll)
189 {
190         if (actively_recording ()) {
191                 return;
192         }
193         unset_preroll_record_punch ();
194         unset_preroll_record_trim ();
195
196         config.set_punch_in (false);
197         config.set_punch_out (false);
198
199         framepos_t pos = std::max ((framepos_t)0, rec_in - preroll);
200         _preroll_record_trim_len = preroll;
201         maybe_enable_record ();
202         request_locate (pos, true);
203         set_requested_return_frame (rec_in);
204 }
205
206 void
207 Session::request_count_in_record ()
208 {
209         if (actively_recording ()) {
210                 return;
211         }
212         if (transport_rolling()) {
213                 return;
214         }
215         maybe_enable_record ();
216         _count_in_once = true;
217         request_transport_speed (1.0, true);
218 }
219
220 void
221 Session::request_play_loop (bool yn, bool change_transport_roll)
222 {
223         if (_slave && yn) {
224                 // don't attempt to loop when not using Internal Transport
225                 // see also gtk2_ardour/ardour_ui_options.cc parameter_changed()
226                 return;
227         }
228
229         SessionEvent* ev;
230         Location *location = _locations->auto_loop_location();
231         double target_speed;
232
233         if (location == 0 && yn) {
234                 error << _("Cannot loop - no loop range defined")
235                       << endmsg;
236                 return;
237         }
238
239         if (change_transport_roll) {
240                 if (transport_rolling()) {
241                         /* start looping at current speed */
242                         target_speed = transport_speed ();
243                 } else {
244                         /* currently stopped */
245                         if (yn) {
246                                 /* start looping at normal speed */
247                                 target_speed = 1.0;
248                         } else {
249                                 target_speed = 0.0;
250                         }
251                 }
252         } else {
253                 /* leave the speed alone */
254                 target_speed = transport_speed ();
255         }
256
257         ev = new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, target_speed, yn);
258         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request set loop = %1, change roll state ? %2\n", yn, change_transport_roll));
259         queue_event (ev);
260
261         if (yn) {
262                 if (!change_transport_roll) {
263                         if (!transport_rolling()) {
264                                 /* we're not changing transport state, but we do want
265                                    to set up position for the new loop. Don't
266                                    do this if we're rolling already.
267                                 */
268                                 request_locate (location->start(), false);
269                         }
270                 }
271         } else {
272                 if (!change_transport_roll && Config->get_seamless_loop() && transport_rolling()) {
273                         // request an immediate locate to refresh the tracks
274                         // after disabling looping
275                         request_locate (_transport_frame-1, false);
276                 }
277         }
278 }
279
280 void
281 Session::request_play_range (list<AudioRange>* range, bool leave_rolling)
282 {
283         SessionEvent* ev = new SessionEvent (SessionEvent::SetPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0));
284         if (range) {
285                 ev->audio_range = *range;
286         } else {
287                 ev->audio_range.clear ();
288         }
289         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request play range, leave rolling ? %1\n", leave_rolling));
290         queue_event (ev);
291 }
292
293 void
294 Session::request_cancel_play_range ()
295 {
296         SessionEvent* ev = new SessionEvent (SessionEvent::CancelPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, 0);
297         queue_event (ev);
298 }
299
300
301 void
302 Session::realtime_stop (bool abort, bool clear_state)
303 {
304         DEBUG_TRACE (DEBUG::Transport, string_compose ("realtime stop @ %1\n", _transport_frame));
305         PostTransportWork todo = PostTransportWork (0);
306
307         /* assume that when we start, we'll be moving forwards */
308
309         if (_transport_speed < 0.0f) {
310                 todo = (PostTransportWork (todo | PostTransportStop | PostTransportReverse));
311                 _default_transport_speed = 1.0;
312         } else {
313                 todo = PostTransportWork (todo | PostTransportStop);
314         }
315
316         /* call routes */
317
318         boost::shared_ptr<RouteList> r = routes.reader ();
319
320         for (RouteList::iterator i = r->begin (); i != r->end(); ++i) {
321                 (*i)->realtime_handle_transport_stopped ();
322         }
323
324         DEBUG_TRACE (DEBUG::Transport, string_compose ("stop complete, auto-return scheduled for return to %1\n", _requested_return_frame));
325
326         /* the duration change is not guaranteed to have happened, but is likely */
327
328         todo = PostTransportWork (todo | PostTransportDuration);
329
330         if (abort) {
331                 todo = PostTransportWork (todo | PostTransportAbort);
332         }
333
334         if (clear_state) {
335                 todo = PostTransportWork (todo | PostTransportClearSubstate);
336         }
337
338         if (todo) {
339                 add_post_transport_work (todo);
340         }
341
342         _clear_event_type (SessionEvent::StopOnce);
343         _clear_event_type (SessionEvent::RangeStop);
344         _clear_event_type (SessionEvent::RangeLocate);
345
346         /* if we're going to clear loop state, then force disabling record BUT only if we're not doing latched rec-enable */
347         disable_record (true, (!Config->get_latched_record_enable() && clear_state));
348
349         if (clear_state && !Config->get_loop_is_mode()) {
350                 unset_play_loop ();
351         }
352
353         reset_slave_state ();
354
355         _transport_speed = 0;
356         _target_transport_speed = 0;
357
358         g_atomic_int_set (&_playback_load, 100);
359         g_atomic_int_set (&_capture_load, 100);
360
361         if (config.get_use_video_sync()) {
362                 waiting_for_sync_offset = true;
363         }
364
365         transport_sub_state = 0;
366 }
367
368 void
369 Session::realtime_locate ()
370 {
371         boost::shared_ptr<RouteList> r = routes.reader ();
372         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
373                 (*i)->realtime_locate ();
374         }
375 }
376
377 void
378 Session::butler_transport_work ()
379 {
380         /* Note: this function executes in the butler thread context */
381
382   restart:
383         bool finished;
384         PostTransportWork ptw;
385         boost::shared_ptr<RouteList> r = routes.reader ();
386         uint64_t before;
387
388         int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
389         finished = true;
390         ptw = post_transport_work();
391
392         DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler transport work, todo = %1 at %2\n", enum_2_string (ptw), (before = g_get_monotonic_time())));
393
394
395         if (ptw & PostTransportLocate) {
396
397                 if (get_play_loop() && !Config->get_seamless_loop()) {
398
399                         DEBUG_TRACE (DEBUG::Butler, "flush loop recording fragment to disk\n");
400
401                         /* this locate might be happening while we are
402                          * loop recording.
403                          *
404                          * Non-seamless looping will require a locate (below) that
405                          * will reset capture buffers and throw away data.
406                          *
407                          * Rather than first find all tracks and see if they
408                          * have outstanding data, just do a flush anyway. It
409                          * may be cheaper this way anyway, and is certainly
410                          * more accurate.
411                          */
412
413                         bool more_disk_io_to_do = false;
414                         uint32_t errors = 0;
415
416                         do {
417                                 more_disk_io_to_do = _butler->flush_tracks_to_disk_after_locate (r, errors);
418
419                                 if (errors) {
420                                         break;
421                                 }
422
423                                 if (more_disk_io_to_do) {
424                                         continue;
425                                 }
426
427                         } while (false);
428
429                 }
430         }
431
432         if (ptw & PostTransportAdjustPlaybackBuffering) {
433                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
434                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
435                         if (tr) {
436                                 tr->adjust_playback_buffering ();
437                                 /* and refill those buffers ... */
438                         }
439                         (*i)->non_realtime_locate (_transport_frame);
440                 }
441                 VCAList v = _vca_manager->vcas ();
442                 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
443                         (*i)->non_realtime_locate (_transport_frame);
444                 }
445         }
446
447         if (ptw & PostTransportAdjustCaptureBuffering) {
448                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
449                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
450                         if (tr) {
451                                 tr->adjust_capture_buffering ();
452                         }
453                 }
454         }
455
456         if (ptw & PostTransportCurveRealloc) {
457                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
458                         (*i)->curve_reallocate();
459                 }
460         }
461
462         if (ptw & PostTransportSpeed) {
463                 non_realtime_set_speed ();
464         }
465
466         if (ptw & PostTransportReverse) {
467
468                 clear_clicks();
469                 cumulative_rf_motion = 0;
470                 reset_rf_scale (0);
471
472                 /* don't seek if locate will take care of that in non_realtime_stop() */
473
474                 if (!(ptw & PostTransportLocate)) {
475                         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
476                                 (*i)->non_realtime_locate (_transport_frame);
477
478                                 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
479                                         /* new request, stop seeking, and start again */
480                                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
481                                         goto restart;
482                                 }
483                         }
484                         VCAList v = _vca_manager->vcas ();
485                         for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
486                                 (*i)->non_realtime_locate (_transport_frame);
487                         }
488                 }
489         }
490
491         if (ptw & PostTransportLocate) {
492                 DEBUG_TRACE (DEBUG::Transport, "nonrealtime locate invoked from BTW\n");
493                 non_realtime_locate ();
494         }
495
496         if (ptw & PostTransportStop) {
497                 non_realtime_stop (ptw & PostTransportAbort, on_entry, finished);
498                 if (!finished) {
499                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
500                         goto restart;
501                 }
502         }
503
504         if (ptw & PostTransportOverWrite) {
505                 non_realtime_overwrite (on_entry, finished);
506                 if (!finished) {
507                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
508                         goto restart;
509                 }
510         }
511
512         if (ptw & PostTransportAudition) {
513                 non_realtime_set_audition ();
514         }
515
516         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
517
518         DEBUG_TRACE (DEBUG::Transport, string_compose (X_("Butler transport work all done after %1 usecs @ %2 trw = %3\n"), g_get_monotonic_time() - before, _transport_frame, _butler->transport_work_requested()));
519 }
520
521 void
522 Session::non_realtime_set_speed ()
523 {
524         boost::shared_ptr<RouteList> rl = routes.reader();
525         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
526                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
527                 if (tr) {
528                         tr->non_realtime_speed_change ();
529                 }
530         }
531 }
532
533 void
534 Session::non_realtime_overwrite (int on_entry, bool& finished)
535 {
536         boost::shared_ptr<RouteList> rl = routes.reader();
537         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
538                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
539                 if (tr && tr->pending_overwrite ()) {
540                         tr->overwrite_existing_buffers ();
541                 }
542                 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
543                         finished = false;
544                         return;
545                 }
546         }
547 }
548
549
550 void
551 Session::non_realtime_locate ()
552 {
553         DEBUG_TRACE (DEBUG::Transport, string_compose ("locate tracks to %1\n", _transport_frame));
554
555         if (Config->get_loop_is_mode() && get_play_loop()) {
556
557                 Location *loc  = _locations->auto_loop_location();
558
559                 if (!loc || (_transport_frame < loc->start() || _transport_frame >= loc->end())) {
560                         /* jumped out of loop range: stop tracks from looping,
561                            but leave loop (mode) enabled.
562                          */
563                         set_track_loop (false);
564
565                 } else if (loc && Config->get_seamless_loop() &&
566                    ((loc->start() <= _transport_frame) ||
567                    (loc->end() > _transport_frame) ) ) {
568
569                         /* jumping to start of loop. This  might have been done before but it is
570                          * idempotent and cheap. Doing it here ensures that when we start playback
571                          * outside the loop we still flip tracks into the magic seamless mode
572                          * when needed.
573                          */
574                         set_track_loop (true);
575
576                 } else if (loc) {
577                         set_track_loop (false);
578                 }
579
580         } else {
581
582                 /* no more looping .. should have been noticed elsewhere */
583         }
584
585
586         microseconds_t begin = get_microseconds ();
587         framepos_t tf;
588
589         {
590                 boost::shared_ptr<RouteList> rl = routes.reader();
591
592           restart:
593                 gint sc = g_atomic_int_get (&_seek_counter);
594                 tf = _transport_frame;
595
596                 cerr << "\n\n >>> START Non-RT locate on routes to " << tf << " counter = " << sc << "\n\n";
597
598                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
599                         (*i)->non_realtime_locate (tf);
600                         //::usleep (250000);
601                         cerr << "\t\tcounter after track: " << g_atomic_int_get (&_seek_counter) << endl;
602                         if (sc != g_atomic_int_get (&_seek_counter)) {
603                                 cerr << "\n\n RESTART locate, new seek delivered\n";
604                                 goto restart;
605                         }
606                 }
607
608                 cerr << "\n\n <<< DONE Non-RT locate on routes\n\n";
609         }
610
611         {
612                 /* VCAs are quick to locate because they have no data (except
613                    automation) associated with them. Don't bother with a
614                    restart mechanism here, but do use the same transport frame
615                    that the Routes used.
616                 */
617                 VCAList v = _vca_manager->vcas ();
618                 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
619                         (*i)->non_realtime_locate (tf);
620                 }
621         }
622
623         microseconds_t end = get_microseconds ();
624         cerr << "Locate took " << setprecision (3) << ((end - begin) /1000000.0) << " secs\n";
625
626         _scene_changer->locate (_transport_frame);
627
628         /* XXX: it would be nice to generate the new clicks here (in the non-RT thread)
629            rather than clearing them so that the RT thread has to spend time constructing
630            them (in Session::click).
631          */
632         clear_clicks ();
633 }
634
635 #ifdef USE_TRACKS_CODE_FEATURES
636 bool
637 Session::select_playhead_priority_target (framepos_t& jump_to)
638 {
639         jump_to = -1;
640
641         AutoReturnTarget autoreturn = Config->get_auto_return_target_list ();
642
643         if (!autoreturn) {
644                 return false;
645         }
646
647         if (Profile->get_trx() && transport_rolling() ) {
648                 // We're playing, so do nothing.
649                 // Next stop will put us where we need to be.
650                 return false;
651         }
652
653         /* Note that the order of checking each AutoReturnTarget flag defines
654            the priority each flag.
655
656            Ardour/Mixbus: Last Locate
657                           Range Selection
658                           Loop Range
659                           Region Selection
660
661            Tracks:        Range Selection
662                           Loop Range
663                           Region Selection
664                           Last Locate
665         */
666
667         if (autoreturn & RangeSelectionStart) {
668                 if (!_range_selection.empty()) {
669                         jump_to = _range_selection.from;
670                 } else {
671                         if (transport_rolling ()) {
672                                 /* Range selection no longer exists, but we're playing,
673                                    so do nothing. Next stop will put us where
674                                    we need to be.
675                                 */
676                                 return false;
677                         }
678                 }
679         }
680
681         if (jump_to < 0 && (autoreturn & Loop) && get_play_loop()) {
682                 /* don't try to handle loop play when synced to JACK */
683
684                 if (!synced_to_engine()) {
685                         Location *location = _locations->auto_loop_location();
686
687                         if (location) {
688                                 jump_to = location->start();
689
690                                 if (Config->get_seamless_loop()) {
691                                         /* need to get track buffers reloaded */
692                                         set_track_loop (true);
693                                 }
694                         }
695                 }
696         }
697
698         if (jump_to < 0 && (autoreturn & RegionSelectionStart)) {
699                 if (!_object_selection.empty()) {
700                         jump_to = _object_selection.from;
701                 }
702         }
703
704         if (jump_to < 0 && (autoreturn & LastLocate)) {
705                 jump_to = _last_roll_location;
706         }
707
708         return jump_to >= 0;
709 }
710 #else
711
712 bool
713 Session::select_playhead_priority_target (framepos_t& jump_to)
714 {
715         if (config.get_external_sync() || !config.get_auto_return()) {
716                 return false;
717         }
718
719         jump_to = _last_roll_location;
720         return jump_to >= 0;
721 }
722
723 #endif
724
725 void
726 Session::follow_playhead_priority ()
727 {
728         framepos_t target;
729
730         if (select_playhead_priority_target (target)) {
731                 request_locate (target);
732         }
733 }
734
735 void
736 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
737 {
738         struct tm* now;
739         time_t     xnow;
740         bool       did_record;
741         bool       saved;
742         PostTransportWork ptw = post_transport_work();
743
744         did_record = false;
745         saved = false;
746
747         boost::shared_ptr<RouteList> rl = routes.reader();
748         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
749                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
750                 if (tr && tr->get_captured_frames () != 0) {
751                         did_record = true;
752                         break;
753                 }
754         }
755
756         /* stop and locate are merged here because they share a lot of common stuff */
757
758         time (&xnow);
759         now = localtime (&xnow);
760
761         if (auditioner) {
762                 auditioner->cancel_audition ();
763         }
764
765         cumulative_rf_motion = 0;
766         reset_rf_scale (0);
767
768         if (did_record) {
769                 begin_reversible_command (Operations::capture);
770                 _have_captured = true;
771         }
772
773         DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: DS stop\n"));
774
775         if (abort && did_record) {
776                 /* no reason to save the session file when we remove sources
777                  */
778                 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
779         }
780
781         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
782                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
783                 if (tr) {
784                         tr->transport_stopped_wallclock (*now, xnow, abort);
785                 }
786         }
787
788         if (abort && did_record) {
789                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
790         }
791
792         boost::shared_ptr<RouteList> r = routes.reader ();
793
794         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
795                 if (!(*i)->is_auditioner()) {
796                         (*i)->set_pending_declick (0);
797                 }
798         }
799
800         if (did_record) {
801                 commit_reversible_command ();
802                 /* increase take name */
803                 if (config.get_track_name_take () && !config.get_take_name ().empty()) {
804                         string newname = config.get_take_name();
805                         config.set_take_name(bump_name_number (newname));
806                 }
807         }
808
809         if (_engine.running()) {
810                 PostTransportWork ptw = post_transport_work ();
811
812                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
813                         (*i)->non_realtime_transport_stop (_transport_frame, !(ptw & PostTransportLocate) || pending_locate_flush);
814                 }
815                 VCAList v = _vca_manager->vcas ();
816                 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
817                         (*i)->non_realtime_transport_stop (_transport_frame, !(ptw & PostTransportLocate) || pending_locate_flush);
818                 }
819
820                 update_latency_compensation ();
821         }
822
823         bool const auto_return_enabled = (!config.get_external_sync() && (Config->get_auto_return_target_list() || abort));
824
825         if (auto_return_enabled ||
826             (ptw & PostTransportLocate) ||
827             (_requested_return_frame >= 0) ||
828             synced_to_engine()) {
829
830                 if (pending_locate_flush) {
831                         flush_all_inserts ();
832                 }
833
834                 // rg: what is the logic behind this case?
835                 // _requested_return_frame should be ignored when synced_to_engine/slaved.
836                 // currently worked around in MTC_Slave by forcing _requested_return_frame to -1
837                 // 2016-01-10
838                 if ((auto_return_enabled || synced_to_engine() || _requested_return_frame >= 0) &&
839                     !(ptw & PostTransportLocate)) {
840
841                         /* no explicit locate queued */
842
843                         bool do_locate = false;
844
845                         if (_requested_return_frame >= 0) {
846
847                                 /* explicit return request pre-queued in event list. overrides everything else */
848
849                                 _transport_frame = _requested_return_frame;
850                                 do_locate = true;
851
852                         } else {
853                                 framepos_t jump_to;
854
855                                 if (select_playhead_priority_target (jump_to)) {
856
857                                         _transport_frame = jump_to;
858                                         do_locate = true;
859
860                                 } else if (abort) {
861
862                                         _transport_frame = _last_roll_location;
863                                         do_locate = true;
864                                 }
865                         }
866
867                         _requested_return_frame = -1;
868
869                         if (do_locate) {
870                                 _engine.transport_locate (_transport_frame);
871                         }
872                 }
873
874         }
875
876         clear_clicks();
877         unset_preroll_record_trim ();
878
879         /* do this before seeking, because otherwise the tracks will do the wrong thing in seamless loop mode.
880         */
881
882         if (ptw & PostTransportClearSubstate) {
883                 unset_play_range ();
884                 if (!Config->get_loop_is_mode()) {
885                         unset_play_loop ();
886                 }
887         }
888
889         /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
890
891         {
892                 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: locate\n"));
893                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
894                         DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler PTW: locate on %1\n", (*i)->name()));
895                         (*i)->non_realtime_locate (_transport_frame);
896
897                         if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
898                                 finished = false;
899                                 /* we will be back */
900                                 return;
901                         }
902                 }
903         }
904
905         {
906                 VCAList v = _vca_manager->vcas ();
907                 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
908                         (*i)->non_realtime_locate (_transport_frame);
909                 }
910         }
911
912         have_looped = false;
913
914         /* don't bother with this stuff if we're disconnected from the engine,
915            because there will be no process callbacks to deliver stuff from
916         */
917
918         if (_engine.connected() && !_engine.freewheeling()) {
919                 // need to queue this in the next RT cycle
920                 _send_timecode_update = true;
921
922                 if (!dynamic_cast<MTC_Slave*>(_slave)) {
923                         send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
924
925                         /* This (::non_realtime_stop()) gets called by main
926                            process thread, which will lead to confusion
927                            when calling AsyncMIDIPort::write().
928
929                            Something must be done. XXX
930                         */
931                         send_mmc_locate (_transport_frame);
932                 }
933         }
934
935         if ((ptw & PostTransportLocate) && get_record_enabled()) {
936                 /* This is scheduled by realtime_stop(), which is also done
937                  * when a slave requests /locate/ for an initial sync.
938                  * We can't hold up the slave for long with a save() here,
939                  * without breaking its initial sync cycle.
940                  *
941                  * save state only if there's no slave or if it's not yet locked.
942                  */
943                 if (!_slave || !_slave->locked()) {
944                         DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: requests save\n"));
945                         SaveSessionRequested (_current_snapshot_name);
946                         saved = true;
947                 }
948         }
949
950         /* always try to get rid of this */
951
952         remove_pending_capture_state ();
953
954         /* save the current state of things if appropriate */
955
956         if (did_record && !saved) {
957                 SaveSessionRequested (_current_snapshot_name);
958         }
959
960         if (ptw & PostTransportStop) {
961                 unset_play_range ();
962                 if (!Config->get_loop_is_mode()) {
963                         unset_play_loop ();
964                 }
965         }
966
967         PositionChanged (_transport_frame); /* EMIT SIGNAL */
968         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC with speed = %1\n", _transport_speed));
969         TransportStateChange (); /* EMIT SIGNAL */
970         AutomationWatch::instance().transport_stop_automation_watches (_transport_frame);
971
972         /* and start it up again if relevant */
973
974         if ((ptw & PostTransportLocate) && !config.get_external_sync() && pending_locate_roll) {
975                 request_transport_speed (1.0);
976         }
977
978         /* Even if we didn't do a pending locate roll this time, we don't want it hanging
979            around for next time.
980         */
981         pending_locate_roll = false;
982 }
983
984 void
985 Session::check_declick_out ()
986 {
987         bool locate_required = transport_sub_state & PendingLocate;
988
989         /* this is called after a process() iteration. if PendingDeclickOut was set,
990            it means that we were waiting to declick the output (which has just been
991            done) before maybe doing something else. this is where we do that "something else".
992
993            note: called from the audio thread.
994         */
995
996         if (transport_sub_state & PendingDeclickOut) {
997
998                 if (locate_required) {
999                         start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
1000                         transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
1001                 } else {
1002                         if (!(transport_sub_state & StopPendingCapture)) {
1003                                 stop_transport (pending_abort);
1004                                 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
1005                         }
1006                 }
1007
1008         } else if (transport_sub_state & PendingLoopDeclickOut) {
1009                 /* Nothing else to do here; we've declicked, and the loop event will be along shortly */
1010                 transport_sub_state &= ~PendingLoopDeclickOut;
1011         }
1012 }
1013
1014 void
1015 Session::unset_play_loop ()
1016 {
1017         if (play_loop) {
1018                 play_loop = false;
1019                 clear_events (SessionEvent::AutoLoop);
1020                 clear_events (SessionEvent::AutoLoopDeclick);
1021                 set_track_loop (false);
1022
1023
1024                 if (Config->get_seamless_loop()) {
1025                         /* likely need to flush track buffers: this will locate us to wherever we are */
1026                         add_post_transport_work (PostTransportLocate);
1027                         _butler->schedule_transport_work ();
1028                 }
1029         }
1030 }
1031
1032 void
1033 Session::set_track_loop (bool yn)
1034 {
1035         Location* loc = _locations->auto_loop_location ();
1036
1037         if (!loc) {
1038                 yn = false;
1039         }
1040
1041         boost::shared_ptr<RouteList> rl = routes.reader ();
1042
1043         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1044                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1045                 if (tr && !tr->is_private_route()) {
1046                         tr->set_loop (yn ? loc : 0);
1047                 }
1048         }
1049 }
1050
1051 void
1052 Session::set_play_loop (bool yn, double speed)
1053 {
1054         /* Called from event-handling context */
1055
1056         Location *loc;
1057
1058         if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) {
1059                 /* nothing to do, or can't change loop status while recording */
1060                 return;
1061         }
1062
1063         if (yn && Config->get_seamless_loop() && synced_to_engine()) {
1064                 warning << string_compose (
1065                         _("Seamless looping cannot be supported while %1 is using JACK transport.\n"
1066                           "Recommend changing the configured options"), PROGRAM_NAME)
1067                         << endmsg;
1068                 return;
1069         }
1070
1071         if (yn) {
1072
1073                 play_loop = true;
1074                 have_looped = false;
1075
1076                 if (loc) {
1077
1078                         unset_play_range ();
1079
1080                         if (Config->get_seamless_loop()) {
1081                                 if (!Config->get_loop_is_mode()) {
1082                                         /* set all tracks to use internal looping */
1083                                         set_track_loop (true);
1084                                 } else {
1085                                         /* we will do this in the locate to the start OR when we hit the end
1086                                          * of the loop for the first time
1087                                          */
1088                                 }
1089                         } else {
1090                                 /* set all tracks to NOT use internal looping */
1091                                 set_track_loop (false);
1092                         }
1093
1094                         /* Put the delick and loop events in into the event list.  The declick event will
1095                            cause a de-clicking fade-out just before the end of the loop, and it will also result
1096                            in a fade-in when the loop restarts.  The AutoLoop event will peform the actual loop.
1097                         */
1098
1099                         framepos_t dcp;
1100                         framecnt_t dcl;
1101                         auto_loop_declick_range (loc, dcp, dcl);
1102                         merge_event (new SessionEvent (SessionEvent::AutoLoopDeclick, SessionEvent::Replace, dcp, dcl, 0.0f));
1103                         merge_event (new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f));
1104
1105                         /* if requested to roll, locate to start of loop and
1106                          * roll but ONLY if we're not already rolling.
1107
1108                            args: positition, roll=true, flush=true, with_loop=false, force buffer refill if seamless looping
1109                         */
1110
1111                         if (Config->get_loop_is_mode()) {
1112                                 /* loop IS a transport mode: if already
1113                                    rolling, do not locate to loop start.
1114                                 */
1115                                 if (!transport_rolling() && (speed != 0.0)) {
1116                                         start_locate (loc->start(), true, true, false, true);
1117                                 }
1118                         } else {
1119                                 if (speed != 0.0) {
1120                                         start_locate (loc->start(), true, true, false, true);
1121                                 }
1122                         }
1123                 }
1124
1125         } else {
1126
1127                 unset_play_loop ();
1128         }
1129
1130         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC2 with speed = %1\n", _transport_speed));
1131         TransportStateChange ();
1132 }
1133 void
1134 Session::flush_all_inserts ()
1135 {
1136         boost::shared_ptr<RouteList> r = routes.reader ();
1137
1138         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1139                 (*i)->flush_processors ();
1140         }
1141 }
1142
1143 void
1144 Session::start_locate (framepos_t target_frame, bool with_roll, bool with_flush, bool for_loop_enabled, bool force)
1145 {
1146         if (target_frame < 0) {
1147                 error << _("Locate called for negative sample position - ignored") << endmsg;
1148                 return;
1149         }
1150
1151         if (synced_to_engine()) {
1152
1153                 double sp;
1154                 framepos_t pos;
1155
1156                 _slave->speed_and_position (sp, pos);
1157
1158                 if (target_frame != pos) {
1159
1160                         if (config.get_jack_time_master()) {
1161                                 /* actually locate now, since otherwise jack_timebase_callback
1162                                    will use the incorrect _transport_frame and report an old
1163                                    and incorrect time to Jack transport
1164                                 */
1165                                 locate (target_frame, with_roll, with_flush, for_loop_enabled, force);
1166                         }
1167
1168                         /* tell JACK to change transport position, and we will
1169                            follow along later in ::follow_slave()
1170                         */
1171
1172                         _engine.transport_locate (target_frame);
1173
1174                         if (sp != 1.0f && with_roll) {
1175                                 _engine.transport_start ();
1176                         }
1177
1178                 }
1179
1180         } else {
1181                 locate (target_frame, with_roll, with_flush, for_loop_enabled, force);
1182         }
1183 }
1184
1185 int
1186 Session::micro_locate (framecnt_t distance)
1187 {
1188         boost::shared_ptr<RouteList> rl = routes.reader();
1189         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1190                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1191                 if (tr && !tr->can_internal_playback_seek (distance)) {
1192                         return -1;
1193                 }
1194         }
1195
1196         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1197                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1198                 if (tr) {
1199                         tr->internal_playback_seek (distance);
1200                 }
1201         }
1202
1203         _transport_frame += distance;
1204         return 0;
1205 }
1206
1207 /** @param with_mmc true to send a MMC locate command when the locate is done */
1208 void
1209 Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool for_loop_enabled, bool force, bool with_mmc)
1210 {
1211         bool need_butler = false;
1212
1213         /* Locates for seamless looping are fairly different from other
1214          * locates. They assume that the diskstream buffers for each track
1215          * already have the correct data in them, and thus there is no need to
1216          * actually tell the tracks to locate. What does need to be done,
1217          * though, is all the housekeeping that is associated with non-linear
1218          * changes in the value of _transport_frame.
1219          */
1220
1221         DEBUG_TRACE (DEBUG::Transport, string_compose ("rt-locate to %1, roll %2 flush %3 loop-enabled %4 force %5 mmc %6\n",
1222                                                        target_frame, with_roll, with_flush, for_loop_enabled, force, with_mmc));
1223
1224         if (!force && _transport_frame == target_frame && !loop_changing && !for_loop_enabled) {
1225
1226                 /* already at the desired position. Not forced to locate,
1227                    the loop isn't changing, so unless we're told to
1228                    start rolling also, there's nothing to do but
1229                    tell the world where we are (again).
1230                 */
1231
1232                 if (with_roll) {
1233                         set_transport_speed (1.0, 0, false);
1234                 }
1235                 loop_changing = false;
1236                 Located (); /* EMIT SIGNAL */
1237                 return;
1238         }
1239
1240         if (_transport_speed && !(for_loop_enabled && Config->get_seamless_loop())) {
1241                 /* Schedule a declick.  We'll be called again when its done.
1242                    We only do it this way for ordinary locates, not those
1243                    due to **seamless** loops.
1244                 */
1245
1246                 if (!(transport_sub_state & PendingDeclickOut)) {
1247                         transport_sub_state |= (PendingDeclickOut|PendingLocate);
1248                         pending_locate_frame = target_frame;
1249                         pending_locate_roll = with_roll;
1250                         pending_locate_flush = with_flush;
1251                         cerr << "Declick scheduled ... back soon\n";
1252                         return;
1253                 }
1254         }
1255
1256         cerr << "... now doing the actual locate\n";
1257
1258         // Update Timecode time
1259         _transport_frame = target_frame;
1260         // Bump seek counter so that any in-process locate in the butler
1261         // thread(s?) can restart.
1262         g_atomic_int_inc (&_seek_counter);
1263         _last_roll_or_reversal_location = target_frame;
1264         timecode_time(_transport_frame, transmitting_timecode_time);
1265
1266         /* do "stopped" stuff if:
1267          *
1268          * we are rolling AND
1269          *    no autoplay in effect AND
1270          *       we're not going to keep rolling after the locate AND
1271          *           !(playing a loop with JACK sync)
1272          *
1273          */
1274
1275         bool transport_was_stopped = !transport_rolling();
1276
1277         if (!transport_was_stopped && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_engine() && play_loop) &&
1278             (!Profile->get_trx() || !(config.get_external_sync() && !synced_to_engine()))) {
1279                 realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
1280                 transport_was_stopped = true;
1281         } else {
1282                 /* otherwise tell the world that we located */
1283                 realtime_locate ();
1284         }
1285
1286         if (force || !for_loop_enabled || loop_changing) {
1287
1288                 PostTransportWork todo = PostTransportLocate;
1289
1290                 if (with_roll && transport_was_stopped) {
1291                         todo = PostTransportWork (todo | PostTransportRoll);
1292                 }
1293
1294                 add_post_transport_work (todo);
1295                 need_butler = true;
1296
1297         } else {
1298
1299                 /* this is functionally what clear_clicks() does but with a tentative lock */
1300
1301                 Glib::Threads::RWLock::WriterLock clickm (click_lock, Glib::Threads::TRY_LOCK);
1302
1303                 if (clickm.locked()) {
1304
1305                         for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
1306                                 delete *i;
1307                         }
1308
1309                         clicks.clear ();
1310                 }
1311         }
1312
1313         if (with_roll) {
1314                 /* switch from input if we're going to roll */
1315                 if (Config->get_monitoring_model() == HardwareMonitoring) {
1316                         set_track_monitor_input_status (!config.get_auto_input());
1317                 }
1318         } else {
1319                 /* otherwise we're going to stop, so do the opposite */
1320                 if (Config->get_monitoring_model() == HardwareMonitoring) {
1321                         set_track_monitor_input_status (true);
1322                 }
1323         }
1324
1325         /* cancel looped playback if transport pos outside of loop range */
1326         if (play_loop) {
1327
1328                 Location* al = _locations->auto_loop_location();
1329
1330                 if (al) {
1331                         if (_transport_frame < al->start() || _transport_frame >= al->end()) {
1332
1333                                 // located outside the loop: cancel looping directly, this is called from event handling context
1334
1335                                 have_looped = false;
1336
1337                                 if (!Config->get_loop_is_mode()) {
1338                                         set_play_loop (false, _transport_speed);
1339                                 } else {
1340                                         if (Config->get_seamless_loop()) {
1341                                                 /* this will make the non_realtime_locate() in the butler
1342                                                    which then causes seek() in tracks actually do the right
1343                                                    thing.
1344                                                 */
1345                                                 set_track_loop (false);
1346                                         }
1347                                 }
1348
1349                         } else if (_transport_frame == al->start()) {
1350
1351                                 // located to start of loop - this is looping, basically
1352
1353                                 if (!have_looped) {
1354                                         /* first time */
1355                                         if (_last_roll_location != al->start()) {
1356                                                 /* didn't start at loop start - playback must have
1357                                                  * started before loop since we've now hit the loop
1358                                                  * end.
1359                                                  */
1360                                                 add_post_transport_work (PostTransportLocate);
1361                                                 need_butler = true;
1362                                         }
1363
1364                                 }
1365
1366                                 boost::shared_ptr<RouteList> rl = routes.reader();
1367
1368                                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1369                                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1370
1371                                         if (tr && tr->rec_enable_control()->get_value()) {
1372                                                 // tell it we've looped, so it can deal with the record state
1373                                                 tr->transport_looped (_transport_frame);
1374                                         }
1375                                 }
1376
1377                                 have_looped = true;
1378                                 TransportLooped(); // EMIT SIGNAL
1379                         }
1380                 }
1381         }
1382
1383         if (need_butler) {
1384                 _butler->schedule_transport_work ();
1385         }
1386
1387         loop_changing = false;
1388
1389         _send_timecode_update = true;
1390
1391         if (with_mmc) {
1392                 send_mmc_locate (_transport_frame);
1393         }
1394
1395         _last_roll_location = _last_roll_or_reversal_location =  _transport_frame;
1396         if (!synced_to_engine () || _transport_frame == _engine.transport_frame ()) {
1397                 Located (); /* EMIT SIGNAL */
1398         }
1399 }
1400
1401 /** Set the transport speed.
1402  *  Called from the process thread.
1403  *  @param speed New speed
1404  */
1405 void
1406 Session::set_transport_speed (double speed, framepos_t destination_frame, bool abort, bool clear_state, bool as_default)
1407 {
1408         DEBUG_TRACE (DEBUG::Transport, string_compose ("@ %5 Set transport speed to %1, abort = %2 clear_state = %3, current = %4 as_default %6\n",
1409                                                        speed, abort, clear_state, _transport_speed, _transport_frame, as_default));
1410
1411         if (_transport_speed == speed) {
1412                 if (as_default && speed == 0.0) { // => reset default transport speed. hacky or what?
1413                         _default_transport_speed = 1.0;
1414                 }
1415                 return;
1416         }
1417
1418         if (actively_recording() && speed != 1.0 && speed != 0.0) {
1419                 /* no varispeed during recording */
1420                 DEBUG_TRACE (DEBUG::Transport, string_compose ("No varispeed during recording cur_speed %1, frame %2\n",
1421                                                        _transport_speed, _transport_frame));
1422                 return;
1423         }
1424
1425         _target_transport_speed = fabs(speed);
1426
1427         /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
1428            and user needs. We really need CD-style "skip" playback for ffwd and rewind.
1429         */
1430
1431         if (speed > 0) {
1432                 speed = min (8.0, speed);
1433         } else if (speed < 0) {
1434                 speed = max (-8.0, speed);
1435         }
1436
1437         if (transport_rolling() && speed == 0.0) {
1438
1439                 /* we are rolling and we want to stop */
1440
1441                 if (Config->get_monitoring_model() == HardwareMonitoring) {
1442                         set_track_monitor_input_status (true);
1443                 }
1444
1445                 if (synced_to_engine ()) {
1446                         if (clear_state) {
1447                                 /* do this here because our response to the slave won't
1448                                    take care of it.
1449                                 */
1450                                 _play_range = false;
1451                                 _count_in_once = false;
1452                                 unset_play_loop ();
1453                         }
1454                         _engine.transport_stop ();
1455                 } else {
1456                         bool const auto_return_enabled = (!config.get_external_sync() && (Config->get_auto_return_target_list() || abort));
1457
1458                         if (!auto_return_enabled) {
1459                                 _requested_return_frame = destination_frame;
1460                         }
1461
1462                         stop_transport (abort);
1463                 }
1464
1465         } else if (transport_stopped() && speed == 1.0) {
1466                 if (as_default) {
1467                         _default_transport_speed = speed;
1468                 }
1469                 /* we are stopped and we want to start rolling at speed 1 */
1470
1471                 if (Config->get_loop_is_mode() && play_loop) {
1472
1473                         Location *location = _locations->auto_loop_location();
1474
1475                         if (location != 0) {
1476                                 if (_transport_frame != location->start()) {
1477
1478                                         if (Config->get_seamless_loop()) {
1479                                                 /* force tracks to do their thing */
1480                                                 set_track_loop (true);
1481                                         }
1482
1483                                         /* jump to start and then roll from there */
1484
1485                                         request_locate (location->start(), true);
1486                                         return;
1487                                 }
1488                         }
1489                 }
1490
1491                 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1492                         set_track_monitor_input_status (false);
1493                 }
1494
1495                 if (synced_to_engine()) {
1496                         _engine.transport_start ();
1497                         _count_in_once = false;
1498                 } else {
1499                         start_transport ();
1500                 }
1501
1502         } else {
1503
1504                 /* not zero, not 1.0 ... varispeed */
1505
1506                 if ((synced_to_engine()) && speed != 0.0 && speed != 1.0) {
1507                         warning << string_compose (
1508                                 _("Global varispeed cannot be supported while %1 is connected to JACK transport control"),
1509                                 PROGRAM_NAME)
1510                                 << endmsg;
1511                         return;
1512                 }
1513
1514                 if (actively_recording()) {
1515                         return;
1516                 }
1517
1518                 if (speed > 0.0 && _transport_frame == current_end_frame()) {
1519                         return;
1520                 }
1521
1522                 if (speed < 0.0 && _transport_frame == 0) {
1523                         return;
1524                 }
1525
1526                 clear_clicks ();
1527
1528                 /* if we are reversing relative to the current speed, or relative to the speed
1529                    before the last stop, then we have to do extra work.
1530                 */
1531
1532                 PostTransportWork todo = PostTransportWork (0);
1533
1534                 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0 && speed < 0.0)) {
1535                         todo = PostTransportWork (todo | PostTransportReverse);
1536                         _last_roll_or_reversal_location = _transport_frame;
1537                 }
1538
1539                 _last_transport_speed = _transport_speed;
1540                 _transport_speed = speed;
1541
1542                 if (as_default) {
1543                         _default_transport_speed = speed;
1544                 }
1545
1546                 boost::shared_ptr<RouteList> rl = routes.reader();
1547                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1548                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1549                         if (tr && tr->realtime_speed_change()) {
1550                                 todo = PostTransportWork (todo | PostTransportSpeed);
1551                         }
1552                 }
1553
1554                 if (todo) {
1555                         add_post_transport_work (todo);
1556                         _butler->schedule_transport_work ();
1557                 }
1558
1559                 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC3 with speed = %1\n", _transport_speed));
1560
1561                 /* throttle signal emissions.
1562                  * when slaved [_last]_transport_speed
1563                  * usually changes every cycle (tiny amounts due to DLL).
1564                  * Emitting a signal every cycle is overkill and unwarranted.
1565                  *
1566                  * Using _last_transport_speed is not acceptable,
1567                  * since it allows for large changes over a long period
1568                  * of time. Hence we introduce a dedicated variable to keep track
1569                  *
1570                  * The 0.2% dead-zone is somewhat arbitrary. Main use-case
1571                  * for TransportStateChange() here is the ShuttleControl display.
1572                  */
1573                 if (fabs (_signalled_varispeed - speed) > .002
1574                     // still, signal hard changes to 1.0 and 0.0:
1575                     || ( speed == 1.0 && _signalled_varispeed != 1.0)
1576                     || ( speed == 0.0 && _signalled_varispeed != 0.0)
1577                    )
1578                 {
1579                         TransportStateChange (); /* EMIT SIGNAL */
1580                         _signalled_varispeed = speed;
1581                 }
1582         }
1583 }
1584
1585
1586 /** Stop the transport.  */
1587 void
1588 Session::stop_transport (bool abort, bool clear_state)
1589 {
1590         _count_in_once = false;
1591         if (_transport_speed == 0.0f) {
1592                 return;
1593         }
1594
1595         DEBUG_TRACE (DEBUG::Transport, string_compose ("stop_transport, declick required? %1\n", get_transport_declick_required()));
1596
1597         if (!get_transport_declick_required()) {
1598
1599                 /* stop has not yet been scheduled */
1600
1601                 boost::shared_ptr<RouteList> rl = routes.reader();
1602                 framepos_t stop_target = audible_frame();
1603
1604                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1605                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1606                         if (tr) {
1607                                 tr->prepare_to_stop (_transport_frame, stop_target);
1608                         }
1609                 }
1610
1611                 SubState new_bits;
1612
1613                 if (actively_recording() &&                           /* we are recording */
1614                     worst_input_latency() > current_block_size) {     /* input latency exceeds block size, so simple 1 cycle delay before stop is not enough */
1615
1616                         /* we need to capture the audio that is still somewhere in the pipeline between
1617                            wherever it was generated and the process callback. This means that even though
1618                            the user (or something else)  has asked us to stop, we have to roll
1619                            past this point and then reset the playhead/transport location to
1620                            the position at which the stop was requested.
1621
1622                            we still need playback to "stop" now, however, which is why we schedule
1623                            a declick below.
1624                         */
1625
1626                         DEBUG_TRACE (DEBUG::Transport, string_compose ("stop transport requested @ %1, scheduled for + %2 = %3, abort = %4\n",
1627                                                                        _transport_frame, _worst_input_latency,
1628                                                                        _transport_frame + _worst_input_latency,
1629                                                                        abort));
1630
1631                         SessionEvent *ev = new SessionEvent (SessionEvent::StopOnce, SessionEvent::Replace,
1632                                                              _transport_frame + _worst_input_latency,
1633                                                              0, 0, abort);
1634
1635                         merge_event (ev);
1636
1637                         /* request a declick at the start of the next process cycle() so that playback ceases.
1638                            It will remain silent until we actually stop (at the StopOnce event somewhere in
1639                            the future). The extra flag (StopPendingCapture) is set to ensure that check_declick_out()
1640                            does not stop the transport too early.
1641                          */
1642                         new_bits = SubState (PendingDeclickOut|StopPendingCapture);
1643
1644                 } else {
1645
1646                         /* Not recording, schedule a declick in the next process() cycle and then stop at its end */
1647
1648                         new_bits = PendingDeclickOut;
1649                         DEBUG_TRACE (DEBUG::Transport, string_compose ("stop scheduled for next process cycle @ %1\n", _transport_frame));
1650                 }
1651
1652                 /* we'll be called again after the declick */
1653                 transport_sub_state = SubState (transport_sub_state|new_bits);
1654                 pending_abort = abort;
1655
1656                 return;
1657
1658         } else {
1659
1660                 DEBUG_TRACE (DEBUG::Transport, "time to actually stop\n");
1661
1662                 /* declick was scheduled, but we've been called again, which means it is really time to stop
1663
1664                    XXX: we should probably split this off into its own method and call it explicitly.
1665                 */
1666
1667                 realtime_stop (abort, clear_state);
1668                 _butler->schedule_transport_work ();
1669         }
1670 }
1671
1672 /** Called from the process thread */
1673 void
1674 Session::start_transport ()
1675 {
1676         DEBUG_TRACE (DEBUG::Transport, "start_transport\n");
1677
1678         _last_roll_location = _transport_frame;
1679         _last_roll_or_reversal_location = _transport_frame;
1680
1681         have_looped = false;
1682
1683         /* if record status is Enabled, move it to Recording. if its
1684            already Recording, move it to Disabled.
1685         */
1686
1687         switch (record_status()) {
1688         case Enabled:
1689                 if (!config.get_punch_in() && !preroll_record_punch_enabled()) {
1690                         enable_record ();
1691                 }
1692                 break;
1693
1694         case Recording:
1695                 if (!play_loop) {
1696                         disable_record (false);
1697                 }
1698                 break;
1699
1700         default:
1701                 break;
1702         }
1703
1704         transport_sub_state |= PendingDeclickIn;
1705
1706         _transport_speed = _default_transport_speed;
1707         _target_transport_speed = _transport_speed;
1708
1709         boost::shared_ptr<RouteList> rl = routes.reader();
1710         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1711                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1712                 if (tr) {
1713                         tr->realtime_speed_change ();
1714                 }
1715         }
1716
1717         if (!_engine.freewheeling()) {
1718                 Timecode::Time time;
1719                 timecode_time_subframes (_transport_frame, time);
1720                 if (!dynamic_cast<MTC_Slave*>(_slave)) {
1721                         send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
1722                 }
1723
1724                 if (actively_recording() && click_data && (config.get_count_in () || _count_in_once)) {
1725                         _count_in_once = false;
1726                         /* calculate count-in duration (in audio samples)
1727                          * - use [fixed] tempo/meter at _transport_frame
1728                          * - calc duration of 1 bar + time-to-beat before or at transport_frame
1729                          */
1730                         const Tempo& tempo = _tempo_map->tempo_at_frame (_transport_frame);
1731                         const Meter& meter = _tempo_map->meter_at_frame (_transport_frame);
1732
1733                         const double num = meter.divisions_per_bar ();
1734                         const double den = meter.note_divisor ();
1735                         const double barbeat = _tempo_map->exact_qn_at_frame (_transport_frame, 0) * den / (4. * num);
1736                         const double bar_fract = fmod (barbeat, 1.0); // fraction of bar elapsed.
1737
1738                         _count_in_samples = meter.frames_per_bar (tempo, _current_frame_rate);
1739
1740                         double dt = _count_in_samples / num;
1741                         if (bar_fract == 0) {
1742                                 /* at bar boundary, count-in 2 bars before start. */
1743                                 _count_in_samples *= 2;
1744                         } else {
1745                                 /* beats left after full bar until roll position */
1746                                 _count_in_samples *= 1. + bar_fract;
1747                         }
1748
1749                         int clickbeat = 0;
1750                         framepos_t cf = _transport_frame - _count_in_samples;
1751                         while (cf < _transport_frame) {
1752                                 add_click (cf - _worst_track_latency, clickbeat == 0);
1753                                 cf += dt;
1754                                 clickbeat = fmod (clickbeat + 1, num);
1755                         }
1756                 }
1757         }
1758
1759         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC4 with speed = %1\n", _transport_speed));
1760         TransportStateChange (); /* EMIT SIGNAL */
1761 }
1762
1763 /** Do any transport work in the audio thread that needs to be done after the
1764  * transport thread is finished.  Audio thread, realtime safe.
1765  */
1766 void
1767 Session::post_transport ()
1768 {
1769         PostTransportWork ptw = post_transport_work ();
1770
1771         if (ptw & PostTransportAudition) {
1772                 if (auditioner && auditioner->auditioning()) {
1773                         process_function = &Session::process_audition;
1774                 } else {
1775                         process_function = &Session::process_with_events;
1776                 }
1777         }
1778
1779         if (ptw & PostTransportStop) {
1780
1781                 transport_sub_state = 0;
1782         }
1783
1784         if (ptw & PostTransportLocate) {
1785
1786                 if (((!config.get_external_sync() && (auto_play_legal && config.get_auto_play())) && !_exporting) || (ptw & PostTransportRoll)) {
1787                         _count_in_once = false;
1788                         start_transport ();
1789                 } else {
1790                         transport_sub_state = 0;
1791                 }
1792         }
1793
1794         set_next_event ();
1795         /* XXX is this really safe? shouldn't we just be unsetting the bits that we actually
1796            know were handled ?
1797         */
1798         set_post_transport_work (PostTransportWork (0));
1799 }
1800
1801 void
1802 Session::reset_rf_scale (framecnt_t motion)
1803 {
1804         cumulative_rf_motion += motion;
1805
1806         if (cumulative_rf_motion < 4 * _current_frame_rate) {
1807                 rf_scale = 1;
1808         } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1809                 rf_scale = 4;
1810         } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1811                 rf_scale = 10;
1812         } else {
1813                 rf_scale = 100;
1814         }
1815
1816         if (motion != 0) {
1817                 set_dirty();
1818         }
1819 }
1820
1821 void
1822 Session::mtc_status_changed (bool yn)
1823 {
1824         g_atomic_int_set (&_mtc_active, yn);
1825         MTCSyncStateChanged( yn );
1826 }
1827
1828 void
1829 Session::ltc_status_changed (bool yn)
1830 {
1831         g_atomic_int_set (&_ltc_active, yn);
1832         LTCSyncStateChanged( yn );
1833 }
1834
1835 void
1836 Session::use_sync_source (Slave* new_slave)
1837 {
1838         /* Runs in process() context */
1839
1840         bool non_rt_required = false;
1841
1842         /* XXX this deletion is problematic because we're in RT context */
1843
1844         delete _slave;
1845         _slave = new_slave;
1846
1847
1848         /* slave change, reset any DiskIO block on disk output because it is no
1849            longer valid with a new slave.
1850         */
1851         DiskReader::set_no_disk_output (false);
1852
1853         MTC_Slave* mtc_slave = dynamic_cast<MTC_Slave*>(_slave);
1854         if (mtc_slave) {
1855                 mtc_slave->ActiveChanged.connect_same_thread (mtc_status_connection, boost::bind (&Session::mtc_status_changed, this, _1));
1856                 MTCSyncStateChanged(mtc_slave->locked() );
1857         } else {
1858                 if (g_atomic_int_get (&_mtc_active) ){
1859                         g_atomic_int_set (&_mtc_active, 0);
1860                         MTCSyncStateChanged( false );
1861                 }
1862                 mtc_status_connection.disconnect ();
1863         }
1864
1865         LTC_Slave* ltc_slave = dynamic_cast<LTC_Slave*> (_slave);
1866         if (ltc_slave) {
1867                 ltc_slave->ActiveChanged.connect_same_thread (ltc_status_connection, boost::bind (&Session::ltc_status_changed, this, _1));
1868                 LTCSyncStateChanged (ltc_slave->locked() );
1869         } else {
1870                 if (g_atomic_int_get (&_ltc_active) ){
1871                         g_atomic_int_set (&_ltc_active, 0);
1872                         LTCSyncStateChanged( false );
1873                 }
1874                 ltc_status_connection.disconnect ();
1875         }
1876
1877         DEBUG_TRACE (DEBUG::Slave, string_compose ("set new slave to %1\n", _slave));
1878
1879         // need to queue this for next process() cycle
1880         _send_timecode_update = true;
1881
1882         boost::shared_ptr<RouteList> rl = routes.reader();
1883         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1884                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1885                 if (tr && !tr->is_private_route()) {
1886                         if (tr->realtime_speed_change()) {
1887                                 non_rt_required = true;
1888                         }
1889                         tr->set_slaved (_slave != 0);
1890                 }
1891         }
1892
1893         if (non_rt_required) {
1894                 add_post_transport_work (PostTransportSpeed);
1895                 _butler->schedule_transport_work ();
1896         }
1897
1898         set_dirty();
1899 }
1900
1901 void
1902 Session::drop_sync_source ()
1903 {
1904         request_sync_source (0);
1905 }
1906
1907 void
1908 Session::switch_to_sync_source (SyncSource src)
1909 {
1910         Slave* new_slave;
1911
1912         DEBUG_TRACE (DEBUG::Slave, string_compose ("Setting up sync source %1\n", enum_2_string (src)));
1913
1914         switch (src) {
1915         case MTC:
1916                 if (_slave && dynamic_cast<MTC_Slave*>(_slave)) {
1917                         return;
1918                 }
1919
1920                 try {
1921                         new_slave = new MTC_Slave (*this, *_midi_ports->mtc_input_port());
1922                 }
1923
1924                 catch (failed_constructor& err) {
1925                         return;
1926                 }
1927                 break;
1928
1929         case LTC:
1930                 if (_slave && dynamic_cast<LTC_Slave*>(_slave)) {
1931                         return;
1932                 }
1933
1934                 try {
1935                         new_slave = new LTC_Slave (*this);
1936                 }
1937
1938                 catch (failed_constructor& err) {
1939                         return;
1940                 }
1941
1942                 break;
1943
1944         case MIDIClock:
1945                 if (_slave && dynamic_cast<MIDIClock_Slave*>(_slave)) {
1946                         return;
1947                 }
1948
1949                 try {
1950                         new_slave = new MIDIClock_Slave (*this, *_midi_ports->midi_clock_input_port(), 24);
1951                 }
1952
1953                 catch (failed_constructor& err) {
1954                         return;
1955                 }
1956                 break;
1957
1958         case Engine:
1959                 if (_slave && dynamic_cast<Engine_Slave*>(_slave)) {
1960                         return;
1961                 }
1962
1963                 if (config.get_video_pullup() != 0.0f) {
1964                         return;
1965                 }
1966
1967                 new_slave = new Engine_Slave (*AudioEngine::instance());
1968                 break;
1969
1970         default:
1971                 new_slave = 0;
1972                 break;
1973         };
1974
1975         request_sync_source (new_slave);
1976 }
1977
1978 void
1979 Session::unset_play_range ()
1980 {
1981         _play_range = false;
1982         _clear_event_type (SessionEvent::RangeStop);
1983         _clear_event_type (SessionEvent::RangeLocate);
1984 }
1985
1986 void
1987 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1988 {
1989         SessionEvent* ev;
1990
1991         /* Called from event-processing context */
1992
1993         unset_play_range ();
1994
1995         if (range.empty()) {
1996                 /* _play_range set to false in unset_play_range()
1997                  */
1998                 if (!leave_rolling) {
1999                         /* stop transport */
2000                         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false);
2001                         merge_event (ev);
2002                 }
2003                 return;
2004         }
2005
2006         _play_range = true;
2007
2008         /* cancel loop play */
2009         unset_play_loop ();
2010
2011         list<AudioRange>::size_type sz = range.size();
2012
2013         if (sz > 1) {
2014
2015                 list<AudioRange>::iterator i = range.begin();
2016                 list<AudioRange>::iterator next;
2017
2018                 while (i != range.end()) {
2019
2020                         next = i;
2021                         ++next;
2022
2023                         /* locating/stopping is subject to delays for declicking.
2024                          */
2025
2026                         framepos_t requested_frame = i->end;
2027
2028                         if (requested_frame > current_block_size) {
2029                                 requested_frame -= current_block_size;
2030                         } else {
2031                                 requested_frame = 0;
2032                         }
2033
2034                         if (next == range.end()) {
2035                                 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_frame, 0, 0.0f);
2036                         } else {
2037                                 ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_frame, (*next).start, 0.0f);
2038                         }
2039
2040                         merge_event (ev);
2041
2042                         i = next;
2043                 }
2044
2045         } else if (sz == 1) {
2046
2047                 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
2048                 merge_event (ev);
2049
2050         }
2051
2052         /* save range so we can do auto-return etc. */
2053
2054         current_audio_range = range;
2055
2056         /* now start rolling at the right place */
2057
2058         ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
2059         merge_event (ev);
2060
2061         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC5 with speed = %1\n", _transport_speed));
2062         TransportStateChange ();
2063 }
2064
2065 void
2066 Session::request_bounded_roll (framepos_t start, framepos_t end)
2067 {
2068         AudioRange ar (start, end, 0);
2069         list<AudioRange> lar;
2070
2071         lar.push_back (ar);
2072         request_play_range (&lar, true);
2073 }
2074
2075 void
2076 Session::set_requested_return_frame (framepos_t return_to)
2077 {
2078         _requested_return_frame = return_to;
2079 }
2080
2081 void
2082 Session::request_roll_at_and_return (framepos_t start, framepos_t return_to)
2083 {
2084         SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
2085         ev->target2_frame = start;
2086         queue_event (ev);
2087 }
2088
2089 void
2090 Session::engine_halted ()
2091 {
2092         bool ignored;
2093
2094         /* there will be no more calls to process(), so
2095            we'd better clean up for ourselves, right now.
2096
2097            but first, make sure the butler is out of
2098            the picture.
2099         */
2100
2101         if (_butler) {
2102                 _butler->stop ();
2103         }
2104
2105         realtime_stop (false, true);
2106         non_realtime_stop (false, 0, ignored);
2107         transport_sub_state = 0;
2108
2109         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC6 with speed = %1\n", _transport_speed));
2110         TransportStateChange (); /* EMIT SIGNAL */
2111 }
2112
2113
2114 void
2115 Session::xrun_recovery ()
2116 {
2117         ++_xrun_count;
2118
2119         Xrun (_transport_frame); /* EMIT SIGNAL */
2120
2121         if (Config->get_stop_recording_on_xrun() && actively_recording()) {
2122
2123                 /* it didn't actually halt, but we need
2124                    to handle things in the same way.
2125                 */
2126
2127                 engine_halted();
2128         }
2129 }
2130
2131 void
2132 Session::route_processors_changed (RouteProcessorChange c)
2133 {
2134         if (g_atomic_int_get (&_ignore_route_processor_changes) > 0) {
2135                 return;
2136         }
2137
2138         if (c.type == RouteProcessorChange::MeterPointChange) {
2139                 set_dirty ();
2140                 return;
2141         }
2142
2143         if (c.type == RouteProcessorChange::RealTimeChange) {
2144                 set_dirty ();
2145                 return;
2146         }
2147
2148         update_latency_compensation ();
2149         resort_routes ();
2150
2151         set_dirty ();
2152 }
2153
2154 void
2155 Session::allow_auto_play (bool yn)
2156 {
2157         auto_play_legal = yn;
2158 }
2159
2160 bool
2161 Session::maybe_stop (framepos_t limit)
2162 {
2163         if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
2164                 if (synced_to_engine () && config.get_jack_time_master ()) {
2165                         _engine.transport_stop ();
2166                 } else if (!synced_to_engine ()) {
2167                         stop_transport ();
2168                 }
2169                 return true;
2170         }
2171         return false;
2172 }
2173
2174 void
2175 Session::send_mmc_locate (framepos_t t)
2176 {
2177         if (t < 0) {
2178                 return;
2179         }
2180
2181         if (!_engine.freewheeling()) {
2182                 Timecode::Time time;
2183                 timecode_time_subframes (t, time);
2184                 send_immediate_mmc (MIDI::MachineControlCommand (time));
2185         }
2186 }
2187
2188 /** Ask the transport to not send timecode until further notice.  The suspension
2189  *  will come into effect some finite time after this call, and timecode_transmission_suspended()
2190  *  should be checked by the caller to find out when.
2191  */
2192 void
2193 Session::request_suspend_timecode_transmission ()
2194 {
2195         SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, false);
2196         queue_event (ev);
2197 }
2198
2199 void
2200 Session::request_resume_timecode_transmission ()
2201 {
2202         SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, true);
2203         queue_event (ev);
2204 }
2205
2206 bool
2207 Session::timecode_transmission_suspended () const
2208 {
2209         return g_atomic_int_get (&_suspend_timecode_transmission) == 1;
2210 }