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