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