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