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