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