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