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