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