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