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