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