2 Copyright (C) 1999-2003 Paul Davis
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.
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.
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.
21 #include "libardour-config.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"
35 #include "midi++/mmc.h"
36 #include "midi++/port.h"
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/location.h"
45 #include "ardour/profile.h"
46 #include "ardour/scene_changer.h"
47 #include "ardour/session.h"
48 #include "ardour/slave.h"
49 #include "ardour/tempo.h"
50 #include "ardour/operations.h"
55 using namespace ARDOUR;
59 Session::add_post_transport_work (PostTransportWork ptw)
61 PostTransportWork oldval;
62 PostTransportWork newval;
66 oldval = (PostTransportWork) g_atomic_int_get (&_post_transport_work);
67 newval = PostTransportWork (oldval | ptw);
68 if (g_atomic_int_compare_and_exchange (&_post_transport_work, oldval, newval)) {
74 error << "Could not set post transport work! Crazy thread madness, call the programmers" << endmsg;
78 Session::request_input_change_handling ()
80 if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
81 SessionEvent* ev = new SessionEvent (SessionEvent::InputConfigurationChange, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
87 Session::request_sync_source (Slave* new_slave)
89 SessionEvent* ev = new SessionEvent (SessionEvent::SetSyncSource, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
92 seamless = Config->get_seamless_loop ();
94 if (dynamic_cast<Engine_Slave*>(new_slave)) {
95 /* JACK cannot support seamless looping at present */
96 Config->set_seamless_loop (false);
98 /* reset to whatever the value was before we last switched slaves */
99 Config->set_seamless_loop (_was_seamless);
102 /* save value of seamless from before the switch */
103 _was_seamless = seamless;
105 ev->slave = new_slave;
106 DEBUG_TRACE (DEBUG::Slave, "sent request for new slave\n");
111 Session::request_transport_speed (double speed, bool as_default)
113 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
114 ev->third_yes_or_no = as_default; // as_default
115 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport speed = %1 as default = %2\n", speed, as_default));
119 /** Request a new transport speed, but if the speed parameter is exactly zero then use
120 * a very small +ve value to prevent the transport actually stopping. This method should
121 * be used by callers who are varying transport speed but don't ever want to stop it.
124 Session::request_transport_speed_nonzero (double speed, bool as_default)
130 request_transport_speed (speed, as_default);
134 Session::request_track_speed (Track* tr, double speed)
136 SessionEvent* ev = new SessionEvent (SessionEvent::SetTrackSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
142 Session::request_stop (bool abort, bool clear_state)
144 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, audible_frame(), 0.0, abort, clear_state);
145 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport stop, audible %3 transport %4 abort = %1, clear state = %2\n", abort, clear_state, audible_frame(), _transport_frame));
150 Session::request_locate (framepos_t target_frame, bool with_roll)
152 SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, false);
153 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request locate to %1\n", target_frame));
158 Session::force_locate (framepos_t target_frame, bool with_roll)
160 SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, true);
161 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request forced locate to %1\n", target_frame));
166 Session::unset_preroll_record_punch ()
168 if (_preroll_record_punch_pos >= 0) {
169 remove_event (_preroll_record_punch_pos, SessionEvent::RecordStart);
171 _preroll_record_punch_pos = -1;
175 Session::unset_preroll_record_trim ()
177 _preroll_record_trim_len = 0;
181 Session::request_preroll_record_punch (framepos_t rec_in, framecnt_t preroll)
183 if (actively_recording ()) {
186 unset_preroll_record_punch ();
187 unset_preroll_record_trim ();
188 framepos_t start = std::max ((framepos_t)0, rec_in - preroll);
190 _preroll_record_punch_pos = rec_in;
191 if (_preroll_record_punch_pos >= 0) {
192 replace_event (SessionEvent::RecordStart, _preroll_record_punch_pos);
193 config.set_punch_in (false);
194 config.set_punch_out (false);
196 maybe_enable_record ();
197 request_locate (start, true);
198 set_requested_return_frame (rec_in);
202 Session::request_preroll_record_trim (framepos_t rec_in, framecnt_t preroll)
204 if (actively_recording ()) {
207 unset_preroll_record_punch ();
208 unset_preroll_record_trim ();
210 config.set_punch_in (false);
211 config.set_punch_out (false);
213 framepos_t pos = std::max ((framepos_t)0, rec_in - preroll);
214 _preroll_record_trim_len = preroll;
215 maybe_enable_record ();
216 request_locate (pos, true);
217 set_requested_return_frame (rec_in);
221 Session::request_count_in_record ()
223 if (actively_recording ()) {
226 if (transport_rolling()) {
229 maybe_enable_record ();
230 _count_in_once = true;
231 request_transport_speed (1.0, true);
235 Session::request_play_loop (bool yn, bool change_transport_roll)
238 // don't attempt to loop when not using Internal Transport
239 // see also gtk2_ardour/ardour_ui_options.cc parameter_changed()
244 Location *location = _locations->auto_loop_location();
247 if (location == 0 && yn) {
248 error << _("Cannot loop - no loop range defined")
253 if (change_transport_roll) {
254 if (transport_rolling()) {
255 /* start looping at current speed */
256 target_speed = transport_speed ();
258 /* currently stopped */
260 /* start looping at normal speed */
267 /* leave the speed alone */
268 target_speed = transport_speed ();
271 ev = new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, target_speed, yn);
272 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request set loop = %1, change roll state ? %2\n", yn, change_transport_roll));
276 if (!change_transport_roll) {
277 if (!transport_rolling()) {
278 /* we're not changing transport state, but we do want
279 to set up position for the new loop. Don't
280 do this if we're rolling already.
282 request_locate (location->start(), false);
286 if (!change_transport_roll && Config->get_seamless_loop() && transport_rolling()) {
287 // request an immediate locate to refresh the tracks
288 // after disabling looping
289 request_locate (_transport_frame-1, false);
295 Session::request_play_range (list<AudioRange>* range, bool leave_rolling)
297 SessionEvent* ev = new SessionEvent (SessionEvent::SetPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0));
299 ev->audio_range = *range;
301 ev->audio_range.clear ();
303 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request play range, leave rolling ? %1\n", leave_rolling));
308 Session::request_cancel_play_range ()
310 SessionEvent* ev = new SessionEvent (SessionEvent::CancelPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, 0);
316 Session::realtime_stop (bool abort, bool clear_state)
318 DEBUG_TRACE (DEBUG::Transport, string_compose ("realtime stop @ %1\n", _transport_frame));
319 PostTransportWork todo = PostTransportWork (0);
321 /* assume that when we start, we'll be moving forwards */
323 if (_transport_speed < 0.0f) {
324 todo = (PostTransportWork (todo | PostTransportStop | PostTransportReverse));
325 _default_transport_speed = 1.0;
327 todo = PostTransportWork (todo | PostTransportStop);
332 boost::shared_ptr<RouteList> r = routes.reader ();
334 for (RouteList::iterator i = r->begin (); i != r->end(); ++i) {
335 (*i)->realtime_handle_transport_stopped ();
338 DEBUG_TRACE (DEBUG::Transport, string_compose ("stop complete, auto-return scheduled for return to %1\n", _requested_return_frame));
340 /* the duration change is not guaranteed to have happened, but is likely */
342 todo = PostTransportWork (todo | PostTransportDuration);
345 todo = PostTransportWork (todo | PostTransportAbort);
349 todo = PostTransportWork (todo | PostTransportClearSubstate);
353 add_post_transport_work (todo);
356 _clear_event_type (SessionEvent::StopOnce);
357 _clear_event_type (SessionEvent::RangeStop);
358 _clear_event_type (SessionEvent::RangeLocate);
360 /* if we're going to clear loop state, then force disabling record BUT only if we're not doing latched rec-enable */
361 disable_record (true, (!Config->get_latched_record_enable() && clear_state));
363 if (clear_state && !Config->get_loop_is_mode()) {
367 reset_slave_state ();
369 _transport_speed = 0;
370 _target_transport_speed = 0;
372 g_atomic_int_set (&_playback_load, 100);
373 g_atomic_int_set (&_capture_load, 100);
375 if (config.get_use_video_sync()) {
376 waiting_for_sync_offset = true;
379 transport_sub_state = 0;
383 Session::realtime_locate ()
385 boost::shared_ptr<RouteList> r = routes.reader ();
386 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
387 (*i)->realtime_locate ();
392 Session::butler_transport_work ()
394 /* Note: this function executes in the butler thread context */
398 PostTransportWork ptw;
399 boost::shared_ptr<RouteList> r = routes.reader ();
402 int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
404 ptw = post_transport_work();
406 DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler transport work, todo = %1 at %2\n", enum_2_string (ptw), (before = g_get_monotonic_time())));
409 if (ptw & PostTransportLocate) {
411 if (get_play_loop() && !Config->get_seamless_loop()) {
413 DEBUG_TRACE (DEBUG::Butler, "flush loop recording fragment to disk\n");
415 /* this locate might be happening while we are
418 * Non-seamless looping will require a locate (below) that
419 * will reset capture buffers and throw away data.
421 * Rather than first find all tracks and see if they
422 * have outstanding data, just do a flush anyway. It
423 * may be cheaper this way anyway, and is certainly
427 bool more_disk_io_to_do = false;
431 more_disk_io_to_do = _butler->flush_tracks_to_disk_after_locate (r, errors);
437 if (more_disk_io_to_do) {
446 if (ptw & PostTransportAdjustPlaybackBuffering) {
447 /* non_realtime_locate() calls Automatable::transport_located()
448 * for every route. This eventually calls
449 * ARDOUR::AutomationList::state () which has a LocaleGuard,
450 * and would switch locales forth/back every time.
453 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
454 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
456 tr->adjust_playback_buffering ();
457 /* and refill those buffers ... */
459 (*i)->non_realtime_locate (_transport_frame);
464 if (ptw & PostTransportAdjustCaptureBuffering) {
465 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
466 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
468 tr->adjust_capture_buffering ();
473 if (ptw & PostTransportCurveRealloc) {
474 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
475 (*i)->curve_reallocate();
479 if (ptw & PostTransportInputChange) {
480 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
481 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
483 tr->non_realtime_input_change ();
488 if (ptw & PostTransportSpeed) {
489 non_realtime_set_speed ();
492 if (ptw & PostTransportReverse) {
495 cumulative_rf_motion = 0;
498 /* don't seek if locate will take care of that in non_realtime_stop() */
500 if (!(ptw & PostTransportLocate)) {
501 LocaleGuard lg; // see note for non_realtime_locate() above
502 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
503 (*i)->non_realtime_locate (_transport_frame);
505 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
506 /* new request, stop seeking, and start again */
507 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
514 if (ptw & PostTransportLocate) {
515 DEBUG_TRACE (DEBUG::Transport, "nonrealtime locate invoked from BTW\n");
516 non_realtime_locate ();
519 if (ptw & PostTransportStop) {
520 non_realtime_stop (ptw & PostTransportAbort, on_entry, finished);
522 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
527 if (ptw & PostTransportOverWrite) {
528 non_realtime_overwrite (on_entry, finished);
530 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
535 if (ptw & PostTransportAudition) {
536 non_realtime_set_audition ();
539 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
541 DEBUG_TRACE (DEBUG::Transport, string_compose (X_("Butler transport work all done after %1 usecs\n"), g_get_monotonic_time() - before));
542 DEBUG_TRACE (DEBUG::Transport, X_(string_compose ("Frame %1\n", _transport_frame)));
546 Session::non_realtime_set_speed ()
548 boost::shared_ptr<RouteList> rl = routes.reader();
549 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
550 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
552 tr->non_realtime_set_speed ();
558 Session::non_realtime_overwrite (int on_entry, bool& finished)
560 boost::shared_ptr<RouteList> rl = routes.reader();
561 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
562 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
563 if (tr && tr->pending_overwrite ()) {
564 tr->overwrite_existing_buffers ();
566 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
575 Session::non_realtime_locate ()
577 DEBUG_TRACE (DEBUG::Transport, string_compose ("locate tracks to %1\n", _transport_frame));
579 if (Config->get_loop_is_mode() && get_play_loop()) {
581 Location *loc = _locations->auto_loop_location();
583 if (!loc || (_transport_frame < loc->start() || _transport_frame >= loc->end())) {
584 /* jumped out of loop range: stop tracks from looping,
585 but leave loop (mode) enabled.
587 set_track_loop (false);
589 } else if (loc && Config->get_seamless_loop() &&
590 ((loc->start() <= _transport_frame) ||
591 (loc->end() > _transport_frame) ) ) {
593 /* jumping to start of loop. This might have been done before but it is
594 * idempotent and cheap. Doing it here ensures that when we start playback
595 * outside the loop we still flip tracks into the magic seamless mode
598 set_track_loop (true);
601 set_track_loop (false);
606 /* no more looping .. should have been noticed elsewhere */
611 LocaleGuard lg; // see note for non_realtime_locate() above
612 boost::shared_ptr<RouteList> rl = routes.reader();
613 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
614 (*i)->non_realtime_locate (_transport_frame);
618 _scene_changer->locate (_transport_frame);
620 /* XXX: it would be nice to generate the new clicks here (in the non-RT thread)
621 rather than clearing them so that the RT thread has to spend time constructing
622 them (in Session::click).
627 #ifdef USE_TRACKS_CODE_FEATURES
629 Session::select_playhead_priority_target (framepos_t& jump_to)
633 AutoReturnTarget autoreturn = Config->get_auto_return_target_list ();
639 if (Profile->get_trx() && transport_rolling() ) {
640 // We're playing, so do nothing.
641 // Next stop will put us where we need to be.
645 /* Note that the order of checking each AutoReturnTarget flag defines
646 the priority each flag.
648 Ardour/Mixbus: Last Locate
653 Tracks: Range Selection
659 if (autoreturn & RangeSelectionStart) {
660 if (!_range_selection.empty()) {
661 jump_to = _range_selection.from;
663 if (transport_rolling ()) {
664 /* Range selection no longer exists, but we're playing,
665 so do nothing. Next stop will put us where
673 if (jump_to < 0 && (autoreturn & Loop) && get_play_loop()) {
674 /* don't try to handle loop play when synced to JACK */
676 if (!synced_to_engine()) {
677 Location *location = _locations->auto_loop_location();
680 jump_to = location->start();
682 if (Config->get_seamless_loop()) {
683 /* need to get track buffers reloaded */
684 set_track_loop (true);
690 if (jump_to < 0 && (autoreturn & RegionSelectionStart)) {
691 if (!_object_selection.empty()) {
692 jump_to = _object_selection.from;
696 if (jump_to < 0 && (autoreturn & LastLocate)) {
697 jump_to = _last_roll_location;
705 Session::select_playhead_priority_target (framepos_t& jump_to)
707 if (config.get_external_sync() || !config.get_auto_return()) {
711 jump_to = _last_roll_location;
718 Session::follow_playhead_priority ()
722 if (select_playhead_priority_target (target)) {
723 request_locate (target);
728 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
734 PostTransportWork ptw = post_transport_work();
739 boost::shared_ptr<RouteList> rl = routes.reader();
740 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
741 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
742 if (tr && tr->get_captured_frames () != 0) {
748 /* stop and locate are merged here because they share a lot of common stuff */
751 now = localtime (&xnow);
754 auditioner->cancel_audition ();
757 cumulative_rf_motion = 0;
761 begin_reversible_command (Operations::capture);
762 _have_captured = true;
765 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: DS stop\n"));
767 if (abort && did_record) {
768 /* no reason to save the session file when we remove sources
770 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
773 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
774 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
776 tr->transport_stopped_wallclock (*now, xnow, abort);
780 if (abort && did_record) {
781 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
784 boost::shared_ptr<RouteList> r = routes.reader ();
786 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
787 if (!(*i)->is_auditioner()) {
788 (*i)->set_pending_declick (0);
793 commit_reversible_command ();
794 /* increase take name */
795 if (config.get_track_name_take () && !config.get_take_name ().empty()) {
796 string newname = config.get_take_name();
797 config.set_take_name(bump_name_number (newname));
801 if (_engine.running()) {
802 PostTransportWork ptw = post_transport_work ();
803 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
804 (*i)->nonrealtime_handle_transport_stopped (abort, (ptw & PostTransportLocate), (!(ptw & PostTransportLocate) || pending_locate_flush));
806 update_latency_compensation ();
809 bool const auto_return_enabled = (!config.get_external_sync() && (Config->get_auto_return_target_list() || abort));
811 if (auto_return_enabled ||
812 (ptw & PostTransportLocate) ||
813 (_requested_return_frame >= 0) ||
814 synced_to_engine()) {
816 if (pending_locate_flush) {
817 flush_all_inserts ();
820 // rg: what is the logic behind this case?
821 // _requested_return_frame should be ignored when synced_to_engine/slaved.
822 // currently worked around in MTC_Slave by forcing _requested_return_frame to -1
824 if ((auto_return_enabled || synced_to_engine() || _requested_return_frame >= 0) &&
825 !(ptw & PostTransportLocate)) {
827 /* no explicit locate queued */
829 bool do_locate = false;
831 if (_requested_return_frame >= 0) {
833 /* explicit return request pre-queued in event list. overrides everything else */
835 _transport_frame = _requested_return_frame;
841 if (select_playhead_priority_target (jump_to)) {
843 _transport_frame = jump_to;
848 _transport_frame = _last_roll_location;
853 _requested_return_frame = -1;
856 _engine.transport_locate (_transport_frame);
863 unset_preroll_record_trim ();
865 /* do this before seeking, because otherwise the tracks will do the wrong thing in seamless loop mode.
868 if (ptw & PostTransportClearSubstate) {
870 if (!Config->get_loop_is_mode()) {
875 /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
878 LocaleGuard lg; // see note for non_realtime_locate() above
879 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: locate\n"));
880 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
881 DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler PTW: locate on %1\n", (*i)->name()));
882 (*i)->non_realtime_locate (_transport_frame);
884 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
886 /* we will be back */
894 /* don't bother with this stuff if we're disconnected from the engine,
895 because there will be no process callbacks to deliver stuff from
898 if (_engine.connected() && !_engine.freewheeling()) {
899 // need to queue this in the next RT cycle
900 _send_timecode_update = true;
902 if (!dynamic_cast<MTC_Slave*>(_slave)) {
903 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
905 /* This (::non_realtime_stop()) gets called by main
906 process thread, which will lead to confusion
907 when calling AsyncMIDIPort::write().
909 Something must be done. XXX
911 send_mmc_locate (_transport_frame);
915 if ((ptw & PostTransportLocate) && get_record_enabled()) {
916 /* This is scheduled by realtime_stop(), which is also done
917 * when a slave requests /locate/ for an initial sync.
918 * We can't hold up the slave for long with a save() here,
919 * without breaking its initial sync cycle.
921 * save state only if there's no slave or if it's not yet locked.
923 if (!_slave || !_slave->locked()) {
924 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: requests save\n"));
925 SaveSessionRequested (_current_snapshot_name);
930 /* always try to get rid of this */
932 remove_pending_capture_state ();
934 /* save the current state of things if appropriate */
936 if (did_record && !saved) {
937 SaveSessionRequested (_current_snapshot_name);
940 if (ptw & PostTransportStop) {
942 if (!Config->get_loop_is_mode()) {
947 PositionChanged (_transport_frame); /* EMIT SIGNAL */
948 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC with speed = %1\n", _transport_speed));
949 TransportStateChange (); /* EMIT SIGNAL */
950 AutomationWatch::instance().transport_stop_automation_watches (_transport_frame);
952 /* and start it up again if relevant */
954 if ((ptw & PostTransportLocate) && !config.get_external_sync() && pending_locate_roll) {
955 request_transport_speed (1.0);
958 /* Even if we didn't do a pending locate roll this time, we don't want it hanging
959 around for next time.
961 pending_locate_roll = false;
965 Session::check_declick_out ()
967 bool locate_required = transport_sub_state & PendingLocate;
969 /* this is called after a process() iteration. if PendingDeclickOut was set,
970 it means that we were waiting to declick the output (which has just been
971 done) before maybe doing something else. this is where we do that "something else".
973 note: called from the audio thread.
976 if (transport_sub_state & PendingDeclickOut) {
978 if (locate_required) {
979 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
980 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
982 if (!(transport_sub_state & StopPendingCapture)) {
983 stop_transport (pending_abort);
984 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
988 } else if (transport_sub_state & PendingLoopDeclickOut) {
989 /* Nothing else to do here; we've declicked, and the loop event will be along shortly */
990 transport_sub_state &= ~PendingLoopDeclickOut;
995 Session::unset_play_loop ()
999 clear_events (SessionEvent::AutoLoop);
1000 clear_events (SessionEvent::AutoLoopDeclick);
1001 set_track_loop (false);
1004 if (Config->get_seamless_loop()) {
1005 /* likely need to flush track buffers: this will locate us to wherever we are */
1006 add_post_transport_work (PostTransportLocate);
1007 _butler->schedule_transport_work ();
1013 Session::set_track_loop (bool yn)
1015 Location* loc = _locations->auto_loop_location ();
1021 boost::shared_ptr<RouteList> rl = routes.reader ();
1023 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1024 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1025 if (tr && !tr->hidden()) {
1026 tr->set_loop (yn ? loc : 0);
1032 Session::set_play_loop (bool yn, double speed)
1034 /* Called from event-handling context */
1038 if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) {
1039 /* nothing to do, or can't change loop status while recording */
1043 if (yn && Config->get_seamless_loop() && synced_to_engine()) {
1044 warning << string_compose (
1045 _("Seamless looping cannot be supported while %1 is using JACK transport.\n"
1046 "Recommend changing the configured options"), PROGRAM_NAME)
1054 have_looped = false;
1058 unset_play_range ();
1060 if (Config->get_seamless_loop()) {
1061 if (!Config->get_loop_is_mode()) {
1062 /* set all tracks to use internal looping */
1063 set_track_loop (true);
1065 /* we will do this in the locate to the start OR when we hit the end
1066 * of the loop for the first time
1070 /* set all tracks to NOT use internal looping */
1071 set_track_loop (false);
1074 /* Put the delick and loop events in into the event list. The declick event will
1075 cause a de-clicking fade-out just before the end of the loop, and it will also result
1076 in a fade-in when the loop restarts. The AutoLoop event will peform the actual loop.
1081 auto_loop_declick_range (loc, dcp, dcl);
1082 merge_event (new SessionEvent (SessionEvent::AutoLoopDeclick, SessionEvent::Replace, dcp, dcl, 0.0f));
1083 merge_event (new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f));
1085 /* if requested to roll, locate to start of loop and
1086 * roll but ONLY if we're not already rolling.
1088 args: positition, roll=true, flush=true, with_loop=false, force buffer refill if seamless looping
1091 if (Config->get_loop_is_mode()) {
1092 /* loop IS a transport mode: if already
1093 rolling, do not locate to loop start.
1095 if (!transport_rolling() && (speed != 0.0)) {
1096 start_locate (loc->start(), true, true, false, true);
1100 start_locate (loc->start(), true, true, false, true);
1110 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC2 with speed = %1\n", _transport_speed));
1111 TransportStateChange ();
1114 Session::flush_all_inserts ()
1116 boost::shared_ptr<RouteList> r = routes.reader ();
1118 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1119 (*i)->flush_processors ();
1124 Session::start_locate (framepos_t target_frame, bool with_roll, bool with_flush, bool for_loop_enabled, bool force)
1126 if (target_frame < 0) {
1127 error << _("Locate called for negative sample position - ignored") << endmsg;
1131 if (synced_to_engine()) {
1136 _slave->speed_and_position (sp, pos);
1138 if (target_frame != pos) {
1140 if (config.get_jack_time_master()) {
1141 /* actually locate now, since otherwise jack_timebase_callback
1142 will use the incorrect _transport_frame and report an old
1143 and incorrect time to Jack transport
1145 locate (target_frame, with_roll, with_flush, for_loop_enabled, force);
1148 /* tell JACK to change transport position, and we will
1149 follow along later in ::follow_slave()
1152 _engine.transport_locate (target_frame);
1154 if (sp != 1.0f && with_roll) {
1155 _engine.transport_start ();
1161 locate (target_frame, with_roll, with_flush, for_loop_enabled, force);
1166 Session::micro_locate (framecnt_t distance)
1168 boost::shared_ptr<RouteList> rl = routes.reader();
1169 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1170 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1171 if (tr && !tr->can_internal_playback_seek (distance)) {
1176 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1177 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1179 tr->internal_playback_seek (distance);
1183 _transport_frame += distance;
1187 /** @param with_mmc true to send a MMC locate command when the locate is done */
1189 Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool for_loop_enabled, bool force, bool with_mmc)
1191 bool need_butler = false;
1193 /* Locates for seamless looping are fairly different from other
1194 * locates. They assume that the diskstream buffers for each track
1195 * already have the correct data in them, and thus there is no need to
1196 * actually tell the tracks to locate. What does need to be done,
1197 * though, is all the housekeeping that is associated with non-linear
1198 * changes in the value of _transport_frame.
1201 DEBUG_TRACE (DEBUG::Transport, string_compose ("rt-locate to %1, roll %2 flush %3 loop-enabled %4 force %5 mmc %6\n",
1202 target_frame, with_roll, with_flush, for_loop_enabled, force, with_mmc));
1204 if (!force && _transport_frame == target_frame && !loop_changing && !for_loop_enabled) {
1206 /* already at the desired position. Not forced to locate,
1207 the loop isn't changing, so unless we're told to
1208 start rolling also, there's nothing to do but
1209 tell the world where we are (again).
1213 set_transport_speed (1.0, 0, false);
1215 loop_changing = false;
1216 Located (); /* EMIT SIGNAL */
1220 if (_transport_speed && !(for_loop_enabled && Config->get_seamless_loop())) {
1221 /* Schedule a declick. We'll be called again when its done.
1222 We only do it this way for ordinary locates, not those
1223 due to **seamless** loops.
1226 if (!(transport_sub_state & PendingDeclickOut)) {
1227 transport_sub_state |= (PendingDeclickOut|PendingLocate);
1228 pending_locate_frame = target_frame;
1229 pending_locate_roll = with_roll;
1230 pending_locate_flush = with_flush;
1235 // Update Timecode time
1236 _transport_frame = target_frame;
1237 _last_roll_or_reversal_location = target_frame;
1238 timecode_time(_transport_frame, transmitting_timecode_time);
1240 /* do "stopped" stuff if:
1242 * we are rolling AND
1243 * no autoplay in effect AND
1244 * we're not going to keep rolling after the locate AND
1245 * !(playing a loop with JACK sync)
1249 bool transport_was_stopped = !transport_rolling();
1251 if (!transport_was_stopped && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_engine() && play_loop) &&
1252 (!Profile->get_trx() || !(config.get_external_sync() && !synced_to_engine()))) {
1253 realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
1254 transport_was_stopped = true;
1256 /* otherwise tell the world that we located */
1260 if (force || !for_loop_enabled || loop_changing) {
1262 PostTransportWork todo = PostTransportLocate;
1264 if (with_roll && transport_was_stopped) {
1265 todo = PostTransportWork (todo | PostTransportRoll);
1268 add_post_transport_work (todo);
1273 /* this is functionally what clear_clicks() does but with a tentative lock */
1275 Glib::Threads::RWLock::WriterLock clickm (click_lock, Glib::Threads::TRY_LOCK);
1277 if (clickm.locked()) {
1279 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
1288 /* switch from input if we're going to roll */
1289 if (Config->get_monitoring_model() == HardwareMonitoring) {
1290 set_track_monitor_input_status (!config.get_auto_input());
1293 /* otherwise we're going to stop, so do the opposite */
1294 if (Config->get_monitoring_model() == HardwareMonitoring) {
1295 set_track_monitor_input_status (true);
1299 /* cancel looped playback if transport pos outside of loop range */
1302 Location* al = _locations->auto_loop_location();
1305 if (_transport_frame < al->start() || _transport_frame >= al->end()) {
1307 // located outside the loop: cancel looping directly, this is called from event handling context
1309 have_looped = false;
1311 if (!Config->get_loop_is_mode()) {
1312 set_play_loop (false, _transport_speed);
1314 if (Config->get_seamless_loop()) {
1315 /* this will make the non_realtime_locate() in the butler
1316 which then causes seek() in tracks actually do the right
1319 set_track_loop (false);
1323 } else if (_transport_frame == al->start()) {
1325 // located to start of loop - this is looping, basically
1329 if (_last_roll_location != al->start()) {
1330 /* didn't start at loop start - playback must have
1331 * started before loop since we've now hit the loop
1334 add_post_transport_work (PostTransportLocate);
1340 boost::shared_ptr<RouteList> rl = routes.reader();
1342 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1343 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1345 if (tr && tr->rec_enable_control()->get_value()) {
1346 // tell it we've looped, so it can deal with the record state
1347 tr->transport_looped (_transport_frame);
1352 TransportLooped(); // EMIT SIGNAL
1358 _butler->schedule_transport_work ();
1361 loop_changing = false;
1363 _send_timecode_update = true;
1366 send_mmc_locate (_transport_frame);
1369 _last_roll_location = _last_roll_or_reversal_location = _transport_frame;
1370 Located (); /* EMIT SIGNAL */
1373 /** Set the transport speed.
1374 * Called from the process thread.
1375 * @param speed New speed
1378 Session::set_transport_speed (double speed, framepos_t destination_frame, bool abort, bool clear_state, bool as_default)
1380 DEBUG_TRACE (DEBUG::Transport, string_compose ("@ %5 Set transport speed to %1, abort = %2 clear_state = %3, current = %4 as_default %6\n",
1381 speed, abort, clear_state, _transport_speed, _transport_frame, as_default));
1383 if (_transport_speed == speed) {
1384 if (as_default && speed == 0.0) { // => reset default transport speed. hacky or what?
1385 _default_transport_speed = 1.0;
1390 if (actively_recording() && speed != 1.0 && speed != 0.0) {
1391 /* no varispeed during recording */
1392 DEBUG_TRACE (DEBUG::Transport, string_compose ("No varispeed during recording cur_speed %1, frame %2\n",
1393 _transport_speed, _transport_frame));
1397 _target_transport_speed = fabs(speed);
1399 /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
1400 and user needs. We really need CD-style "skip" playback for ffwd and rewind.
1404 speed = min (8.0, speed);
1405 } else if (speed < 0) {
1406 speed = max (-8.0, speed);
1409 if (transport_rolling() && speed == 0.0) {
1411 /* we are rolling and we want to stop */
1413 if (Config->get_monitoring_model() == HardwareMonitoring) {
1414 set_track_monitor_input_status (true);
1417 if (synced_to_engine ()) {
1419 /* do this here because our response to the slave won't
1422 _play_range = false;
1423 _count_in_once = false;
1426 _engine.transport_stop ();
1428 bool const auto_return_enabled = (!config.get_external_sync() && (Config->get_auto_return_target_list() || abort));
1430 if (!auto_return_enabled) {
1431 _requested_return_frame = destination_frame;
1434 stop_transport (abort);
1437 } else if (transport_stopped() && speed == 1.0) {
1439 _default_transport_speed = speed;
1441 /* we are stopped and we want to start rolling at speed 1 */
1443 if (Config->get_loop_is_mode() && play_loop) {
1445 Location *location = _locations->auto_loop_location();
1447 if (location != 0) {
1448 if (_transport_frame != location->start()) {
1450 if (Config->get_seamless_loop()) {
1451 /* force tracks to do their thing */
1452 set_track_loop (true);
1455 /* jump to start and then roll from there */
1457 request_locate (location->start(), true);
1463 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1464 set_track_monitor_input_status (false);
1467 if (synced_to_engine()) {
1468 _engine.transport_start ();
1469 _count_in_once = false;
1476 /* not zero, not 1.0 ... varispeed */
1478 if ((synced_to_engine()) && speed != 0.0 && speed != 1.0) {
1479 warning << string_compose (
1480 _("Global varispeed cannot be supported while %1 is connected to JACK transport control"),
1486 if (actively_recording()) {
1490 if (speed > 0.0 && _transport_frame == current_end_frame()) {
1494 if (speed < 0.0 && _transport_frame == 0) {
1500 /* if we are reversing relative to the current speed, or relative to the speed
1501 before the last stop, then we have to do extra work.
1504 PostTransportWork todo = PostTransportWork (0);
1506 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0 && speed < 0.0)) {
1507 todo = PostTransportWork (todo | PostTransportReverse);
1508 _last_roll_or_reversal_location = _transport_frame;
1511 _last_transport_speed = _transport_speed;
1512 _transport_speed = speed;
1515 _default_transport_speed = speed;
1518 boost::shared_ptr<RouteList> rl = routes.reader();
1519 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1520 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1521 if (tr && tr->realtime_set_speed (tr->speed(), true)) {
1522 todo = PostTransportWork (todo | PostTransportSpeed);
1527 add_post_transport_work (todo);
1528 _butler->schedule_transport_work ();
1531 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC3 with speed = %1\n", _transport_speed));
1533 /* throttle signal emissions.
1534 * when slaved [_last]_transport_speed
1535 * usually changes every cycle (tiny amounts due to DLL).
1536 * Emitting a signal every cycle is overkill and unwarranted.
1538 * Using _last_transport_speed is not acceptable,
1539 * since it allows for large changes over a long period
1540 * of time. Hence we introduce a dedicated variable to keep track
1542 * The 0.2% dead-zone is somewhat arbitrary. Main use-case
1543 * for TransportStateChange() here is the ShuttleControl display.
1545 if (fabs (_signalled_varispeed - speed) > .002
1546 // still, signal hard changes to 1.0 and 0.0:
1547 || ( speed == 1.0 && _signalled_varispeed != 1.0)
1548 || ( speed == 0.0 && _signalled_varispeed != 0.0)
1551 TransportStateChange (); /* EMIT SIGNAL */
1552 _signalled_varispeed = speed;
1558 /** Stop the transport. */
1560 Session::stop_transport (bool abort, bool clear_state)
1562 _count_in_once = false;
1563 if (_transport_speed == 0.0f) {
1567 DEBUG_TRACE (DEBUG::Transport, string_compose ("stop_transport, declick required? %1\n", get_transport_declick_required()));
1569 if (!get_transport_declick_required()) {
1571 /* stop has not yet been scheduled */
1573 boost::shared_ptr<RouteList> rl = routes.reader();
1574 framepos_t stop_target = audible_frame();
1576 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1577 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1579 tr->prepare_to_stop (_transport_frame, stop_target);
1585 if (actively_recording() && /* we are recording */
1586 worst_input_latency() > current_block_size) { /* input latency exceeds block size, so simple 1 cycle delay before stop is not enough */
1588 /* we need to capture the audio that is still somewhere in the pipeline between
1589 wherever it was generated and the process callback. This means that even though
1590 the user (or something else) has asked us to stop, we have to roll
1591 past this point and then reset the playhead/transport location to
1592 the position at which the stop was requested.
1594 we still need playback to "stop" now, however, which is why we schedule
1598 DEBUG_TRACE (DEBUG::Transport, string_compose ("stop transport requested @ %1, scheduled for + %2 = %3, abort = %4\n",
1599 _transport_frame, _worst_input_latency,
1600 _transport_frame + _worst_input_latency,
1603 SessionEvent *ev = new SessionEvent (SessionEvent::StopOnce, SessionEvent::Replace,
1604 _transport_frame + _worst_input_latency,
1609 /* request a declick at the start of the next process cycle() so that playback ceases.
1610 It will remain silent until we actually stop (at the StopOnce event somewhere in
1611 the future). The extra flag (StopPendingCapture) is set to ensure that check_declick_out()
1612 does not stop the transport too early.
1614 new_bits = SubState (PendingDeclickOut|StopPendingCapture);
1618 /* Not recording, schedule a declick in the next process() cycle and then stop at its end */
1620 new_bits = PendingDeclickOut;
1621 DEBUG_TRACE (DEBUG::Transport, string_compose ("stop scheduled for next process cycle @ %1\n", _transport_frame));
1624 /* we'll be called again after the declick */
1625 transport_sub_state = SubState (transport_sub_state|new_bits);
1626 pending_abort = abort;
1632 DEBUG_TRACE (DEBUG::Transport, "time to actually stop\n");
1634 /* declick was scheduled, but we've been called again, which means it is really time to stop
1636 XXX: we should probably split this off into its own method and call it explicitly.
1639 realtime_stop (abort, clear_state);
1640 _butler->schedule_transport_work ();
1644 /** Called from the process thread */
1646 Session::start_transport ()
1648 DEBUG_TRACE (DEBUG::Transport, "start_transport\n");
1650 _last_roll_location = _transport_frame;
1651 _last_roll_or_reversal_location = _transport_frame;
1653 have_looped = false;
1655 /* if record status is Enabled, move it to Recording. if its
1656 already Recording, move it to Disabled.
1659 switch (record_status()) {
1661 if (!config.get_punch_in() && !preroll_record_punch_enabled()) {
1668 disable_record (false);
1676 transport_sub_state |= PendingDeclickIn;
1678 _transport_speed = _default_transport_speed;
1679 _target_transport_speed = _transport_speed;
1681 boost::shared_ptr<RouteList> rl = routes.reader();
1682 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1683 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1685 tr->realtime_set_speed (tr->speed(), true);
1689 if (!_engine.freewheeling()) {
1690 Timecode::Time time;
1691 timecode_time_subframes (_transport_frame, time);
1692 if (!dynamic_cast<MTC_Slave*>(_slave)) {
1693 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
1696 if (actively_recording() && click_data && (config.get_count_in () || _count_in_once)) {
1697 _count_in_once = false;
1698 /* calculate count-in duration (in audio samples)
1699 * - use [fixed] tempo/meter at _transport_frame
1700 * - calc duration of 1 bar + time-to-beat before or at transport_frame
1702 const Tempo& tempo = _tempo_map->tempo_at_frame (_transport_frame);
1703 const Meter& meter = _tempo_map->meter_at_frame (_transport_frame);
1705 const double num = meter.divisions_per_bar ();
1706 const double den = meter.note_divisor ();
1707 const double barbeat = _tempo_map->exact_qn_at_frame (_transport_frame, 0) * den / (4. * num);
1708 const double bar_fract = fmod (barbeat, 1.0); // fraction of bar elapsed.
1710 _count_in_samples = meter.frames_per_bar (tempo, _current_frame_rate);
1712 double dt = _count_in_samples / num;
1713 if (bar_fract == 0) {
1714 /* at bar boundary, count-in 2 bars before start. */
1715 _count_in_samples *= 2;
1717 /* beats left after full bar until roll position */
1718 _count_in_samples *= 1. + bar_fract;
1722 framepos_t cf = _transport_frame - _count_in_samples;
1723 while (cf < _transport_frame) {
1724 add_click (cf - _worst_track_latency, clickbeat == 0);
1726 clickbeat = fmod (clickbeat + 1, num);
1731 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC4 with speed = %1\n", _transport_speed));
1732 TransportStateChange (); /* EMIT SIGNAL */
1735 /** Do any transport work in the audio thread that needs to be done after the
1736 * transport thread is finished. Audio thread, realtime safe.
1739 Session::post_transport ()
1741 PostTransportWork ptw = post_transport_work ();
1743 if (ptw & PostTransportAudition) {
1744 if (auditioner && auditioner->auditioning()) {
1745 process_function = &Session::process_audition;
1747 process_function = &Session::process_with_events;
1751 if (ptw & PostTransportStop) {
1753 transport_sub_state = 0;
1756 if (ptw & PostTransportLocate) {
1758 if (((!config.get_external_sync() && (auto_play_legal && config.get_auto_play())) && !_exporting) || (ptw & PostTransportRoll)) {
1759 _count_in_once = false;
1762 transport_sub_state = 0;
1767 /* XXX is this really safe? shouldn't we just be unsetting the bits that we actually
1770 set_post_transport_work (PostTransportWork (0));
1774 Session::reset_rf_scale (framecnt_t motion)
1776 cumulative_rf_motion += motion;
1778 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1780 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1782 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1794 Session::mtc_status_changed (bool yn)
1796 g_atomic_int_set (&_mtc_active, yn);
1797 MTCSyncStateChanged( yn );
1801 Session::ltc_status_changed (bool yn)
1803 g_atomic_int_set (&_ltc_active, yn);
1804 LTCSyncStateChanged( yn );
1808 Session::use_sync_source (Slave* new_slave)
1810 /* Runs in process() context */
1812 bool non_rt_required = false;
1814 /* XXX this deletion is problematic because we're in RT context */
1819 MTC_Slave* mtc_slave = dynamic_cast<MTC_Slave*>(_slave);
1821 mtc_slave->ActiveChanged.connect_same_thread (mtc_status_connection, boost::bind (&Session::mtc_status_changed, this, _1));
1822 MTCSyncStateChanged(mtc_slave->locked() );
1824 if (g_atomic_int_get (&_mtc_active) ){
1825 g_atomic_int_set (&_mtc_active, 0);
1826 MTCSyncStateChanged( false );
1828 mtc_status_connection.disconnect ();
1831 LTC_Slave* ltc_slave = dynamic_cast<LTC_Slave*> (_slave);
1833 ltc_slave->ActiveChanged.connect_same_thread (ltc_status_connection, boost::bind (&Session::ltc_status_changed, this, _1));
1834 LTCSyncStateChanged (ltc_slave->locked() );
1836 if (g_atomic_int_get (&_ltc_active) ){
1837 g_atomic_int_set (&_ltc_active, 0);
1838 LTCSyncStateChanged( false );
1840 ltc_status_connection.disconnect ();
1843 DEBUG_TRACE (DEBUG::Slave, string_compose ("set new slave to %1\n", _slave));
1845 // need to queue this for next process() cycle
1846 _send_timecode_update = true;
1848 boost::shared_ptr<RouteList> rl = routes.reader();
1849 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1850 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1851 if (tr && !tr->hidden()) {
1852 if (tr->realtime_set_speed (tr->speed(), true)) {
1853 non_rt_required = true;
1855 tr->set_slaved (_slave != 0);
1859 if (non_rt_required) {
1860 add_post_transport_work (PostTransportSpeed);
1861 _butler->schedule_transport_work ();
1868 Session::drop_sync_source ()
1870 request_sync_source (0);
1874 Session::switch_to_sync_source (SyncSource src)
1878 DEBUG_TRACE (DEBUG::Slave, string_compose ("Setting up sync source %1\n", enum_2_string (src)));
1882 if (_slave && dynamic_cast<MTC_Slave*>(_slave)) {
1887 new_slave = new MTC_Slave (*this, *_midi_ports->mtc_input_port());
1890 catch (failed_constructor& err) {
1896 if (_slave && dynamic_cast<LTC_Slave*>(_slave)) {
1901 new_slave = new LTC_Slave (*this);
1904 catch (failed_constructor& err) {
1911 if (_slave && dynamic_cast<MIDIClock_Slave*>(_slave)) {
1916 new_slave = new MIDIClock_Slave (*this, *_midi_ports->midi_clock_input_port(), 24);
1919 catch (failed_constructor& err) {
1925 if (_slave && dynamic_cast<Engine_Slave*>(_slave)) {
1929 if (config.get_video_pullup() != 0.0f) {
1933 new_slave = new Engine_Slave (*AudioEngine::instance());
1941 request_sync_source (new_slave);
1945 Session::set_track_speed (Track* track, double speed)
1947 if (track->realtime_set_speed (speed, false)) {
1948 add_post_transport_work (PostTransportSpeed);
1949 _butler->schedule_transport_work ();
1955 Session::unset_play_range ()
1957 _play_range = false;
1958 _clear_event_type (SessionEvent::RangeStop);
1959 _clear_event_type (SessionEvent::RangeLocate);
1963 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1967 /* Called from event-processing context */
1969 unset_play_range ();
1971 if (range.empty()) {
1972 /* _play_range set to false in unset_play_range()
1974 if (!leave_rolling) {
1975 /* stop transport */
1976 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false);
1984 /* cancel loop play */
1987 list<AudioRange>::size_type sz = range.size();
1991 list<AudioRange>::iterator i = range.begin();
1992 list<AudioRange>::iterator next;
1994 while (i != range.end()) {
1999 /* locating/stopping is subject to delays for declicking.
2002 framepos_t requested_frame = i->end;
2004 if (requested_frame > current_block_size) {
2005 requested_frame -= current_block_size;
2007 requested_frame = 0;
2010 if (next == range.end()) {
2011 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_frame, 0, 0.0f);
2013 ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_frame, (*next).start, 0.0f);
2021 } else if (sz == 1) {
2023 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
2028 /* save range so we can do auto-return etc. */
2030 current_audio_range = range;
2032 /* now start rolling at the right place */
2034 ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
2037 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC5 with speed = %1\n", _transport_speed));
2038 TransportStateChange ();
2042 Session::request_bounded_roll (framepos_t start, framepos_t end)
2044 AudioRange ar (start, end, 0);
2045 list<AudioRange> lar;
2048 request_play_range (&lar, true);
2052 Session::set_requested_return_frame (framepos_t return_to)
2054 _requested_return_frame = return_to;
2058 Session::request_roll_at_and_return (framepos_t start, framepos_t return_to)
2060 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
2061 ev->target2_frame = start;
2066 Session::engine_halted ()
2070 /* there will be no more calls to process(), so
2071 we'd better clean up for ourselves, right now.
2073 but first, make sure the butler is out of
2081 realtime_stop (false, true);
2082 non_realtime_stop (false, 0, ignored);
2083 transport_sub_state = 0;
2085 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC6 with speed = %1\n", _transport_speed));
2086 TransportStateChange (); /* EMIT SIGNAL */
2091 Session::xrun_recovery ()
2095 Xrun (_transport_frame); /* EMIT SIGNAL */
2097 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
2099 /* it didn't actually halt, but we need
2100 to handle things in the same way.
2108 Session::route_processors_changed (RouteProcessorChange c)
2110 if (g_atomic_int_get (&_ignore_route_processor_changes) > 0) {
2114 if (c.type == RouteProcessorChange::MeterPointChange) {
2119 if (c.type == RouteProcessorChange::RealTimeChange) {
2124 update_latency_compensation ();
2131 Session::allow_auto_play (bool yn)
2133 auto_play_legal = yn;
2137 Session::maybe_stop (framepos_t limit)
2139 if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
2140 if (synced_to_engine () && config.get_jack_time_master ()) {
2141 _engine.transport_stop ();
2142 } else if (!synced_to_engine ()) {
2151 Session::send_mmc_locate (framepos_t t)
2157 if (!_engine.freewheeling()) {
2158 Timecode::Time time;
2159 timecode_time_subframes (t, time);
2160 send_immediate_mmc (MIDI::MachineControlCommand (time));
2164 /** Ask the transport to not send timecode until further notice. The suspension
2165 * will come into effect some finite time after this call, and timecode_transmission_suspended()
2166 * should be checked by the caller to find out when.
2169 Session::request_suspend_timecode_transmission ()
2171 SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, false);
2176 Session::request_resume_timecode_transmission ()
2178 SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, true);
2183 Session::timecode_transmission_suspended () const
2185 return g_atomic_int_get (&_suspend_timecode_transmission) == 1;