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