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