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