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