latency computation debugging, part one (of many?)
[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                                 _requested_return_frame = -1;
398                         }
399
400                         if (synced_to_jack() && !play_loop) {
401                                 do_locate = true;
402                         }
403                         
404                         if (do_locate) {
405                                 // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl;
406                                 _engine.transport_locate (_transport_frame);
407                         }
408                 } 
409
410 #ifndef LEAVE_TRANSPORT_UNADJUSTED
411         }
412 #endif
413
414                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
415                         if (!(*i)->hidden()) {
416                                 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
417                                         (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
418                                 }
419                                 else {
420                                         (*i)->seek (_transport_frame);
421                                 }
422                         }
423                         if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
424                                 finished = false;
425                                 /* we will be back */
426                                 return;
427                         }
428                 }
429 #ifdef LEAVE_TRANSPORT_UNADJUSTED
430         }
431 #endif
432
433         if (_requested_return_frame < 0) {
434                 last_stop_frame = _transport_frame;
435         } else {
436                 last_stop_frame = _requested_return_frame;
437                 _requested_return_frame = -1;
438         }
439
440         send_full_time_code ();
441         deliver_mmc (MIDI::MachineControl::cmdStop, 0);
442         deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
443
444         if (did_record) {
445
446                 /* XXX its a little odd that we're doing this here
447                    when realtime_stop(), which has already executed,
448                    will have done this.
449                    JLC - so let's not because it seems unnecessary and breaks loop record
450                 */
451 #if 0
452                 if (!Config->get_latched_record_enable()) {
453                         g_atomic_int_set (&_record_status, Disabled);
454                 } else {
455                         g_atomic_int_set (&_record_status, Enabled);
456                 }
457                 RecordStateChanged (); /* emit signal */
458 #endif
459         }
460         
461         if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
462                 /* capture start has been changed, so save pending state */
463                 save_state ("", true);
464                 saved = true;
465         }
466
467         /* always try to get rid of this */
468
469         remove_pending_capture_state ();
470         
471         /* save the current state of things if appropriate */
472
473         if (did_record && !saved) {
474                 save_state (_current_snapshot_name);
475         }
476
477         if (post_transport_work & PostTransportDuration) {
478                 DurationChanged (); /* EMIT SIGNAL */
479         }
480
481         if (post_transport_work & PostTransportStop) { 
482                 _play_range = false;
483
484                 /* do not turn off autoloop on stop */
485                 
486         }
487
488         nframes_t tf = _transport_frame;
489
490         PositionChanged (tf); /* EMIT SIGNAL */
491         TransportStateChange (); /* EMIT SIGNAL */
492
493         /* and start it up again if relevant */
494
495         if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
496                 request_transport_speed (1.0);
497                 pending_locate_roll = false;
498         }
499 }
500
501 void
502 Session::check_declick_out ()
503 {
504         bool locate_required = transport_sub_state & PendingLocate;
505
506         /* this is called after a process() iteration. if PendingDeclickOut was set,
507            it means that we were waiting to declick the output (which has just been
508            done) before doing something else. this is where we do that "something else".
509            
510            note: called from the audio thread.
511         */
512
513         if (transport_sub_state & PendingDeclickOut) {
514
515                 if (locate_required) {
516                         start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
517                         transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
518                 } else {
519                         stop_transport (pending_abort);
520                         transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
521                 }
522         }
523 }
524
525 void
526 Session::set_play_loop (bool yn)
527 {
528         /* Called from event-handling context */
529         
530         if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
531                 return;
532         }
533         
534         set_dirty();
535
536         if (yn && Config->get_seamless_loop() && synced_to_jack()) {
537                 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
538                              "Recommend changing the configured options")
539                         << endmsg;
540                 return;
541         }
542
543         
544         if ((play_loop = yn)) {
545
546                 Location *loc;
547
548                 
549                 if ((loc = _locations.auto_loop_location()) != 0) {
550
551                         if (Config->get_seamless_loop()) {
552                                 // set all diskstreams to use internal looping
553                                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
554                                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
555                                         if (!(*i)->hidden()) {
556                                                 (*i)->set_loop (loc);
557                                         }
558                                 }
559                         }
560                         else {
561                                 // set all diskstreams to NOT use internal looping
562                                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
563                                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
564                                         if (!(*i)->hidden()) {
565                                                 (*i)->set_loop (0);
566                                         }
567                                 }
568                         }
569                         
570                         /* stick in the loop event */
571                         
572                         Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
573                         merge_event (event);
574
575                         /* locate to start of loop and roll if current pos is outside of the loop range */
576                         if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
577                                 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
578                                 merge_event (event);
579                         }
580                         else {
581                                 // locate to current position (+ 1 to force reload)
582                                 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
583                                 merge_event (event);
584                         }
585                 }
586
587
588
589         } else {
590                 clear_events (Event::AutoLoop);
591
592                 // set all diskstreams to NOT use internal looping
593                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
594                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
595                         if (!(*i)->hidden()) {
596                                 (*i)->set_loop (0);
597                         }
598                 }
599                 
600         }
601 }
602
603 void
604 Session::flush_all_redirects ()
605 {
606         boost::shared_ptr<RouteList> r = routes.reader ();
607
608         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
609                 (*i)->flush_redirects ();
610         }
611 }
612
613 void
614 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
615 {
616         if (synced_to_jack()) {
617
618                 float sp;
619                 nframes_t pos;
620
621                 _slave->speed_and_position (sp, pos);
622
623                 if (target_frame != pos) {
624
625                         /* tell JACK to change transport position, and we will
626                            follow along later in ::follow_slave()
627                         */
628
629                         _engine.transport_locate (target_frame);
630
631                         if (sp != 1.0f && with_roll) {
632                                 _engine.transport_start ();
633                         }
634
635                 }
636
637         } else {
638
639                 locate (target_frame, with_roll, with_flush, with_loop);
640         }
641 }
642
643 void
644 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
645 {
646         if (actively_recording() && !with_loop) {
647                 return;
648         }
649
650         if (_transport_frame == target_frame && !loop_changing && !with_loop) {
651                 if (with_roll) {
652                         set_transport_speed (1.0, false);
653                 }
654                 loop_changing = false;
655                 return;
656         }
657
658         _transport_frame = target_frame;
659
660         if (_transport_speed && (!with_loop || loop_changing)) {
661                 /* schedule a declick. we'll be called again when its done */
662
663                 if (!(transport_sub_state & PendingDeclickOut)) {
664                         transport_sub_state |= (PendingDeclickOut|PendingLocate);
665                         pending_locate_frame = target_frame;
666                         pending_locate_roll = with_roll;
667                         pending_locate_flush = with_flush;
668                         return;
669                 } 
670         }
671
672         if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
673                 realtime_stop (false);
674         } 
675
676         if ( !with_loop || loop_changing) {
677
678                 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
679                 
680                 if (with_roll) {
681                         post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
682                 }
683
684                 schedule_butler_transport_work ();
685
686         } else {
687
688                 /* this is functionally what clear_clicks() does but with a tentative lock */
689
690                 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
691         
692                 if (clickm.locked()) {
693                         
694                         for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
695                                 delete *i;
696                         }
697                 
698                         clicks.clear ();
699                 }
700         }
701
702         if (with_roll) {
703                 /* switch from input if we're going to roll */
704                 if (Config->get_monitoring_model() == HardwareMonitoring) {
705
706                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
707
708                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
709                                 if ((*i)->record_enabled ()) {
710                                         //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
711                                         (*i)->monitor_input (!Config->get_auto_input());
712                                 }
713                         }
714                 }
715         } else {
716                 /* otherwise we're going to stop, so do the opposite */
717                 if (Config->get_monitoring_model() == HardwareMonitoring) {
718                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
719
720                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
721                                 if ((*i)->record_enabled ()) {
722                                         //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
723                                         (*i)->monitor_input (true);
724                                 }
725                         }
726                 }
727         }
728
729         /* cancel looped playback if transport pos outside of loop range */
730         if (play_loop) {
731                 Location* al = _locations.auto_loop_location();
732                 
733                 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
734                         // cancel looping directly, this is called from event handling context
735                         set_play_loop (false);
736                 }
737                 else if (al && _transport_frame == al->start()) {
738                         if (with_loop) {
739                                 // this is only necessary for seamless looping
740
741                                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
742                                 
743                                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
744                                         if ((*i)->record_enabled ()) {
745                                                 // tell it we've looped, so it can deal with the record state
746                                                 (*i)->transport_looped(_transport_frame);
747                                         }
748                                 }
749                         }
750
751                         TransportLooped(); // EMIT SIGNAL
752                 }
753         }
754         
755         loop_changing = false;
756 }
757
758 void
759 Session::set_transport_speed (float speed, bool abort)
760 {
761         if (_transport_speed == speed) {
762                 return;
763         }
764
765         if (speed > 0) {
766                 speed = min (8.0f, speed);
767         } else if (speed < 0) {
768                 speed = max (-8.0f, speed);
769         }
770
771         if (transport_rolling() && speed == 0.0) {
772
773                 if (Config->get_monitoring_model() == HardwareMonitoring)
774                 {
775                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
776
777                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
778                                 if ((*i)->record_enabled ()) {
779                                         //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
780                                         (*i)->monitor_input (true);     
781                                 }
782                         }
783                 }
784
785                 if (synced_to_jack ()) {
786                         _engine.transport_stop ();
787                 } else {
788                         stop_transport (abort);
789                 }
790                 
791         } else if (transport_stopped() && speed == 1.0) {
792
793                 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
794                         return;
795                 }
796
797                 if (Config->get_monitoring_model() == HardwareMonitoring) {
798
799                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
800
801                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
802                                 if (Config->get_auto_input() && (*i)->record_enabled ()) {
803                                         //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
804                                         (*i)->monitor_input (false);    
805                                 }
806                         }
807                 }
808
809                 if (synced_to_jack()) {
810                         _engine.transport_start ();
811                 } else {
812                         start_transport ();
813                 }
814
815         } else {
816
817                 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
818                         return;
819                 }
820
821                 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
822                         warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
823                                 << endmsg;
824                         return;
825                 }
826
827                 if (actively_recording()) {
828                         return;
829                 }
830
831                 if (speed > 0.0f && _transport_frame == current_end_frame()) {
832                         return;
833                 }
834
835                 if (speed < 0.0f && _transport_frame == 0) {
836                         return;
837                 }
838                 
839                 clear_clicks ();
840
841                 /* if we are reversing relative to the current speed, or relative to the speed
842                    before the last stop, then we have to do extra work.
843                 */
844
845                 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
846                         post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
847                 }
848                 
849                 _last_transport_speed = _transport_speed;
850                 _transport_speed = speed;
851                 
852                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
853                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
854                         if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
855                                 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
856                         }
857                 }
858                 
859                 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
860                         schedule_butler_transport_work ();
861                 }
862         }
863 }
864
865 void
866 Session::stop_transport (bool abort)
867 {
868         if (_transport_speed == 0.0f) {
869                 return;
870         }
871         
872         if (actively_recording() && !(transport_sub_state & StopPendingCapture) && 
873             _worst_output_latency > current_block_size) 
874         {
875                 
876                 /* we need to capture the audio that has still not yet been received by the system
877                    at the time the stop is requested, so we have to roll past that time.
878
879                    we want to declick before stopping, so schedule the autostop for one
880                    block before the actual end. we'll declick in the subsequent block,
881                    and then we'll really be stopped.
882                 */
883                 
884                 Event *ev = new Event (Event::StopOnce, Event::Replace, 
885                                        _transport_frame + _worst_output_latency - current_block_size,
886                                        0, 0, abort);
887                 
888                 merge_event (ev);
889                 transport_sub_state |= StopPendingCapture;
890                 pending_abort = abort;
891                 return;
892         } 
893
894
895         if ((transport_sub_state & PendingDeclickOut) == 0) {
896                 transport_sub_state |= PendingDeclickOut;
897                 /* we'll be called again after the declick */
898                 pending_abort = abort;
899                 return;
900         }
901
902         realtime_stop (abort);
903         schedule_butler_transport_work ();
904 }
905
906 void
907 Session::start_transport ()
908 {
909         _last_roll_location = _transport_frame;
910
911         /* if record status is Enabled, move it to Recording. if its
912            already Recording, move it to Disabled. 
913         */
914
915         switch (record_status()) {
916         case Enabled:
917                 if (!Config->get_punch_in()) {
918                         enable_record ();
919                 }
920                 break;
921
922         case Recording:
923                 if (!play_loop) {
924                         disable_record (false);
925                 }
926                 break;
927
928         default:
929                 break;
930         }
931
932         if (!synced_to_jack() || _exporting) {
933                 actually_start_transport ();
934         } else {
935                 waiting_to_start = true;
936         }
937 }
938
939 void
940 Session::actually_start_transport ()
941 {
942         waiting_to_start = false;
943
944         transport_sub_state |= PendingDeclickIn;
945         _transport_speed = 1.0;
946         
947         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
948         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
949                 (*i)->realtime_set_speed ((*i)->speed(), true);
950         }
951
952         send_mmc_in_another_thread (MIDI::MachineControl::cmdDeferredPlay, 0);
953         
954         TransportStateChange (); /* EMIT SIGNAL */
955 }
956
957 void
958 Session::post_transport ()
959 {
960         if (post_transport_work & PostTransportAudition) {
961                 if (auditioner && auditioner->active()) {
962                         process_function = &Session::process_audition;
963                 } else {
964                         process_function = &Session::process_with_events;
965                 }
966         }
967
968         if (post_transport_work & PostTransportStop) {
969
970                 transport_sub_state = 0;
971         }
972
973         if (post_transport_work & PostTransportLocate) {
974
975                 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
976                         start_transport ();
977                         
978                 } else {
979                         transport_sub_state = 0;
980                 }
981         }
982
983         set_next_event ();
984
985         post_transport_work = PostTransportWork (0);
986 }
987
988 void
989 Session::reset_rf_scale (nframes_t motion)
990 {
991         cumulative_rf_motion += motion;
992
993         if (cumulative_rf_motion < 4 * _current_frame_rate) {
994                 rf_scale = 1;
995         } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
996                 rf_scale = 4;
997         } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
998                 rf_scale = 10;
999         } else {
1000                 rf_scale = 100;
1001         }
1002
1003         if (motion != 0) {
1004                 set_dirty();
1005         }
1006 }
1007
1008 void
1009 Session::set_slave_source (SlaveSource src)
1010 {
1011         bool reverse = false;
1012         bool non_rt_required = false;
1013
1014         if (_transport_speed) {
1015                 error << _("please stop the transport before adjusting slave settings") << endmsg;
1016                 return;
1017         }
1018
1019 //      if (src == JACK && Config->get_jack_time_master()) {
1020 //              return;
1021 //      }
1022         
1023         if (_slave) {
1024                 delete _slave;
1025                 _slave = 0;
1026         }
1027
1028         if (_transport_speed < 0.0) {
1029                 reverse = true;
1030         }
1031
1032         switch (src) {
1033         case None:
1034                 stop_transport ();
1035                 break;
1036                 
1037         case MTC:
1038                 if (_mtc_port) {
1039                         try {
1040                                 _slave = new MTC_Slave (*this, *_mtc_port);
1041                         }
1042
1043                         catch (failed_constructor& err) {
1044                                 return;
1045                         }
1046
1047                 } else {
1048                         error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1049                         return;
1050                 }
1051                 _desired_transport_speed = _transport_speed;
1052                 break;
1053                 
1054         case JACK:
1055                 _slave = new JACK_Slave (_engine.jack());
1056                 _desired_transport_speed = _transport_speed;
1057                 break;
1058         };
1059
1060         Config->set_slave_source (src);
1061         
1062         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1063         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1064                 if (!(*i)->hidden()) {
1065                         if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1066                                 non_rt_required = true;
1067                         }
1068                         (*i)->set_slaved (_slave);
1069                 }
1070         }
1071
1072         if (reverse) {
1073                 reverse_diskstream_buffers ();
1074         }
1075
1076         if (non_rt_required) {
1077                 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1078                 schedule_butler_transport_work ();
1079         }
1080
1081         set_dirty();
1082 }
1083
1084 void
1085 Session::reverse_diskstream_buffers ()
1086 {
1087         post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1088         schedule_butler_transport_work ();
1089 }
1090
1091 void
1092 Session::set_diskstream_speed (Diskstream* stream, float speed)
1093 {
1094         if (stream->realtime_set_speed (speed, false)) {
1095                 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1096                 schedule_butler_transport_work ();
1097                 set_dirty ();
1098         }
1099 }
1100
1101 void
1102 Session::set_audio_range (list<AudioRange>& range)
1103 {
1104         Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1105         ev->audio_range = range;
1106         queue_event (ev);
1107 }
1108
1109 void
1110 Session::request_play_range (bool yn)
1111 {
1112         Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1113         queue_event (ev);
1114 }
1115
1116 void
1117 Session::set_play_range (bool yn)
1118 {
1119         /* Called from event-processing context */
1120
1121         if (_play_range != yn) {
1122                 _play_range = yn;
1123                 setup_auto_play ();
1124
1125                 if (!_play_range) {
1126                         /* stop transport */
1127                         Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1128                         merge_event (ev);
1129                 }
1130         }
1131 }
1132
1133 void
1134 Session::setup_auto_play ()
1135 {
1136         /* Called from event-processing context */
1137
1138         Event* ev;
1139         
1140         _clear_event_type (Event::RangeStop);
1141         _clear_event_type (Event::RangeLocate);
1142
1143         if (!_play_range) {
1144                 return;
1145         }
1146
1147         list<AudioRange>::size_type sz = current_audio_range.size();
1148         
1149         if (sz > 1) {
1150                 
1151                 list<AudioRange>::iterator i = current_audio_range.begin(); 
1152                 list<AudioRange>::iterator next;
1153                 
1154                 while (i != current_audio_range.end()) {
1155                         
1156                         next = i;
1157                         ++next;
1158                         
1159                         /* locating/stopping is subject to delays for declicking.
1160                          */
1161                         
1162                         nframes_t requested_frame = (*i).end;
1163                         
1164                         if (requested_frame > current_block_size) {
1165                                 requested_frame -= current_block_size;
1166                         } else {
1167                                 requested_frame = 0;
1168                         }
1169                         
1170                         if (next == current_audio_range.end()) {
1171                                 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1172                         } else {
1173                                 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1174                         }
1175                         
1176                         merge_event (ev);
1177                         
1178                         i = next;
1179                 }
1180                 
1181         } else if (sz == 1) {
1182                 
1183                 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1184                 merge_event (ev);
1185                 
1186         } 
1187
1188         /* now start rolling at the right place */
1189         
1190         ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1191         merge_event (ev);
1192 }
1193
1194 void
1195 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1196 {
1197         Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1198         ev->target2_frame = start;
1199         queue_event (ev);
1200 }
1201
1202 void
1203 Session::request_bounded_roll (nframes_t start, nframes_t end)
1204 {
1205         request_stop ();
1206         Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1207         queue_event (ev);
1208         request_locate (start, true);
1209 }
1210
1211 void
1212 Session::engine_halted ()
1213 {
1214         bool ignored;
1215
1216         /* there will be no more calls to process(), so
1217            we'd better clean up for ourselves, right now.
1218
1219            but first, make sure the butler is out of 
1220            the picture.
1221         */
1222
1223         g_atomic_int_set (&butler_should_do_transport_work, 0);
1224         post_transport_work = PostTransportWork (0);
1225         stop_butler ();
1226         
1227         realtime_stop (false);
1228         non_realtime_stop (false, 0, ignored);
1229         transport_sub_state = 0;
1230
1231         TransportStateChange (); /* EMIT SIGNAL */
1232 }
1233
1234
1235 void
1236 Session::xrun_recovery ()
1237 {
1238         Xrun (transport_frame()); //EMIT SIGNAL
1239
1240         if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1241
1242                 /* it didn't actually halt, but we need
1243                    to handle things in the same way.
1244                 */
1245
1246                 engine_halted();
1247         } 
1248 }
1249
1250 void
1251 Session::update_latency_compensation (bool with_stop, bool abort)
1252 {
1253         bool update_jack = false;
1254
1255         if (_state_of_the_state & Deletion) {
1256                 return;
1257         }
1258
1259         _worst_track_latency = 0;
1260
1261 #define DEBUG_LATENCY
1262 #ifdef DEBUG_LATENCY
1263         cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1264 #endif
1265
1266         boost::shared_ptr<RouteList> r = routes.reader ();
1267
1268         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1269                 if (with_stop) {
1270                         (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate), 
1271                                                         (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1272                 }
1273
1274                 nframes_t old_latency = (*i)->signal_latency ();
1275                 nframes_t track_latency = (*i)->update_total_latency ();
1276
1277                 if (old_latency != track_latency) {
1278                         update_jack = true;
1279                 }
1280                 
1281                 if (!(*i)->hidden() && ((*i)->active())) {
1282                         _worst_track_latency = max (_worst_track_latency, track_latency);
1283                 }
1284         }
1285
1286 #ifdef DEBUG_LATENCY
1287         cerr << "\tworst was " << _worst_track_latency << endl;
1288 #endif
1289
1290         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1291                 (*i)->set_latency_delay (_worst_track_latency);
1292         }
1293
1294         /* tell JACK to play catch up */
1295
1296         if (update_jack) {
1297                 _engine.update_total_latencies ();
1298         }
1299
1300         set_worst_io_latencies ();
1301
1302         /* reflect any changes in latencies into capture offsets
1303         */
1304         
1305         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1306
1307         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1308                 (*i)->set_capture_offset ();
1309         }
1310 }
1311
1312 void
1313 Session::update_latency_compensation_proxy (void* ignored)
1314 {
1315         update_latency_compensation (false, false);
1316 }
1317
1318 void
1319 Session::allow_auto_play (bool yn)
1320 {
1321         auto_play_legal = yn;
1322 }
1323
1324 void
1325 Session::reset_jack_connection (jack_client_t* jack)
1326 {
1327         JACK_Slave* js;
1328
1329         if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1330                 js->reset_client (jack);
1331         }
1332 }