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