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"
51 #include "ardour/vca.h"
52 #include "ardour/vca_manager.h"
57 using namespace ARDOUR;
61 Session::add_post_transport_work (PostTransportWork ptw)
63 PostTransportWork oldval;
64 PostTransportWork newval;
68 oldval = (PostTransportWork) g_atomic_int_get (&_post_transport_work);
69 newval = PostTransportWork (oldval | ptw);
70 if (g_atomic_int_compare_and_exchange (&_post_transport_work, oldval, newval)) {
76 error << "Could not set post transport work! Crazy thread madness, call the programmers" << endmsg;
80 Session::request_sync_source (Slave* new_slave)
82 SessionEvent* ev = new SessionEvent (SessionEvent::SetSyncSource, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
85 seamless = Config->get_seamless_loop ();
87 if (dynamic_cast<Engine_Slave*>(new_slave)) {
88 /* JACK cannot support seamless looping at present */
89 Config->set_seamless_loop (false);
91 /* reset to whatever the value was before we last switched slaves */
92 Config->set_seamless_loop (_was_seamless);
95 /* save value of seamless from before the switch */
96 _was_seamless = seamless;
98 ev->slave = new_slave;
99 DEBUG_TRACE (DEBUG::Slave, "sent request for new slave\n");
104 Session::request_transport_speed (double speed, bool as_default)
106 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
107 ev->third_yes_or_no = as_default; // as_default
108 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport speed = %1 as default = %2\n", speed, as_default));
112 /** Request a new transport speed, but if the speed parameter is exactly zero then use
113 * a very small +ve value to prevent the transport actually stopping. This method should
114 * be used by callers who are varying transport speed but don't ever want to stop it.
117 Session::request_transport_speed_nonzero (double speed, bool as_default)
123 request_transport_speed (speed, as_default);
127 Session::request_stop (bool abort, bool clear_state)
129 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, audible_frame(), 0.0, abort, clear_state);
130 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));
135 Session::request_locate (framepos_t target_frame, bool with_roll)
137 SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, false);
138 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request locate to %1\n", target_frame));
143 Session::force_locate (framepos_t target_frame, bool with_roll)
145 SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, true);
146 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request forced locate to %1\n", target_frame));
151 Session::unset_preroll_record_punch ()
153 if (_preroll_record_punch_pos >= 0) {
154 remove_event (_preroll_record_punch_pos, SessionEvent::RecordStart);
156 _preroll_record_punch_pos = -1;
160 Session::unset_preroll_record_trim ()
162 _preroll_record_trim_len = 0;
166 Session::request_preroll_record_punch (framepos_t rec_in, framecnt_t preroll)
168 if (actively_recording ()) {
171 unset_preroll_record_punch ();
172 unset_preroll_record_trim ();
173 framepos_t start = std::max ((framepos_t)0, rec_in - preroll);
175 _preroll_record_punch_pos = rec_in;
176 if (_preroll_record_punch_pos >= 0) {
177 replace_event (SessionEvent::RecordStart, _preroll_record_punch_pos);
178 config.set_punch_in (false);
179 config.set_punch_out (false);
181 maybe_enable_record ();
182 request_locate (start, true);
183 set_requested_return_frame (rec_in);
187 Session::request_preroll_record_trim (framepos_t rec_in, framecnt_t preroll)
189 if (actively_recording ()) {
192 unset_preroll_record_punch ();
193 unset_preroll_record_trim ();
195 config.set_punch_in (false);
196 config.set_punch_out (false);
198 framepos_t pos = std::max ((framepos_t)0, rec_in - preroll);
199 _preroll_record_trim_len = preroll;
200 maybe_enable_record ();
201 request_locate (pos, true);
202 set_requested_return_frame (rec_in);
206 Session::request_count_in_record ()
208 if (actively_recording ()) {
211 if (transport_rolling()) {
214 maybe_enable_record ();
215 _count_in_once = true;
216 request_transport_speed (1.0, true);
220 Session::request_play_loop (bool yn, bool change_transport_roll)
223 // don't attempt to loop when not using Internal Transport
224 // see also gtk2_ardour/ardour_ui_options.cc parameter_changed()
229 Location *location = _locations->auto_loop_location();
232 if (location == 0 && yn) {
233 error << _("Cannot loop - no loop range defined")
238 if (change_transport_roll) {
239 if (transport_rolling()) {
240 /* start looping at current speed */
241 target_speed = transport_speed ();
243 /* currently stopped */
245 /* start looping at normal speed */
252 /* leave the speed alone */
253 target_speed = transport_speed ();
256 ev = new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, target_speed, yn);
257 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request set loop = %1, change roll state ? %2\n", yn, change_transport_roll));
261 if (!change_transport_roll) {
262 if (!transport_rolling()) {
263 /* we're not changing transport state, but we do want
264 to set up position for the new loop. Don't
265 do this if we're rolling already.
267 request_locate (location->start(), false);
271 if (!change_transport_roll && Config->get_seamless_loop() && transport_rolling()) {
272 // request an immediate locate to refresh the tracks
273 // after disabling looping
274 request_locate (_transport_frame-1, false);
280 Session::request_play_range (list<AudioRange>* range, bool leave_rolling)
282 SessionEvent* ev = new SessionEvent (SessionEvent::SetPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0));
284 ev->audio_range = *range;
286 ev->audio_range.clear ();
288 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request play range, leave rolling ? %1\n", leave_rolling));
293 Session::request_cancel_play_range ()
295 SessionEvent* ev = new SessionEvent (SessionEvent::CancelPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, 0);
301 Session::realtime_stop (bool abort, bool clear_state)
303 DEBUG_TRACE (DEBUG::Transport, string_compose ("realtime stop @ %1\n", _transport_frame));
304 PostTransportWork todo = PostTransportWork (0);
306 /* assume that when we start, we'll be moving forwards */
308 if (_transport_speed < 0.0f) {
309 todo = (PostTransportWork (todo | PostTransportStop | PostTransportReverse));
310 _default_transport_speed = 1.0;
312 todo = PostTransportWork (todo | PostTransportStop);
317 boost::shared_ptr<RouteList> r = routes.reader ();
319 for (RouteList::iterator i = r->begin (); i != r->end(); ++i) {
320 (*i)->realtime_handle_transport_stopped ();
323 DEBUG_TRACE (DEBUG::Transport, string_compose ("stop complete, auto-return scheduled for return to %1\n", _requested_return_frame));
325 /* the duration change is not guaranteed to have happened, but is likely */
327 todo = PostTransportWork (todo | PostTransportDuration);
330 todo = PostTransportWork (todo | PostTransportAbort);
334 todo = PostTransportWork (todo | PostTransportClearSubstate);
338 add_post_transport_work (todo);
341 _clear_event_type (SessionEvent::StopOnce);
342 _clear_event_type (SessionEvent::RangeStop);
343 _clear_event_type (SessionEvent::RangeLocate);
345 /* if we're going to clear loop state, then force disabling record BUT only if we're not doing latched rec-enable */
346 disable_record (true, (!Config->get_latched_record_enable() && clear_state));
348 if (clear_state && !Config->get_loop_is_mode()) {
352 reset_slave_state ();
354 _transport_speed = 0;
355 _target_transport_speed = 0;
357 g_atomic_int_set (&_playback_load, 100);
358 g_atomic_int_set (&_capture_load, 100);
360 if (config.get_use_video_sync()) {
361 waiting_for_sync_offset = true;
364 transport_sub_state = 0;
368 Session::realtime_locate ()
370 boost::shared_ptr<RouteList> r = routes.reader ();
371 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
372 (*i)->realtime_locate ();
377 Session::butler_transport_work ()
379 /* Note: this function executes in the butler thread context */
383 PostTransportWork ptw;
384 boost::shared_ptr<RouteList> r = routes.reader ();
387 int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
389 ptw = post_transport_work();
391 DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler transport work, todo = %1 at %2\n", enum_2_string (ptw), (before = g_get_monotonic_time())));
394 if (ptw & PostTransportLocate) {
396 if (get_play_loop() && !Config->get_seamless_loop()) {
398 DEBUG_TRACE (DEBUG::Butler, "flush loop recording fragment to disk\n");
400 /* this locate might be happening while we are
403 * Non-seamless looping will require a locate (below) that
404 * will reset capture buffers and throw away data.
406 * Rather than first find all tracks and see if they
407 * have outstanding data, just do a flush anyway. It
408 * may be cheaper this way anyway, and is certainly
412 bool more_disk_io_to_do = false;
416 more_disk_io_to_do = _butler->flush_tracks_to_disk_after_locate (r, errors);
422 if (more_disk_io_to_do) {
431 if (ptw & PostTransportAdjustPlaybackBuffering) {
432 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
433 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
435 tr->adjust_playback_buffering ();
436 /* and refill those buffers ... */
438 (*i)->non_realtime_locate (_transport_frame);
440 VCAList v = _vca_manager->vcas ();
441 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
442 (*i)->non_realtime_locate (_transport_frame);
446 if (ptw & PostTransportAdjustCaptureBuffering) {
447 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
448 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
450 tr->adjust_capture_buffering ();
455 if (ptw & PostTransportCurveRealloc) {
456 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
457 (*i)->curve_reallocate();
461 if (ptw & PostTransportSpeed) {
462 non_realtime_set_speed ();
465 if (ptw & PostTransportReverse) {
468 cumulative_rf_motion = 0;
471 /* don't seek if locate will take care of that in non_realtime_stop() */
473 if (!(ptw & PostTransportLocate)) {
474 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
475 (*i)->non_realtime_locate (_transport_frame);
477 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
478 /* new request, stop seeking, and start again */
479 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
483 VCAList v = _vca_manager->vcas ();
484 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
485 (*i)->non_realtime_locate (_transport_frame);
490 if (ptw & PostTransportLocate) {
491 DEBUG_TRACE (DEBUG::Transport, "nonrealtime locate invoked from BTW\n");
492 non_realtime_locate ();
495 if (ptw & PostTransportStop) {
496 non_realtime_stop (ptw & PostTransportAbort, on_entry, finished);
498 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
503 if (ptw & PostTransportOverWrite) {
504 non_realtime_overwrite (on_entry, finished);
506 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
511 if (ptw & PostTransportAudition) {
512 non_realtime_set_audition ();
515 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
517 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_frame, _butler->transport_work_requested()));
521 Session::non_realtime_set_speed ()
523 boost::shared_ptr<RouteList> rl = routes.reader();
524 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
525 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
527 tr->non_realtime_speed_change ();
533 Session::non_realtime_overwrite (int on_entry, bool& finished)
535 boost::shared_ptr<RouteList> rl = routes.reader();
536 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
537 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
538 if (tr && tr->pending_overwrite ()) {
539 tr->overwrite_existing_buffers ();
541 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
550 Session::non_realtime_locate ()
552 DEBUG_TRACE (DEBUG::Transport, string_compose ("locate tracks to %1\n", _transport_frame));
554 if (Config->get_loop_is_mode() && get_play_loop()) {
556 Location *loc = _locations->auto_loop_location();
558 if (!loc || (_transport_frame < loc->start() || _transport_frame >= loc->end())) {
559 /* jumped out of loop range: stop tracks from looping,
560 but leave loop (mode) enabled.
562 set_track_loop (false);
564 } else if (loc && Config->get_seamless_loop() &&
565 ((loc->start() <= _transport_frame) ||
566 (loc->end() > _transport_frame) ) ) {
568 /* jumping to start of loop. This might have been done before but it is
569 * idempotent and cheap. Doing it here ensures that when we start playback
570 * outside the loop we still flip tracks into the magic seamless mode
573 set_track_loop (true);
576 set_track_loop (false);
581 /* no more looping .. should have been noticed elsewhere */
585 microseconds_t begin = get_microseconds ();
588 boost::shared_ptr<RouteList> rl = routes.reader();
591 const framepos_t tf = _transport_frame;
593 cerr << "\n\n >>> START Non-RT locate on routes to " << tf << "\n\n";
595 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
596 (*i)->non_realtime_locate (_transport_frame);
597 if (tf != _transport_frame) {
598 /* new locate request arrived while processing
599 this one. start over.
601 cerr << "\n\n\n\n RESTART LOCATE @ " << _transport_frame << endl;
606 cerr << "\n\n <<< DONE Non-RT locate on routes\n\n";
610 VCAList v = _vca_manager->vcas ();
611 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
612 (*i)->non_realtime_locate (_transport_frame);
616 microseconds_t end = get_microseconds ();
617 cerr << "Locate took " << setprecision (3) << ((end - begin) /1000000.0) << " secs\n";
619 _scene_changer->locate (_transport_frame);
621 /* XXX: it would be nice to generate the new clicks here (in the non-RT thread)
622 rather than clearing them so that the RT thread has to spend time constructing
623 them (in Session::click).
628 #ifdef USE_TRACKS_CODE_FEATURES
630 Session::select_playhead_priority_target (framepos_t& jump_to)
634 AutoReturnTarget autoreturn = Config->get_auto_return_target_list ();
640 if (Profile->get_trx() && transport_rolling() ) {
641 // We're playing, so do nothing.
642 // Next stop will put us where we need to be.
646 /* Note that the order of checking each AutoReturnTarget flag defines
647 the priority each flag.
649 Ardour/Mixbus: Last Locate
654 Tracks: Range Selection
660 if (autoreturn & RangeSelectionStart) {
661 if (!_range_selection.empty()) {
662 jump_to = _range_selection.from;
664 if (transport_rolling ()) {
665 /* Range selection no longer exists, but we're playing,
666 so do nothing. Next stop will put us where
674 if (jump_to < 0 && (autoreturn & Loop) && get_play_loop()) {
675 /* don't try to handle loop play when synced to JACK */
677 if (!synced_to_engine()) {
678 Location *location = _locations->auto_loop_location();
681 jump_to = location->start();
683 if (Config->get_seamless_loop()) {
684 /* need to get track buffers reloaded */
685 set_track_loop (true);
691 if (jump_to < 0 && (autoreturn & RegionSelectionStart)) {
692 if (!_object_selection.empty()) {
693 jump_to = _object_selection.from;
697 if (jump_to < 0 && (autoreturn & LastLocate)) {
698 jump_to = _last_roll_location;
706 Session::select_playhead_priority_target (framepos_t& jump_to)
708 if (config.get_external_sync() || !config.get_auto_return()) {
712 jump_to = _last_roll_location;
719 Session::follow_playhead_priority ()
723 if (select_playhead_priority_target (target)) {
724 request_locate (target);
729 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
735 PostTransportWork ptw = post_transport_work();
740 boost::shared_ptr<RouteList> rl = routes.reader();
741 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
742 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
743 if (tr && tr->get_captured_frames () != 0) {
749 /* stop and locate are merged here because they share a lot of common stuff */
752 now = localtime (&xnow);
755 auditioner->cancel_audition ();
758 cumulative_rf_motion = 0;
762 begin_reversible_command (Operations::capture);
763 _have_captured = true;
766 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: DS stop\n"));
768 if (abort && did_record) {
769 /* no reason to save the session file when we remove sources
771 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
774 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
775 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
777 tr->transport_stopped_wallclock (*now, xnow, abort);
781 if (abort && did_record) {
782 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
785 boost::shared_ptr<RouteList> r = routes.reader ();
787 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
788 if (!(*i)->is_auditioner()) {
789 (*i)->set_pending_declick (0);
794 commit_reversible_command ();
795 /* increase take name */
796 if (config.get_track_name_take () && !config.get_take_name ().empty()) {
797 string newname = config.get_take_name();
798 config.set_take_name(bump_name_number (newname));
802 if (_engine.running()) {
803 PostTransportWork ptw = post_transport_work ();
805 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
806 (*i)->non_realtime_transport_stop (_transport_frame, !(ptw & PostTransportLocate) || pending_locate_flush);
808 VCAList v = _vca_manager->vcas ();
809 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
810 (*i)->non_realtime_transport_stop (_transport_frame, !(ptw & PostTransportLocate) || pending_locate_flush);
813 update_latency_compensation ();
816 bool const auto_return_enabled = (!config.get_external_sync() && (Config->get_auto_return_target_list() || abort));
818 if (auto_return_enabled ||
819 (ptw & PostTransportLocate) ||
820 (_requested_return_frame >= 0) ||
821 synced_to_engine()) {
823 if (pending_locate_flush) {
824 flush_all_inserts ();
827 // rg: what is the logic behind this case?
828 // _requested_return_frame should be ignored when synced_to_engine/slaved.
829 // currently worked around in MTC_Slave by forcing _requested_return_frame to -1
831 if ((auto_return_enabled || synced_to_engine() || _requested_return_frame >= 0) &&
832 !(ptw & PostTransportLocate)) {
834 /* no explicit locate queued */
836 bool do_locate = false;
838 if (_requested_return_frame >= 0) {
840 /* explicit return request pre-queued in event list. overrides everything else */
842 _transport_frame = _requested_return_frame;
848 if (select_playhead_priority_target (jump_to)) {
850 _transport_frame = jump_to;
855 _transport_frame = _last_roll_location;
860 _requested_return_frame = -1;
863 _engine.transport_locate (_transport_frame);
870 unset_preroll_record_trim ();
872 /* do this before seeking, because otherwise the tracks will do the wrong thing in seamless loop mode.
875 if (ptw & PostTransportClearSubstate) {
877 if (!Config->get_loop_is_mode()) {
882 /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
885 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: locate\n"));
886 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
887 DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler PTW: locate on %1\n", (*i)->name()));
888 (*i)->non_realtime_locate (_transport_frame);
890 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
892 /* we will be back */
899 VCAList v = _vca_manager->vcas ();
900 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
901 (*i)->non_realtime_locate (_transport_frame);
907 /* don't bother with this stuff if we're disconnected from the engine,
908 because there will be no process callbacks to deliver stuff from
911 if (_engine.connected() && !_engine.freewheeling()) {
912 // need to queue this in the next RT cycle
913 _send_timecode_update = true;
915 if (!dynamic_cast<MTC_Slave*>(_slave)) {
916 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
918 /* This (::non_realtime_stop()) gets called by main
919 process thread, which will lead to confusion
920 when calling AsyncMIDIPort::write().
922 Something must be done. XXX
924 send_mmc_locate (_transport_frame);
928 if ((ptw & PostTransportLocate) && get_record_enabled()) {
929 /* This is scheduled by realtime_stop(), which is also done
930 * when a slave requests /locate/ for an initial sync.
931 * We can't hold up the slave for long with a save() here,
932 * without breaking its initial sync cycle.
934 * save state only if there's no slave or if it's not yet locked.
936 if (!_slave || !_slave->locked()) {
937 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: requests save\n"));
938 SaveSessionRequested (_current_snapshot_name);
943 /* always try to get rid of this */
945 remove_pending_capture_state ();
947 /* save the current state of things if appropriate */
949 if (did_record && !saved) {
950 SaveSessionRequested (_current_snapshot_name);
953 if (ptw & PostTransportStop) {
955 if (!Config->get_loop_is_mode()) {
960 PositionChanged (_transport_frame); /* EMIT SIGNAL */
961 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC with speed = %1\n", _transport_speed));
962 TransportStateChange (); /* EMIT SIGNAL */
963 AutomationWatch::instance().transport_stop_automation_watches (_transport_frame);
965 /* and start it up again if relevant */
967 if ((ptw & PostTransportLocate) && !config.get_external_sync() && pending_locate_roll) {
968 request_transport_speed (1.0);
971 /* Even if we didn't do a pending locate roll this time, we don't want it hanging
972 around for next time.
974 pending_locate_roll = false;
978 Session::check_declick_out ()
980 bool locate_required = transport_sub_state & PendingLocate;
982 /* this is called after a process() iteration. if PendingDeclickOut was set,
983 it means that we were waiting to declick the output (which has just been
984 done) before maybe doing something else. this is where we do that "something else".
986 note: called from the audio thread.
989 if (transport_sub_state & PendingDeclickOut) {
991 if (locate_required) {
992 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
993 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
995 if (!(transport_sub_state & StopPendingCapture)) {
996 stop_transport (pending_abort);
997 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
1001 } else if (transport_sub_state & PendingLoopDeclickOut) {
1002 /* Nothing else to do here; we've declicked, and the loop event will be along shortly */
1003 transport_sub_state &= ~PendingLoopDeclickOut;
1008 Session::unset_play_loop ()
1012 clear_events (SessionEvent::AutoLoop);
1013 clear_events (SessionEvent::AutoLoopDeclick);
1014 set_track_loop (false);
1017 if (Config->get_seamless_loop()) {
1018 /* likely need to flush track buffers: this will locate us to wherever we are */
1019 add_post_transport_work (PostTransportLocate);
1020 _butler->schedule_transport_work ();
1026 Session::set_track_loop (bool yn)
1028 Location* loc = _locations->auto_loop_location ();
1034 boost::shared_ptr<RouteList> rl = routes.reader ();
1036 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1037 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1038 if (tr && !tr->is_private_route()) {
1039 tr->set_loop (yn ? loc : 0);
1045 Session::set_play_loop (bool yn, double speed)
1047 /* Called from event-handling context */
1051 if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) {
1052 /* nothing to do, or can't change loop status while recording */
1056 if (yn && Config->get_seamless_loop() && synced_to_engine()) {
1057 warning << string_compose (
1058 _("Seamless looping cannot be supported while %1 is using JACK transport.\n"
1059 "Recommend changing the configured options"), PROGRAM_NAME)
1067 have_looped = false;
1071 unset_play_range ();
1073 if (Config->get_seamless_loop()) {
1074 if (!Config->get_loop_is_mode()) {
1075 /* set all tracks to use internal looping */
1076 set_track_loop (true);
1078 /* we will do this in the locate to the start OR when we hit the end
1079 * of the loop for the first time
1083 /* set all tracks to NOT use internal looping */
1084 set_track_loop (false);
1087 /* Put the delick and loop events in into the event list. The declick event will
1088 cause a de-clicking fade-out just before the end of the loop, and it will also result
1089 in a fade-in when the loop restarts. The AutoLoop event will peform the actual loop.
1094 auto_loop_declick_range (loc, dcp, dcl);
1095 merge_event (new SessionEvent (SessionEvent::AutoLoopDeclick, SessionEvent::Replace, dcp, dcl, 0.0f));
1096 merge_event (new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f));
1098 /* if requested to roll, locate to start of loop and
1099 * roll but ONLY if we're not already rolling.
1101 args: positition, roll=true, flush=true, with_loop=false, force buffer refill if seamless looping
1104 if (Config->get_loop_is_mode()) {
1105 /* loop IS a transport mode: if already
1106 rolling, do not locate to loop start.
1108 if (!transport_rolling() && (speed != 0.0)) {
1109 start_locate (loc->start(), true, true, false, true);
1113 start_locate (loc->start(), true, true, false, true);
1123 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC2 with speed = %1\n", _transport_speed));
1124 TransportStateChange ();
1127 Session::flush_all_inserts ()
1129 boost::shared_ptr<RouteList> r = routes.reader ();
1131 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1132 (*i)->flush_processors ();
1137 Session::start_locate (framepos_t target_frame, bool with_roll, bool with_flush, bool for_loop_enabled, bool force)
1139 if (target_frame < 0) {
1140 error << _("Locate called for negative sample position - ignored") << endmsg;
1144 if (synced_to_engine()) {
1149 _slave->speed_and_position (sp, pos);
1151 if (target_frame != pos) {
1153 if (config.get_jack_time_master()) {
1154 /* actually locate now, since otherwise jack_timebase_callback
1155 will use the incorrect _transport_frame and report an old
1156 and incorrect time to Jack transport
1158 locate (target_frame, with_roll, with_flush, for_loop_enabled, force);
1161 /* tell JACK to change transport position, and we will
1162 follow along later in ::follow_slave()
1165 _engine.transport_locate (target_frame);
1167 if (sp != 1.0f && with_roll) {
1168 _engine.transport_start ();
1174 locate (target_frame, with_roll, with_flush, for_loop_enabled, force);
1179 Session::micro_locate (framecnt_t distance)
1181 boost::shared_ptr<RouteList> rl = routes.reader();
1182 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1183 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1184 if (tr && !tr->can_internal_playback_seek (distance)) {
1189 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1190 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1192 tr->internal_playback_seek (distance);
1196 _transport_frame += distance;
1200 /** @param with_mmc true to send a MMC locate command when the locate is done */
1202 Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool for_loop_enabled, bool force, bool with_mmc)
1204 bool need_butler = false;
1206 /* Locates for seamless looping are fairly different from other
1207 * locates. They assume that the diskstream buffers for each track
1208 * already have the correct data in them, and thus there is no need to
1209 * actually tell the tracks to locate. What does need to be done,
1210 * though, is all the housekeeping that is associated with non-linear
1211 * changes in the value of _transport_frame.
1214 DEBUG_TRACE (DEBUG::Transport, string_compose ("rt-locate to %1, roll %2 flush %3 loop-enabled %4 force %5 mmc %6\n",
1215 target_frame, with_roll, with_flush, for_loop_enabled, force, with_mmc));
1217 if (!force && _transport_frame == target_frame && !loop_changing && !for_loop_enabled) {
1219 /* already at the desired position. Not forced to locate,
1220 the loop isn't changing, so unless we're told to
1221 start rolling also, there's nothing to do but
1222 tell the world where we are (again).
1226 set_transport_speed (1.0, 0, false);
1228 loop_changing = false;
1229 Located (); /* EMIT SIGNAL */
1233 if (_transport_speed && !(for_loop_enabled && Config->get_seamless_loop())) {
1234 /* Schedule a declick. We'll be called again when its done.
1235 We only do it this way for ordinary locates, not those
1236 due to **seamless** loops.
1239 if (!(transport_sub_state & PendingDeclickOut)) {
1240 transport_sub_state |= (PendingDeclickOut|PendingLocate);
1241 pending_locate_frame = target_frame;
1242 pending_locate_roll = with_roll;
1243 pending_locate_flush = with_flush;
1248 // Update Timecode time
1249 _transport_frame = target_frame;
1250 _last_roll_or_reversal_location = target_frame;
1251 timecode_time(_transport_frame, transmitting_timecode_time);
1253 /* do "stopped" stuff if:
1255 * we are rolling AND
1256 * no autoplay in effect AND
1257 * we're not going to keep rolling after the locate AND
1258 * !(playing a loop with JACK sync)
1262 bool transport_was_stopped = !transport_rolling();
1264 if (!transport_was_stopped && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_engine() && play_loop) &&
1265 (!Profile->get_trx() || !(config.get_external_sync() && !synced_to_engine()))) {
1266 realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
1267 transport_was_stopped = true;
1269 /* otherwise tell the world that we located */
1273 if (force || !for_loop_enabled || loop_changing) {
1275 PostTransportWork todo = PostTransportLocate;
1277 if (with_roll && transport_was_stopped) {
1278 todo = PostTransportWork (todo | PostTransportRoll);
1281 add_post_transport_work (todo);
1286 /* this is functionally what clear_clicks() does but with a tentative lock */
1288 Glib::Threads::RWLock::WriterLock clickm (click_lock, Glib::Threads::TRY_LOCK);
1290 if (clickm.locked()) {
1292 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
1301 /* switch from input if we're going to roll */
1302 if (Config->get_monitoring_model() == HardwareMonitoring) {
1303 set_track_monitor_input_status (!config.get_auto_input());
1306 /* otherwise we're going to stop, so do the opposite */
1307 if (Config->get_monitoring_model() == HardwareMonitoring) {
1308 set_track_monitor_input_status (true);
1312 /* cancel looped playback if transport pos outside of loop range */
1315 Location* al = _locations->auto_loop_location();
1318 if (_transport_frame < al->start() || _transport_frame >= al->end()) {
1320 // located outside the loop: cancel looping directly, this is called from event handling context
1322 have_looped = false;
1324 if (!Config->get_loop_is_mode()) {
1325 set_play_loop (false, _transport_speed);
1327 if (Config->get_seamless_loop()) {
1328 /* this will make the non_realtime_locate() in the butler
1329 which then causes seek() in tracks actually do the right
1332 set_track_loop (false);
1336 } else if (_transport_frame == al->start()) {
1338 // located to start of loop - this is looping, basically
1342 if (_last_roll_location != al->start()) {
1343 /* didn't start at loop start - playback must have
1344 * started before loop since we've now hit the loop
1347 add_post_transport_work (PostTransportLocate);
1353 boost::shared_ptr<RouteList> rl = routes.reader();
1355 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1356 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1358 if (tr && tr->rec_enable_control()->get_value()) {
1359 // tell it we've looped, so it can deal with the record state
1360 tr->transport_looped (_transport_frame);
1365 TransportLooped(); // EMIT SIGNAL
1371 _butler->schedule_transport_work ();
1374 loop_changing = false;
1376 _send_timecode_update = true;
1379 send_mmc_locate (_transport_frame);
1382 _last_roll_location = _last_roll_or_reversal_location = _transport_frame;
1383 if (!synced_to_engine () || _transport_frame == _engine.transport_frame ()) {
1384 Located (); /* EMIT SIGNAL */
1388 /** Set the transport speed.
1389 * Called from the process thread.
1390 * @param speed New speed
1393 Session::set_transport_speed (double speed, framepos_t destination_frame, bool abort, bool clear_state, bool as_default)
1395 DEBUG_TRACE (DEBUG::Transport, string_compose ("@ %5 Set transport speed to %1, abort = %2 clear_state = %3, current = %4 as_default %6\n",
1396 speed, abort, clear_state, _transport_speed, _transport_frame, as_default));
1398 if (_transport_speed == speed) {
1399 if (as_default && speed == 0.0) { // => reset default transport speed. hacky or what?
1400 _default_transport_speed = 1.0;
1405 if (actively_recording() && speed != 1.0 && speed != 0.0) {
1406 /* no varispeed during recording */
1407 DEBUG_TRACE (DEBUG::Transport, string_compose ("No varispeed during recording cur_speed %1, frame %2\n",
1408 _transport_speed, _transport_frame));
1412 _target_transport_speed = fabs(speed);
1414 /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
1415 and user needs. We really need CD-style "skip" playback for ffwd and rewind.
1419 speed = min (8.0, speed);
1420 } else if (speed < 0) {
1421 speed = max (-8.0, speed);
1424 if (transport_rolling() && speed == 0.0) {
1426 /* we are rolling and we want to stop */
1428 if (Config->get_monitoring_model() == HardwareMonitoring) {
1429 set_track_monitor_input_status (true);
1432 if (synced_to_engine ()) {
1434 /* do this here because our response to the slave won't
1437 _play_range = false;
1438 _count_in_once = false;
1441 _engine.transport_stop ();
1443 bool const auto_return_enabled = (!config.get_external_sync() && (Config->get_auto_return_target_list() || abort));
1445 if (!auto_return_enabled) {
1446 _requested_return_frame = destination_frame;
1449 stop_transport (abort);
1452 } else if (transport_stopped() && speed == 1.0) {
1454 _default_transport_speed = speed;
1456 /* we are stopped and we want to start rolling at speed 1 */
1458 if (Config->get_loop_is_mode() && play_loop) {
1460 Location *location = _locations->auto_loop_location();
1462 if (location != 0) {
1463 if (_transport_frame != location->start()) {
1465 if (Config->get_seamless_loop()) {
1466 /* force tracks to do their thing */
1467 set_track_loop (true);
1470 /* jump to start and then roll from there */
1472 request_locate (location->start(), true);
1478 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1479 set_track_monitor_input_status (false);
1482 if (synced_to_engine()) {
1483 _engine.transport_start ();
1484 _count_in_once = false;
1491 /* not zero, not 1.0 ... varispeed */
1493 if ((synced_to_engine()) && speed != 0.0 && speed != 1.0) {
1494 warning << string_compose (
1495 _("Global varispeed cannot be supported while %1 is connected to JACK transport control"),
1501 if (actively_recording()) {
1505 if (speed > 0.0 && _transport_frame == current_end_frame()) {
1509 if (speed < 0.0 && _transport_frame == 0) {
1515 /* if we are reversing relative to the current speed, or relative to the speed
1516 before the last stop, then we have to do extra work.
1519 PostTransportWork todo = PostTransportWork (0);
1521 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0 && speed < 0.0)) {
1522 todo = PostTransportWork (todo | PostTransportReverse);
1523 _last_roll_or_reversal_location = _transport_frame;
1526 _last_transport_speed = _transport_speed;
1527 _transport_speed = speed;
1530 _default_transport_speed = speed;
1533 boost::shared_ptr<RouteList> rl = routes.reader();
1534 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1535 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1536 if (tr && tr->realtime_speed_change()) {
1537 todo = PostTransportWork (todo | PostTransportSpeed);
1542 add_post_transport_work (todo);
1543 _butler->schedule_transport_work ();
1546 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC3 with speed = %1\n", _transport_speed));
1548 /* throttle signal emissions.
1549 * when slaved [_last]_transport_speed
1550 * usually changes every cycle (tiny amounts due to DLL).
1551 * Emitting a signal every cycle is overkill and unwarranted.
1553 * Using _last_transport_speed is not acceptable,
1554 * since it allows for large changes over a long period
1555 * of time. Hence we introduce a dedicated variable to keep track
1557 * The 0.2% dead-zone is somewhat arbitrary. Main use-case
1558 * for TransportStateChange() here is the ShuttleControl display.
1560 if (fabs (_signalled_varispeed - speed) > .002
1561 // still, signal hard changes to 1.0 and 0.0:
1562 || ( speed == 1.0 && _signalled_varispeed != 1.0)
1563 || ( speed == 0.0 && _signalled_varispeed != 0.0)
1566 TransportStateChange (); /* EMIT SIGNAL */
1567 _signalled_varispeed = speed;
1573 /** Stop the transport. */
1575 Session::stop_transport (bool abort, bool clear_state)
1577 _count_in_once = false;
1578 if (_transport_speed == 0.0f) {
1582 DEBUG_TRACE (DEBUG::Transport, string_compose ("stop_transport, declick required? %1\n", get_transport_declick_required()));
1584 if (!get_transport_declick_required()) {
1586 /* stop has not yet been scheduled */
1588 boost::shared_ptr<RouteList> rl = routes.reader();
1589 framepos_t stop_target = audible_frame();
1591 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1592 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1594 tr->prepare_to_stop (_transport_frame, stop_target);
1600 if (actively_recording() && /* we are recording */
1601 worst_input_latency() > current_block_size) { /* input latency exceeds block size, so simple 1 cycle delay before stop is not enough */
1603 /* we need to capture the audio that is still somewhere in the pipeline between
1604 wherever it was generated and the process callback. This means that even though
1605 the user (or something else) has asked us to stop, we have to roll
1606 past this point and then reset the playhead/transport location to
1607 the position at which the stop was requested.
1609 we still need playback to "stop" now, however, which is why we schedule
1613 DEBUG_TRACE (DEBUG::Transport, string_compose ("stop transport requested @ %1, scheduled for + %2 = %3, abort = %4\n",
1614 _transport_frame, _worst_input_latency,
1615 _transport_frame + _worst_input_latency,
1618 SessionEvent *ev = new SessionEvent (SessionEvent::StopOnce, SessionEvent::Replace,
1619 _transport_frame + _worst_input_latency,
1624 /* request a declick at the start of the next process cycle() so that playback ceases.
1625 It will remain silent until we actually stop (at the StopOnce event somewhere in
1626 the future). The extra flag (StopPendingCapture) is set to ensure that check_declick_out()
1627 does not stop the transport too early.
1629 new_bits = SubState (PendingDeclickOut|StopPendingCapture);
1633 /* Not recording, schedule a declick in the next process() cycle and then stop at its end */
1635 new_bits = PendingDeclickOut;
1636 DEBUG_TRACE (DEBUG::Transport, string_compose ("stop scheduled for next process cycle @ %1\n", _transport_frame));
1639 /* we'll be called again after the declick */
1640 transport_sub_state = SubState (transport_sub_state|new_bits);
1641 pending_abort = abort;
1647 DEBUG_TRACE (DEBUG::Transport, "time to actually stop\n");
1649 /* declick was scheduled, but we've been called again, which means it is really time to stop
1651 XXX: we should probably split this off into its own method and call it explicitly.
1654 realtime_stop (abort, clear_state);
1655 _butler->schedule_transport_work ();
1659 /** Called from the process thread */
1661 Session::start_transport ()
1663 DEBUG_TRACE (DEBUG::Transport, "start_transport\n");
1665 _last_roll_location = _transport_frame;
1666 _last_roll_or_reversal_location = _transport_frame;
1668 have_looped = false;
1670 /* if record status is Enabled, move it to Recording. if its
1671 already Recording, move it to Disabled.
1674 switch (record_status()) {
1676 if (!config.get_punch_in() && !preroll_record_punch_enabled()) {
1683 disable_record (false);
1691 transport_sub_state |= PendingDeclickIn;
1693 _transport_speed = _default_transport_speed;
1694 _target_transport_speed = _transport_speed;
1696 boost::shared_ptr<RouteList> rl = routes.reader();
1697 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1698 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1700 tr->realtime_speed_change ();
1704 if (!_engine.freewheeling()) {
1705 Timecode::Time time;
1706 timecode_time_subframes (_transport_frame, time);
1707 if (!dynamic_cast<MTC_Slave*>(_slave)) {
1708 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
1711 if (actively_recording() && click_data && (config.get_count_in () || _count_in_once)) {
1712 _count_in_once = false;
1713 /* calculate count-in duration (in audio samples)
1714 * - use [fixed] tempo/meter at _transport_frame
1715 * - calc duration of 1 bar + time-to-beat before or at transport_frame
1717 const Tempo& tempo = _tempo_map->tempo_at_frame (_transport_frame);
1718 const Meter& meter = _tempo_map->meter_at_frame (_transport_frame);
1720 const double num = meter.divisions_per_bar ();
1721 const double den = meter.note_divisor ();
1722 const double barbeat = _tempo_map->exact_qn_at_frame (_transport_frame, 0) * den / (4. * num);
1723 const double bar_fract = fmod (barbeat, 1.0); // fraction of bar elapsed.
1725 _count_in_samples = meter.frames_per_bar (tempo, _current_frame_rate);
1727 double dt = _count_in_samples / num;
1728 if (bar_fract == 0) {
1729 /* at bar boundary, count-in 2 bars before start. */
1730 _count_in_samples *= 2;
1732 /* beats left after full bar until roll position */
1733 _count_in_samples *= 1. + bar_fract;
1737 framepos_t cf = _transport_frame - _count_in_samples;
1738 while (cf < _transport_frame) {
1739 add_click (cf - _worst_track_latency, clickbeat == 0);
1741 clickbeat = fmod (clickbeat + 1, num);
1746 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC4 with speed = %1\n", _transport_speed));
1747 TransportStateChange (); /* EMIT SIGNAL */
1750 /** Do any transport work in the audio thread that needs to be done after the
1751 * transport thread is finished. Audio thread, realtime safe.
1754 Session::post_transport ()
1756 PostTransportWork ptw = post_transport_work ();
1758 if (ptw & PostTransportAudition) {
1759 if (auditioner && auditioner->auditioning()) {
1760 process_function = &Session::process_audition;
1762 process_function = &Session::process_with_events;
1766 if (ptw & PostTransportStop) {
1768 transport_sub_state = 0;
1771 if (ptw & PostTransportLocate) {
1773 if (((!config.get_external_sync() && (auto_play_legal && config.get_auto_play())) && !_exporting) || (ptw & PostTransportRoll)) {
1774 _count_in_once = false;
1777 transport_sub_state = 0;
1782 /* XXX is this really safe? shouldn't we just be unsetting the bits that we actually
1785 set_post_transport_work (PostTransportWork (0));
1789 Session::reset_rf_scale (framecnt_t motion)
1791 cumulative_rf_motion += motion;
1793 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1795 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1797 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1809 Session::mtc_status_changed (bool yn)
1811 g_atomic_int_set (&_mtc_active, yn);
1812 MTCSyncStateChanged( yn );
1816 Session::ltc_status_changed (bool yn)
1818 g_atomic_int_set (&_ltc_active, yn);
1819 LTCSyncStateChanged( yn );
1823 Session::use_sync_source (Slave* new_slave)
1825 /* Runs in process() context */
1827 bool non_rt_required = false;
1829 /* XXX this deletion is problematic because we're in RT context */
1834 MTC_Slave* mtc_slave = dynamic_cast<MTC_Slave*>(_slave);
1836 mtc_slave->ActiveChanged.connect_same_thread (mtc_status_connection, boost::bind (&Session::mtc_status_changed, this, _1));
1837 MTCSyncStateChanged(mtc_slave->locked() );
1839 if (g_atomic_int_get (&_mtc_active) ){
1840 g_atomic_int_set (&_mtc_active, 0);
1841 MTCSyncStateChanged( false );
1843 mtc_status_connection.disconnect ();
1846 LTC_Slave* ltc_slave = dynamic_cast<LTC_Slave*> (_slave);
1848 ltc_slave->ActiveChanged.connect_same_thread (ltc_status_connection, boost::bind (&Session::ltc_status_changed, this, _1));
1849 LTCSyncStateChanged (ltc_slave->locked() );
1851 if (g_atomic_int_get (&_ltc_active) ){
1852 g_atomic_int_set (&_ltc_active, 0);
1853 LTCSyncStateChanged( false );
1855 ltc_status_connection.disconnect ();
1858 DEBUG_TRACE (DEBUG::Slave, string_compose ("set new slave to %1\n", _slave));
1860 // need to queue this for next process() cycle
1861 _send_timecode_update = true;
1863 boost::shared_ptr<RouteList> rl = routes.reader();
1864 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1865 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1866 if (tr && !tr->is_private_route()) {
1867 if (tr->realtime_speed_change()) {
1868 non_rt_required = true;
1870 tr->set_slaved (_slave != 0);
1874 if (non_rt_required) {
1875 add_post_transport_work (PostTransportSpeed);
1876 _butler->schedule_transport_work ();
1883 Session::drop_sync_source ()
1885 request_sync_source (0);
1889 Session::switch_to_sync_source (SyncSource src)
1893 DEBUG_TRACE (DEBUG::Slave, string_compose ("Setting up sync source %1\n", enum_2_string (src)));
1897 if (_slave && dynamic_cast<MTC_Slave*>(_slave)) {
1902 new_slave = new MTC_Slave (*this, *_midi_ports->mtc_input_port());
1905 catch (failed_constructor& err) {
1911 if (_slave && dynamic_cast<LTC_Slave*>(_slave)) {
1916 new_slave = new LTC_Slave (*this);
1919 catch (failed_constructor& err) {
1926 if (_slave && dynamic_cast<MIDIClock_Slave*>(_slave)) {
1931 new_slave = new MIDIClock_Slave (*this, *_midi_ports->midi_clock_input_port(), 24);
1934 catch (failed_constructor& err) {
1940 if (_slave && dynamic_cast<Engine_Slave*>(_slave)) {
1944 if (config.get_video_pullup() != 0.0f) {
1948 new_slave = new Engine_Slave (*AudioEngine::instance());
1956 request_sync_source (new_slave);
1960 Session::unset_play_range ()
1962 _play_range = false;
1963 _clear_event_type (SessionEvent::RangeStop);
1964 _clear_event_type (SessionEvent::RangeLocate);
1968 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1972 /* Called from event-processing context */
1974 unset_play_range ();
1976 if (range.empty()) {
1977 /* _play_range set to false in unset_play_range()
1979 if (!leave_rolling) {
1980 /* stop transport */
1981 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false);
1989 /* cancel loop play */
1992 list<AudioRange>::size_type sz = range.size();
1996 list<AudioRange>::iterator i = range.begin();
1997 list<AudioRange>::iterator next;
1999 while (i != range.end()) {
2004 /* locating/stopping is subject to delays for declicking.
2007 framepos_t requested_frame = i->end;
2009 if (requested_frame > current_block_size) {
2010 requested_frame -= current_block_size;
2012 requested_frame = 0;
2015 if (next == range.end()) {
2016 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_frame, 0, 0.0f);
2018 ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_frame, (*next).start, 0.0f);
2026 } else if (sz == 1) {
2028 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
2033 /* save range so we can do auto-return etc. */
2035 current_audio_range = range;
2037 /* now start rolling at the right place */
2039 ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
2042 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC5 with speed = %1\n", _transport_speed));
2043 TransportStateChange ();
2047 Session::request_bounded_roll (framepos_t start, framepos_t end)
2049 AudioRange ar (start, end, 0);
2050 list<AudioRange> lar;
2053 request_play_range (&lar, true);
2057 Session::set_requested_return_frame (framepos_t return_to)
2059 _requested_return_frame = return_to;
2063 Session::request_roll_at_and_return (framepos_t start, framepos_t return_to)
2065 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
2066 ev->target2_frame = start;
2071 Session::engine_halted ()
2075 /* there will be no more calls to process(), so
2076 we'd better clean up for ourselves, right now.
2078 but first, make sure the butler is out of
2086 realtime_stop (false, true);
2087 non_realtime_stop (false, 0, ignored);
2088 transport_sub_state = 0;
2090 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC6 with speed = %1\n", _transport_speed));
2091 TransportStateChange (); /* EMIT SIGNAL */
2096 Session::xrun_recovery ()
2100 Xrun (_transport_frame); /* EMIT SIGNAL */
2102 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
2104 /* it didn't actually halt, but we need
2105 to handle things in the same way.
2113 Session::route_processors_changed (RouteProcessorChange c)
2115 if (g_atomic_int_get (&_ignore_route_processor_changes) > 0) {
2119 if (c.type == RouteProcessorChange::MeterPointChange) {
2124 if (c.type == RouteProcessorChange::RealTimeChange) {
2129 update_latency_compensation ();
2136 Session::allow_auto_play (bool yn)
2138 auto_play_legal = yn;
2142 Session::maybe_stop (framepos_t limit)
2144 if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
2145 if (synced_to_engine () && config.get_jack_time_master ()) {
2146 _engine.transport_stop ();
2147 } else if (!synced_to_engine ()) {
2156 Session::send_mmc_locate (framepos_t t)
2162 if (!_engine.freewheeling()) {
2163 Timecode::Time time;
2164 timecode_time_subframes (t, time);
2165 send_immediate_mmc (MIDI::MachineControlCommand (time));
2169 /** Ask the transport to not send timecode until further notice. The suspension
2170 * will come into effect some finite time after this call, and timecode_transmission_suspended()
2171 * should be checked by the caller to find out when.
2174 Session::request_suspend_timecode_transmission ()
2176 SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, false);
2181 Session::request_resume_timecode_transmission ()
2183 SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, true);
2188 Session::timecode_transmission_suspended () const
2190 return g_atomic_int_get (&_suspend_timecode_transmission) == 1;