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