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