Back-port tim mayberry's fixes for import; fix JACK slaving to never pay attention...
[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 #include <sigc++/bind.h>
25 #include <sigc++/retype.h>
26
27 #include <pbd/undo.h>
28 #include <pbd/error.h>
29 #include <glibmm/thread.h>
30 #include <pbd/pthread_utils.h>
31 #include <pbd/memento_command.h>
32 #include <pbd/stacktrace.h>
33
34 #include <midi++/mmc.h>
35 #include <midi++/port.h>
36
37 #include <ardour/ardour.h>
38 #include <ardour/audioengine.h>
39 #include <ardour/session.h>
40 #include <ardour/audio_diskstream.h>
41 #include <ardour/auditioner.h>
42 #include <ardour/slave.h>
43 #include <ardour/location.h>
44
45 #include "i18n.h"
46
47 using namespace std;
48 using namespace ARDOUR;
49 using namespace sigc;
50 using namespace PBD;
51
52 void
53 Session::request_input_change_handling ()
54 {
55         if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
56                 Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0);
57                 queue_event (ev);
58         }
59 }
60
61 void
62 Session::request_slave_source (SlaveSource src)
63 {
64         Event* ev = new Event (Event::SetSlaveSource, Event::Add, Event::Immediate, 0, 0.0);
65
66         if (src == JACK) {
67                 /* could set_seamless_loop() be disposed of entirely?*/
68                 Config->set_seamless_loop (false);
69         } else {
70                 Config->set_seamless_loop (true);
71         }
72         ev->slave = src;
73         queue_event (ev);
74 }
75
76 void
77 Session::request_transport_speed (float speed)
78 {
79         Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, speed);
80         queue_event (ev);
81 }
82
83 void
84 Session::request_diskstream_speed (Diskstream& ds, float speed)
85 {
86         Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed);
87         ev->set_ptr (&ds);
88         queue_event (ev);
89 }
90
91 void
92 Session::request_stop (bool abort)
93 {
94         Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0, abort);
95         queue_event (ev);
96 }
97
98 void
99 Session::request_locate (nframes_t target_frame, bool with_roll)
100 {
101         Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, false);
102         queue_event (ev);
103 }
104
105 void
106 Session::force_locate (nframes_t target_frame, bool with_roll)
107 {
108         Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, true);
109         queue_event (ev);
110 }
111
112 void
113 Session::request_play_loop (bool yn)
114 {
115         Event* ev;      
116         Location *location = _locations.auto_loop_location();
117
118         if (location == 0 && yn) {
119                 error << _("Cannot loop - no loop range defined")
120                       << endmsg;
121                 return;
122         }
123
124         ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, 0.0, yn);
125         queue_event (ev);
126
127         if (!yn && Config->get_seamless_loop() && transport_rolling()) {
128                 // request an immediate locate to refresh the diskstreams
129                 // after disabling looping
130                 request_locate (_transport_frame-1, false);
131         }
132 }
133
134 void
135 Session::realtime_stop (bool abort)
136 {
137         /* assume that when we start, we'll be moving forwards */
138
139         if (_transport_speed < 0.0f) {
140                 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop | PostTransportReverse);
141         } else {
142                 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop);
143         }
144
145         if (actively_recording()) {
146
147                 /* move the transport position back to where the
148                    request for a stop was noticed. we rolled
149                    past that point to pick up delayed input.
150                 */
151
152 #ifndef LEAVE_TRANSPORT_UNADJUSTED
153                 decrement_transport_position (_worst_output_latency);
154 #endif
155
156                 /* the duration change is not guaranteed to have happened, but is likely */
157
158                 post_transport_work = PostTransportWork (post_transport_work | PostTransportDuration);
159         }
160
161         if (abort) {
162                 post_transport_work = PostTransportWork (post_transport_work | PostTransportAbort);
163         }
164
165         _clear_event_type (Event::StopOnce);
166         _clear_event_type (Event::RangeStop);
167         _clear_event_type (Event::RangeLocate);
168
169         disable_record (true);
170
171         reset_slave_state ();
172                 
173         _transport_speed = 0;
174
175         if (Config->get_use_video_sync()) {
176                 waiting_for_sync_offset = true;
177         }
178
179         transport_sub_state = ((Config->get_slave_source() == None && Config->get_auto_return()) ? AutoReturning : 0);
180 }
181
182 void
183 Session::butler_transport_work ()
184 {
185   restart:
186         bool finished;
187         boost::shared_ptr<RouteList> r = routes.reader ();
188         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
189
190         int on_entry = g_atomic_int_get (&butler_should_do_transport_work);
191         finished = true;
192
193         if (post_transport_work & PostTransportCurveRealloc) {
194                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
195                         (*i)->curve_reallocate();
196                 }
197         }
198
199         if (post_transport_work & PostTransportInputChange) {
200                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
201                         (*i)->non_realtime_input_change ();
202                 }
203         }
204
205         if (post_transport_work & PostTransportSpeed) {
206                 non_realtime_set_speed ();
207         }
208
209         if (post_transport_work & PostTransportReverse) {
210
211
212                 clear_clicks();
213                 cumulative_rf_motion = 0;
214                 reset_rf_scale (0);
215
216                 /* don't seek if locate will take care of that in non_realtime_stop() */
217
218                 if (!(post_transport_work & PostTransportLocate)) {
219                         
220                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
221                                 if (!(*i)->hidden()) {
222                                         if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
223                                                 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
224                                         }
225                                         else {
226                                                 (*i)->seek (_transport_frame);
227                                         }
228                                 }
229                                 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
230                                         /* new request, stop seeking, and start again */
231                                         g_atomic_int_dec_and_test (&butler_should_do_transport_work);
232                                         goto restart;
233                                 }
234                         }
235                 }
236         }
237
238         if (post_transport_work & (PostTransportStop|PostTransportLocate)) {
239                 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
240                 if (!finished) {
241                         g_atomic_int_dec_and_test (&butler_should_do_transport_work);
242                         goto restart;
243                 }
244         }
245
246         if (post_transport_work & PostTransportOverWrite) {
247                 non_realtime_overwrite (on_entry, finished);
248                 if (!finished) {
249                         g_atomic_int_dec_and_test (&butler_should_do_transport_work);
250                         goto restart;
251                 }
252         }
253
254         if (post_transport_work & PostTransportAudition) {
255                 non_realtime_set_audition ();
256         }
257         
258         g_atomic_int_dec_and_test (&butler_should_do_transport_work);
259 }
260
261 void
262 Session::non_realtime_set_speed ()
263 {
264         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
265
266         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
267                 (*i)->non_realtime_set_speed ();
268         }
269 }
270
271 void
272 Session::non_realtime_overwrite (int on_entry, bool& finished)
273 {
274         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
275
276         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
277                 if ((*i)->pending_overwrite) {
278                         (*i)->overwrite_existing_buffers ();
279                 }
280                 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
281                         finished = false;
282                         return;
283                 }
284         }
285 }
286
287 void
288 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
289 {
290         struct tm* now;
291         time_t     xnow;
292         bool       did_record;
293         bool       saved;
294
295         did_record = false;
296         saved = false;
297
298         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
299         
300         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
301                 if ((*i)->get_captured_frames () != 0) {
302                         did_record = true;
303                         break;
304                 }
305         }
306
307         /* stop and locate are merged here because they share a lot of common stuff */
308         
309         time (&xnow);
310         now = localtime (&xnow);
311
312         if (auditioner) {
313                 auditioner->cancel_audition ();
314         }
315
316         clear_clicks();
317         cumulative_rf_motion = 0;
318         reset_rf_scale (0);
319
320         if (did_record) {
321                 begin_reversible_command ("capture");
322                 
323                 Location* loc = _locations.end_location();
324                 bool change_end = false;
325                 
326                 if (_transport_frame < loc->end()) {
327
328                         /* stopped recording before current end */
329
330                         if (_end_location_is_free) {
331
332                                 /* first capture for this session, move end back to where we are */
333
334                                 change_end = true;
335                         } 
336
337                 } else if (_transport_frame > loc->end()) {
338                         
339                         /* stopped recording after the current end, extend it */
340
341                         change_end = true;
342                 }
343                 
344                 if (change_end) {
345                         XMLNode &before = loc->get_state();
346                         loc->set_end(_transport_frame);
347                         XMLNode &after = loc->get_state();
348                         add_command (new MementoCommand<Location>(*loc, &before, &after));
349                 }
350
351                 _end_location_is_free = false;
352                 _have_captured = true;
353         }
354
355         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
356                 (*i)->transport_stopped (*now, xnow, abort);
357         }
358         
359         boost::shared_ptr<RouteList> r = routes.reader ();
360
361         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
362                 if (!(*i)->hidden()) {
363                         (*i)->set_pending_declick (0);
364                 }
365         }
366         
367         if (did_record) {
368                 commit_reversible_command ();
369         }       
370         
371         if (_engine.running()) {
372                 update_latency_compensation (true, abort);
373         }
374
375         if ((Config->get_slave_source() == None && Config->get_auto_return()) || 
376             (post_transport_work & PostTransportLocate) || 
377             (_requested_return_frame >= 0) ||
378             synced_to_jack()) {
379                 
380                 if (pending_locate_flush) {
381                         flush_all_redirects ();
382                 }
383                 
384                 if (((Config->get_slave_source() == None && Config->get_auto_return()) || 
385                      synced_to_jack() ||
386                      _requested_return_frame >= 0) &&
387                     !(post_transport_work & PostTransportLocate)) {
388
389                         bool do_locate = false;
390
391                         if (_requested_return_frame >= 0) {
392                                 _transport_frame = _requested_return_frame;
393                                 _requested_return_frame = -1;
394                                 do_locate = true;
395                         } else {
396                                 _transport_frame = last_stop_frame;
397                         }
398
399                         if (synced_to_jack() && !play_loop) {
400                                 do_locate = true;
401                         }
402                         
403                         if (do_locate) {
404                                 // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl;
405                                 _engine.transport_locate (_transport_frame);
406                         }
407                 } 
408
409 #ifndef LEAVE_TRANSPORT_UNADJUSTED
410         }
411 #endif
412
413                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
414                         if (!(*i)->hidden()) {
415                                 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
416                                         (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
417                                 }
418                                 else {
419                                         (*i)->seek (_transport_frame);
420                                 }
421                         }
422                         if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
423                                 finished = false;
424                                 /* we will be back */
425                                 return;
426                         }
427                 }
428 #ifdef LEAVE_TRANSPORT_UNADJUSTED
429         }
430 #endif
431
432         last_stop_frame = _transport_frame;
433
434         send_full_time_code ();
435         deliver_mmc (MIDI::MachineControl::cmdStop, 0);
436         deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
437
438         if (did_record) {
439
440                 /* XXX its a little odd that we're doing this here
441                    when realtime_stop(), which has already executed,
442                    will have done this.
443                    JLC - so let's not because it seems unnecessary and breaks loop record
444                 */
445 #if 0
446                 if (!Config->get_latched_record_enable()) {
447                         g_atomic_int_set (&_record_status, Disabled);
448                 } else {
449                         g_atomic_int_set (&_record_status, Enabled);
450                 }
451                 RecordStateChanged (); /* emit signal */
452 #endif
453         }
454         
455         if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
456                 /* capture start has been changed, so save pending state */
457                 save_state ("", true);
458                 saved = true;
459         }
460
461         /* always try to get rid of this */
462
463         remove_pending_capture_state ();
464         
465         /* save the current state of things if appropriate */
466
467         if (did_record && !saved) {
468                 save_state (_current_snapshot_name);
469         }
470
471         if (post_transport_work & PostTransportDuration) {
472                 DurationChanged (); /* EMIT SIGNAL */
473         }
474
475         if (post_transport_work & PostTransportStop) { 
476                 _play_range = false;
477
478                 /* do not turn off autoloop on stop */
479                 
480         }
481
482         nframes_t tf = _transport_frame;
483
484         PositionChanged (tf); /* EMIT SIGNAL */
485         TransportStateChange (); /* EMIT SIGNAL */
486
487         /* and start it up again if relevant */
488
489         if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
490                 request_transport_speed (1.0);
491                 pending_locate_roll = false;
492         }
493 }
494
495 void
496 Session::check_declick_out ()
497 {
498         bool locate_required = transport_sub_state & PendingLocate;
499
500         /* this is called after a process() iteration. if PendingDeclickOut was set,
501            it means that we were waiting to declick the output (which has just been
502            done) before doing something else. this is where we do that "something else".
503            
504            note: called from the audio thread.
505         */
506
507         if (transport_sub_state & PendingDeclickOut) {
508
509                 if (locate_required) {
510                         start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
511                         transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
512                 } else {
513                         stop_transport (pending_abort);
514                         transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
515                 }
516         }
517 }
518
519 void
520 Session::set_play_loop (bool yn)
521 {
522         /* Called from event-handling context */
523         
524         if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
525                 return;
526         }
527         
528         set_dirty();
529
530         if (yn && Config->get_seamless_loop() && synced_to_jack()) {
531                 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
532                              "Recommend changing the configured options")
533                         << endmsg;
534                 return;
535         }
536
537         
538         if ((play_loop = yn)) {
539
540                 Location *loc;
541
542                 
543                 if ((loc = _locations.auto_loop_location()) != 0) {
544
545                         if (Config->get_seamless_loop()) {
546                                 // set all diskstreams to use internal looping
547                                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
548                                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
549                                         if (!(*i)->hidden()) {
550                                                 (*i)->set_loop (loc);
551                                         }
552                                 }
553                         }
554                         else {
555                                 // set all diskstreams to NOT use internal looping
556                                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
557                                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
558                                         if (!(*i)->hidden()) {
559                                                 (*i)->set_loop (0);
560                                         }
561                                 }
562                         }
563                         
564                         /* stick in the loop event */
565                         
566                         Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
567                         merge_event (event);
568
569                         /* locate to start of loop and roll if current pos is outside of the loop range */
570                         if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
571                                 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
572                                 merge_event (event);
573                         }
574                         else {
575                                 // locate to current position (+ 1 to force reload)
576                                 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
577                                 merge_event (event);
578                         }
579                 }
580
581
582
583         } else {
584                 clear_events (Event::AutoLoop);
585
586                 // set all diskstreams to NOT use internal looping
587                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
588                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
589                         if (!(*i)->hidden()) {
590                                 (*i)->set_loop (0);
591                         }
592                 }
593                 
594         }
595 }
596
597 void
598 Session::flush_all_redirects ()
599 {
600         boost::shared_ptr<RouteList> r = routes.reader ();
601
602         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
603                 (*i)->flush_redirects ();
604         }
605 }
606
607 void
608 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
609 {
610         if (synced_to_jack()) {
611
612                 float sp;
613                 nframes_t pos;
614
615                 _slave->speed_and_position (sp, pos);
616
617                 if (target_frame != pos) {
618
619                         /* tell JACK to change transport position, and we will
620                            follow along later in ::follow_slave()
621                         */
622
623                         _engine.transport_locate (target_frame);
624
625                         if (sp != 1.0f && with_roll) {
626                                 _engine.transport_start ();
627                         }
628
629                 }
630
631         } else {
632
633                 locate (target_frame, with_roll, with_flush, with_loop);
634         }
635 }
636
637 void
638 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
639 {
640         if (actively_recording() && !with_loop) {
641                 return;
642         }
643
644         if (_transport_frame == target_frame && !loop_changing && !with_loop) {
645                 if (with_roll) {
646                         set_transport_speed (1.0, false);
647                 }
648                 loop_changing = false;
649                 return;
650         }
651
652         _transport_frame = target_frame;
653
654         if (_transport_speed && (!with_loop || loop_changing)) {
655                 /* schedule a declick. we'll be called again when its done */
656
657                 if (!(transport_sub_state & PendingDeclickOut)) {
658                         transport_sub_state |= (PendingDeclickOut|PendingLocate);
659                         pending_locate_frame = target_frame;
660                         pending_locate_roll = with_roll;
661                         pending_locate_flush = with_flush;
662                         return;
663                 } 
664         }
665
666         if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
667                 realtime_stop (false);
668         } 
669
670         if ( !with_loop || loop_changing) {
671
672                 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
673                 
674                 if (with_roll) {
675                         post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
676                 }
677
678                 schedule_butler_transport_work ();
679
680         } else {
681
682                 /* this is functionally what clear_clicks() does but with a tentative lock */
683
684                 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
685         
686                 if (clickm.locked()) {
687                         
688                         for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
689                                 delete *i;
690                         }
691                 
692                         clicks.clear ();
693                 }
694         }
695
696         if (with_roll) {
697                 /* switch from input if we're going to roll */
698                 if (Config->get_monitoring_model() == HardwareMonitoring) {
699
700                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
701
702                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
703                                 if ((*i)->record_enabled ()) {
704                                         //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
705                                         (*i)->monitor_input (!Config->get_auto_input());
706                                 }
707                         }
708                 }
709         } else {
710                 /* otherwise we're going to stop, so do the opposite */
711                 if (Config->get_monitoring_model() == HardwareMonitoring) {
712                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
713
714                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
715                                 if ((*i)->record_enabled ()) {
716                                         //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
717                                         (*i)->monitor_input (true);
718                                 }
719                         }
720                 }
721         }
722
723         /* cancel looped playback if transport pos outside of loop range */
724         if (play_loop) {
725                 Location* al = _locations.auto_loop_location();
726                 
727                 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
728                         // cancel looping directly, this is called from event handling context
729                         set_play_loop (false);
730                 }
731                 else if (al && _transport_frame == al->start()) {
732                         if (with_loop) {
733                                 // this is only necessary for seamless looping
734
735                                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
736                                 
737                                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
738                                         if ((*i)->record_enabled ()) {
739                                                 // tell it we've looped, so it can deal with the record state
740                                                 (*i)->transport_looped(_transport_frame);
741                                         }
742                                 }
743                         }
744
745                         TransportLooped(); // EMIT SIGNAL
746                 }
747         }
748         
749         loop_changing = false;
750 }
751
752 void
753 Session::set_transport_speed (float speed, bool abort)
754 {
755         if (_transport_speed == speed) {
756                 return;
757         }
758
759         if (speed > 0) {
760                 speed = min (8.0f, speed);
761         } else if (speed < 0) {
762                 speed = max (-8.0f, speed);
763         }
764
765         if (transport_rolling() && speed == 0.0) {
766
767                 if (Config->get_monitoring_model() == HardwareMonitoring)
768                 {
769                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
770
771                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
772                                 if ((*i)->record_enabled ()) {
773                                         //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
774                                         (*i)->monitor_input (true);     
775                                 }
776                         }
777                 }
778
779                 if (synced_to_jack ()) {
780                         _engine.transport_stop ();
781                 } else {
782                         stop_transport (abort);
783                 }
784                 
785         } else if (transport_stopped() && speed == 1.0) {
786
787                 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
788                         return;
789                 }
790
791                 if (Config->get_monitoring_model() == HardwareMonitoring) {
792
793                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
794
795                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
796                                 if (Config->get_auto_input() && (*i)->record_enabled ()) {
797                                         //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
798                                         (*i)->monitor_input (false);    
799                                 }
800                         }
801                 }
802
803                 if (synced_to_jack()) {
804                         _engine.transport_start ();
805                 } else {
806                         start_transport ();
807                 }
808
809         } else {
810
811                 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
812                         return;
813                 }
814
815                 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
816                         warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
817                                 << endmsg;
818                         return;
819                 }
820
821                 if (actively_recording()) {
822                         return;
823                 }
824
825                 if (speed > 0.0f && _transport_frame == current_end_frame()) {
826                         return;
827                 }
828
829                 if (speed < 0.0f && _transport_frame == 0) {
830                         return;
831                 }
832                 
833                 clear_clicks ();
834
835                 /* if we are reversing relative to the current speed, or relative to the speed
836                    before the last stop, then we have to do extra work.
837                 */
838
839                 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
840                         post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
841                 }
842                 
843                 _last_transport_speed = _transport_speed;
844                 _transport_speed = speed;
845                 
846                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
847                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
848                         if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
849                                 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
850                         }
851                 }
852                 
853                 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
854                         schedule_butler_transport_work ();
855                 }
856         }
857 }
858
859 void
860 Session::stop_transport (bool abort)
861 {
862         if (_transport_speed == 0.0f) {
863                 return;
864         }
865         
866         if (actively_recording() && !(transport_sub_state & StopPendingCapture) && 
867             _worst_output_latency > current_block_size) 
868         {
869                 
870                 /* we need to capture the audio that has still not yet been received by the system
871                    at the time the stop is requested, so we have to roll past that time.
872
873                    we want to declick before stopping, so schedule the autostop for one
874                    block before the actual end. we'll declick in the subsequent block,
875                    and then we'll really be stopped.
876                 */
877                 
878                 Event *ev = new Event (Event::StopOnce, Event::Replace, 
879                                        _transport_frame + _worst_output_latency - current_block_size,
880                                        0, 0, abort);
881                 
882                 merge_event (ev);
883                 transport_sub_state |= StopPendingCapture;
884                 pending_abort = abort;
885                 return;
886         } 
887
888
889         if ((transport_sub_state & PendingDeclickOut) == 0) {
890                 transport_sub_state |= PendingDeclickOut;
891                 /* we'll be called again after the declick */
892                 pending_abort = abort;
893                 return;
894         }
895
896         realtime_stop (abort);
897         schedule_butler_transport_work ();
898 }
899
900 void
901 Session::start_transport ()
902 {
903         _last_roll_location = _transport_frame;
904
905         /* if record status is Enabled, move it to Recording. if its
906            already Recording, move it to Disabled. 
907         */
908
909         switch (record_status()) {
910         case Enabled:
911                 if (!Config->get_punch_in()) {
912                         enable_record ();
913                 }
914                 break;
915
916         case Recording:
917                 if (!play_loop) {
918                         disable_record (false);
919                 }
920                 break;
921
922         default:
923                 break;
924         }
925
926         if (!synced_to_jack() || _exporting) {
927                 actually_start_transport ();
928         } else {
929                 waiting_to_start = true;
930         }
931 }
932
933 void
934 Session::actually_start_transport ()
935 {
936         waiting_to_start = false;
937
938         transport_sub_state |= PendingDeclickIn;
939         _transport_speed = 1.0;
940         
941         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
942         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
943                 (*i)->realtime_set_speed ((*i)->speed(), true);
944         }
945
946         send_mmc_in_another_thread (MIDI::MachineControl::cmdDeferredPlay, 0);
947         
948         TransportStateChange (); /* EMIT SIGNAL */
949 }
950
951 void
952 Session::post_transport ()
953 {
954         if (post_transport_work & PostTransportAudition) {
955                 if (auditioner && auditioner->active()) {
956                         process_function = &Session::process_audition;
957                 } else {
958                         process_function = &Session::process_with_events;
959                 }
960         }
961
962         if (post_transport_work & PostTransportStop) {
963
964                 transport_sub_state = 0;
965         }
966
967         if (post_transport_work & PostTransportLocate) {
968
969                 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
970                         start_transport ();
971                         
972                 } else {
973                         transport_sub_state = 0;
974                 }
975         }
976
977         set_next_event ();
978
979         post_transport_work = PostTransportWork (0);
980 }
981
982 void
983 Session::reset_rf_scale (nframes_t motion)
984 {
985         cumulative_rf_motion += motion;
986
987         if (cumulative_rf_motion < 4 * _current_frame_rate) {
988                 rf_scale = 1;
989         } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
990                 rf_scale = 4;
991         } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
992                 rf_scale = 10;
993         } else {
994                 rf_scale = 100;
995         }
996
997         if (motion != 0) {
998                 set_dirty();
999         }
1000 }
1001
1002 void
1003 Session::set_slave_source (SlaveSource src)
1004 {
1005         bool reverse = false;
1006         bool non_rt_required = false;
1007
1008         if (_transport_speed) {
1009                 error << _("please stop the transport before adjusting slave settings") << endmsg;
1010                 return;
1011         }
1012
1013 //      if (src == JACK && Config->get_jack_time_master()) {
1014 //              return;
1015 //      }
1016         
1017         if (_slave) {
1018                 delete _slave;
1019                 _slave = 0;
1020         }
1021
1022         if (_transport_speed < 0.0) {
1023                 reverse = true;
1024         }
1025
1026         switch (src) {
1027         case None:
1028                 stop_transport ();
1029                 break;
1030                 
1031         case MTC:
1032                 if (_mtc_port) {
1033                         try {
1034                                 _slave = new MTC_Slave (*this, *_mtc_port);
1035                         }
1036
1037                         catch (failed_constructor& err) {
1038                                 return;
1039                         }
1040
1041                 } else {
1042                         error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1043                         return;
1044                 }
1045                 _desired_transport_speed = _transport_speed;
1046                 break;
1047                 
1048         case JACK:
1049                 _slave = new JACK_Slave (_engine.jack());
1050                 _desired_transport_speed = _transport_speed;
1051                 break;
1052         };
1053
1054         Config->set_slave_source (src);
1055         
1056         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1057         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1058                 if (!(*i)->hidden()) {
1059                         if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1060                                 non_rt_required = true;
1061                         }
1062                         (*i)->set_slaved (_slave);
1063                 }
1064         }
1065
1066         if (reverse) {
1067                 reverse_diskstream_buffers ();
1068         }
1069
1070         if (non_rt_required) {
1071                 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1072                 schedule_butler_transport_work ();
1073         }
1074
1075         set_dirty();
1076 }
1077
1078 void
1079 Session::reverse_diskstream_buffers ()
1080 {
1081         post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1082         schedule_butler_transport_work ();
1083 }
1084
1085 void
1086 Session::set_diskstream_speed (Diskstream* stream, float speed)
1087 {
1088         if (stream->realtime_set_speed (speed, false)) {
1089                 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1090                 schedule_butler_transport_work ();
1091                 set_dirty ();
1092         }
1093 }
1094
1095 void
1096 Session::set_audio_range (list<AudioRange>& range)
1097 {
1098         Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1099         ev->audio_range = range;
1100         queue_event (ev);
1101 }
1102
1103 void
1104 Session::request_play_range (bool yn)
1105 {
1106         Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1107         queue_event (ev);
1108 }
1109
1110 void
1111 Session::set_play_range (bool yn)
1112 {
1113         /* Called from event-processing context */
1114
1115         if (_play_range != yn) {
1116                 _play_range = yn;
1117                 setup_auto_play ();
1118
1119                 if (!_play_range) {
1120                         /* stop transport */
1121                         Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1122                         merge_event (ev);
1123                 }
1124         }
1125 }
1126
1127 void
1128 Session::setup_auto_play ()
1129 {
1130         /* Called from event-processing context */
1131
1132         Event* ev;
1133         
1134         _clear_event_type (Event::RangeStop);
1135         _clear_event_type (Event::RangeLocate);
1136
1137         if (!_play_range) {
1138                 return;
1139         }
1140
1141         list<AudioRange>::size_type sz = current_audio_range.size();
1142         
1143         if (sz > 1) {
1144                 
1145                 list<AudioRange>::iterator i = current_audio_range.begin(); 
1146                 list<AudioRange>::iterator next;
1147                 
1148                 while (i != current_audio_range.end()) {
1149                         
1150                         next = i;
1151                         ++next;
1152                         
1153                         /* locating/stopping is subject to delays for declicking.
1154                          */
1155                         
1156                         nframes_t requested_frame = (*i).end;
1157                         
1158                         if (requested_frame > current_block_size) {
1159                                 requested_frame -= current_block_size;
1160                         } else {
1161                                 requested_frame = 0;
1162                         }
1163                         
1164                         if (next == current_audio_range.end()) {
1165                                 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1166                         } else {
1167                                 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1168                         }
1169                         
1170                         merge_event (ev);
1171                         
1172                         i = next;
1173                 }
1174                 
1175         } else if (sz == 1) {
1176                 
1177                 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1178                 merge_event (ev);
1179                 
1180         } 
1181
1182         /* now start rolling at the right place */
1183         
1184         ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1185         merge_event (ev);
1186 }
1187
1188 void
1189 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1190 {
1191         request_locate (start, false);
1192         Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1193         queue_event (ev);
1194 }
1195
1196 void
1197 Session::request_bounded_roll (nframes_t start, nframes_t end)
1198 {
1199         request_stop ();
1200         Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1201         queue_event (ev);
1202         request_locate (start, true);
1203 }
1204
1205 void
1206 Session::engine_halted ()
1207 {
1208         bool ignored;
1209
1210         /* there will be no more calls to process(), so
1211            we'd better clean up for ourselves, right now.
1212
1213            but first, make sure the butler is out of 
1214            the picture.
1215         */
1216
1217         g_atomic_int_set (&butler_should_do_transport_work, 0);
1218         post_transport_work = PostTransportWork (0);
1219         stop_butler ();
1220         
1221         realtime_stop (false);
1222         non_realtime_stop (false, 0, ignored);
1223         transport_sub_state = 0;
1224
1225         TransportStateChange (); /* EMIT SIGNAL */
1226 }
1227
1228
1229 void
1230 Session::xrun_recovery ()
1231 {
1232         if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1233
1234                  HaltOnXrun (); /* EMIT SIGNAL */
1235
1236                 /* it didn't actually halt, but we need
1237                    to handle things in the same way.
1238                 */
1239
1240                 engine_halted();
1241         } 
1242 }
1243
1244 void
1245 Session::update_latency_compensation (bool with_stop, bool abort)
1246 {
1247         bool update_jack = false;
1248
1249         if (_state_of_the_state & Deletion) {
1250                 return;
1251         }
1252
1253         _worst_track_latency = 0;
1254
1255         boost::shared_ptr<RouteList> r = routes.reader ();
1256
1257         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1258                 if (with_stop) {
1259                         (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate), 
1260                                                         (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1261                 }
1262
1263                 nframes_t old_latency = (*i)->signal_latency ();
1264                 nframes_t track_latency = (*i)->update_total_latency ();
1265
1266                 if (old_latency != track_latency) {
1267                         update_jack = true;
1268                 }
1269                 
1270                 if (!(*i)->hidden() && ((*i)->active())) {
1271                         _worst_track_latency = max (_worst_track_latency, track_latency);
1272                 }
1273         }
1274
1275         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1276                 (*i)->set_latency_delay (_worst_track_latency);
1277         }
1278
1279         /* tell JACK to play catch up */
1280
1281         if (update_jack) {
1282                 _engine.update_total_latencies ();
1283         }
1284
1285         set_worst_io_latencies ();
1286
1287         /* reflect any changes in latencies into capture offsets
1288         */
1289         
1290         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1291
1292         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1293                 (*i)->set_capture_offset ();
1294         }
1295 }
1296
1297 void
1298 Session::update_latency_compensation_proxy (void* ignored)
1299 {
1300         update_latency_compensation (false, false);
1301 }
1302
1303 void
1304 Session::allow_auto_play (bool yn)
1305 {
1306         auto_play_legal = yn;
1307 }
1308
1309 void
1310 Session::reset_jack_connection (jack_client_t* jack)
1311 {
1312         JACK_Slave* js;
1313
1314         if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1315                 js->reset_client (jack);
1316         }
1317 }