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