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