new transport slave/master implementation, libs/ edition
[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 #ifdef WAF_BUILD
21 #include "libardour-config.h"
22 #endif
23
24 #include <cmath>
25 #include <cerrno>
26 #include <unistd.h>
27
28 #include "pbd/undo.h"
29 #include "pbd/error.h"
30 #include "pbd/enumwriter.h"
31 #include "pbd/pthread_utils.h"
32 #include "pbd/memento_command.h"
33 #include "pbd/stacktrace.h"
34
35 #include "midi++/mmc.h"
36 #include "midi++/port.h"
37
38 #include "ardour/audioengine.h"
39 #include "ardour/auditioner.h"
40 #include "ardour/automation_watch.h"
41 #include "ardour/butler.h"
42 #include "ardour/click.h"
43 #include "ardour/debug.h"
44 #include "ardour/disk_reader.h"
45 #include "ardour/location.h"
46 #include "ardour/playlist.h"
47 #include "ardour/profile.h"
48 #include "ardour/scene_changer.h"
49 #include "ardour/session.h"
50 #include "ardour/transport_master.h"
51 #include "ardour/transport_master_manager.h"
52 #include "ardour/tempo.h"
53 #include "ardour/operations.h"
54 #include "ardour/vca.h"
55 #include "ardour/vca_manager.h"
56
57 #include "pbd/i18n.h"
58
59 using namespace std;
60 using namespace ARDOUR;
61 using namespace PBD;
62
63 void
64 Session::add_post_transport_work (PostTransportWork ptw)
65 {
66         PostTransportWork oldval;
67         PostTransportWork newval;
68         int tries = 0;
69
70         while (tries < 8) {
71                 oldval = (PostTransportWork) g_atomic_int_get (&_post_transport_work);
72                 newval = PostTransportWork (oldval | ptw);
73                 if (g_atomic_int_compare_and_exchange (&_post_transport_work, oldval, newval)) {
74                         /* success */
75                         return;
76                 }
77         }
78
79         error << "Could not set post transport work! Crazy thread madness, call the programmers" << endmsg;
80 }
81
82 bool
83 Session::should_ignore_transport_request (TransportRequestSource src, TransportRequestType type) const
84 {
85         if (config.get_external_sync()) {
86                 if (TransportMasterManager::instance().current()->allow_request (src, type)) {
87                         return false;
88                 } else {
89                         return true;
90                 }
91         }
92         return false;
93 }
94
95 void
96 Session::request_sync_source (boost::shared_ptr<TransportMaster> tm)
97 {
98         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportMaster, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
99         ev->transport_master = tm;
100         DEBUG_TRACE (DEBUG::Slave, "sent request for new transport master\n");
101         queue_event (ev);
102 }
103
104 void
105 Session::request_transport_speed (double speed, bool as_default, TransportRequestSource origin)
106 {
107         if (should_ignore_transport_request (origin, TR_Speed)) {
108                 return;
109         }
110         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
111         ev->third_yes_or_no = as_default; // as_default
112         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport speed = %1 as default = %2\n", speed, as_default));
113         queue_event (ev);
114 }
115
116 /** Request a new transport speed, but if the speed parameter is exactly zero then use
117  *  a very small +ve value to prevent the transport actually stopping.  This method should
118  *  be used by callers who are varying transport speed but don't ever want to stop it.
119  */
120 void
121 Session::request_transport_speed_nonzero (double speed, bool as_default, TransportRequestSource origin)
122 {
123         if (should_ignore_transport_request (origin, TransportRequestType (TR_Speed|TR_Start))) {
124                 return;
125         }
126
127         if (speed == 0) {
128                 speed = DBL_EPSILON;
129         }
130
131         request_transport_speed (speed, as_default);
132 }
133
134 void
135 Session::request_stop (bool abort, bool clear_state, TransportRequestSource origin)
136 {
137         if (should_ignore_transport_request (origin, TR_Stop)) {
138                 return;
139         }
140
141         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, audible_sample(), 0.0, abort, clear_state);
142         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport stop, audible %3 transport %4 abort = %1, clear state = %2\n", abort, clear_state, audible_sample(), _transport_sample));
143         queue_event (ev);
144 }
145
146 void
147 Session::request_locate (samplepos_t target_sample, bool with_roll, TransportRequestSource origin)
148 {
149         if (should_ignore_transport_request (origin, TR_Locate)) {
150                 return;
151         }
152
153         SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_sample, 0, false);
154         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request locate to %1\n", target_sample));
155         queue_event (ev);
156 }
157
158 void
159 Session::force_locate (samplepos_t target_sample, bool with_roll)
160 {
161         SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_sample, 0, true);
162         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request forced locate to %1\n", target_sample));
163         queue_event (ev);
164 }
165
166 void
167 Session::unset_preroll_record_trim ()
168 {
169         _preroll_record_trim_len = 0;
170 }
171
172 void
173 Session::request_preroll_record_trim (samplepos_t rec_in, samplecnt_t preroll)
174 {
175         if (actively_recording ()) {
176                 return;
177         }
178         unset_preroll_record_trim ();
179
180         config.set_punch_in (false);
181         config.set_punch_out (false);
182
183         samplepos_t pos = std::max ((samplepos_t)0, rec_in - preroll);
184         _preroll_record_trim_len = preroll;
185         maybe_enable_record ();
186         request_locate (pos, true);
187         set_requested_return_sample (rec_in);
188 }
189
190 void
191 Session::request_count_in_record ()
192 {
193         if (actively_recording ()) {
194                 return;
195         }
196         if (transport_rolling()) {
197                 return;
198         }
199         maybe_enable_record ();
200         _count_in_once = true;
201         request_transport_speed (1.0, true);
202 }
203
204 void
205 Session::request_play_loop (bool yn, bool change_transport_roll)
206 {
207         if (transport_master_is_external() && yn) {
208                 // don't attempt to loop when not using Internal Transport
209                 // see also gtk2_ardour/ardour_ui_options.cc parameter_changed()
210                 return;
211         }
212
213         SessionEvent* ev;
214         Location *location = _locations->auto_loop_location();
215         double target_speed;
216
217         if (location == 0 && yn) {
218                 error << _("Cannot loop - no loop range defined")
219                       << endmsg;
220                 return;
221         }
222
223         if (change_transport_roll) {
224                 if (transport_rolling()) {
225                         /* start looping at current speed */
226                         target_speed = transport_speed ();
227                 } else {
228                         /* currently stopped */
229                         if (yn) {
230                                 /* start looping at normal speed */
231                                 target_speed = 1.0;
232                         } else {
233                                 target_speed = 0.0;
234                         }
235                 }
236         } else {
237                 /* leave the speed alone */
238                 target_speed = transport_speed ();
239         }
240
241         ev = new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, target_speed, yn);
242         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request set loop = %1, change roll state ? %2\n", yn, change_transport_roll));
243         queue_event (ev);
244
245         if (yn) {
246                 if (!change_transport_roll) {
247                         if (!transport_rolling()) {
248                                 /* we're not changing transport state, but we do want
249                                    to set up position for the new loop. Don't
250                                    do this if we're rolling already.
251                                 */
252                                 request_locate (location->start(), false);
253                         }
254                 }
255         } else {
256                 if (!change_transport_roll && Config->get_seamless_loop() && transport_rolling()) {
257                         // request an immediate locate to refresh the tracks
258                         // after disabling looping
259                         request_locate (_transport_sample-1, false);
260                 }
261         }
262 }
263
264 void
265 Session::request_play_range (list<AudioRange>* range, bool leave_rolling)
266 {
267         SessionEvent* ev = new SessionEvent (SessionEvent::SetPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0));
268         if (range) {
269                 ev->audio_range = *range;
270         } else {
271                 ev->audio_range.clear ();
272         }
273         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request play range, leave rolling ? %1\n", leave_rolling));
274         queue_event (ev);
275 }
276
277 void
278 Session::request_cancel_play_range ()
279 {
280         SessionEvent* ev = new SessionEvent (SessionEvent::CancelPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, 0);
281         queue_event (ev);
282 }
283
284
285 bool
286 Session::solo_selection_active ()
287 {
288         if ( _soloSelection.empty() ) {
289                 return false;
290         }
291         return true;
292 }
293
294 void
295 Session::solo_selection ( StripableList &list, bool new_state  )
296 {
297         boost::shared_ptr<ControlList> solo_list (new ControlList);
298         boost::shared_ptr<ControlList> unsolo_list (new ControlList);
299
300         if (new_state)
301                 _soloSelection = list;
302         else
303                 _soloSelection.clear();
304
305         boost::shared_ptr<RouteList> rl = get_routes();
306
307         for (ARDOUR::RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
308
309                 if ( !(*i)->is_track() ) {
310                         continue;
311                 }
312
313                 boost::shared_ptr<Stripable> s (*i);
314
315                 bool found = (std::find(list.begin(), list.end(), s) != list.end());
316                 if ( new_state && found ) {
317
318                         solo_list->push_back (s->solo_control());
319
320                         //must invalidate playlists on selected tracks, so only selected regions get heard
321                         boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track> (*i);
322                         if (track) {
323                                 boost::shared_ptr<Playlist> playlist = track->playlist();
324                                 if (playlist) {
325                                         playlist->ContentsChanged();
326                                 }
327                         }
328                 } else {
329                         unsolo_list->push_back (s->solo_control());
330                 }
331         }
332
333         set_controls (solo_list, 1.0, Controllable::NoGroup);
334         set_controls (unsolo_list, 0.0, Controllable::NoGroup);
335 }
336
337 void
338 Session::realtime_stop (bool abort, bool clear_state)
339 {
340         DEBUG_TRACE (DEBUG::Transport, string_compose ("realtime stop @ %1\n", _transport_sample));
341         PostTransportWork todo = PostTransportWork (0);
342
343         /* assume that when we start, we'll be moving forwards */
344
345         if (_transport_speed < 0.0f) {
346                 todo = (PostTransportWork (todo | PostTransportStop | PostTransportReverse));
347                 _default_transport_speed = 1.0;
348         } else {
349                 todo = PostTransportWork (todo | PostTransportStop);
350         }
351
352         /* call routes */
353
354         boost::shared_ptr<RouteList> r = routes.reader ();
355
356         for (RouteList::iterator i = r->begin (); i != r->end(); ++i) {
357                 (*i)->realtime_handle_transport_stopped ();
358         }
359
360         DEBUG_TRACE (DEBUG::Transport, string_compose ("stop complete, auto-return scheduled for return to %1\n", _requested_return_sample));
361
362         /* the duration change is not guaranteed to have happened, but is likely */
363
364         todo = PostTransportWork (todo | PostTransportDuration);
365
366         if (abort) {
367                 todo = PostTransportWork (todo | PostTransportAbort);
368         }
369
370         if (clear_state) {
371                 todo = PostTransportWork (todo | PostTransportClearSubstate);
372         }
373
374         if (todo) {
375                 add_post_transport_work (todo);
376         }
377
378         _clear_event_type (SessionEvent::StopOnce);
379         _clear_event_type (SessionEvent::RangeStop);
380         _clear_event_type (SessionEvent::RangeLocate);
381
382         //clear our solo-selection, if there is one
383         if ( solo_selection_active() ) {
384                 solo_selection ( _soloSelection, false );
385         }
386
387         /* if we're going to clear loop state, then force disabling record BUT only if we're not doing latched rec-enable */
388         disable_record (true, (!Config->get_latched_record_enable() && clear_state));
389
390         if (clear_state && !Config->get_loop_is_mode()) {
391                 unset_play_loop ();
392         }
393
394         reset_slave_state ();
395
396         _transport_speed = 0;
397         _target_transport_speed = 0;
398         _engine_speed = 1.0;
399
400         g_atomic_int_set (&_playback_load, 100);
401         g_atomic_int_set (&_capture_load, 100);
402
403         if (config.get_use_video_sync()) {
404                 waiting_for_sync_offset = true;
405         }
406
407         transport_sub_state = 0;
408 }
409
410 void
411 Session::realtime_locate ()
412 {
413         boost::shared_ptr<RouteList> r = routes.reader ();
414         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
415                 (*i)->realtime_locate ();
416         }
417 }
418
419 void
420 Session::butler_transport_work ()
421 {
422         /* Note: this function executes in the butler thread context */
423
424   restart:
425         bool finished;
426         PostTransportWork ptw;
427         boost::shared_ptr<RouteList> r = routes.reader ();
428         uint64_t before;
429
430         int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
431         finished = true;
432         ptw = post_transport_work();
433
434         DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler transport work, todo = %1 at %2\n", enum_2_string (ptw), (before = g_get_monotonic_time())));
435
436
437         if (ptw & PostTransportLocate) {
438
439                 if (get_play_loop() && !Config->get_seamless_loop()) {
440
441                         DEBUG_TRACE (DEBUG::Butler, "flush loop recording fragment to disk\n");
442
443                         /* this locate might be happening while we are
444                          * loop recording.
445                          *
446                          * Non-seamless looping will require a locate (below) that
447                          * will reset capture buffers and throw away data.
448                          *
449                          * Rather than first find all tracks and see if they
450                          * have outstanding data, just do a flush anyway. It
451                          * may be cheaper this way anyway, and is certainly
452                          * more accurate.
453                          */
454
455                         bool more_disk_io_to_do = false;
456                         uint32_t errors = 0;
457
458                         do {
459                                 more_disk_io_to_do = _butler->flush_tracks_to_disk_after_locate (r, errors);
460
461                                 if (errors) {
462                                         break;
463                                 }
464
465                                 if (more_disk_io_to_do) {
466                                         continue;
467                                 }
468
469                         } while (false);
470
471                 }
472         }
473
474         if (ptw & PostTransportAdjustPlaybackBuffering) {
475                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
476                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
477                         if (tr) {
478                                 tr->adjust_playback_buffering ();
479                                 /* and refill those buffers ... */
480                         }
481                         (*i)->non_realtime_locate (_transport_sample);
482                 }
483                 VCAList v = _vca_manager->vcas ();
484                 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
485                         (*i)->non_realtime_locate (_transport_sample);
486                 }
487         }
488
489         if (ptw & PostTransportAdjustCaptureBuffering) {
490                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
491                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
492                         if (tr) {
493                                 tr->adjust_capture_buffering ();
494                         }
495                 }
496         }
497
498         if (ptw & PostTransportCurveRealloc) {
499                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
500                         (*i)->curve_reallocate();
501                 }
502         }
503
504         if (ptw & PostTransportReverse) {
505
506                 clear_clicks();
507                 cumulative_rf_motion = 0;
508                 reset_rf_scale (0);
509
510                 /* don't seek if locate will take care of that in non_realtime_stop() */
511
512                 if (!(ptw & PostTransportLocate)) {
513                         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
514                                 (*i)->non_realtime_locate (_transport_sample);
515
516                                 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
517                                         /* new request, stop seeking, and start again */
518                                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
519                                         goto restart;
520                                 }
521                         }
522                         VCAList v = _vca_manager->vcas ();
523                         for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
524                                 (*i)->non_realtime_locate (_transport_sample);
525                         }
526                 }
527         }
528
529         if (ptw & PostTransportLocate) {
530                 DEBUG_TRACE (DEBUG::Transport, "nonrealtime locate invoked from BTW\n");
531                 non_realtime_locate ();
532         }
533
534         if (ptw & PostTransportStop) {
535                 non_realtime_stop (ptw & PostTransportAbort, on_entry, finished);
536                 if (!finished) {
537                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
538                         goto restart;
539                 }
540         }
541
542         if (ptw & PostTransportOverWrite) {
543                 non_realtime_overwrite (on_entry, finished);
544                 if (!finished) {
545                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
546                         goto restart;
547                 }
548         }
549
550         if (ptw & PostTransportAudition) {
551                 non_realtime_set_audition ();
552         }
553
554         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
555
556         DEBUG_TRACE (DEBUG::Transport, string_compose (X_("Butler transport work all done after %1 usecs @ %2 trw = %3\n"), g_get_monotonic_time() - before, _transport_sample, _butler->transport_work_requested()));
557 }
558
559 void
560 Session::non_realtime_overwrite (int on_entry, bool& finished)
561 {
562         boost::shared_ptr<RouteList> rl = routes.reader();
563         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
564                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
565                 if (tr && tr->pending_overwrite ()) {
566                         tr->overwrite_existing_buffers ();
567                 }
568                 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
569                         finished = false;
570                         return;
571                 }
572         }
573 }
574
575
576 void
577 Session::non_realtime_locate ()
578 {
579         DEBUG_TRACE (DEBUG::Transport, string_compose ("locate tracks to %1\n", _transport_sample));
580
581         if (Config->get_loop_is_mode() && get_play_loop()) {
582
583                 Location *loc  = _locations->auto_loop_location();
584
585                 if (!loc || (_transport_sample < loc->start() || _transport_sample >= loc->end())) {
586                         /* jumped out of loop range: stop tracks from looping,
587                            but leave loop (mode) enabled.
588                          */
589                         set_track_loop (false);
590
591                 } else if (loc && Config->get_seamless_loop() &&
592                    ((loc->start() <= _transport_sample) ||
593                    (loc->end() > _transport_sample) ) ) {
594
595                         /* jumping to start of loop. This  might have been done before but it is
596                          * idempotent and cheap. Doing it here ensures that when we start playback
597                          * outside the loop we still flip tracks into the magic seamless mode
598                          * when needed.
599                          */
600                         set_track_loop (true);
601
602                 } else if (loc) {
603                         set_track_loop (false);
604                 }
605
606         } else {
607
608                 /* no more looping .. should have been noticed elsewhere */
609         }
610
611
612         samplepos_t tf;
613
614         {
615                 boost::shared_ptr<RouteList> rl = routes.reader();
616
617           restart:
618                 gint sc = g_atomic_int_get (&_seek_counter);
619                 tf = _transport_sample;
620
621                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
622                         (*i)->non_realtime_locate (tf);
623                         if (sc != g_atomic_int_get (&_seek_counter)) {
624                                 goto restart;
625                         }
626                 }
627         }
628
629         {
630                 /* VCAs are quick to locate because they have no data (except
631                    automation) associated with them. Don't bother with a
632                    restart mechanism here, but do use the same transport sample
633                    that the Routes used.
634                 */
635                 VCAList v = _vca_manager->vcas ();
636                 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
637                         (*i)->non_realtime_locate (tf);
638                 }
639         }
640
641         _scene_changer->locate (_transport_sample);
642
643         /* XXX: it would be nice to generate the new clicks here (in the non-RT thread)
644            rather than clearing them so that the RT thread has to spend time constructing
645            them (in Session::click).
646          */
647         clear_clicks ();
648 }
649
650 #ifdef USE_TRACKS_CODE_FEATURES
651 bool
652 Session::select_playhead_priority_target (samplepos_t& jump_to)
653 {
654         jump_to = -1;
655
656         AutoReturnTarget autoreturn = Config->get_auto_return_target_list ();
657
658         if (!autoreturn) {
659                 return false;
660         }
661
662         if (Profile->get_trx() && transport_rolling() ) {
663                 // We're playing, so do nothing.
664                 // Next stop will put us where we need to be.
665                 return false;
666         }
667
668         /* Note that the order of checking each AutoReturnTarget flag defines
669            the priority each flag.
670
671            Ardour/Mixbus: Last Locate
672                           Range Selection
673                           Loop Range
674                           Region Selection
675
676            Tracks:        Range Selection
677                           Loop Range
678                           Region Selection
679                           Last Locate
680         */
681
682         if (autoreturn & RangeSelectionStart) {
683                 if (!_range_selection.empty()) {
684                         jump_to = _range_selection.from;
685                 } else {
686                         if (transport_rolling ()) {
687                                 /* Range selection no longer exists, but we're playing,
688                                    so do nothing. Next stop will put us where
689                                    we need to be.
690                                 */
691                                 return false;
692                         }
693                 }
694         }
695
696         if (jump_to < 0 && (autoreturn & Loop) && get_play_loop()) {
697                 /* don't try to handle loop play when synced to JACK */
698
699                 if (!synced_to_engine()) {
700                         Location *location = _locations->auto_loop_location();
701
702                         if (location) {
703                                 jump_to = location->start();
704
705                                 if (Config->get_seamless_loop()) {
706                                         /* need to get track buffers reloaded */
707                                         set_track_loop (true);
708                                 }
709                         }
710                 }
711         }
712
713         if (jump_to < 0 && (autoreturn & RegionSelectionStart)) {
714                 if (!_object_selection.empty()) {
715                         jump_to = _object_selection.from;
716                 }
717         }
718
719         if (jump_to < 0 && (autoreturn & LastLocate)) {
720                 jump_to = _last_roll_location;
721         }
722
723         return jump_to >= 0;
724 }
725 #else
726
727 bool
728 Session::select_playhead_priority_target (samplepos_t& jump_to)
729 {
730         if (config.get_external_sync() || !config.get_auto_return()) {
731                 return false;
732         }
733
734         jump_to = _last_roll_location;
735         return jump_to >= 0;
736 }
737
738 #endif
739
740 void
741 Session::follow_playhead_priority ()
742 {
743         samplepos_t target;
744
745         if (select_playhead_priority_target (target)) {
746                 request_locate (target);
747         }
748 }
749
750 void
751 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
752 {
753         struct tm* now;
754         time_t     xnow;
755         bool       did_record;
756         bool       saved;
757         PostTransportWork ptw = post_transport_work();
758
759         did_record = false;
760         saved = false;
761
762         boost::shared_ptr<RouteList> rl = routes.reader();
763         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
764                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
765                 if (tr && tr->get_captured_samples () != 0) {
766                         did_record = true;
767                         break;
768                 }
769         }
770
771         /* stop and locate are merged here because they share a lot of common stuff */
772
773         time (&xnow);
774         now = localtime (&xnow);
775
776         if (auditioner) {
777                 auditioner->cancel_audition ();
778         }
779
780         cumulative_rf_motion = 0;
781         reset_rf_scale (0);
782
783         if (did_record) {
784                 begin_reversible_command (Operations::capture);
785                 _have_captured = true;
786         }
787
788         DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: DS stop\n"));
789
790         if (abort && did_record) {
791                 /* no reason to save the session file when we remove sources
792                  */
793                 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
794         }
795
796         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
797                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
798                 if (tr) {
799                         tr->transport_stopped_wallclock (*now, xnow, abort);
800                 }
801         }
802
803         if (abort && did_record) {
804                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
805         }
806
807         boost::shared_ptr<RouteList> r = routes.reader ();
808
809         if (did_record) {
810                 commit_reversible_command ();
811                 /* increase take name */
812                 if (config.get_track_name_take () && !config.get_take_name ().empty()) {
813                         string newname = config.get_take_name();
814                         config.set_take_name(bump_name_number (newname));
815                 }
816         }
817
818         if (_engine.running()) {
819                 PostTransportWork ptw = post_transport_work ();
820
821                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
822                         (*i)->non_realtime_transport_stop (_transport_sample, !(ptw & PostTransportLocate));
823                 }
824                 VCAList v = _vca_manager->vcas ();
825                 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
826                         (*i)->non_realtime_transport_stop (_transport_sample, !(ptw & PostTransportLocate));
827                 }
828
829                 update_latency_compensation ();
830         }
831
832         bool const auto_return_enabled = (!config.get_external_sync() && (Config->get_auto_return_target_list() || abort));
833
834         if (auto_return_enabled ||
835             (ptw & PostTransportLocate) ||
836             (_requested_return_sample >= 0) ||
837             synced_to_engine()) {
838
839                 // rg: what is the logic behind this case?
840                 // _requested_return_sample should be ignored when synced_to_engine/slaved.
841                 // currently worked around in MTC_Slave by forcing _requested_return_sample to -1
842                 // 2016-01-10
843                 if ((auto_return_enabled || synced_to_engine() || _requested_return_sample >= 0) &&
844                     !(ptw & PostTransportLocate)) {
845
846                         /* no explicit locate queued */
847
848                         bool do_locate = false;
849
850                         if (_requested_return_sample >= 0) {
851
852                                 /* explicit return request pre-queued in event list. overrides everything else */
853
854                                 _transport_sample = _requested_return_sample;
855                                 do_locate = true;
856
857                         } else {
858                                 samplepos_t jump_to;
859
860                                 if (select_playhead_priority_target (jump_to)) {
861
862                                         _transport_sample = jump_to;
863                                         do_locate = true;
864
865                                 } else if (abort) {
866
867                                         _transport_sample = _last_roll_location;
868                                         do_locate = true;
869                                 }
870                         }
871
872                         _requested_return_sample = -1;
873
874                         if (do_locate) {
875                                 _engine.transport_locate (_transport_sample);
876                         }
877                 }
878
879         }
880
881         clear_clicks();
882         unset_preroll_record_trim ();
883
884         /* do this before seeking, because otherwise the tracks will do the wrong thing in seamless loop mode.
885         */
886
887         if (ptw & PostTransportClearSubstate) {
888                 unset_play_range ();
889                 if (!Config->get_loop_is_mode()) {
890                         unset_play_loop ();
891                 }
892         }
893
894         /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
895
896         {
897                 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: locate\n"));
898                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
899                         DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler PTW: locate on %1\n", (*i)->name()));
900                         (*i)->non_realtime_locate (_transport_sample);
901
902                         if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
903                                 finished = false;
904                                 /* we will be back */
905                                 return;
906                         }
907                 }
908         }
909
910         {
911                 VCAList v = _vca_manager->vcas ();
912                 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
913                         (*i)->non_realtime_locate (_transport_sample);
914                 }
915         }
916
917         have_looped = false;
918
919         /* don't bother with this stuff if we're disconnected from the engine,
920            because there will be no process callbacks to deliver stuff from
921         */
922
923         if (_engine.connected() && !_engine.freewheeling()) {
924                 // need to queue this in the next RT cycle
925                 _send_timecode_update = true;
926
927                 if (transport_master()->type() == MTC) {
928                         send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
929
930                         /* This (::non_realtime_stop()) gets called by main
931                            process thread, which will lead to confusion
932                            when calling AsyncMIDIPort::write().
933
934                            Something must be done. XXX
935                         */
936                         send_mmc_locate (_transport_sample);
937                 }
938         }
939
940         if ((ptw & PostTransportLocate) && get_record_enabled()) {
941                 /* This is scheduled by realtime_stop(), which is also done
942                  * when a slave requests /locate/ for an initial sync.
943                  * We can't hold up the slave for long with a save() here,
944                  * without breaking its initial sync cycle.
945                  *
946                  * save state only if there's no slave or if it's not yet locked.
947                  */
948                 if (!transport_master_is_external() || !transport_master()->locked()) {
949                         DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: requests save\n"));
950                         SaveSessionRequested (_current_snapshot_name);
951                         saved = true;
952                 }
953         }
954
955         /* always try to get rid of this */
956
957         remove_pending_capture_state ();
958
959         /* save the current state of things if appropriate */
960
961         if (did_record && !saved) {
962                 SaveSessionRequested (_current_snapshot_name);
963         }
964
965         if (ptw & PostTransportStop) {
966                 unset_play_range ();
967                 if (!Config->get_loop_is_mode()) {
968                         unset_play_loop ();
969                 }
970         }
971
972         PositionChanged (_transport_sample); /* EMIT SIGNAL */
973         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC with speed = %1\n", _transport_speed));
974         TransportStateChange (); /* EMIT SIGNAL */
975         AutomationWatch::instance().transport_stop_automation_watches (_transport_sample);
976
977         /* and start it up again if relevant */
978
979         if ((ptw & PostTransportLocate) && !config.get_external_sync()) {
980                 request_transport_speed (1.0);
981         }
982 }
983
984 void
985 Session::unset_play_loop ()
986 {
987         if (play_loop) {
988                 play_loop = false;
989                 clear_events (SessionEvent::AutoLoop);
990                 set_track_loop (false);
991
992
993                 if (Config->get_seamless_loop()) {
994                         /* likely need to flush track buffers: this will locate us to wherever we are */
995                         add_post_transport_work (PostTransportLocate);
996                         _butler->schedule_transport_work ();
997                 }
998         }
999 }
1000
1001 void
1002 Session::set_track_loop (bool yn)
1003 {
1004         Location* loc = _locations->auto_loop_location ();
1005
1006         if (!loc) {
1007                 yn = false;
1008         }
1009
1010         boost::shared_ptr<RouteList> rl = routes.reader ();
1011
1012         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1013                 if (*i && !(*i)->is_private_route()) {
1014                         (*i)->set_loop (yn ? loc : 0);
1015                 }
1016         }
1017 }
1018
1019 void
1020 Session::set_play_loop (bool yn, double speed)
1021 {
1022         /* Called from event-handling context */
1023
1024         Location *loc;
1025
1026         if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) {
1027                 /* nothing to do, or can't change loop status while recording */
1028                 return;
1029         }
1030
1031         if (yn && Config->get_seamless_loop() && synced_to_engine()) {
1032                 warning << string_compose (
1033                         _("Seamless looping cannot be supported while %1 is using JACK transport.\n"
1034                           "Recommend changing the configured options"), PROGRAM_NAME)
1035                         << endmsg;
1036                 return;
1037         }
1038
1039         if (yn) {
1040
1041                 play_loop = true;
1042                 have_looped = false;
1043
1044                 if (loc) {
1045
1046                         unset_play_range ();
1047
1048                         if (Config->get_seamless_loop()) {
1049                                 if (!Config->get_loop_is_mode()) {
1050                                         /* set all tracks to use internal looping */
1051                                         set_track_loop (true);
1052                                 } else {
1053                                         /* we will do this in the locate to the start OR when we hit the end
1054                                          * of the loop for the first time
1055                                          */
1056                                 }
1057                         } else {
1058                                 /* set all tracks to NOT use internal looping */
1059                                 set_track_loop (false);
1060                         }
1061
1062                         /* Put the delick and loop events in into the event list.  The declick event will
1063                            cause a de-clicking fade-out just before the end of the loop, and it will also result
1064                            in a fade-in when the loop restarts.  The AutoLoop event will peform the actual loop.
1065                         */
1066
1067                         samplepos_t dcp;
1068                         samplecnt_t dcl;
1069                         auto_loop_declick_range (loc, dcp, dcl);
1070                         merge_event (new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f));
1071
1072                         /* if requested to roll, locate to start of loop and
1073                          * roll but ONLY if we're not already rolling.
1074
1075                            args: positition, roll=true, flush=true, with_loop=false, force buffer refill if seamless looping
1076                         */
1077
1078                         if (Config->get_loop_is_mode()) {
1079                                 /* loop IS a transport mode: if already
1080                                    rolling, do not locate to loop start.
1081                                 */
1082                                 if (!transport_rolling() && (speed != 0.0)) {
1083                                         start_locate (loc->start(), true, true, false, true);
1084                                 }
1085                         } else {
1086                                 if (speed != 0.0) {
1087                                         start_locate (loc->start(), true, true, false, true);
1088                                 }
1089                         }
1090                 }
1091
1092         } else {
1093
1094                 unset_play_loop ();
1095         }
1096
1097         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC2 with speed = %1\n", _transport_speed));
1098         TransportStateChange ();
1099 }
1100 void
1101 Session::flush_all_inserts ()
1102 {
1103         boost::shared_ptr<RouteList> r = routes.reader ();
1104
1105         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1106                 (*i)->flush_processors ();
1107         }
1108 }
1109
1110 void
1111 Session::start_locate (samplepos_t target_sample, bool with_roll, bool with_flush, bool for_loop_enabled, bool force)
1112 {
1113         if (target_sample < 0) {
1114                 error << _("Locate called for negative sample position - ignored") << endmsg;
1115                 return;
1116         }
1117
1118         if (synced_to_engine()) {
1119
1120                 double sp;
1121                 samplepos_t pos;
1122
1123                 transport_master()->speed_and_position (sp, pos, 0);
1124
1125                 if (target_sample != pos) {
1126
1127                         if (config.get_jack_time_master()) {
1128                                 /* actually locate now, since otherwise jack_timebase_callback
1129                                    will use the incorrect _transport_sample and report an old
1130                                    and incorrect time to Jack transport
1131                                 */
1132                                 locate (target_sample, with_roll, with_flush, for_loop_enabled, force);
1133                         }
1134
1135                         /* tell JACK to change transport position, and we will
1136                            follow along later in ::follow_slave()
1137                         */
1138
1139                         _engine.transport_locate (target_sample);
1140
1141                         if (sp != 1.0f && with_roll) {
1142                                 _engine.transport_start ();
1143                         }
1144
1145                 }
1146
1147         } else {
1148                 locate (target_sample, with_roll, with_flush, for_loop_enabled, force);
1149         }
1150 }
1151
1152 samplecnt_t
1153 Session::worst_latency_preroll () const
1154 {
1155         return _worst_output_latency + _worst_input_latency;
1156 }
1157
1158 int
1159 Session::micro_locate (samplecnt_t distance)
1160 {
1161         boost::shared_ptr<RouteList> rl = routes.reader();
1162         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1163                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1164                 if (tr && !tr->can_internal_playback_seek (distance)) {
1165                         return -1;
1166                 }
1167         }
1168
1169         DEBUG_TRACE (DEBUG::Transport, string_compose ("micro-locate by %1\n", distance));
1170
1171         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1172                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1173                 if (tr) {
1174                         tr->internal_playback_seek (distance);
1175                 }
1176         }
1177
1178         _transport_sample += distance;
1179         return 0;
1180 }
1181
1182 /** @param with_mmc true to send a MMC locate command when the locate is done */
1183 void
1184 Session::locate (samplepos_t target_sample, bool with_roll, bool with_flush, bool for_loop_enabled, bool force, bool with_mmc)
1185 {
1186         bool need_butler = false;
1187
1188         /* Locates for seamless looping are fairly different from other
1189          * locates. They assume that the diskstream buffers for each track
1190          * already have the correct data in them, and thus there is no need to
1191          * actually tell the tracks to locate. What does need to be done,
1192          * though, is all the housekeeping that is associated with non-linear
1193          * changes in the value of _transport_sample.
1194          */
1195
1196         DEBUG_TRACE (DEBUG::Transport, string_compose ("rt-locate to %1, roll %2 flush %3 loop-enabled %4 force %5 mmc %6\n",
1197                                                        target_sample, with_roll, with_flush, for_loop_enabled, force, with_mmc));
1198
1199         if (!force && _transport_sample == target_sample && !loop_changing && !for_loop_enabled) {
1200
1201                 /* already at the desired position. Not forced to locate,
1202                    the loop isn't changing, so unless we're told to
1203                    start rolling also, there's nothing to do but
1204                    tell the world where we are (again).
1205                 */
1206
1207                 if (with_roll) {
1208                         set_transport_speed (1.0, 0, false);
1209                 }
1210                 loop_changing = false;
1211                 Located (); /* EMIT SIGNAL */
1212                 return;
1213         }
1214
1215         cerr << "... now doing the actual locate\n";
1216
1217         // Update Timecode time
1218         _transport_sample = target_sample;
1219         // Bump seek counter so that any in-process locate in the butler
1220         // thread(s?) can restart.
1221         g_atomic_int_inc (&_seek_counter);
1222         _last_roll_or_reversal_location = target_sample;
1223         _remaining_latency_preroll = worst_latency_preroll ();
1224         timecode_time(_transport_sample, transmitting_timecode_time); // XXX here?
1225
1226         /* do "stopped" stuff if:
1227          *
1228          * we are rolling AND
1229          * no autoplay in effect AND
1230          * we're not going to keep rolling after the locate AND
1231          * !(playing a loop with JACK sync)
1232          *
1233          */
1234
1235         bool transport_was_stopped = !transport_rolling();
1236
1237         if (!transport_was_stopped && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_engine() && play_loop) &&
1238             (!Profile->get_trx() || !(config.get_external_sync() && !synced_to_engine()))) {
1239                 realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
1240                 transport_was_stopped = true;
1241         } else {
1242                 /* otherwise tell the world that we located */
1243                 realtime_locate ();
1244         }
1245
1246         if (force || !for_loop_enabled || loop_changing) {
1247
1248                 PostTransportWork todo = PostTransportLocate;
1249
1250                 if (with_roll && transport_was_stopped) {
1251                         todo = PostTransportWork (todo | PostTransportRoll);
1252                 }
1253
1254                 add_post_transport_work (todo);
1255                 need_butler = true;
1256
1257         } else {
1258
1259                 /* this is functionally what clear_clicks() does but with a tentative lock */
1260
1261                 Glib::Threads::RWLock::WriterLock clickm (click_lock, Glib::Threads::TRY_LOCK);
1262
1263                 if (clickm.locked()) {
1264
1265                         for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
1266                                 delete *i;
1267                         }
1268
1269                         clicks.clear ();
1270                 }
1271         }
1272
1273         if (with_roll) {
1274                 /* switch from input if we're going to roll */
1275                 if (Config->get_monitoring_model() == HardwareMonitoring) {
1276                         set_track_monitor_input_status (!config.get_auto_input());
1277                 }
1278         } else {
1279                 /* otherwise we're going to stop, so do the opposite */
1280                 if (Config->get_monitoring_model() == HardwareMonitoring) {
1281                         set_track_monitor_input_status (true);
1282                 }
1283         }
1284
1285         /* cancel looped playback if transport pos outside of loop range */
1286         if (play_loop) {
1287
1288                 Location* al = _locations->auto_loop_location();
1289
1290                 if (al) {
1291                         if (_transport_sample < al->start() || _transport_sample >= al->end()) {
1292
1293                                 // located outside the loop: cancel looping directly, this is called from event handling context
1294
1295                                 have_looped = false;
1296
1297                                 if (!Config->get_loop_is_mode()) {
1298                                         set_play_loop (false, _transport_speed);
1299                                 } else {
1300                                         if (Config->get_seamless_loop()) {
1301                                                 /* this will make the non_realtime_locate() in the butler
1302                                                    which then causes seek() in tracks actually do the right
1303                                                    thing.
1304                                                 */
1305                                                 set_track_loop (false);
1306                                         }
1307                                 }
1308
1309                         } else if (_transport_sample == al->start()) {
1310
1311                                 // located to start of loop - this is looping, basically
1312
1313                                 if (!have_looped) {
1314                                         /* first time */
1315                                         if (_last_roll_location != al->start()) {
1316                                                 /* didn't start at loop start - playback must have
1317                                                  * started before loop since we've now hit the loop
1318                                                  * end.
1319                                                  */
1320                                                 add_post_transport_work (PostTransportLocate);
1321                                                 need_butler = true;
1322                                         }
1323
1324                                 }
1325
1326                                 boost::shared_ptr<RouteList> rl = routes.reader();
1327
1328                                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1329                                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1330
1331                                         if (tr && tr->rec_enable_control()->get_value()) {
1332                                                 // tell it we've looped, so it can deal with the record state
1333                                                 tr->transport_looped (_transport_sample);
1334                                         }
1335                                 }
1336
1337                                 have_looped = true;
1338                                 TransportLooped(); // EMIT SIGNAL
1339                         }
1340                 }
1341         }
1342
1343         if (need_butler) {
1344                 _butler->schedule_transport_work ();
1345         }
1346
1347         loop_changing = false;
1348
1349         _send_timecode_update = true;
1350
1351         if (with_mmc) {
1352                 send_mmc_locate (_transport_sample);
1353         }
1354
1355         _last_roll_location = _last_roll_or_reversal_location =  _transport_sample;
1356         if (!synced_to_engine () || _transport_sample == _engine.transport_sample ()) {
1357                 Located (); /* EMIT SIGNAL */
1358         }
1359 }
1360
1361 /** Set the transport speed.
1362  *  Called from the process thread.
1363  *  @param speed New speed
1364  */
1365 void
1366 Session::set_transport_speed (double speed, samplepos_t destination_sample, bool abort, bool clear_state, bool as_default)
1367 {
1368         DEBUG_TRACE (DEBUG::Transport, string_compose ("@ %5 Set transport speed to %1, abort = %2 clear_state = %3, current = %4 as_default %6\n",
1369                                                        speed, abort, clear_state, _transport_speed, _transport_sample, as_default));
1370
1371         /* max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
1372            and user needs. We really need CD-style "skip" playback for ffwd and rewind.
1373         */
1374
1375         if (speed > 0) {
1376                 speed = min (8.0, speed);
1377         } else if (speed < 0) {
1378                 speed = max (-8.0, speed);
1379         }
1380
1381         double new_engine_speed = 1.0;
1382         if (speed != 0) {
1383                 new_engine_speed = fabs (speed);
1384                 if (speed < 0) speed = -1;
1385                 if (speed > 0) speed = 1;
1386         }
1387
1388         if (_transport_speed == speed && new_engine_speed == _engine_speed) {
1389                 if (as_default && speed == 0.0) { // => reset default transport speed. hacky or what?
1390                         _default_transport_speed = 1.0;
1391                 }
1392                 return;
1393         }
1394
1395 #if 0 // TODO pref: allow vari-speed recording
1396         if (actively_recording() && speed != 1.0 && speed != 0.0) {
1397                 /* no varispeed during recording */
1398                 DEBUG_TRACE (DEBUG::Transport, string_compose ("No varispeed during recording cur_speed %1, sample %2\n",
1399                                                        _transport_speed, _transport_sample));
1400                 return;
1401         }
1402 #endif
1403
1404         _target_transport_speed = fabs(speed);
1405         _engine_speed = new_engine_speed;
1406
1407         if (transport_rolling() && speed == 0.0) {
1408
1409                 /* we are rolling and we want to stop */
1410
1411                 if (Config->get_monitoring_model() == HardwareMonitoring) {
1412                         set_track_monitor_input_status (true);
1413                 }
1414
1415                 if (synced_to_engine ()) {
1416                         if (clear_state) {
1417                                 /* do this here because our response to the slave won't
1418                                    take care of it.
1419                                 */
1420                                 _play_range = false;
1421                                 _count_in_once = false;
1422                                 unset_play_loop ();
1423                         }
1424                         _engine.transport_stop ();
1425                 } else {
1426                         bool const auto_return_enabled = (!config.get_external_sync() && (Config->get_auto_return_target_list() || abort));
1427
1428                         if (!auto_return_enabled) {
1429                                 _requested_return_sample = destination_sample;
1430                         }
1431
1432                         stop_transport (abort);
1433                 }
1434
1435         } else if (transport_stopped() && speed == 1.0) {
1436                 if (as_default) {
1437                         _default_transport_speed = speed;
1438                 }
1439                 /* we are stopped and we want to start rolling at speed 1 */
1440
1441                 if (Config->get_loop_is_mode() && play_loop) {
1442
1443                         Location *location = _locations->auto_loop_location();
1444
1445                         if (location != 0) {
1446                                 if (_transport_sample != location->start()) {
1447
1448                                         if (Config->get_seamless_loop()) {
1449                                                 /* force tracks to do their thing */
1450                                                 set_track_loop (true);
1451                                         }
1452
1453                                         /* jump to start and then roll from there */
1454
1455                                         request_locate (location->start(), true);
1456                                         return;
1457                                 }
1458                         }
1459                 }
1460
1461                 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1462                         set_track_monitor_input_status (false);
1463                 }
1464
1465                 if (synced_to_engine()) {
1466                         _engine.transport_start ();
1467                         _count_in_once = false;
1468                 } else {
1469                         start_transport ();
1470                 }
1471
1472         } else {
1473
1474                 /* not zero, not 1.0 ... varispeed */
1475
1476                 // TODO handled transport start..  _remaining_latency_preroll
1477                 // and reversal of playback direction.
1478
1479                 if ((synced_to_engine()) && speed != 0.0 && speed != 1.0) {
1480                         warning << string_compose (
1481                                 _("Global varispeed cannot be supported while %1 is connected to JACK transport control"),
1482                                 PROGRAM_NAME)
1483                                 << endmsg;
1484                         return;
1485                 }
1486
1487 #if 0
1488                 if (actively_recording()) {
1489                         return;
1490                 }
1491 #endif
1492
1493                 if (speed > 0.0 && _transport_sample == current_end_sample()) {
1494                         return;
1495                 }
1496
1497                 if (speed < 0.0 && _transport_sample == 0) {
1498                         return;
1499                 }
1500
1501                 clear_clicks ();
1502
1503                 /* if we are reversing relative to the current speed, or relative to the speed
1504                    before the last stop, then we have to do extra work.
1505                 */
1506
1507                 PostTransportWork todo = PostTransportWork (0);
1508
1509                 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0 && speed < 0.0)) {
1510                         todo = PostTransportWork (todo | PostTransportReverse);
1511                         _last_roll_or_reversal_location = _transport_sample;
1512                 }
1513
1514                 _last_transport_speed = _transport_speed;
1515                 _transport_speed = speed;
1516
1517                 if (as_default) {
1518                         _default_transport_speed = speed;
1519                 }
1520
1521                 if (todo) {
1522                         add_post_transport_work (todo);
1523                         _butler->schedule_transport_work ();
1524                 }
1525
1526                 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC3 with speed = %1\n", _transport_speed));
1527
1528                 /* throttle signal emissions.
1529                  * when slaved [_last]_transport_speed
1530                  * usually changes every cycle (tiny amounts due to DLL).
1531                  * Emitting a signal every cycle is overkill and unwarranted.
1532                  *
1533                  * Using _last_transport_speed is not acceptable,
1534                  * since it allows for large changes over a long period
1535                  * of time. Hence we introduce a dedicated variable to keep track
1536                  *
1537                  * The 0.2% dead-zone is somewhat arbitrary. Main use-case
1538                  * for TransportStateChange() here is the ShuttleControl display.
1539                  */
1540                 if (fabs (_signalled_varispeed - actual_speed ()) > .002
1541                     // still, signal hard changes to 1.0 and 0.0:
1542                     || (actual_speed () == 1.0 && _signalled_varispeed != 1.0)
1543                     || (actual_speed () == 0.0 && _signalled_varispeed != 0.0)
1544                    )
1545                 {
1546                         TransportStateChange (); /* EMIT SIGNAL */
1547                         _signalled_varispeed = actual_speed ();
1548                 }
1549         }
1550 }
1551
1552
1553 /** Stop the transport.  */
1554 void
1555 Session::stop_transport (bool abort, bool clear_state)
1556 {
1557         _count_in_once = false;
1558         if (_transport_speed == 0.0f) {
1559                 return;
1560         }
1561
1562         DEBUG_TRACE (DEBUG::Transport, "time to actually stop\n");
1563
1564         realtime_stop (abort, clear_state);
1565         _butler->schedule_transport_work ();
1566 }
1567
1568 /** Called from the process thread */
1569 void
1570 Session::start_transport ()
1571 {
1572         DEBUG_TRACE (DEBUG::Transport, "start_transport\n");
1573
1574         _last_roll_location = _transport_sample;
1575         _last_roll_or_reversal_location = _transport_sample;
1576         _remaining_latency_preroll = worst_latency_preroll ();
1577
1578         have_looped = false;
1579
1580         /* if record status is Enabled, move it to Recording. if its
1581            already Recording, move it to Disabled.
1582         */
1583
1584         switch (record_status()) {
1585         case Enabled:
1586                 if (!config.get_punch_in()) {
1587                         /* This is only for UIs (keep blinking rec-en before
1588                          * punch-in, don't show rec-region etc). The UI still
1589                          * depends on SessionEvent::PunchIn and ensuing signals.
1590                          *
1591                          * The disk-writers handle punch in/out internally
1592                          * in their local delay-compensated timeframe.
1593                          */
1594                         enable_record ();
1595                 }
1596                 break;
1597
1598         case Recording:
1599                 if (!play_loop) {
1600                         disable_record (false);
1601                 }
1602                 break;
1603
1604         default:
1605                 break;
1606         }
1607
1608         _transport_speed = _default_transport_speed;
1609         _target_transport_speed = _transport_speed;
1610
1611         if (!_engine.freewheeling()) {
1612                 Timecode::Time time;
1613                 timecode_time_subframes (_transport_sample, time);
1614                 if (transport_master()->type() == MTC) {
1615                         send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
1616                 }
1617
1618                 if (actively_recording() && click_data && (config.get_count_in () || _count_in_once)) {
1619                         _count_in_once = false;
1620                         /* calculate count-in duration (in audio samples)
1621                          * - use [fixed] tempo/meter at _transport_sample
1622                          * - calc duration of 1 bar + time-to-beat before or at transport_sample
1623                          */
1624                         const Tempo& tempo = _tempo_map->tempo_at_sample (_transport_sample);
1625                         const Meter& meter = _tempo_map->meter_at_sample (_transport_sample);
1626
1627                         const double num = meter.divisions_per_bar ();
1628                         const double den = meter.note_divisor ();
1629                         const double barbeat = _tempo_map->exact_qn_at_sample (_transport_sample, 0) * den / (4. * num);
1630                         const double bar_fract = fmod (barbeat, 1.0); // fraction of bar elapsed.
1631
1632                         _count_in_samples = meter.samples_per_bar (tempo, _current_sample_rate);
1633
1634                         double dt = _count_in_samples / num;
1635                         if (bar_fract == 0) {
1636                                 /* at bar boundary, count-in 2 bars before start. */
1637                                 _count_in_samples *= 2;
1638                         } else {
1639                                 /* beats left after full bar until roll position */
1640                                 _count_in_samples *= 1. + bar_fract;
1641                         }
1642
1643                         if (_count_in_samples > _remaining_latency_preroll) {
1644                                 _remaining_latency_preroll = _count_in_samples;
1645                         }
1646
1647                         int clickbeat = 0;
1648                         samplepos_t cf = _transport_sample - _count_in_samples;
1649                         samplecnt_t offset = _click_io->connected_latency (true);
1650                         while (cf < _transport_sample + offset) {
1651                                 add_click (cf, clickbeat == 0);
1652                                 cf += dt;
1653                                 clickbeat = fmod (clickbeat + 1, num);
1654                         }
1655
1656                         if (_count_in_samples < _remaining_latency_preroll) {
1657                                 _count_in_samples = _remaining_latency_preroll;
1658                         }
1659                 }
1660         }
1661
1662         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC4 with speed = %1\n", _transport_speed));
1663         TransportStateChange (); /* EMIT SIGNAL */
1664 }
1665
1666 /** Do any transport work in the audio thread that needs to be done after the
1667  * transport thread is finished.  Audio thread, realtime safe.
1668  */
1669 void
1670 Session::post_transport ()
1671 {
1672         PostTransportWork ptw = post_transport_work ();
1673
1674         if (ptw & PostTransportAudition) {
1675                 if (auditioner && auditioner->auditioning()) {
1676                         process_function = &Session::process_audition;
1677                 } else {
1678                         process_function = &Session::process_with_events;
1679                 }
1680         }
1681
1682         if (ptw & PostTransportStop) {
1683
1684                 transport_sub_state = 0;
1685         }
1686
1687         if (ptw & PostTransportLocate) {
1688
1689                 if (((!config.get_external_sync() && (auto_play_legal && config.get_auto_play())) && !_exporting) || (ptw & PostTransportRoll)) {
1690                         _count_in_once = false;
1691                         start_transport ();
1692                 } else {
1693                         transport_sub_state = 0;
1694                 }
1695         }
1696
1697         set_next_event ();
1698         /* XXX is this really safe? shouldn't we just be unsetting the bits that we actually
1699            know were handled ?
1700         */
1701         set_post_transport_work (PostTransportWork (0));
1702 }
1703
1704 void
1705 Session::reset_rf_scale (samplecnt_t motion)
1706 {
1707         cumulative_rf_motion += motion;
1708
1709         if (cumulative_rf_motion < 4 * _current_sample_rate) {
1710                 rf_scale = 1;
1711         } else if (cumulative_rf_motion < 8 * _current_sample_rate) {
1712                 rf_scale = 4;
1713         } else if (cumulative_rf_motion < 16 * _current_sample_rate) {
1714                 rf_scale = 10;
1715         } else {
1716                 rf_scale = 100;
1717         }
1718
1719         if (motion != 0) {
1720                 set_dirty();
1721         }
1722 }
1723
1724 void
1725 Session::unset_play_range ()
1726 {
1727         _play_range = false;
1728         _clear_event_type (SessionEvent::RangeStop);
1729         _clear_event_type (SessionEvent::RangeLocate);
1730 }
1731
1732 void
1733 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1734 {
1735         SessionEvent* ev;
1736
1737         /* Called from event-processing context */
1738
1739         unset_play_range ();
1740
1741         if (range.empty()) {
1742                 /* _play_range set to false in unset_play_range()
1743                  */
1744                 if (!leave_rolling) {
1745                         /* stop transport */
1746                         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false);
1747                         merge_event (ev);
1748                 }
1749                 return;
1750         }
1751
1752         _play_range = true;
1753
1754         /* cancel loop play */
1755         unset_play_loop ();
1756
1757         list<AudioRange>::size_type sz = range.size();
1758
1759         if (sz > 1) {
1760
1761                 list<AudioRange>::iterator i = range.begin();
1762                 list<AudioRange>::iterator next;
1763
1764                 while (i != range.end()) {
1765
1766                         next = i;
1767                         ++next;
1768
1769                         /* locating/stopping is subject to delays for declicking.
1770                          */
1771
1772                         samplepos_t requested_sample = i->end;
1773
1774                         if (requested_sample > current_block_size) {
1775                                 requested_sample -= current_block_size;
1776                         } else {
1777                                 requested_sample = 0;
1778                         }
1779
1780                         if (next == range.end()) {
1781                                 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_sample, 0, 0.0f);
1782                         } else {
1783                                 ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_sample, (*next).start, 0.0f);
1784                         }
1785
1786                         merge_event (ev);
1787
1788                         i = next;
1789                 }
1790
1791         } else if (sz == 1) {
1792
1793                 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
1794                 merge_event (ev);
1795
1796         }
1797
1798         /* save range so we can do auto-return etc. */
1799
1800         current_audio_range = range;
1801
1802         /* now start rolling at the right place */
1803
1804         ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
1805         merge_event (ev);
1806
1807         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC5 with speed = %1\n", _transport_speed));
1808         TransportStateChange ();
1809 }
1810
1811 void
1812 Session::request_bounded_roll (samplepos_t start, samplepos_t end)
1813 {
1814         AudioRange ar (start, end, 0);
1815         list<AudioRange> lar;
1816
1817         lar.push_back (ar);
1818         request_play_range (&lar, true);
1819 }
1820
1821 void
1822 Session::set_requested_return_sample (samplepos_t return_to)
1823 {
1824         _requested_return_sample = return_to;
1825 }
1826
1827 void
1828 Session::request_roll_at_and_return (samplepos_t start, samplepos_t return_to)
1829 {
1830         SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
1831         ev->target2_sample = start;
1832         queue_event (ev);
1833 }
1834
1835 void
1836 Session::engine_halted ()
1837 {
1838         bool ignored;
1839
1840         /* there will be no more calls to process(), so
1841            we'd better clean up for ourselves, right now.
1842
1843            but first, make sure the butler is out of
1844            the picture.
1845         */
1846
1847         if (_butler) {
1848                 _butler->stop ();
1849         }
1850
1851         realtime_stop (false, true);
1852         non_realtime_stop (false, 0, ignored);
1853         transport_sub_state = 0;
1854
1855         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC6 with speed = %1\n", _transport_speed));
1856         TransportStateChange (); /* EMIT SIGNAL */
1857 }
1858
1859
1860 void
1861 Session::xrun_recovery ()
1862 {
1863         ++_xrun_count;
1864
1865         Xrun (_transport_sample); /* EMIT SIGNAL */
1866
1867         if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1868
1869                 /* it didn't actually halt, but we need
1870                    to handle things in the same way.
1871                 */
1872
1873                 engine_halted();
1874         }
1875 }
1876
1877 void
1878 Session::route_processors_changed (RouteProcessorChange c)
1879 {
1880         if (g_atomic_int_get (&_ignore_route_processor_changes) > 0) {
1881                 return;
1882         }
1883
1884         if (c.type == RouteProcessorChange::MeterPointChange) {
1885                 set_dirty ();
1886                 return;
1887         }
1888
1889         if (c.type == RouteProcessorChange::RealTimeChange) {
1890                 set_dirty ();
1891                 return;
1892         }
1893
1894         update_latency_compensation ();
1895         resort_routes ();
1896
1897         set_dirty ();
1898 }
1899
1900 void
1901 Session::allow_auto_play (bool yn)
1902 {
1903         auto_play_legal = yn;
1904 }
1905
1906 bool
1907 Session::maybe_stop (samplepos_t limit)
1908 {
1909         if ((_transport_speed > 0.0f && _transport_sample >= limit) || (_transport_speed < 0.0f && _transport_sample == 0)) {
1910                 if (synced_to_engine () && config.get_jack_time_master ()) {
1911                         _engine.transport_stop ();
1912                 } else if (!synced_to_engine ()) {
1913                         stop_transport ();
1914                 }
1915                 return true;
1916         }
1917         return false;
1918 }
1919
1920 void
1921 Session::send_mmc_locate (samplepos_t t)
1922 {
1923         if (t < 0) {
1924                 return;
1925         }
1926
1927         if (!_engine.freewheeling()) {
1928                 Timecode::Time time;
1929                 timecode_time_subframes (t, time);
1930                 send_immediate_mmc (MIDI::MachineControlCommand (time));
1931         }
1932 }
1933
1934 /** Ask the transport to not send timecode until further notice.  The suspension
1935  *  will come into effect some finite time after this call, and timecode_transmission_suspended()
1936  *  should be checked by the caller to find out when.
1937  */
1938 void
1939 Session::request_suspend_timecode_transmission ()
1940 {
1941         SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, false);
1942         queue_event (ev);
1943 }
1944
1945 void
1946 Session::request_resume_timecode_transmission ()
1947 {
1948         SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, true);
1949         queue_event (ev);
1950 }
1951
1952 bool
1953 Session::timecode_transmission_suspended () const
1954 {
1955         return g_atomic_int_get (&_suspend_timecode_transmission) == 1;
1956 }
1957
1958 boost::shared_ptr<TransportMaster>
1959 Session::transport_master() const
1960 {
1961         return TransportMasterManager::instance().current();
1962 }
1963
1964 bool
1965 Session::transport_master_is_external () const
1966 {
1967         return config.get_external_sync();
1968 }
1969
1970 void
1971 Session::sync_source_changed (SyncSource type, samplepos_t pos, pframes_t cycle_nframes)
1972 {
1973         /* Runs in process() context */
1974
1975         boost::shared_ptr<TransportMaster> master = TransportMasterManager::instance().current();
1976
1977         /* save value of seamless from before the switch */
1978         _was_seamless = Config->get_seamless_loop ();
1979
1980         if (type == Engine) {
1981                 /* JACK cannot support seamless looping at present */
1982                 Config->set_seamless_loop (false);
1983         } else {
1984                 /* reset to whatever the value was before we last switched slaves */
1985                 Config->set_seamless_loop (_was_seamless);
1986         }
1987
1988         if (master->can_loop()) {
1989                 request_play_loop (false);
1990         } else if (master->has_loop()) {
1991                 request_play_loop (true);
1992         }
1993
1994         /* slave change, reset any DiskIO block on disk output because it is no
1995            longer valid with a new slave.
1996         */
1997
1998         DiskReader::set_no_disk_output (false);
1999
2000 #if 0
2001         we should not be treating specific transport masters as special cases because there maybe > 1 of a particular type
2002
2003         boost::shared_ptr<MTC_TransportMaster> mtc_master = boost::dynamic_pointer_cast<MTC_TransportMaster> (master);
2004
2005         if (mtc_master) {
2006                 mtc_master->ActiveChanged.connect_same_thread (mtc_status_connection, boost::bind (&Session::mtc_status_changed, this, _1));
2007                 MTCSyncStateChanged(mtc_master->locked() );
2008         } else {
2009                 if (g_atomic_int_compare_and_exchange (&_mtc_active, 1, 0)) {
2010                         MTCSyncStateChanged( false );
2011                 }
2012                 mtc_status_connection.disconnect ();
2013         }
2014
2015         boost::shared_ptr<LTC_TransportMaster> ltc_master = boost::dynamic_pointer_cast<LTC_TransportMaster> (master);
2016
2017         if (ltc_master) {
2018                 ltc_master->ActiveChanged.connect_same_thread (ltc_status_connection, boost::bind (&Session::ltc_status_changed, this, _1));
2019                 LTCSyncStateChanged (ltc_master->locked() );
2020         } else {
2021                 if (g_atomic_int_compare_and_exchange (&_ltc_active, 1, 0)) {
2022                         LTCSyncStateChanged( false );
2023                 }
2024                 ltc_status_connection.disconnect ();
2025         }
2026 #endif
2027
2028         DEBUG_TRACE (DEBUG::Slave, string_compose ("set new slave to %1\n", master));
2029
2030         // need to queue this for next process() cycle
2031         _send_timecode_update = true;
2032
2033         boost::shared_ptr<RouteList> rl = routes.reader();
2034         const bool externally_slaved = transport_master_is_external();
2035
2036         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2037                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2038                 if (tr && !tr->is_private_route()) {
2039                         tr->set_slaved (externally_slaved);
2040                 }
2041         }
2042
2043         set_dirty();
2044 }