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