3c500656846ac6fb806cca3bca2088830b765a75
[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 (framepos_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 (framepos_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         PositionChanged (_transport_frame); /* EMIT SIGNAL */
597         TransportStateChange (); /* EMIT SIGNAL */
598
599         /* and start it up again if relevant */
600
601         if ((ptw & PostTransportLocate) && !config.get_external_sync() && pending_locate_roll) {
602                 request_transport_speed (1.0);
603                 pending_locate_roll = false;
604         }
605 }
606
607 void
608 Session::check_declick_out ()
609 {
610         bool locate_required = transport_sub_state & PendingLocate;
611
612         /* this is called after a process() iteration. if PendingDeclickOut was set,
613            it means that we were waiting to declick the output (which has just been
614            done) before doing something else. this is where we do that "something else".
615
616            note: called from the audio thread.
617         */
618
619         if (transport_sub_state & PendingDeclickOut) {
620
621                 if (locate_required) {
622                         start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
623                         transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
624                 } else {
625                         stop_transport (pending_abort);
626                         transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
627                 }
628         }
629 }
630
631 void
632 Session::unset_play_loop ()
633 {
634         play_loop = false;
635         clear_events (SessionEvent::AutoLoop);
636         
637         // set all tracks to NOT use internal looping
638         boost::shared_ptr<RouteList> rl = routes.reader ();
639         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
640                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
641                 if (tr && !tr->hidden()) {
642                         tr->set_loop (0);
643                 }
644         }
645 }
646
647 void
648 Session::set_play_loop (bool yn)
649 {
650         /* Called from event-handling context */
651
652         Location *loc;
653
654         if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) {
655                 /* nothing to do, or can't change loop status while recording */
656                 return;
657         }
658         
659         if (yn && Config->get_seamless_loop() && synced_to_jack()) {
660                 warning << string_compose (_("Seamless looping cannot be supported while %1 is using JACK transport.\n"
661                                              "Recommend changing the configured options"), PROGRAM_NAME)
662                         << endmsg;
663                 return;
664         }
665         
666         if (yn) {
667
668                 play_loop = true;
669
670                 if (loc) {
671
672                         unset_play_range ();
673
674                         if (Config->get_seamless_loop()) {
675                                 // set all tracks to use internal looping
676                                 boost::shared_ptr<RouteList> rl = routes.reader ();
677                                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
678                                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
679                                         if (tr && !tr->hidden()) {
680                                                 tr->set_loop (loc);
681                                         }
682                                 }
683                         }
684                         else {
685                                 // set all tracks to NOT use internal looping
686                                 boost::shared_ptr<RouteList> rl = routes.reader ();
687                                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
688                                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
689                                         if (tr && !tr->hidden()) {
690                                                 tr->set_loop (0);
691                                         }
692                                 }
693                         }
694                         
695                         /* put the loop event into the event list */
696                         
697                         SessionEvent* event = new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f);
698                         merge_event (event);
699
700                         /* locate to start of loop and roll. If doing seamless loop, force a 
701                            locate+buffer refill even if we are positioned there already.
702                         */
703
704                         start_locate (loc->start(), true, true, false, Config->get_seamless_loop());
705                 }
706
707         } else {
708
709                 unset_play_loop ();
710         }
711
712         TransportStateChange ();
713 }
714 void
715 Session::flush_all_inserts ()
716 {
717         boost::shared_ptr<RouteList> r = routes.reader ();
718
719         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
720                 (*i)->flush_processors ();
721         }
722 }
723
724 void
725 Session::start_locate (framepos_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
726 {
727         if (synced_to_jack()) {
728
729                 double sp;
730                 framepos_t pos;
731
732                 _slave->speed_and_position (sp, pos);
733
734                 if (target_frame != pos) {
735
736                         /* tell JACK to change transport position, and we will
737                            follow along later in ::follow_slave()
738                         */
739
740                         _engine.transport_locate (target_frame);
741
742                         if (sp != 1.0f && with_roll) {
743                                 _engine.transport_start ();
744                         }
745
746                 }
747
748         } else {
749                 locate (target_frame, with_roll, with_flush, with_loop, force);
750         }
751 }
752
753 int
754 Session::micro_locate (nframes_t distance)
755 {
756         boost::shared_ptr<RouteList> rl = routes.reader();
757         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
758                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
759                 if (tr && !tr->can_internal_playback_seek (distance)) {
760                         return -1;
761                 }
762         }
763
764         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
765                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
766                 if (tr) {
767                         tr->internal_playback_seek (distance);
768                 }
769         }
770
771         _transport_frame += distance;
772         return 0;
773 }
774
775 /** @param with_mmc true to send a MMC locate command when the locate is done */
776 void
777 Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force, bool with_mmc)
778 {
779         if (actively_recording() && !with_loop) {
780                 return;
781         }
782
783         if (!force && _transport_frame == target_frame && !loop_changing && !with_loop) {
784                 if (with_roll) {
785                         set_transport_speed (1.0, false);
786                 }
787                 loop_changing = false;
788                 Located (); /* EMIT SIGNAL */
789                 return;
790         }
791
792         // Update Timecode time
793         // [DR] FIXME: find out exactly where this should go below
794         _transport_frame = target_frame;
795         timecode_time(_transport_frame, transmitting_timecode_time);
796         outbound_mtc_timecode_frame = _transport_frame;
797         next_quarter_frame_to_send = 0;
798
799         if (_transport_speed && (!with_loop || loop_changing)) {
800                 /* schedule a declick. we'll be called again when its done */
801
802                 if (!(transport_sub_state & PendingDeclickOut)) {
803                         transport_sub_state |= (PendingDeclickOut|PendingLocate);
804                         pending_locate_frame = target_frame;
805                         pending_locate_roll = with_roll;
806                         pending_locate_flush = with_flush;
807                         return;
808                 }
809         }
810
811         if (transport_rolling() && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
812                 realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
813         }
814
815         if (force || !with_loop || loop_changing) {
816
817                 PostTransportWork todo = PostTransportLocate;
818
819                 if (with_roll) {
820                         todo = PostTransportWork (todo | PostTransportRoll);
821                 } 
822
823                 add_post_transport_work (todo);
824                 _butler->schedule_transport_work ();
825
826         } else {
827
828                 /* this is functionally what clear_clicks() does but with a tentative lock */
829
830                 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
831
832                 if (clickm.locked()) {
833
834                         for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
835                                 delete *i;
836                         }
837
838                         clicks.clear ();
839                 }
840         }
841
842         if (with_roll) {
843                 /* switch from input if we're going to roll */
844                 if (Config->get_monitoring_model() == HardwareMonitoring) {
845
846                         boost::shared_ptr<RouteList> rl = routes.reader();
847                         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
848                                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
849                                 if (tr && tr->record_enabled ()) {
850                                         //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
851                                         tr->monitor_input (!config.get_auto_input());
852                                 }
853                         }
854                 }
855         } else {
856                 /* otherwise we're going to stop, so do the opposite */
857                 if (Config->get_monitoring_model() == HardwareMonitoring) {
858
859                         boost::shared_ptr<RouteList> rl = routes.reader();
860                         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
861                                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
862                                 if (tr && tr->record_enabled ()) {
863                                         //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
864                                         tr->monitor_input (true);
865                                 }
866                         }
867                 }
868         }
869
870         /* cancel looped playback if transport pos outside of loop range */
871         if (play_loop) {
872                 Location* al = _locations->auto_loop_location();
873
874                 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
875                         // cancel looping directly, this is called from event handling context
876                         set_play_loop (false);
877                 }
878                 else if (al && _transport_frame == al->start()) {
879                         if (with_loop) {
880                                 // this is only necessary for seamless looping
881
882                                 boost::shared_ptr<RouteList> rl = routes.reader();
883                                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
884                                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
885                                         if (tr && tr->record_enabled ()) {
886                                                 // tell it we've looped, so it can deal with the record state
887                                                 tr->transport_looped(_transport_frame);
888                                         }
889                                 }
890                         }
891                         have_looped = true;
892                         TransportLooped(); // EMIT SIGNAL
893                 }
894         }
895
896         loop_changing = false;
897
898         _send_timecode_update = true;
899
900         if (with_mmc) {
901                 send_mmc_locate (_transport_frame);
902         }
903
904         Located (); /* EMIT SIGNAL */
905 }
906
907 /** Set the transport speed.
908  * @param speed New speed
909  * @param abort
910  */
911 void
912 Session::set_transport_speed (double speed, bool abort, bool clear_state)
913 {
914         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));
915
916         if (_transport_speed == speed) {
917                 return;
918         }
919
920         _target_transport_speed = fabs(speed);
921
922         /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
923            and user needs. We really need CD-style "skip" playback for ffwd and rewind.
924         */
925
926         if (speed > 0) {
927                 speed = min (8.0, speed);
928         } else if (speed < 0) {
929                 speed = max (-8.0, speed);
930         }
931
932         if (transport_rolling() && speed == 0.0) {
933
934                 /* we are rolling and we want to stop */
935
936                 if (Config->get_monitoring_model() == HardwareMonitoring)
937                 {
938                         boost::shared_ptr<RouteList> rl = routes.reader();
939                         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
940                                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
941                                 if (tr && tr->record_enabled ()) {
942                                         //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
943                                         tr->monitor_input (true);
944                                 }
945                         }
946                 }
947
948                 if (synced_to_jack ()) {
949                         if (clear_state) {
950                                 /* do this here because our response to the slave won't 
951                                    take care of it.
952                                 */
953                                 _play_range = false;
954                                 unset_play_loop ();
955                         }
956                         _engine.transport_stop ();
957                 } else {
958                         stop_transport (abort);
959                 }
960
961         } else if (transport_stopped() && speed == 1.0) {
962
963                 /* we are stopped and we want to start rolling at speed 1 */
964
965                 if (Config->get_monitoring_model() == HardwareMonitoring) {
966
967                         boost::shared_ptr<RouteList> rl = routes.reader();
968                         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
969                                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
970                                 if (config.get_auto_input() && tr && tr->record_enabled ()) {
971                                         //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
972                                         tr->monitor_input (false);
973                                 }
974                         }
975                 }
976
977                 if (synced_to_jack()) {
978                         _engine.transport_start ();
979                 } else {
980                         start_transport ();
981                 }
982
983         } else {
984
985                 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
986                         warning << string_compose (_("Global varispeed cannot be supported while %1 is connected to JACK transport control"),
987                                                    PROGRAM_NAME)
988                                 << endmsg;
989                         return;
990                 }
991
992                 if (actively_recording()) {
993                         return;
994                 }
995
996                 if (speed > 0.0 && _transport_frame == current_end_frame()) {
997                         return;
998                 }
999
1000                 if (speed < 0.0 && _transport_frame == 0) {
1001                         return;
1002                 }
1003
1004                 clear_clicks ();
1005
1006                 /* if we are reversing relative to the current speed, or relative to the speed
1007                    before the last stop, then we have to do extra work.
1008                 */
1009                 
1010                 PostTransportWork todo = PostTransportWork (0);
1011
1012                 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
1013                         todo = PostTransportWork (todo | PostTransportReverse);
1014                         _last_roll_or_reversal_location = _transport_frame;
1015                 }
1016
1017                 _last_transport_speed = _transport_speed;
1018                 _transport_speed = speed;
1019
1020                 boost::shared_ptr<RouteList> rl = routes.reader();
1021                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1022                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1023                         if (tr && tr->realtime_set_speed (tr->speed(), true)) {
1024                                 todo = PostTransportWork (todo | PostTransportSpeed);
1025                                 break;
1026                         }
1027                 }
1028
1029                 if (todo) {
1030                         add_post_transport_work (todo);
1031                         _butler->schedule_transport_work ();
1032                 }
1033         }
1034 }
1035
1036
1037 /** Stop the transport.  */
1038 void
1039 Session::stop_transport (bool abort, bool clear_state)
1040 {
1041         if (_transport_speed == 0.0f) {
1042                 return;
1043         }
1044
1045         if (actively_recording() && !(transport_sub_state & StopPendingCapture) && _worst_output_latency > current_block_size) {
1046
1047                 boost::shared_ptr<RouteList> rl = routes.reader();
1048                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1049                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1050                         if (tr) {
1051                                 tr->prepare_to_stop (_transport_frame);
1052                         }
1053                 }
1054
1055                 /* we need to capture the audio that has still not yet been received by the system
1056                    at the time the stop is requested, so we have to roll past that time.
1057
1058                    we want to declick before stopping, so schedule the autostop for one
1059                    block before the actual end. we'll declick in the subsequent block,
1060                    and then we'll really be stopped.
1061                 */
1062
1063                 SessionEvent *ev = new SessionEvent (SessionEvent::StopOnce, SessionEvent::Replace,
1064                                        _transport_frame + _worst_output_latency - current_block_size,
1065                                        0, 0, abort);
1066
1067                 merge_event (ev);
1068                 transport_sub_state |= StopPendingCapture;
1069                 pending_abort = abort;
1070                 return;
1071         }
1072
1073
1074         if ((transport_sub_state & PendingDeclickOut) == 0) {
1075
1076                 if (!(transport_sub_state & StopPendingCapture)) {
1077                         boost::shared_ptr<RouteList> rl = routes.reader();
1078                         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1079                                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1080                                 if (tr) {
1081                                         tr->prepare_to_stop (_transport_frame);
1082                                 }
1083                         }
1084                 }
1085                 
1086                 transport_sub_state |= PendingDeclickOut;
1087                 /* we'll be called again after the declick */
1088                 pending_abort = abort;
1089                 return;
1090         }
1091
1092         realtime_stop (abort, clear_state);
1093         _butler->schedule_transport_work ();
1094 }
1095
1096 void
1097 Session::start_transport ()
1098 {
1099         _last_roll_location = _transport_frame;
1100         _last_roll_or_reversal_location = _transport_frame;
1101         
1102         have_looped = false;
1103
1104         /* if record status is Enabled, move it to Recording. if its
1105            already Recording, move it to Disabled.
1106         */
1107
1108         switch (record_status()) {
1109         case Enabled:
1110                 if (!config.get_punch_in()) {
1111                         enable_record ();
1112                 }
1113                 break;
1114
1115         case Recording:
1116                 if (!play_loop) {
1117                         disable_record (false);
1118                 }
1119                 break;
1120
1121         default:
1122                 break;
1123         }
1124
1125         transport_sub_state |= PendingDeclickIn;
1126
1127         _transport_speed = 1.0;
1128         _target_transport_speed = 1.0;
1129
1130         boost::shared_ptr<RouteList> rl = routes.reader();
1131         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1132                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1133                 if (tr) {
1134                         tr->realtime_set_speed (tr->speed(), true);
1135                 }
1136                 (*i)->automation_snapshot (_transport_frame, true);
1137         }
1138
1139         Timecode::Time time;
1140         timecode_time_subframes (_transport_frame, time);
1141         MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
1142
1143         TransportStateChange (); /* EMIT SIGNAL */
1144 }
1145
1146 /** Do any transport work in the audio thread that needs to be done after the
1147  * transport thread is finished.  Audio thread, realtime safe.
1148  */
1149 void
1150 Session::post_transport ()
1151 {
1152         PostTransportWork ptw = post_transport_work ();
1153
1154         if (ptw & PostTransportAudition) {
1155                 if (auditioner && auditioner->auditioning()) {
1156                         process_function = &Session::process_audition;
1157                 } else {
1158                         process_function = &Session::process_with_events;
1159                 }
1160         }
1161
1162         if (ptw & PostTransportStop) {
1163
1164                 transport_sub_state = 0;
1165         }
1166
1167         if (ptw & PostTransportLocate) {
1168
1169                 if (((!config.get_external_sync() && (auto_play_legal && config.get_auto_play())) && !_exporting) || (ptw & PostTransportRoll)) {
1170                         start_transport ();
1171
1172                 } else {
1173                         transport_sub_state = 0;
1174                 }
1175         }
1176
1177         set_next_event ();
1178         /* XXX is this really safe? shouldn't we just be unsetting the bits that we actually
1179            know were handled ?
1180         */
1181         set_post_transport_work (PostTransportWork (0));
1182 }
1183
1184 void
1185 Session::reset_rf_scale (nframes_t motion)
1186 {
1187         cumulative_rf_motion += motion;
1188
1189         if (cumulative_rf_motion < 4 * _current_frame_rate) {
1190                 rf_scale = 1;
1191         } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1192                 rf_scale = 4;
1193         } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1194                 rf_scale = 10;
1195         } else {
1196                 rf_scale = 100;
1197         }
1198
1199         if (motion != 0) {
1200                 set_dirty();
1201         }
1202 }
1203
1204 void
1205 Session::use_sync_source (Slave* new_slave)
1206 {
1207         /* Runs in process() context */
1208
1209         bool non_rt_required = false;
1210
1211         /* XXX this deletion is problematic because we're in RT context */
1212
1213         delete _slave;
1214         _slave = new_slave;
1215
1216         boost::shared_ptr<RouteList> rl = routes.reader();
1217         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1218                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1219                 if (tr && !tr->hidden()) {
1220                         if (tr->realtime_set_speed (tr->speed(), true)) {
1221                                 non_rt_required = true;
1222                         }
1223                         tr->set_slaved (_slave != 0);
1224                 }
1225         }
1226
1227         if (non_rt_required) {
1228                 add_post_transport_work (PostTransportSpeed);
1229                 _butler->schedule_transport_work ();
1230         }
1231
1232         set_dirty();
1233 }
1234
1235 void
1236 Session::drop_sync_source ()
1237 {
1238         request_sync_source (0);
1239 }
1240
1241 void
1242 Session::switch_to_sync_source (SyncSource src)
1243 {
1244         Slave* new_slave;
1245
1246         DEBUG_TRACE (DEBUG::Slave, string_compose ("Setting up sync source %1\n", enum_2_string (src)));
1247
1248         switch (src) {
1249         case MTC:
1250                 if (_slave && dynamic_cast<MTC_Slave*>(_slave)) {
1251                         return;
1252                 }
1253
1254                 try {
1255                         new_slave = new MTC_Slave (*this, *MIDI::Manager::instance()->mtc_input_port());
1256                 }
1257
1258                 catch (failed_constructor& err) {
1259                         return;
1260                 }
1261                 break;
1262
1263         case MIDIClock:
1264                 if (_slave && dynamic_cast<MIDIClock_Slave*>(_slave)) {
1265                         return;
1266                 }
1267
1268                 try {
1269                         new_slave = new MIDIClock_Slave (*this, *MIDI::Manager::instance()->midi_clock_input_port(), 24);
1270                 }
1271                 
1272                 catch (failed_constructor& err) {
1273                         return;
1274                 }
1275                 break;
1276
1277         case JACK:
1278                 if (_slave && dynamic_cast<JACK_Slave*>(_slave)) {
1279                         return;
1280                 }
1281
1282                 if (config.get_video_pullup() != 0.0f) {
1283                         return;
1284                 }
1285
1286                 new_slave = new JACK_Slave (_engine.jack());
1287                 break;
1288                 
1289         default:
1290                 new_slave = 0;
1291                 break;
1292         };
1293
1294         request_sync_source (new_slave);
1295 }
1296
1297 void
1298 Session::reverse_track_buffers ()
1299 {
1300         add_post_transport_work (PostTransportReverse);
1301         _butler->schedule_transport_work ();
1302 }
1303
1304 void
1305 Session::set_track_speed (Track* track, double speed)
1306 {
1307         if (track->realtime_set_speed (speed, false)) {
1308                 add_post_transport_work (PostTransportSpeed);
1309                 _butler->schedule_transport_work ();
1310                 set_dirty ();
1311         }
1312 }
1313
1314 void
1315 Session::unset_play_range ()
1316 {
1317         _play_range = false;
1318         _clear_event_type (SessionEvent::RangeStop);
1319         _clear_event_type (SessionEvent::RangeLocate);
1320 }
1321
1322 void
1323 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1324 {
1325         SessionEvent* ev;
1326
1327         /* Called from event-processing context */
1328
1329         unset_play_range ();
1330         
1331         if (range.empty()) {
1332                 /* _play_range set to false in unset_play_range()
1333                  */
1334                 if (!leave_rolling) {
1335                         /* stop transport */
1336                         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false);
1337                         merge_event (ev);
1338                 }
1339                 return;
1340         }
1341
1342         _play_range = true;
1343
1344         /* cancel loop play */
1345         unset_play_loop ();
1346
1347         list<AudioRange>::size_type sz = range.size();
1348         
1349         if (sz > 1) {
1350                 
1351                 list<AudioRange>::iterator i = range.begin(); 
1352                 list<AudioRange>::iterator next;
1353                 
1354                 while (i != range.end()) {
1355                         
1356                         next = i;
1357                         ++next;
1358                         
1359                         /* locating/stopping is subject to delays for declicking.
1360                          */
1361                         
1362                         nframes_t requested_frame = (*i).end;
1363                         
1364                         if (requested_frame > current_block_size) {
1365                                 requested_frame -= current_block_size;
1366                         } else {
1367                                 requested_frame = 0;
1368                         }
1369                         
1370                         if (next == range.end()) {
1371                                 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_frame, 0, 0.0f);
1372                         } else {
1373                                 ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_frame, (*next).start, 0.0f);
1374                         }
1375                         
1376                         merge_event (ev);
1377                         
1378                         i = next;
1379                 }
1380                 
1381         } else if (sz == 1) {
1382
1383                 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
1384                 merge_event (ev);
1385                 
1386         } 
1387
1388         /* save range so we can do auto-return etc. */
1389
1390         current_audio_range = range;
1391
1392         /* now start rolling at the right place */
1393
1394         ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
1395         merge_event (ev);
1396         
1397         TransportStateChange ();
1398 }
1399
1400 void
1401 Session::request_bounded_roll (framepos_t start, framepos_t end)
1402 {
1403         AudioRange ar (start, end, 0);
1404         list<AudioRange> lar;
1405
1406         lar.push_back (ar);
1407         request_play_range (&lar, true);
1408 }
1409 void
1410 Session::request_roll_at_and_return (framepos_t start, framepos_t return_to)
1411 {
1412         SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
1413         ev->target2_frame = start;
1414         queue_event (ev);
1415 }
1416
1417 void
1418 Session::engine_halted ()
1419 {
1420         bool ignored;
1421
1422         /* there will be no more calls to process(), so
1423            we'd better clean up for ourselves, right now.
1424
1425            but first, make sure the butler is out of
1426            the picture.
1427         */
1428
1429         g_atomic_int_set (&_butler->should_do_transport_work, 0);
1430         set_post_transport_work (PostTransportWork (0));
1431         _butler->stop ();
1432
1433         realtime_stop (false, true);
1434         non_realtime_stop (false, 0, ignored);
1435         transport_sub_state = 0;
1436
1437         TransportStateChange (); /* EMIT SIGNAL */
1438 }
1439
1440
1441 void
1442 Session::xrun_recovery ()
1443 {
1444         Xrun (_transport_frame); //EMIT SIGNAL
1445
1446         if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1447
1448                 /* it didn't actually halt, but we need
1449                    to handle things in the same way.
1450                 */
1451
1452                 engine_halted();
1453         }
1454 }
1455
1456 void
1457 Session::route_processors_changed (RouteProcessorChange c)
1458 {
1459         if (c.type == RouteProcessorChange::MeterPointChange) {
1460                 return;
1461         }
1462
1463         update_latency_compensation (false, false);
1464         resort_routes ();
1465 }
1466
1467 void
1468 Session::update_latency_compensation (bool with_stop, bool abort)
1469 {
1470         bool update_jack = false;
1471         PostTransportWork ptw;
1472
1473         if (_state_of_the_state & Deletion) {
1474                 return;
1475         }
1476
1477         _worst_track_latency = 0;
1478         ptw = post_transport_work();
1479
1480 #undef DEBUG_LATENCY
1481 #ifdef DEBUG_LATENCY
1482         cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1483 #endif
1484
1485         boost::shared_ptr<RouteList> r = routes.reader ();
1486
1487         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1488
1489                 if (with_stop) {
1490                         (*i)->handle_transport_stopped (abort, (ptw & PostTransportLocate), (!(ptw & PostTransportLocate) || pending_locate_flush));
1491                 }
1492
1493                 nframes_t old_latency = (*i)->output()->signal_latency ();
1494                 nframes_t track_latency = (*i)->update_total_latency ();
1495
1496                 if (old_latency != track_latency) {
1497                         (*i)->input()->update_port_total_latencies ();
1498                         (*i)->output()->update_port_total_latencies ();
1499                         update_jack = true;
1500                 }
1501
1502                 if (!(*i)->is_hidden() && ((*i)->active())) {
1503                         _worst_track_latency = max (_worst_track_latency, track_latency);
1504                 }
1505         }
1506
1507         if (update_jack) {
1508                 _engine.update_total_latencies ();
1509         }
1510
1511 #ifdef DEBUG_LATENCY
1512         cerr << "\tworst was " << _worst_track_latency << endl;
1513 #endif
1514
1515         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1516                 (*i)->set_latency_delay (_worst_track_latency);
1517         }
1518
1519         set_worst_io_latencies ();
1520
1521         /* reflect any changes in latencies into capture offsets
1522         */
1523         
1524         boost::shared_ptr<RouteList> rl = routes.reader();
1525         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1526                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1527                 if (tr) {
1528                         tr->set_capture_offset ();
1529                 }
1530         }
1531 }
1532
1533 void
1534 Session::allow_auto_play (bool yn)
1535 {
1536         auto_play_legal = yn;
1537 }
1538
1539 void
1540 Session::reset_jack_connection (jack_client_t* jack)
1541 {
1542         JACK_Slave* js;
1543
1544         if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1545                 js->reset_client (jack);
1546         }
1547 }
1548
1549 bool
1550 Session::maybe_stop (nframes_t limit)
1551 {
1552        if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
1553                if (synced_to_jack () && config.get_jack_time_master ()) {
1554                        _engine.transport_stop ();
1555                } else if (!synced_to_jack ()) {
1556                        stop_transport ();
1557                }
1558                return true;
1559        }
1560        return false;
1561 }
1562
1563 void
1564 Session::send_mmc_locate (framepos_t t)
1565 {
1566         Timecode::Time time;
1567         timecode_time_subframes (t, time);
1568         MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (time));
1569 }
1570
1571 /** Ask the transport to not send timecode until further notice.  The suspension
1572  *  will come into effect some finite time after this call, and timecode_transmission_suspended()
1573  *  should be checked by the caller to find out when.
1574  */
1575 void
1576 Session::request_suspend_timecode_transmission ()
1577 {
1578         SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, false);
1579         queue_event (ev);
1580 }
1581
1582 void
1583 Session::request_resume_timecode_transmission ()
1584 {
1585         SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, true);
1586         queue_event (ev);
1587 }
1588
1589 bool
1590 Session::timecode_transmission_suspended () const
1591 {
1592         return g_atomic_int_get (&_suspend_timecode_transmission) == 1;
1593 }