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