d032e31b93febad22c2b8b90147888ab71d19ea4
[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 /** Set the transport speed.
722  * @param speed New speed
723  * @param abort
724  */
725 void
726 Session::set_transport_speed (float speed, bool abort)
727 {
728         if (_transport_speed == speed) {
729                 return;
730         }
731
732         if (speed > 0) {
733                 speed = min (8.0f, speed);
734         } else if (speed < 0) {
735                 speed = max (-8.0f, speed);
736         }
737
738         if (transport_rolling() && speed == 0.0) {
739
740                 /* we are rolling and we want to stop */
741
742                 if (Config->get_monitoring_model() == HardwareMonitoring)
743                 {
744                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
745
746                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
747                                 if ((*i)->record_enabled ()) {
748                                         //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
749                                         (*i)->monitor_input (true);     
750                                 }
751                         }
752                 }
753
754                 if (synced_to_jack ()) {
755                         _engine.transport_stop ();
756                 } else {
757                         stop_transport (abort);
758                 }
759                 
760         } else if (transport_stopped() && speed == 1.0) {
761
762                 /* we are stopped and we want to start rolling at speed 1 */
763
764                 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
765                         return;
766                 }
767
768                 if (Config->get_monitoring_model() == HardwareMonitoring) {
769
770                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
771
772                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
773                                 if (Config->get_auto_input() && (*i)->record_enabled ()) {
774                                         //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
775                                         (*i)->monitor_input (false);    
776                                 }
777                         }
778                 }
779
780                 if (synced_to_jack()) {
781                         _engine.transport_start ();
782                 } else {
783                         start_transport ();
784                 }
785
786         } else {
787
788                 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
789                         return;
790                 }
791
792                 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
793                         warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
794                                 << endmsg;
795                         return;
796                 }
797
798                 if (actively_recording()) {
799                         return;
800                 }
801
802                 if (speed > 0.0f && _transport_frame == current_end_frame()) {
803                         return;
804                 }
805
806                 if (speed < 0.0f && _transport_frame == 0) {
807                         return;
808                 }
809                 
810                 clear_clicks ();
811
812                 /* if we are reversing relative to the current speed, or relative to the speed
813                    before the last stop, then we have to do extra work.
814                 */
815
816                 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
817                         post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
818                 }
819                 
820                 _last_transport_speed = _transport_speed;
821                 _transport_speed = speed;
822                 
823                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
824                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
825                         if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
826                                 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
827                         }
828                 }
829                 
830                 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
831                         schedule_butler_transport_work ();
832                 }
833         }
834 }
835
836
837 /** Stop the transport.  */
838 void
839 Session::stop_transport (bool abort)
840 {
841         if (_transport_speed == 0.0f) {
842                 return;
843         }
844         
845         if (actively_recording() && !(transport_sub_state & StopPendingCapture) && 
846             _worst_output_latency > current_block_size) 
847         {
848                 
849                 /* we need to capture the audio that has still not yet been received by the system
850                    at the time the stop is requested, so we have to roll past that time.
851
852                    we want to declick before stopping, so schedule the autostop for one
853                    block before the actual end. we'll declick in the subsequent block,
854                    and then we'll really be stopped.
855                 */
856                 
857                 Event *ev = new Event (Event::StopOnce, Event::Replace, 
858                                        _transport_frame + _worst_output_latency - current_block_size,
859                                        0, 0, abort);
860                 
861                 merge_event (ev);
862                 transport_sub_state |= StopPendingCapture;
863                 pending_abort = abort;
864                 return;
865         } 
866
867
868         if ((transport_sub_state & PendingDeclickOut) == 0) {
869                 transport_sub_state |= PendingDeclickOut;
870                 /* we'll be called again after the declick */
871                 pending_abort = abort;
872                 return;
873         }
874
875         realtime_stop (abort);
876         schedule_butler_transport_work ();
877 }
878
879 void
880 Session::start_transport ()
881 {
882         _last_roll_location = _transport_frame;
883
884         /* if record status is Enabled, move it to Recording. if its
885            already Recording, move it to Disabled. 
886         */
887
888         switch (record_status()) {
889         case Enabled:
890                 if (!Config->get_punch_in()) {
891                         enable_record ();
892                 }
893                 break;
894
895         case Recording:
896                 disable_record (false);
897                 break;
898
899         default:
900                 break;
901         }
902
903         if (!synced_to_jack() || _exporting) {
904                 actually_start_transport ();
905         } else {
906                 waiting_to_start = true;
907         }
908 }
909
910 void
911 Session::actually_start_transport ()
912 {
913         waiting_to_start = false;
914
915         transport_sub_state |= PendingDeclickIn;
916         _transport_speed = 1.0;
917         
918         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
919         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
920                 (*i)->realtime_set_speed ((*i)->speed(), true);
921         }
922
923         deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
924
925         TransportStateChange (); /* EMIT SIGNAL */
926 }
927
928 /** Do any transport work in the audio thread that needs to be done after the
929  * transport thread is finished.  Audio thread, realtime safe.
930  */
931 void
932 Session::post_transport ()
933 {
934         if (post_transport_work & PostTransportAudition) {
935                 if (auditioner && auditioner->active()) {
936                         process_function = &Session::process_audition;
937                 } else {
938                         process_function = &Session::process_with_events;
939                 }
940         }
941
942         if (post_transport_work & PostTransportStop) {
943
944                 transport_sub_state = 0;
945         }
946
947         if (post_transport_work & PostTransportLocate) {
948
949                 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
950                         start_transport ();
951                         
952                 } else {
953                         transport_sub_state = 0;
954                 }
955         }
956
957         set_next_event ();
958
959         post_transport_work = PostTransportWork (0);
960 }
961
962 void
963 Session::reset_rf_scale (nframes_t motion)
964 {
965         cumulative_rf_motion += motion;
966
967         if (cumulative_rf_motion < 4 * _current_frame_rate) {
968                 rf_scale = 1;
969         } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
970                 rf_scale = 4;
971         } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
972                 rf_scale = 10;
973         } else {
974                 rf_scale = 100;
975         }
976
977         if (motion != 0) {
978                 set_dirty();
979         }
980 }
981
982 void
983 Session::set_slave_source (SlaveSource src)
984 {
985         bool reverse = false;
986         bool non_rt_required = false;
987
988         if (_transport_speed) {
989                 error << _("please stop the transport before adjusting slave settings") << endmsg;
990                 return;
991         }
992
993 //      if (src == JACK && Config->get_jack_time_master()) {
994 //              return;
995 //      }
996         
997         if (_slave) {
998                 delete _slave;
999                 _slave = 0;
1000         }
1001
1002         if (_transport_speed < 0.0) {
1003                 reverse = true;
1004         }
1005
1006         switch (src) {
1007         case None:
1008                 stop_transport ();
1009                 break;
1010                 
1011         case MTC:
1012                 if (_mtc_port) {
1013                         try {
1014                                 _slave = new MTC_Slave (*this, *_mtc_port);
1015                         }
1016
1017                         catch (failed_constructor& err) {
1018                                 return;
1019                         }
1020
1021                 } else {
1022                         error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1023                         return;
1024                 }
1025                 _desired_transport_speed = _transport_speed;
1026                 break;
1027                 
1028         case JACK:
1029                 _slave = new JACK_Slave (_engine.jack());
1030                 _desired_transport_speed = _transport_speed;
1031                 break;
1032         };
1033
1034         Config->set_slave_source (src);
1035         
1036         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1037         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1038                 if (!(*i)->hidden()) {
1039                         if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1040                                 non_rt_required = true;
1041                         }
1042                         (*i)->set_slaved (_slave);
1043                 }
1044         }
1045
1046         if (reverse) {
1047                 reverse_diskstream_buffers ();
1048         }
1049
1050         if (non_rt_required) {
1051                 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1052                 schedule_butler_transport_work ();
1053         }
1054
1055         set_dirty();
1056 }
1057
1058 void
1059 Session::reverse_diskstream_buffers ()
1060 {
1061         post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1062         schedule_butler_transport_work ();
1063 }
1064
1065 void
1066 Session::set_diskstream_speed (Diskstream* stream, float speed)
1067 {
1068         if (stream->realtime_set_speed (speed, false)) {
1069                 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1070                 schedule_butler_transport_work ();
1071                 set_dirty ();
1072         }
1073 }
1074
1075 void
1076 Session::set_audio_range (list<AudioRange>& range)
1077 {
1078         Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1079         ev->audio_range = range;
1080         queue_event (ev);
1081 }
1082
1083 void
1084 Session::request_play_range (bool yn)
1085 {
1086         Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1087         queue_event (ev);
1088 }
1089
1090 void
1091 Session::set_play_range (bool yn)
1092 {
1093         /* Called from event-processing context */
1094
1095         if (_play_range != yn) {
1096                 _play_range = yn;
1097                 setup_auto_play ();
1098
1099                 if (!_play_range) {
1100                         /* stop transport */
1101                         Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1102                         merge_event (ev);
1103                 }
1104         }
1105 }
1106
1107 void
1108 Session::setup_auto_play ()
1109 {
1110         /* Called from event-processing context */
1111
1112         Event* ev;
1113         
1114         _clear_event_type (Event::RangeStop);
1115         _clear_event_type (Event::RangeLocate);
1116
1117         if (!_play_range) {
1118                 return;
1119         }
1120
1121         list<AudioRange>::size_type sz = current_audio_range.size();
1122         
1123         if (sz > 1) {
1124                 
1125                 list<AudioRange>::iterator i = current_audio_range.begin(); 
1126                 list<AudioRange>::iterator next;
1127                 
1128                 while (i != current_audio_range.end()) {
1129                         
1130                         next = i;
1131                         ++next;
1132                         
1133                         /* locating/stopping is subject to delays for declicking.
1134                          */
1135                         
1136                         nframes_t requested_frame = (*i).end;
1137                         
1138                         if (requested_frame > current_block_size) {
1139                                 requested_frame -= current_block_size;
1140                         } else {
1141                                 requested_frame = 0;
1142                         }
1143                         
1144                         if (next == current_audio_range.end()) {
1145                                 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1146                         } else {
1147                                 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1148                         }
1149                         
1150                         merge_event (ev);
1151                         
1152                         i = next;
1153                 }
1154                 
1155         } else if (sz == 1) {
1156                 
1157                 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1158                 merge_event (ev);
1159                 
1160         } 
1161
1162         /* now start rolling at the right place */
1163         
1164         ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1165         merge_event (ev);
1166 }
1167
1168 void
1169 Session::request_bounded_roll (nframes_t start, nframes_t end)
1170 {
1171         request_stop ();
1172         Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1173         queue_event (ev);
1174         request_locate (start, true);
1175 }
1176
1177 void
1178 Session::engine_halted ()
1179 {
1180         bool ignored;
1181
1182         /* there will be no more calls to process(), so
1183            we'd better clean up for ourselves, right now.
1184
1185            but first, make sure the butler is out of 
1186            the picture.
1187         */
1188
1189         g_atomic_int_set (&butler_should_do_transport_work, 0);
1190         post_transport_work = PostTransportWork (0);
1191         stop_butler ();
1192         
1193         realtime_stop (false);
1194         non_realtime_stop (false, 0, ignored);
1195         transport_sub_state = 0;
1196
1197         TransportStateChange (); /* EMIT SIGNAL */
1198 }
1199
1200
1201 void
1202 Session::xrun_recovery ()
1203 {
1204         if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1205
1206                  HaltOnXrun (); /* EMIT SIGNAL */
1207
1208                 /* it didn't actually halt, but we need
1209                    to handle things in the same way.
1210                 */
1211
1212                 engine_halted();
1213         } 
1214 }
1215
1216 void
1217 Session::update_latency_compensation (bool with_stop, bool abort)
1218 {
1219         bool update_jack = false;
1220
1221         if (_state_of_the_state & Deletion) {
1222                 return;
1223         }
1224
1225         _worst_track_latency = 0;
1226
1227         boost::shared_ptr<RouteList> r = routes.reader ();
1228
1229         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1230                 if (with_stop) {
1231                         (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate), 
1232                                                         (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1233                 }
1234
1235                 nframes_t old_latency = (*i)->signal_latency ();
1236                 nframes_t track_latency = (*i)->update_total_latency ();
1237
1238                 if (old_latency != track_latency) {
1239                         update_jack = true;
1240                 }
1241                 
1242                 if (!(*i)->hidden() && ((*i)->active())) {
1243                         _worst_track_latency = max (_worst_track_latency, track_latency);
1244                 }
1245         }
1246
1247         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1248                 (*i)->set_latency_delay (_worst_track_latency);
1249         }
1250
1251         /* tell JACK to play catch up */
1252
1253         if (update_jack) {
1254                 _engine.update_total_latencies ();
1255         }
1256
1257         set_worst_io_latencies ();
1258
1259         /* reflect any changes in latencies into capture offsets
1260         */
1261         
1262         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1263
1264         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1265                 (*i)->set_capture_offset ();
1266         }
1267 }
1268
1269 void
1270 Session::update_latency_compensation_proxy (void* ignored)
1271 {
1272         update_latency_compensation (false, false);
1273 }
1274
1275 void
1276 Session::allow_auto_play (bool yn)
1277 {
1278         auto_play_legal = yn;
1279 }
1280
1281 void
1282 Session::reset_jack_connection (jack_client_t* jack)
1283 {
1284         JACK_Slave* js;
1285
1286         if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1287                 js->reset_client (jack);
1288         }
1289 }