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