lock processor list and reconfigure processors after moving meter or control outs...
[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_sync_source (SyncSource src)
83 {
84         Event* ev = new Event (Event::SetSyncSource, 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->sync_source = 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_external_sync()&& 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_external_sync() && 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_external_sync() && 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_external_sync() && (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::drop_sync_source ()
1146 {
1147         bool non_rt_required = false;
1148
1149         if (_transport_speed) {
1150                 error << _("please stop the transport before adjusting slave settings") << endmsg;
1151                 return;
1152         }
1153
1154         delete _slave;
1155         _slave = 0;
1156
1157         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1158         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1159                 if (!(*i)->hidden()) {
1160                         if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1161                                 non_rt_required = true;
1162                         }
1163                         (*i)->set_slaved (0);
1164                 }
1165         }
1166
1167         if (non_rt_required) {
1168                 add_post_transport_work (PostTransportSpeed);
1169                 _butler->schedule_transport_work ();
1170         }
1171
1172         set_dirty();
1173 }
1174
1175 void
1176 Session::use_sync_source (SyncSource src)
1177 {
1178         bool reverse = false;
1179         bool non_rt_required = false;
1180
1181         if (_transport_speed) {
1182                 error << _("please stop the transport before adjusting slave settings") << endmsg;
1183                 return;
1184         }
1185
1186         delete _slave;
1187         _slave = 0;
1188
1189         switch (src) {
1190         case MTC:
1191                 if (_mtc_port) {
1192                         try {
1193                                 _slave = new MTC_Slave (*this, *_mtc_port);
1194                         }
1195
1196                         catch (failed_constructor& err) {
1197                                 return;
1198                         }
1199
1200                 } else {
1201                         error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1202                         return;
1203                 }
1204                 break;
1205
1206         case MIDIClock:
1207                 if (_midi_clock_port) {
1208                         try {
1209                                 _slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24);
1210                         }
1211
1212                         catch (failed_constructor& err) {
1213                                 return;
1214                         }
1215
1216                 } else {
1217                         error << _("No MIDI Clock port defined: MIDI Clock slaving is impossible.") << endmsg;
1218                         return;
1219                 }
1220                 break;
1221
1222         case JACK:
1223                 _slave = new JACK_Slave (_engine.jack());
1224                 break;
1225
1226         };
1227
1228         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1229         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1230                 if (!(*i)->hidden()) {
1231                         if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1232                                 non_rt_required = true;
1233                         }
1234                         (*i)->set_slaved (_slave);
1235                 }
1236         }
1237
1238         if (reverse) {
1239                 reverse_diskstream_buffers ();
1240         }
1241
1242         if (non_rt_required) {
1243                 add_post_transport_work (PostTransportSpeed);
1244                 _butler->schedule_transport_work ();
1245         }
1246
1247         set_dirty();
1248 }
1249
1250 void
1251 Session::reverse_diskstream_buffers ()
1252 {
1253         add_post_transport_work (PostTransportReverse);
1254         _butler->schedule_transport_work ();
1255 }
1256
1257 void
1258 Session::set_diskstream_speed (Diskstream* stream, double speed)
1259 {
1260         if (stream->realtime_set_speed (speed, false)) {
1261                 add_post_transport_work (PostTransportSpeed);
1262                 _butler->schedule_transport_work ();
1263                 set_dirty ();
1264         }
1265 }
1266
1267 void
1268 Session::unset_play_range ()
1269 {
1270         _play_range = false;
1271         _clear_event_type (Event::RangeStop);
1272         _clear_event_type (Event::RangeLocate);
1273 }
1274
1275 void
1276 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1277 {
1278         Event* ev;
1279
1280         /* Called from event-processing context */
1281
1282         unset_play_range ();
1283         
1284         if (range.empty()) {
1285                 /* _play_range set to false in unset_play_range()
1286                  */
1287                 if (!leave_rolling) {
1288                         /* stop transport */
1289                         Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1290                         merge_event (ev);
1291                 }
1292                 return;
1293         }
1294
1295         _play_range = true;
1296
1297         /* cancel loop play */
1298         unset_play_loop ();
1299
1300         list<AudioRange>::size_type sz = range.size();
1301         
1302         if (sz > 1) {
1303                 
1304                 list<AudioRange>::iterator i = range.begin(); 
1305                 list<AudioRange>::iterator next;
1306                 
1307                 while (i != range.end()) {
1308                         
1309                         next = i;
1310                         ++next;
1311                         
1312                         /* locating/stopping is subject to delays for declicking.
1313                          */
1314                         
1315                         nframes_t requested_frame = (*i).end;
1316                         
1317                         if (requested_frame > current_block_size) {
1318                                 requested_frame -= current_block_size;
1319                         } else {
1320                                 requested_frame = 0;
1321                         }
1322                         
1323                         if (next == range.end()) {
1324                                 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1325                         } else {
1326                                 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1327                         }
1328                         
1329                         merge_event (ev);
1330                         
1331                         i = next;
1332                 }
1333                 
1334         } else if (sz == 1) {
1335
1336                 ev = new Event (Event::RangeStop, Event::Add, range.front().end, 0, 0.0f);
1337                 merge_event (ev);
1338                 
1339         } 
1340
1341         /* save range so we can do auto-return etc. */
1342
1343         current_audio_range = range;
1344
1345         /* now start rolling at the right place */
1346
1347         ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, range.front().start, 0.0f, false);
1348         merge_event (ev);
1349         
1350         TransportStateChange ();
1351 }
1352
1353 void
1354 Session::request_bounded_roll (nframes_t start, nframes_t end)
1355 {
1356         AudioRange ar (start, end, 0);
1357         list<AudioRange> lar;
1358
1359         lar.push_back (ar);
1360         request_play_range (&lar, true);
1361 }
1362 void
1363 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1364 {
1365         Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1366         ev->target2_frame = start;
1367         queue_event (ev);
1368 }
1369
1370 void
1371 Session::engine_halted ()
1372 {
1373         bool ignored;
1374
1375         /* there will be no more calls to process(), so
1376            we'd better clean up for ourselves, right now.
1377
1378            but first, make sure the butler is out of
1379            the picture.
1380         */
1381
1382         g_atomic_int_set (&_butler->should_do_transport_work, 0);
1383         set_post_transport_work (PostTransportWork (0));
1384         _butler->stop ();
1385
1386         realtime_stop (false, true);
1387         non_realtime_stop (false, 0, ignored);
1388         transport_sub_state = 0;
1389
1390         TransportStateChange (); /* EMIT SIGNAL */
1391 }
1392
1393
1394 void
1395 Session::xrun_recovery ()
1396 {
1397         Xrun ((nframes64_t)_transport_frame); //EMIT SIGNAL
1398
1399         if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1400
1401                 /* it didn't actually halt, but we need
1402                    to handle things in the same way.
1403                 */
1404
1405                 engine_halted();
1406         }
1407 }
1408
1409 void
1410 Session::update_latency_compensation (bool with_stop, bool abort)
1411 {
1412         bool update_jack = false;
1413         PostTransportWork ptw;
1414
1415         if (_state_of_the_state & Deletion) {
1416                 return;
1417         }
1418
1419         _worst_track_latency = 0;
1420         ptw = post_transport_work();
1421
1422 #undef DEBUG_LATENCY
1423 #ifdef DEBUG_LATENCY
1424         cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1425 #endif
1426
1427         boost::shared_ptr<RouteList> r = routes.reader ();
1428
1429         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1430
1431                 if (with_stop) {
1432                         (*i)->handle_transport_stopped (abort, (ptw & PostTransportLocate), (!(ptw & PostTransportLocate) || pending_locate_flush));
1433                 }
1434
1435                 nframes_t old_latency = (*i)->output()->signal_latency ();
1436                 nframes_t track_latency = (*i)->update_total_latency ();
1437
1438                 if (old_latency != track_latency) {
1439                         (*i)->input()->update_port_total_latencies ();
1440                         (*i)->output()->update_port_total_latencies ();
1441                         update_jack = true;
1442                 }
1443
1444                 if (!(*i)->is_hidden() && ((*i)->active())) {
1445                         _worst_track_latency = max (_worst_track_latency, track_latency);
1446                 }
1447         }
1448
1449         if (update_jack) {
1450                 _engine.update_total_latencies ();
1451         }
1452
1453 #ifdef DEBUG_LATENCY
1454         cerr << "\tworst was " << _worst_track_latency << endl;
1455 #endif
1456
1457         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1458                 (*i)->set_latency_delay (_worst_track_latency);
1459         }
1460
1461         set_worst_io_latencies ();
1462
1463         /* reflect any changes in latencies into capture offsets
1464         */
1465
1466         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1467
1468         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1469                 (*i)->set_capture_offset ();
1470         }
1471 }
1472
1473 void
1474 Session::allow_auto_play (bool yn)
1475 {
1476         auto_play_legal = yn;
1477 }
1478
1479 void
1480 Session::reset_jack_connection (jack_client_t* jack)
1481 {
1482         JACK_Slave* js;
1483
1484         if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1485                 js->reset_client (jack);
1486         }
1487 }
1488
1489 bool
1490 Session::maybe_stop (nframes_t limit)
1491 {
1492        if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
1493                if (synced_to_jack () && config.get_jack_time_master ()) {
1494                        _engine.transport_stop ();
1495                } else if (!synced_to_jack ()) {
1496                        stop_transport ();
1497                }
1498                return true;
1499        }
1500        return false;
1501 }