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