remove Glib::ustring from libardour; allow any characters except '/' and '\' in paths...
[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 #include <cmath>
21 #include <cerrno>
22 #include <unistd.h>
23
24
25 #include "pbd/undo.h"
26 #include "pbd/error.h"
27 #include "pbd/enumwriter.h"
28 #include "pbd/pthread_utils.h"
29 #include "pbd/memento_command.h"
30
31 #include "midi++/mmc.h"
32 #include "midi++/port.h"
33 #include "midi++/manager.h"
34
35 #include "ardour/ardour.h"
36 #include "ardour/audioengine.h"
37 #include "ardour/auditioner.h"
38 #include "ardour/butler.h"
39 #include "ardour/debug.h"
40 #include "ardour/location.h"
41 #include "ardour/session.h"
42 #include "ardour/slave.h"
43
44 #include "i18n.h"
45
46 using namespace std;
47 using namespace ARDOUR;
48 using namespace PBD;
49
50 void
51 Session::add_post_transport_work (PostTransportWork ptw)
52 {
53         PostTransportWork oldval;
54         PostTransportWork newval;
55         int tries = 0;
56
57         while (tries < 8) {
58                 oldval = (PostTransportWork) g_atomic_int_get (&_post_transport_work);
59                 newval = PostTransportWork (oldval | ptw);
60                 if (g_atomic_int_compare_and_exchange (&_post_transport_work, oldval, newval)) {
61                         /* success */
62                         return;
63                 }
64         }
65
66         error << "Could not set post transport work! Crazy thread madness, call the programmers" << endmsg;
67 }
68
69 void
70 Session::request_input_change_handling ()
71 {
72         if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
73                 SessionEvent* ev = new SessionEvent (SessionEvent::InputConfigurationChange, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
74                 queue_event (ev);
75         }
76 }
77
78 void
79 Session::request_sync_source (Slave* new_slave)
80 {
81         SessionEvent* ev = new SessionEvent (SessionEvent::SetSyncSource, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
82         bool seamless;
83
84         seamless = Config->get_seamless_loop ();
85
86         if (dynamic_cast<JACK_Slave*>(new_slave)) {
87                 /* JACK cannot support seamless looping at present */
88                 Config->set_seamless_loop (false);
89         } else {
90                 /* reset to whatever the value was before we last switched slaves */
91                 Config->set_seamless_loop (_was_seamless);
92         }
93
94         /* save value of seamless from before the switch */
95         _was_seamless = seamless;
96
97         ev->slave = new_slave;
98         queue_event (ev);
99 }
100
101 void
102 Session::request_transport_speed (double speed)
103 {
104         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
105         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport speed = %1\n", speed));
106         queue_event (ev);
107 }
108
109 void
110 Session::request_track_speed (Track* tr, double speed)
111 {
112         SessionEvent* ev = new SessionEvent (SessionEvent::SetTrackSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
113         ev->set_ptr (tr);
114         queue_event (ev);
115 }
116
117 void
118 Session::request_stop (bool abort, bool clear_state)
119 {
120         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0, abort, clear_state);
121         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport stop, abort = %1, clear state = %2\n", abort, clear_state));
122         queue_event (ev);
123 }
124
125 void
126 Session::request_locate (nframes_t target_frame, bool with_roll)
127 {
128         SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, false);
129         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request locate to %1\n", target_frame));
130         queue_event (ev);
131 }
132
133 void
134 Session::force_locate (nframes64_t target_frame, bool with_roll)
135 {
136         SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, true);
137         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request forced locate to %1\n", target_frame));
138         queue_event (ev);
139 }
140
141 void
142 Session::request_play_loop (bool yn, bool leave_rolling)
143 {
144         SessionEvent* ev;
145         Location *location = _locations->auto_loop_location();
146
147         if (location == 0 && yn) {
148                 error << _("Cannot loop - no loop range defined")
149                       << endmsg;
150                 return;
151         }
152
153         ev = new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn);
154         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request set loop = %1, leave rolling ? %2\n", yn, leave_rolling));
155         queue_event (ev);
156
157         if (!leave_rolling && !yn && Config->get_seamless_loop() && transport_rolling()) {
158                 // request an immediate locate to refresh the tracks
159                 // after disabling looping
160                 request_locate (_transport_frame-1, false);
161         }
162 }
163
164 void
165 Session::request_play_range (list<AudioRange>* range, bool leave_rolling)
166 {
167         SessionEvent* ev = new SessionEvent (SessionEvent::SetPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0));
168         if (range) {
169                 ev->audio_range = *range;
170         } else {
171                 ev->audio_range.clear ();
172         }
173         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request play range, leave rolling ? %1\n", leave_rolling));
174         queue_event (ev);
175 }
176
177 void
178 Session::realtime_stop (bool abort, bool clear_state)
179 {
180         DEBUG_TRACE (DEBUG::Transport, "realtime stop\n");
181         PostTransportWork todo = PostTransportWork (0);
182
183         /* assume that when we start, we'll be moving forwards */
184
185         if (_transport_speed < 0.0f) {
186                 todo = (PostTransportWork (todo | PostTransportStop | PostTransportReverse));
187         } else {
188                 todo = PostTransportWork (todo | PostTransportStop);
189         }
190
191         if (actively_recording()) {
192
193                 /* move the transport position back to where the
194                    request for a stop was noticed. we rolled
195                    past that point to pick up delayed input (and/or to delick)
196                 */
197
198                 if (_worst_output_latency > current_block_size) {
199                         /* we rolled past the stop point to pick up data that had
200                            not yet arrived. move back to where the stop occured.
201                         */
202                         decrement_transport_position (current_block_size + (_worst_output_latency - current_block_size));
203                 } else {
204                         decrement_transport_position (current_block_size);
205                 }
206
207                 /* the duration change is not guaranteed to have happened, but is likely */
208
209                 todo = PostTransportWork (todo | PostTransportDuration);
210         }
211
212         if (abort) {
213                 todo = PostTransportWork (todo | PostTransportAbort);
214         }
215
216         if (clear_state) {
217                 todo = PostTransportWork (todo | PostTransportClearSubstate);
218         }
219
220         if (todo) {
221                 add_post_transport_work (todo);
222         }
223
224         _clear_event_type (SessionEvent::StopOnce);
225         _clear_event_type (SessionEvent::RangeStop);
226         _clear_event_type (SessionEvent::RangeLocate);
227
228         /* if we're going to clear loop state, then force disabling record BUT only if we're not doing latched rec-enable */
229         disable_record (true, (!Config->get_latched_record_enable() && clear_state));
230         
231         reset_slave_state ();
232
233         _transport_speed = 0;
234         _target_transport_speed = 0;
235
236         g_atomic_int_set (&_playback_load, 100);
237         g_atomic_int_set (&_capture_load, 100);
238
239         if (config.get_use_video_sync()) {
240                 waiting_for_sync_offset = true;
241         }
242
243         transport_sub_state = 0;
244 }
245
246 void
247 Session::butler_transport_work ()
248 {
249   restart:
250         bool finished;
251         PostTransportWork ptw;
252         boost::shared_ptr<RouteList> r = routes.reader ();
253
254         int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
255         finished = true;
256         ptw = post_transport_work();
257
258         DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler transport work, todo = %1\n", enum_2_string (ptw)));
259
260         if (ptw & PostTransportAdjustPlaybackBuffering) {
261                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
262                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
263                         if (tr) {
264                                 tr->adjust_playback_buffering ();
265                                 /* and refill those buffers ... */
266                                 tr->non_realtime_locate (_transport_frame);
267                         }
268                 }
269                 
270         }
271
272         if (ptw & PostTransportAdjustCaptureBuffering) {
273                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
274                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
275                         if (tr) {
276                                 tr->adjust_capture_buffering ();
277                         }
278                 }
279         }
280
281         if (ptw & PostTransportCurveRealloc) {
282                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
283                         (*i)->curve_reallocate();
284                 }
285         }
286
287         if (ptw & PostTransportInputChange) {
288                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
289                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
290                         if (tr) {
291                                 tr->non_realtime_input_change ();
292                         }
293                 }
294         }
295
296         if (ptw & PostTransportSpeed) {
297                 non_realtime_set_speed ();
298         }
299
300         if (ptw & PostTransportReverse) {
301
302                 clear_clicks();
303                 cumulative_rf_motion = 0;
304                 reset_rf_scale (0);
305
306                 /* don't seek if locate will take care of that in non_realtime_stop() */
307
308                 if (!(ptw & PostTransportLocate)) {
309
310                         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
311                                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
312                                 if (tr && !tr->hidden()) {
313                                         tr->non_realtime_locate (_transport_frame);
314                                 }
315                                 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
316                                         /* new request, stop seeking, and start again */
317                                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
318                                         goto restart;
319                                 }
320                         }
321                 }
322         }
323
324         if (ptw & PostTransportLocate) {
325                 non_realtime_locate ();
326         }
327
328         if (ptw & PostTransportStop) {
329                 non_realtime_stop (ptw & PostTransportAbort, on_entry, finished);
330                 if (!finished) {
331                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
332                         goto restart;
333                 }
334         }
335
336         if (ptw & PostTransportOverWrite) {
337                 non_realtime_overwrite (on_entry, finished);
338                 if (!finished) {
339                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
340                         goto restart;
341                 }
342         }
343
344         if (ptw & PostTransportAudition) {
345                 non_realtime_set_audition ();
346         }
347
348         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
349
350         DEBUG_TRACE (DEBUG::Transport, X_("Butler transport work all done\n"));
351 }
352
353 void
354 Session::non_realtime_set_speed ()
355 {
356         boost::shared_ptr<RouteList> rl = routes.reader();
357         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
358                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
359                 if (tr) {
360                         tr->non_realtime_set_speed ();
361                 }
362         }
363 }
364
365 void
366 Session::non_realtime_overwrite (int on_entry, bool& finished)
367 {
368         boost::shared_ptr<RouteList> rl = routes.reader();
369         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
370                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
371                 if (tr && tr->pending_overwrite ()) {
372                         tr->overwrite_existing_buffers ();
373                 }
374                 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
375                         finished = false;
376                         return;
377                 }
378         }
379 }
380
381
382 void
383 Session::non_realtime_locate ()
384 {
385         boost::shared_ptr<RouteList> rl = routes.reader();
386         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
387                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
388                 if (tr) {
389                         tr->non_realtime_locate (_transport_frame);
390                 }
391         }
392 }
393
394
395 void
396 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
397 {
398         struct tm* now;
399         time_t     xnow;
400         bool       did_record;
401         bool       saved;
402         PostTransportWork ptw = post_transport_work();
403
404         did_record = false;
405         saved = false;
406
407         boost::shared_ptr<RouteList> rl = routes.reader();
408         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
409                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
410                 if (tr && tr->get_captured_frames () != 0) {
411                         did_record = true;
412                         break;
413                 }
414         }
415
416         /* stop and locate are merged here because they share a lot of common stuff */
417
418         time (&xnow);
419         now = localtime (&xnow);
420
421         if (auditioner) {
422                 auditioner->cancel_audition ();
423         }
424
425         clear_clicks();
426         cumulative_rf_motion = 0;
427         reset_rf_scale (0);
428
429         if (did_record) {
430                 begin_reversible_command ("capture");
431                 _have_captured = true;
432         }
433
434         DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: DS stop\n"));
435
436         if (abort && did_record) {
437                 /* no reason to save the session file when we remove sources
438                  */
439                 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
440         }
441
442         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
443                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
444                 if (tr) {
445                         tr->transport_stopped_wallclock (*now, xnow, abort);
446                 }
447         }
448
449         if (abort && did_record) {
450                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);                
451         }
452
453         boost::shared_ptr<RouteList> r = routes.reader ();
454
455         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
456                 if (!(*i)->is_hidden()) {
457                         (*i)->set_pending_declick (0);
458                 }
459         }
460
461         if (did_record) {
462                 commit_reversible_command ();
463         }
464
465         if (_engine.running()) {
466                 update_latency_compensation (true, abort);
467         }
468
469         bool const auto_return_enabled =
470                 (!config.get_external_sync() && config.get_auto_return());
471
472         if (auto_return_enabled ||
473             (ptw & PostTransportLocate) ||
474             (_requested_return_frame >= 0) ||
475             synced_to_jack()) {
476
477                 if (pending_locate_flush) {
478                         flush_all_inserts ();
479                 }
480
481                 if ((auto_return_enabled || synced_to_jack() || _requested_return_frame >= 0) &&
482                     !(ptw & PostTransportLocate)) {
483
484                         /* no explicit locate queued */
485
486                         bool do_locate = false;
487
488                         if (_requested_return_frame >= 0) {
489
490                                 /* explicit return request pre-queued in event list. overrides everything else */
491                                 
492                                 cerr << "explicit auto-return to " << _requested_return_frame << endl;
493
494                                 _transport_frame = _requested_return_frame;
495                                 do_locate = true;
496
497                         } else {
498                                 if (config.get_auto_return()) {
499
500                                         if (play_loop) {
501
502                                                 /* don't try to handle loop play when synced to JACK */
503
504                                                 if (!synced_to_jack()) {
505
506                                                         Location *location = _locations->auto_loop_location();
507                                                         
508                                                         if (location != 0) {
509                                                                 _transport_frame = location->start();
510                                                         } else {
511                                                                 _transport_frame = _last_roll_location;
512                                                         }
513                                                         do_locate = true;
514                                                 }
515
516                                         } else if (_play_range) {
517
518                                                 /* return to start of range */
519
520                                                 if (!current_audio_range.empty()) {
521                                                         _transport_frame = current_audio_range.front().start;
522                                                         do_locate = true;
523                                                 }
524
525                                         } else {
526                                                 
527                                                 /* regular auto-return */
528                                                 
529                                                 _transport_frame = _last_roll_location;
530                                                 do_locate = true;
531                                         }
532                                 } 
533                         }
534
535                         _requested_return_frame = -1;                   
536
537                         if (do_locate) {
538                                 _engine.transport_locate (_transport_frame);
539                         }
540                 } 
541
542         }
543
544         /* do this before seeking, because otherwise the tracks will do the wrong thing in seamless loop mode.
545         */
546
547         if (ptw & PostTransportClearSubstate) {
548                 _play_range = false;
549                 unset_play_loop ();
550         }
551
552         /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
553
554         DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: locate\n"));
555         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
556                 DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler PTW: locate on %1\n", (*i)->name()));
557                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
558                 if (tr && !tr->hidden()) {
559                         tr->non_realtime_locate (_transport_frame);
560                 }
561
562                 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
563                         finished = false;
564                         /* we will be back */
565                         return;
566                 }
567         }
568
569         have_looped = false;
570
571         send_full_time_code (_transport_frame);
572         MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
573         send_mmc_locate (_transport_frame);
574
575         if ((ptw & PostTransportLocate) && get_record_enabled()) {
576                 /* capture start has been changed, so save pending state */
577                 save_state ("", true);
578                 saved = true;
579         }
580
581         /* always try to get rid of this */
582
583         remove_pending_capture_state ();
584
585         /* save the current state of things if appropriate */
586
587         if (did_record && !saved) {
588                 save_state (_current_snapshot_name);
589         }
590
591         if (ptw & PostTransportStop) {
592                 _play_range = false;
593                 play_loop = false;
594         }
595
596         // can't cast away volatile so copy and emit that
597         nframes64_t tframe = _transport_frame;
598         PositionChanged (tframe); /* EMIT SIGNAL */
599         TransportStateChange (); /* EMIT SIGNAL */
600
601         /* and start it up again if relevant */
602
603         if ((ptw & PostTransportLocate) && !config.get_external_sync() && pending_locate_roll) {
604                 request_transport_speed (1.0);
605                 pending_locate_roll = false;
606         }
607 }
608
609 void
610 Session::check_declick_out ()
611 {
612         bool locate_required = transport_sub_state & PendingLocate;
613
614         /* this is called after a process() iteration. if PendingDeclickOut was set,
615            it means that we were waiting to declick the output (which has just been
616            done) before doing something else. this is where we do that "something else".
617
618            note: called from the audio thread.
619         */
620
621         if (transport_sub_state & PendingDeclickOut) {
622
623                 if (locate_required) {
624                         start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
625                         transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
626                 } else {
627                         stop_transport (pending_abort);
628                         transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
629                 }
630         }
631 }
632
633 void
634 Session::unset_play_loop ()
635 {
636         play_loop = false;
637         clear_events (SessionEvent::AutoLoop);
638         
639         // set all tracks to NOT use internal looping
640         boost::shared_ptr<RouteList> rl = routes.reader ();
641         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
642                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
643                 if (tr && !tr->hidden()) {
644                         tr->set_loop (0);
645                 }
646         }
647 }
648
649 void
650 Session::set_play_loop (bool yn)
651 {
652         /* Called from event-handling context */
653
654         Location *loc;
655
656         if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) {
657                 /* nothing to do, or can't change loop status while recording */
658                 return;
659         }
660         
661         if (yn && Config->get_seamless_loop() && synced_to_jack()) {
662                 warning << string_compose (_("Seamless looping cannot be supported while %1 is using JACK transport.\n"
663                                              "Recommend changing the configured options"), PROGRAM_NAME)
664                         << endmsg;
665                 return;
666         }
667         
668         if (yn) {
669
670                 play_loop = true;
671
672                 if (loc) {
673
674                         unset_play_range ();
675
676                         if (Config->get_seamless_loop()) {
677                                 // set all tracks to use internal looping
678                                 boost::shared_ptr<RouteList> rl = routes.reader ();
679                                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
680                                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
681                                         if (tr && !tr->hidden()) {
682                                                 tr->set_loop (loc);
683                                         }
684                                 }
685                         }
686                         else {
687                                 // set all tracks to NOT use internal looping
688                                 boost::shared_ptr<RouteList> rl = routes.reader ();
689                                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
690                                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
691                                         if (tr && !tr->hidden()) {
692                                                 tr->set_loop (0);
693                                         }
694                                 }
695                         }
696                         
697                         /* put the loop event into the event list */
698                         
699                         SessionEvent* event = new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f);
700                         merge_event (event);
701
702                         /* locate to start of loop and roll. If doing seamless loop, force a 
703                            locate+buffer refill even if we are positioned there already.
704                         */
705
706                         start_locate (loc->start(), true, true, false, Config->get_seamless_loop());
707                 }
708
709         } else {
710
711                 unset_play_loop ();
712         }
713
714         TransportStateChange ();
715 }
716 void
717 Session::flush_all_inserts ()
718 {
719         boost::shared_ptr<RouteList> r = routes.reader ();
720
721         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
722                 (*i)->flush_processors ();
723         }
724 }
725
726 void
727 Session::start_locate (nframes64_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
728 {
729         if (synced_to_jack()) {
730
731                 double sp;
732                 nframes64_t pos;
733
734                 _slave->speed_and_position (sp, pos);
735
736                 if (target_frame != pos) {
737
738                         /* tell JACK to change transport position, and we will
739                            follow along later in ::follow_slave()
740                         */
741
742                         _engine.transport_locate (target_frame);
743
744                         if (sp != 1.0f && with_roll) {
745                                 _engine.transport_start ();
746                         }
747
748                 }
749
750         } else {
751                 locate (target_frame, with_roll, with_flush, with_loop, force);
752         }
753 }
754
755 int
756 Session::micro_locate (nframes_t distance)
757 {
758         boost::shared_ptr<RouteList> rl = routes.reader();
759         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
760                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
761                 if (tr && !tr->can_internal_playback_seek (distance)) {
762                         return -1;
763                 }
764         }
765
766         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
767                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
768                 if (tr) {
769                         tr->internal_playback_seek (distance);
770                 }
771         }
772
773         _transport_frame += distance;
774         return 0;
775 }
776
777 /** @param with_mmc true to send a MMC locate command when the locate is done */
778 void
779 Session::locate (nframes64_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force, bool with_mmc)
780 {
781         if (actively_recording() && !with_loop) {
782                 return;
783         }
784
785         if (!force && _transport_frame == target_frame && !loop_changing && !with_loop) {
786                 if (with_roll) {
787                         set_transport_speed (1.0, false);
788                 }
789                 loop_changing = false;
790                 Located (); /* EMIT SIGNAL */
791                 return;
792         }
793
794         // Update Timecode time
795         // [DR] FIXME: find out exactly where this should go below
796         _transport_frame = target_frame;
797         timecode_time(_transport_frame, transmitting_timecode_time);
798         outbound_mtc_timecode_frame = _transport_frame;
799         next_quarter_frame_to_send = 0;
800
801         if (_transport_speed && (!with_loop || loop_changing)) {
802                 /* schedule a declick. we'll be called again when its done */
803
804                 if (!(transport_sub_state & PendingDeclickOut)) {
805                         transport_sub_state |= (PendingDeclickOut|PendingLocate);
806                         pending_locate_frame = target_frame;
807                         pending_locate_roll = with_roll;
808                         pending_locate_flush = with_flush;
809                         return;
810                 }
811         }
812
813         if (transport_rolling() && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
814                 realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
815         }
816
817         if (force || !with_loop || loop_changing) {
818
819                 PostTransportWork todo = PostTransportLocate;
820
821                 if (with_roll) {
822                         todo = PostTransportWork (todo | PostTransportRoll);
823                 } 
824
825                 add_post_transport_work (todo);
826                 _butler->schedule_transport_work ();
827
828         } else {
829
830                 /* this is functionally what clear_clicks() does but with a tentative lock */
831
832                 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
833
834                 if (clickm.locked()) {
835
836                         for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
837                                 delete *i;
838                         }
839
840                         clicks.clear ();
841                 }
842         }
843
844         if (with_roll) {
845                 /* switch from input if we're going to roll */
846                 if (Config->get_monitoring_model() == HardwareMonitoring) {
847
848                         boost::shared_ptr<RouteList> rl = routes.reader();
849                         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
850                                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
851                                 if (tr && tr->record_enabled ()) {
852                                         //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
853                                         tr->monitor_input (!config.get_auto_input());
854                                 }
855                         }
856                 }
857         } else {
858                 /* otherwise we're going to stop, so do the opposite */
859                 if (Config->get_monitoring_model() == HardwareMonitoring) {
860
861                         boost::shared_ptr<RouteList> rl = routes.reader();
862                         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
863                                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
864                                 if (tr && tr->record_enabled ()) {
865                                         //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
866                                         tr->monitor_input (true);
867                                 }
868                         }
869                 }
870         }
871
872         /* cancel looped playback if transport pos outside of loop range */
873         if (play_loop) {
874                 Location* al = _locations->auto_loop_location();
875
876                 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
877                         // cancel looping directly, this is called from event handling context
878                         set_play_loop (false);
879                 }
880                 else if (al && _transport_frame == al->start()) {
881                         if (with_loop) {
882                                 // this is only necessary for seamless looping
883
884                                 boost::shared_ptr<RouteList> rl = routes.reader();
885                                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
886                                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
887                                         if (tr && tr->record_enabled ()) {
888                                                 // tell it we've looped, so it can deal with the record state
889                                                 tr->transport_looped(_transport_frame);
890                                         }
891                                 }
892                         }
893                         have_looped = true;
894                         TransportLooped(); // EMIT SIGNAL
895                 }
896         }
897
898         loop_changing = false;
899
900         _send_timecode_update = true;
901
902         if (with_mmc) {
903                 send_mmc_locate (_transport_frame);
904         }
905
906         Located (); /* EMIT SIGNAL */
907 }
908
909 /** Set the transport speed.
910  * @param speed New speed
911  * @param abort
912  */
913 void
914 Session::set_transport_speed (double speed, bool abort, bool clear_state)
915 {
916         DEBUG_TRACE (DEBUG::Transport, string_compose ("Set transport speed to %1, abort = %2 clear_state = %3, current = %4\n", speed, abort, clear_state, _transport_speed));
917
918         if (_transport_speed == speed) {
919                 return;
920         }
921
922         _target_transport_speed = fabs(speed);
923
924         /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
925            and user needs. We really need CD-style "skip" playback for ffwd and rewind.
926         */
927
928         if (speed > 0) {
929                 speed = min (8.0, speed);
930         } else if (speed < 0) {
931                 speed = max (-8.0, speed);
932         }
933
934         if (transport_rolling() && speed == 0.0) {
935
936                 /* we are rolling and we want to stop */
937
938                 if (Config->get_monitoring_model() == HardwareMonitoring)
939                 {
940                         boost::shared_ptr<RouteList> rl = routes.reader();
941                         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
942                                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
943                                 if (tr && tr->record_enabled ()) {
944                                         //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
945                                         tr->monitor_input (true);
946                                 }
947                         }
948                 }
949
950                 if (synced_to_jack ()) {
951                         if (clear_state) {
952                                 /* do this here because our response to the slave won't 
953                                    take care of it.
954                                 */
955                                 _play_range = false;
956                                 unset_play_loop ();
957                         }
958                         _engine.transport_stop ();
959                 } else {
960                         stop_transport (abort);
961                 }
962
963         } else if (transport_stopped() && speed == 1.0) {
964
965                 /* we are stopped and we want to start rolling at speed 1 */
966
967                 if (Config->get_monitoring_model() == HardwareMonitoring) {
968
969                         boost::shared_ptr<RouteList> rl = routes.reader();
970                         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
971                                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
972                                 if (config.get_auto_input() && tr && tr->record_enabled ()) {
973                                         //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
974                                         tr->monitor_input (false);
975                                 }
976                         }
977                 }
978
979                 if (synced_to_jack()) {
980                         _engine.transport_start ();
981                 } else {
982                         start_transport ();
983                 }
984
985         } else {
986
987                 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
988                         warning << string_compose (_("Global varispeed cannot be supported while %1 is connected to JACK transport control"),
989                                                    PROGRAM_NAME)
990                                 << endmsg;
991                         return;
992                 }
993
994                 if (actively_recording()) {
995                         return;
996                 }
997
998                 if (speed > 0.0 && _transport_frame == current_end_frame()) {
999                         return;
1000                 }
1001
1002                 if (speed < 0.0 && _transport_frame == 0) {
1003                         return;
1004                 }
1005
1006                 clear_clicks ();
1007
1008                 /* if we are reversing relative to the current speed, or relative to the speed
1009                    before the last stop, then we have to do extra work.
1010                 */
1011                 
1012                 PostTransportWork todo = PostTransportWork (0);
1013
1014                 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
1015                         todo = PostTransportWork (todo | PostTransportReverse);
1016                         _last_roll_or_reversal_location = _transport_frame;
1017                 }
1018
1019                 _last_transport_speed = _transport_speed;
1020                 _transport_speed = speed;
1021
1022                 boost::shared_ptr<RouteList> rl = routes.reader();
1023                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1024                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1025                         if (tr && tr->realtime_set_speed (tr->speed(), true)) {
1026                                 todo = PostTransportWork (todo | PostTransportSpeed);
1027                                 break;
1028                         }
1029                 }
1030
1031                 if (todo) {
1032                         add_post_transport_work (todo);
1033                         _butler->schedule_transport_work ();
1034                 }
1035         }
1036 }
1037
1038
1039 /** Stop the transport.  */
1040 void
1041 Session::stop_transport (bool abort, bool clear_state)
1042 {
1043         if (_transport_speed == 0.0f) {
1044                 return;
1045         }
1046
1047         if (actively_recording() && !(transport_sub_state & StopPendingCapture) && _worst_output_latency > current_block_size) {
1048
1049                 boost::shared_ptr<RouteList> rl = routes.reader();
1050                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1051                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1052                         if (tr) {
1053                                 tr->prepare_to_stop (_transport_frame);
1054                         }
1055                 }
1056
1057                 /* we need to capture the audio that has still not yet been received by the system
1058                    at the time the stop is requested, so we have to roll past that time.
1059
1060                    we want to declick before stopping, so schedule the autostop for one
1061                    block before the actual end. we'll declick in the subsequent block,
1062                    and then we'll really be stopped.
1063                 */
1064
1065                 SessionEvent *ev = new SessionEvent (SessionEvent::StopOnce, SessionEvent::Replace,
1066                                        _transport_frame + _worst_output_latency - current_block_size,
1067                                        0, 0, abort);
1068
1069                 merge_event (ev);
1070                 transport_sub_state |= StopPendingCapture;
1071                 pending_abort = abort;
1072                 return;
1073         }
1074
1075
1076         if ((transport_sub_state & PendingDeclickOut) == 0) {
1077
1078                 if (!(transport_sub_state & StopPendingCapture)) {
1079                         boost::shared_ptr<RouteList> rl = routes.reader();
1080                         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1081                                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1082                                 if (tr) {
1083                                         tr->prepare_to_stop (_transport_frame);
1084                                 }
1085                         }
1086                 }
1087                 
1088                 transport_sub_state |= PendingDeclickOut;
1089                 /* we'll be called again after the declick */
1090                 pending_abort = abort;
1091                 return;
1092         }
1093
1094         realtime_stop (abort, clear_state);
1095         _butler->schedule_transport_work ();
1096 }
1097
1098 void
1099 Session::start_transport ()
1100 {
1101         _last_roll_location = _transport_frame;
1102         _last_roll_or_reversal_location = _transport_frame;
1103         
1104         have_looped = false;
1105
1106         /* if record status is Enabled, move it to Recording. if its
1107            already Recording, move it to Disabled.
1108         */
1109
1110         switch (record_status()) {
1111         case Enabled:
1112                 if (!config.get_punch_in()) {
1113                         enable_record ();
1114                 }
1115                 break;
1116
1117         case Recording:
1118                 if (!play_loop) {
1119                         disable_record (false);
1120                 }
1121                 break;
1122
1123         default:
1124                 break;
1125         }
1126
1127         transport_sub_state |= PendingDeclickIn;
1128
1129         _transport_speed = 1.0;
1130         _target_transport_speed = 1.0;
1131
1132         boost::shared_ptr<RouteList> rl = routes.reader();
1133         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1134                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1135                 if (tr) {
1136                         tr->realtime_set_speed (tr->speed(), true);
1137                 }
1138                 (*i)->automation_snapshot (_transport_frame, true);
1139         }
1140
1141         Timecode::Time time;
1142         timecode_time_subframes (_transport_frame, time);
1143         MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
1144
1145         TransportStateChange (); /* EMIT SIGNAL */
1146 }
1147
1148 /** Do any transport work in the audio thread that needs to be done after the
1149  * transport thread is finished.  Audio thread, realtime safe.
1150  */
1151 void
1152 Session::post_transport ()
1153 {
1154         PostTransportWork ptw = post_transport_work ();
1155
1156         if (ptw & PostTransportAudition) {
1157                 if (auditioner && auditioner->auditioning()) {
1158                         process_function = &Session::process_audition;
1159                 } else {
1160                         process_function = &Session::process_with_events;
1161                 }
1162         }
1163
1164         if (ptw & PostTransportStop) {
1165
1166                 transport_sub_state = 0;
1167         }
1168
1169         if (ptw & PostTransportLocate) {
1170
1171                 if (((!config.get_external_sync() && (auto_play_legal && config.get_auto_play())) && !_exporting) || (ptw & PostTransportRoll)) {
1172                         start_transport ();
1173
1174                 } else {
1175                         transport_sub_state = 0;
1176                 }
1177         }
1178
1179         set_next_event ();
1180         /* XXX is this really safe? shouldn't we just be unsetting the bits that we actually
1181            know were handled ?
1182         */
1183         set_post_transport_work (PostTransportWork (0));
1184 }
1185
1186 void
1187 Session::reset_rf_scale (nframes_t motion)
1188 {
1189         cumulative_rf_motion += motion;
1190
1191         if (cumulative_rf_motion < 4 * _current_frame_rate) {
1192                 rf_scale = 1;
1193         } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1194                 rf_scale = 4;
1195         } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1196                 rf_scale = 10;
1197         } else {
1198                 rf_scale = 100;
1199         }
1200
1201         if (motion != 0) {
1202                 set_dirty();
1203         }
1204 }
1205
1206 void
1207 Session::use_sync_source (Slave* new_slave)
1208 {
1209         /* Runs in process() context */
1210
1211         bool non_rt_required = false;
1212
1213         /* XXX this deletion is problematic because we're in RT context */
1214
1215         delete _slave;
1216         _slave = new_slave;
1217
1218         boost::shared_ptr<RouteList> rl = routes.reader();
1219         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1220                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1221                 if (tr && !tr->hidden()) {
1222                         if (tr->realtime_set_speed (tr->speed(), true)) {
1223                                 non_rt_required = true;
1224                         }
1225                         tr->set_slaved (_slave != 0);
1226                 }
1227         }
1228
1229         if (non_rt_required) {
1230                 add_post_transport_work (PostTransportSpeed);
1231                 _butler->schedule_transport_work ();
1232         }
1233
1234         set_dirty();
1235 }
1236
1237 void
1238 Session::drop_sync_source ()
1239 {
1240         request_sync_source (0);
1241 }
1242
1243 void
1244 Session::switch_to_sync_source (SyncSource src)
1245 {
1246         Slave* new_slave;
1247
1248         DEBUG_TRACE (DEBUG::Slave, string_compose ("Setting up sync source %1\n", enum_2_string (src)));
1249
1250         switch (src) {
1251         case MTC:
1252                 if (_slave && dynamic_cast<MTC_Slave*>(_slave)) {
1253                         return;
1254                 }
1255
1256                 try {
1257                         new_slave = new MTC_Slave (*this, *MIDI::Manager::instance()->mtc_input_port());
1258                 }
1259
1260                 catch (failed_constructor& err) {
1261                         return;
1262                 }
1263                 break;
1264
1265         case MIDIClock:
1266                 if (_slave && dynamic_cast<MIDIClock_Slave*>(_slave)) {
1267                         return;
1268                 }
1269
1270                 try {
1271                         new_slave = new MIDIClock_Slave (*this, *MIDI::Manager::instance()->midi_clock_input_port(), 24);
1272                 }
1273                 
1274                 catch (failed_constructor& err) {
1275                         return;
1276                 }
1277                 break;
1278
1279         case JACK:
1280                 if (_slave && dynamic_cast<JACK_Slave*>(_slave)) {
1281                         return;
1282                 }
1283
1284                 if (config.get_video_pullup() != 0.0f) {
1285                         return;
1286                 }
1287
1288                 new_slave = new JACK_Slave (_engine.jack());
1289                 break;
1290                 
1291         default:
1292                 new_slave = 0;
1293                 break;
1294         };
1295
1296         request_sync_source (new_slave);
1297 }
1298
1299 void
1300 Session::reverse_track_buffers ()
1301 {
1302         add_post_transport_work (PostTransportReverse);
1303         _butler->schedule_transport_work ();
1304 }
1305
1306 void
1307 Session::set_track_speed (Track* track, double speed)
1308 {
1309         if (track->realtime_set_speed (speed, false)) {
1310                 add_post_transport_work (PostTransportSpeed);
1311                 _butler->schedule_transport_work ();
1312                 set_dirty ();
1313         }
1314 }
1315
1316 void
1317 Session::unset_play_range ()
1318 {
1319         _play_range = false;
1320         _clear_event_type (SessionEvent::RangeStop);
1321         _clear_event_type (SessionEvent::RangeLocate);
1322 }
1323
1324 void
1325 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1326 {
1327         SessionEvent* ev;
1328
1329         /* Called from event-processing context */
1330
1331         unset_play_range ();
1332         
1333         if (range.empty()) {
1334                 /* _play_range set to false in unset_play_range()
1335                  */
1336                 if (!leave_rolling) {
1337                         /* stop transport */
1338                         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false);
1339                         merge_event (ev);
1340                 }
1341                 return;
1342         }
1343
1344         _play_range = true;
1345
1346         /* cancel loop play */
1347         unset_play_loop ();
1348
1349         list<AudioRange>::size_type sz = range.size();
1350         
1351         if (sz > 1) {
1352                 
1353                 list<AudioRange>::iterator i = range.begin(); 
1354                 list<AudioRange>::iterator next;
1355                 
1356                 while (i != range.end()) {
1357                         
1358                         next = i;
1359                         ++next;
1360                         
1361                         /* locating/stopping is subject to delays for declicking.
1362                          */
1363                         
1364                         nframes_t requested_frame = (*i).end;
1365                         
1366                         if (requested_frame > current_block_size) {
1367                                 requested_frame -= current_block_size;
1368                         } else {
1369                                 requested_frame = 0;
1370                         }
1371                         
1372                         if (next == range.end()) {
1373                                 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_frame, 0, 0.0f);
1374                         } else {
1375                                 ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_frame, (*next).start, 0.0f);
1376                         }
1377                         
1378                         merge_event (ev);
1379                         
1380                         i = next;
1381                 }
1382                 
1383         } else if (sz == 1) {
1384
1385                 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
1386                 merge_event (ev);
1387                 
1388         } 
1389
1390         /* save range so we can do auto-return etc. */
1391
1392         current_audio_range = range;
1393
1394         /* now start rolling at the right place */
1395
1396         ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
1397         merge_event (ev);
1398         
1399         TransportStateChange ();
1400 }
1401
1402 void
1403 Session::request_bounded_roll (nframes_t start, nframes_t end)
1404 {
1405         AudioRange ar (start, end, 0);
1406         list<AudioRange> lar;
1407
1408         lar.push_back (ar);
1409         request_play_range (&lar, true);
1410 }
1411 void
1412 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1413 {
1414         SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
1415         ev->target2_frame = start;
1416         queue_event (ev);
1417 }
1418
1419 void
1420 Session::engine_halted ()
1421 {
1422         bool ignored;
1423
1424         /* there will be no more calls to process(), so
1425            we'd better clean up for ourselves, right now.
1426
1427            but first, make sure the butler is out of
1428            the picture.
1429         */
1430
1431         g_atomic_int_set (&_butler->should_do_transport_work, 0);
1432         set_post_transport_work (PostTransportWork (0));
1433         _butler->stop ();
1434
1435         realtime_stop (false, true);
1436         non_realtime_stop (false, 0, ignored);
1437         transport_sub_state = 0;
1438
1439         TransportStateChange (); /* EMIT SIGNAL */
1440 }
1441
1442
1443 void
1444 Session::xrun_recovery ()
1445 {
1446         // can't cast away volatile so copy and emit that
1447         nframes64_t tframe = _transport_frame;
1448         Xrun (tframe); //EMIT SIGNAL
1449
1450         if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1451
1452                 /* it didn't actually halt, but we need
1453                    to handle things in the same way.
1454                 */
1455
1456                 engine_halted();
1457         }
1458 }
1459
1460 void
1461 Session::route_processors_changed (RouteProcessorChange c)
1462 {
1463         if (c.type == RouteProcessorChange::MeterPointChange) {
1464                 return;
1465         }
1466
1467         update_latency_compensation (false, false);
1468         resort_routes ();
1469 }
1470
1471 void
1472 Session::update_latency_compensation (bool with_stop, bool abort)
1473 {
1474         bool update_jack = false;
1475         PostTransportWork ptw;
1476
1477         if (_state_of_the_state & Deletion) {
1478                 return;
1479         }
1480
1481         _worst_track_latency = 0;
1482         ptw = post_transport_work();
1483
1484 #undef DEBUG_LATENCY
1485 #ifdef DEBUG_LATENCY
1486         cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1487 #endif
1488
1489         boost::shared_ptr<RouteList> r = routes.reader ();
1490
1491         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1492
1493                 if (with_stop) {
1494                         (*i)->handle_transport_stopped (abort, (ptw & PostTransportLocate), (!(ptw & PostTransportLocate) || pending_locate_flush));
1495                 }
1496
1497                 nframes_t old_latency = (*i)->output()->signal_latency ();
1498                 nframes_t track_latency = (*i)->update_total_latency ();
1499
1500                 if (old_latency != track_latency) {
1501                         (*i)->input()->update_port_total_latencies ();
1502                         (*i)->output()->update_port_total_latencies ();
1503                         update_jack = true;
1504                 }
1505
1506                 if (!(*i)->is_hidden() && ((*i)->active())) {
1507                         _worst_track_latency = max (_worst_track_latency, track_latency);
1508                 }
1509         }
1510
1511         if (update_jack) {
1512                 _engine.update_total_latencies ();
1513         }
1514
1515 #ifdef DEBUG_LATENCY
1516         cerr << "\tworst was " << _worst_track_latency << endl;
1517 #endif
1518
1519         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1520                 (*i)->set_latency_delay (_worst_track_latency);
1521         }
1522
1523         set_worst_io_latencies ();
1524
1525         /* reflect any changes in latencies into capture offsets
1526         */
1527         
1528         boost::shared_ptr<RouteList> rl = routes.reader();
1529         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1530                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1531                 if (tr) {
1532                         tr->set_capture_offset ();
1533                 }
1534         }
1535 }
1536
1537 void
1538 Session::allow_auto_play (bool yn)
1539 {
1540         auto_play_legal = yn;
1541 }
1542
1543 void
1544 Session::reset_jack_connection (jack_client_t* jack)
1545 {
1546         JACK_Slave* js;
1547
1548         if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1549                 js->reset_client (jack);
1550         }
1551 }
1552
1553 bool
1554 Session::maybe_stop (nframes_t limit)
1555 {
1556        if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
1557                if (synced_to_jack () && config.get_jack_time_master ()) {
1558                        _engine.transport_stop ();
1559                } else if (!synced_to_jack ()) {
1560                        stop_transport ();
1561                }
1562                return true;
1563        }
1564        return false;
1565 }
1566
1567 void
1568 Session::send_mmc_locate (nframes64_t t)
1569 {
1570         Timecode::Time time;
1571         timecode_time_subframes (t, time);
1572         MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (time));
1573 }
1574
1575 /** Ask the transport to not send timecode until further notice.  The suspension
1576  *  will come into effect some finite time after this call, and timecode_transmission_suspended()
1577  *  should be checked by the caller to find out when.
1578  */
1579 void
1580 Session::request_suspend_timecode_transmission ()
1581 {
1582         SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, false);
1583         queue_event (ev);
1584 }
1585
1586 void
1587 Session::request_resume_timecode_transmission ()
1588 {
1589         SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, true);
1590         queue_event (ev);
1591 }
1592
1593 bool
1594 Session::timecode_transmission_suspended () const
1595 {
1596         return g_atomic_int_get (&_suspend_timecode_transmission) == 1;
1597 }