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