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