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