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