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