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/disk_reader.h"
45 #include "ardour/location.h"
46 #include "ardour/profile.h"
47 #include "ardour/scene_changer.h"
48 #include "ardour/session.h"
49 #include "ardour/slave.h"
50 #include "ardour/tempo.h"
51 #include "ardour/operations.h"
52 #include "ardour/vca.h"
53 #include "ardour/vca_manager.h"
58 using namespace ARDOUR;
62 Session::add_post_transport_work (PostTransportWork ptw)
64 PostTransportWork oldval;
65 PostTransportWork newval;
69 oldval = (PostTransportWork) g_atomic_int_get (&_post_transport_work);
70 newval = PostTransportWork (oldval | ptw);
71 if (g_atomic_int_compare_and_exchange (&_post_transport_work, oldval, newval)) {
77 error << "Could not set post transport work! Crazy thread madness, call the programmers" << endmsg;
81 Session::request_sync_source (Slave* new_slave)
83 SessionEvent* ev = new SessionEvent (SessionEvent::SetSyncSource, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
86 seamless = Config->get_seamless_loop ();
88 if (dynamic_cast<Engine_Slave*>(new_slave)) {
89 /* JACK cannot support seamless looping at present */
90 Config->set_seamless_loop (false);
92 /* reset to whatever the value was before we last switched slaves */
93 Config->set_seamless_loop (_was_seamless);
96 /* save value of seamless from before the switch */
97 _was_seamless = seamless;
99 ev->slave = new_slave;
100 DEBUG_TRACE (DEBUG::Slave, "sent request for new slave\n");
105 Session::request_transport_speed (double speed, bool as_default)
107 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
108 ev->third_yes_or_no = as_default; // as_default
109 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport speed = %1 as default = %2\n", speed, as_default));
113 /** Request a new transport speed, but if the speed parameter is exactly zero then use
114 * a very small +ve value to prevent the transport actually stopping. This method should
115 * be used by callers who are varying transport speed but don't ever want to stop it.
118 Session::request_transport_speed_nonzero (double speed, bool as_default)
124 request_transport_speed (speed, as_default);
128 Session::request_stop (bool abort, bool clear_state)
130 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, audible_sample(), 0.0, abort, clear_state);
131 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport stop, audible %3 transport %4 abort = %1, clear state = %2\n", abort, clear_state, audible_sample(), _transport_sample));
136 Session::request_locate (samplepos_t target_sample, bool with_roll)
138 SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_sample, 0, false);
139 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request locate to %1\n", target_sample));
144 Session::force_locate (samplepos_t target_sample, bool with_roll)
146 SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_sample, 0, true);
147 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request forced locate to %1\n", target_sample));
152 Session::unset_preroll_record_punch ()
154 if (_preroll_record_punch_pos >= 0) {
155 remove_event (_preroll_record_punch_pos, SessionEvent::RecordStart);
157 _preroll_record_punch_pos = -1;
161 Session::unset_preroll_record_trim ()
163 _preroll_record_trim_len = 0;
167 Session::request_preroll_record_punch (samplepos_t rec_in, samplecnt_t preroll)
169 if (actively_recording ()) {
172 unset_preroll_record_punch ();
173 unset_preroll_record_trim ();
174 samplepos_t start = std::max ((samplepos_t)0, rec_in - preroll);
176 _preroll_record_punch_pos = rec_in;
177 if (_preroll_record_punch_pos >= 0) {
178 replace_event (SessionEvent::RecordStart, _preroll_record_punch_pos);
179 config.set_punch_in (false);
180 config.set_punch_out (false);
182 maybe_enable_record ();
183 request_locate (start, true);
184 set_requested_return_sample (rec_in);
188 Session::request_preroll_record_trim (samplepos_t rec_in, samplecnt_t preroll)
190 if (actively_recording ()) {
193 unset_preroll_record_punch ();
194 unset_preroll_record_trim ();
196 config.set_punch_in (false);
197 config.set_punch_out (false);
199 samplepos_t pos = std::max ((samplepos_t)0, rec_in - preroll);
200 _preroll_record_trim_len = preroll;
201 maybe_enable_record ();
202 request_locate (pos, true);
203 set_requested_return_sample (rec_in);
207 Session::request_count_in_record ()
209 if (actively_recording ()) {
212 if (transport_rolling()) {
215 maybe_enable_record ();
216 _count_in_once = true;
217 request_transport_speed (1.0, true);
221 Session::request_play_loop (bool yn, bool change_transport_roll)
224 // don't attempt to loop when not using Internal Transport
225 // see also gtk2_ardour/ardour_ui_options.cc parameter_changed()
230 Location *location = _locations->auto_loop_location();
233 if (location == 0 && yn) {
234 error << _("Cannot loop - no loop range defined")
239 if (change_transport_roll) {
240 if (transport_rolling()) {
241 /* start looping at current speed */
242 target_speed = transport_speed ();
244 /* currently stopped */
246 /* start looping at normal speed */
253 /* leave the speed alone */
254 target_speed = transport_speed ();
257 ev = new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, target_speed, yn);
258 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request set loop = %1, change roll state ? %2\n", yn, change_transport_roll));
262 if (!change_transport_roll) {
263 if (!transport_rolling()) {
264 /* we're not changing transport state, but we do want
265 to set up position for the new loop. Don't
266 do this if we're rolling already.
268 request_locate (location->start(), false);
272 if (!change_transport_roll && Config->get_seamless_loop() && transport_rolling()) {
273 // request an immediate locate to refresh the tracks
274 // after disabling looping
275 request_locate (_transport_sample-1, false);
281 Session::request_play_range (list<AudioRange>* range, bool leave_rolling)
283 SessionEvent* ev = new SessionEvent (SessionEvent::SetPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0));
285 ev->audio_range = *range;
287 ev->audio_range.clear ();
289 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request play range, leave rolling ? %1\n", leave_rolling));
294 Session::request_cancel_play_range ()
296 SessionEvent* ev = new SessionEvent (SessionEvent::CancelPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, 0);
302 Session::realtime_stop (bool abort, bool clear_state)
304 DEBUG_TRACE (DEBUG::Transport, string_compose ("realtime stop @ %1\n", _transport_sample));
305 PostTransportWork todo = PostTransportWork (0);
307 /* assume that when we start, we'll be moving forwards */
309 if (_transport_speed < 0.0f) {
310 todo = (PostTransportWork (todo | PostTransportStop | PostTransportReverse));
311 _default_transport_speed = 1.0;
313 todo = PostTransportWork (todo | PostTransportStop);
318 boost::shared_ptr<RouteList> r = routes.reader ();
320 for (RouteList::iterator i = r->begin (); i != r->end(); ++i) {
321 (*i)->realtime_handle_transport_stopped ();
324 DEBUG_TRACE (DEBUG::Transport, string_compose ("stop complete, auto-return scheduled for return to %1\n", _requested_return_sample));
326 /* the duration change is not guaranteed to have happened, but is likely */
328 todo = PostTransportWork (todo | PostTransportDuration);
331 todo = PostTransportWork (todo | PostTransportAbort);
335 todo = PostTransportWork (todo | PostTransportClearSubstate);
339 add_post_transport_work (todo);
342 _clear_event_type (SessionEvent::StopOnce);
343 _clear_event_type (SessionEvent::RangeStop);
344 _clear_event_type (SessionEvent::RangeLocate);
346 /* if we're going to clear loop state, then force disabling record BUT only if we're not doing latched rec-enable */
347 disable_record (true, (!Config->get_latched_record_enable() && clear_state));
349 if (clear_state && !Config->get_loop_is_mode()) {
353 reset_slave_state ();
355 _transport_speed = 0;
356 _target_transport_speed = 0;
358 g_atomic_int_set (&_playback_load, 100);
359 g_atomic_int_set (&_capture_load, 100);
361 if (config.get_use_video_sync()) {
362 waiting_for_sync_offset = true;
365 transport_sub_state = 0;
369 Session::realtime_locate ()
371 boost::shared_ptr<RouteList> r = routes.reader ();
372 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
373 (*i)->realtime_locate ();
378 Session::butler_transport_work ()
380 /* Note: this function executes in the butler thread context */
384 PostTransportWork ptw;
385 boost::shared_ptr<RouteList> r = routes.reader ();
388 int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
390 ptw = post_transport_work();
392 DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler transport work, todo = %1 at %2\n", enum_2_string (ptw), (before = g_get_monotonic_time())));
395 if (ptw & PostTransportLocate) {
397 if (get_play_loop() && !Config->get_seamless_loop()) {
399 DEBUG_TRACE (DEBUG::Butler, "flush loop recording fragment to disk\n");
401 /* this locate might be happening while we are
404 * Non-seamless looping will require a locate (below) that
405 * will reset capture buffers and throw away data.
407 * Rather than first find all tracks and see if they
408 * have outstanding data, just do a flush anyway. It
409 * may be cheaper this way anyway, and is certainly
413 bool more_disk_io_to_do = false;
417 more_disk_io_to_do = _butler->flush_tracks_to_disk_after_locate (r, errors);
423 if (more_disk_io_to_do) {
432 if (ptw & PostTransportAdjustPlaybackBuffering) {
433 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
434 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
436 tr->adjust_playback_buffering ();
437 /* and refill those buffers ... */
439 (*i)->non_realtime_locate (_transport_sample);
441 VCAList v = _vca_manager->vcas ();
442 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
443 (*i)->non_realtime_locate (_transport_sample);
447 if (ptw & PostTransportAdjustCaptureBuffering) {
448 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
449 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
451 tr->adjust_capture_buffering ();
456 if (ptw & PostTransportCurveRealloc) {
457 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
458 (*i)->curve_reallocate();
462 if (ptw & PostTransportSpeed) {
463 non_realtime_set_speed ();
466 if (ptw & PostTransportReverse) {
469 cumulative_rf_motion = 0;
472 /* don't seek if locate will take care of that in non_realtime_stop() */
474 if (!(ptw & PostTransportLocate)) {
475 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
476 (*i)->non_realtime_locate (_transport_sample);
478 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
479 /* new request, stop seeking, and start again */
480 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
484 VCAList v = _vca_manager->vcas ();
485 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
486 (*i)->non_realtime_locate (_transport_sample);
491 if (ptw & PostTransportLocate) {
492 DEBUG_TRACE (DEBUG::Transport, "nonrealtime locate invoked from BTW\n");
493 non_realtime_locate ();
496 if (ptw & PostTransportStop) {
497 non_realtime_stop (ptw & PostTransportAbort, on_entry, finished);
499 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
504 if (ptw & PostTransportOverWrite) {
505 non_realtime_overwrite (on_entry, finished);
507 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
512 if (ptw & PostTransportAudition) {
513 non_realtime_set_audition ();
516 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
518 DEBUG_TRACE (DEBUG::Transport, string_compose (X_("Butler transport work all done after %1 usecs @ %2 trw = %3\n"), g_get_monotonic_time() - before, _transport_sample, _butler->transport_work_requested()));
522 Session::non_realtime_set_speed ()
524 boost::shared_ptr<RouteList> rl = routes.reader();
525 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
526 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
528 tr->non_realtime_speed_change ();
534 Session::non_realtime_overwrite (int on_entry, bool& finished)
536 boost::shared_ptr<RouteList> rl = routes.reader();
537 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
538 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
539 if (tr && tr->pending_overwrite ()) {
540 tr->overwrite_existing_buffers ();
542 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
551 Session::non_realtime_locate ()
553 DEBUG_TRACE (DEBUG::Transport, string_compose ("locate tracks to %1\n", _transport_sample));
555 if (Config->get_loop_is_mode() && get_play_loop()) {
557 Location *loc = _locations->auto_loop_location();
559 if (!loc || (_transport_sample < loc->start() || _transport_sample >= loc->end())) {
560 /* jumped out of loop range: stop tracks from looping,
561 but leave loop (mode) enabled.
563 set_track_loop (false);
565 } else if (loc && Config->get_seamless_loop() &&
566 ((loc->start() <= _transport_sample) ||
567 (loc->end() > _transport_sample) ) ) {
569 /* jumping to start of loop. This might have been done before but it is
570 * idempotent and cheap. Doing it here ensures that when we start playback
571 * outside the loop we still flip tracks into the magic seamless mode
574 set_track_loop (true);
577 set_track_loop (false);
582 /* no more looping .. should have been noticed elsewhere */
589 boost::shared_ptr<RouteList> rl = routes.reader();
592 gint sc = g_atomic_int_get (&_seek_counter);
593 tf = _transport_sample;
595 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
596 (*i)->non_realtime_locate (tf);
597 if (sc != g_atomic_int_get (&_seek_counter)) {
604 /* VCAs are quick to locate because they have no data (except
605 automation) associated with them. Don't bother with a
606 restart mechanism here, but do use the same transport sample
607 that the Routes used.
609 VCAList v = _vca_manager->vcas ();
610 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
611 (*i)->non_realtime_locate (tf);
615 _scene_changer->locate (_transport_sample);
617 /* XXX: it would be nice to generate the new clicks here (in the non-RT thread)
618 rather than clearing them so that the RT thread has to spend time constructing
619 them (in Session::click).
624 #ifdef USE_TRACKS_CODE_FEATURES
626 Session::select_playhead_priority_target (samplepos_t& jump_to)
630 AutoReturnTarget autoreturn = Config->get_auto_return_target_list ();
636 if (Profile->get_trx() && transport_rolling() ) {
637 // We're playing, so do nothing.
638 // Next stop will put us where we need to be.
642 /* Note that the order of checking each AutoReturnTarget flag defines
643 the priority each flag.
645 Ardour/Mixbus: Last Locate
650 Tracks: Range Selection
656 if (autoreturn & RangeSelectionStart) {
657 if (!_range_selection.empty()) {
658 jump_to = _range_selection.from;
660 if (transport_rolling ()) {
661 /* Range selection no longer exists, but we're playing,
662 so do nothing. Next stop will put us where
670 if (jump_to < 0 && (autoreturn & Loop) && get_play_loop()) {
671 /* don't try to handle loop play when synced to JACK */
673 if (!synced_to_engine()) {
674 Location *location = _locations->auto_loop_location();
677 jump_to = location->start();
679 if (Config->get_seamless_loop()) {
680 /* need to get track buffers reloaded */
681 set_track_loop (true);
687 if (jump_to < 0 && (autoreturn & RegionSelectionStart)) {
688 if (!_object_selection.empty()) {
689 jump_to = _object_selection.from;
693 if (jump_to < 0 && (autoreturn & LastLocate)) {
694 jump_to = _last_roll_location;
702 Session::select_playhead_priority_target (samplepos_t& jump_to)
704 if (config.get_external_sync() || !config.get_auto_return()) {
708 jump_to = _last_roll_location;
715 Session::follow_playhead_priority ()
719 if (select_playhead_priority_target (target)) {
720 request_locate (target);
725 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
731 PostTransportWork ptw = post_transport_work();
736 boost::shared_ptr<RouteList> rl = routes.reader();
737 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
738 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
739 if (tr && tr->get_captured_samples () != 0) {
745 /* stop and locate are merged here because they share a lot of common stuff */
748 now = localtime (&xnow);
751 auditioner->cancel_audition ();
754 cumulative_rf_motion = 0;
758 begin_reversible_command (Operations::capture);
759 _have_captured = true;
762 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: DS stop\n"));
764 if (abort && did_record) {
765 /* no reason to save the session file when we remove sources
767 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
770 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
771 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
773 tr->transport_stopped_wallclock (*now, xnow, abort);
777 if (abort && did_record) {
778 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
781 boost::shared_ptr<RouteList> r = routes.reader ();
783 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
784 if (!(*i)->is_auditioner()) {
785 (*i)->set_pending_declick (0);
790 commit_reversible_command ();
791 /* increase take name */
792 if (config.get_track_name_take () && !config.get_take_name ().empty()) {
793 string newname = config.get_take_name();
794 config.set_take_name(bump_name_number (newname));
798 if (_engine.running()) {
799 PostTransportWork ptw = post_transport_work ();
801 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
802 (*i)->non_realtime_transport_stop (_transport_sample, !(ptw & PostTransportLocate) || pending_locate_flush);
804 VCAList v = _vca_manager->vcas ();
805 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
806 (*i)->non_realtime_transport_stop (_transport_sample, !(ptw & PostTransportLocate) || pending_locate_flush);
809 update_latency_compensation ();
812 bool const auto_return_enabled = (!config.get_external_sync() && (Config->get_auto_return_target_list() || abort));
814 if (auto_return_enabled ||
815 (ptw & PostTransportLocate) ||
816 (_requested_return_sample >= 0) ||
817 synced_to_engine()) {
819 if (pending_locate_flush) {
820 flush_all_inserts ();
823 // rg: what is the logic behind this case?
824 // _requested_return_sample should be ignored when synced_to_engine/slaved.
825 // currently worked around in MTC_Slave by forcing _requested_return_sample to -1
827 if ((auto_return_enabled || synced_to_engine() || _requested_return_sample >= 0) &&
828 !(ptw & PostTransportLocate)) {
830 /* no explicit locate queued */
832 bool do_locate = false;
834 if (_requested_return_sample >= 0) {
836 /* explicit return request pre-queued in event list. overrides everything else */
838 _transport_sample = _requested_return_sample;
844 if (select_playhead_priority_target (jump_to)) {
846 _transport_sample = jump_to;
851 _transport_sample = _last_roll_location;
856 _requested_return_sample = -1;
859 _engine.transport_locate (_transport_sample);
866 unset_preroll_record_trim ();
868 /* do this before seeking, because otherwise the tracks will do the wrong thing in seamless loop mode.
871 if (ptw & PostTransportClearSubstate) {
873 if (!Config->get_loop_is_mode()) {
878 /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
881 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: locate\n"));
882 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
883 DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler PTW: locate on %1\n", (*i)->name()));
884 (*i)->non_realtime_locate (_transport_sample);
886 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
888 /* we will be back */
895 VCAList v = _vca_manager->vcas ();
896 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
897 (*i)->non_realtime_locate (_transport_sample);
903 /* don't bother with this stuff if we're disconnected from the engine,
904 because there will be no process callbacks to deliver stuff from
907 if (_engine.connected() && !_engine.freewheeling()) {
908 // need to queue this in the next RT cycle
909 _send_timecode_update = true;
911 if (!dynamic_cast<MTC_Slave*>(_slave)) {
912 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
914 /* This (::non_realtime_stop()) gets called by main
915 process thread, which will lead to confusion
916 when calling AsyncMIDIPort::write().
918 Something must be done. XXX
920 send_mmc_locate (_transport_sample);
924 if ((ptw & PostTransportLocate) && get_record_enabled()) {
925 /* This is scheduled by realtime_stop(), which is also done
926 * when a slave requests /locate/ for an initial sync.
927 * We can't hold up the slave for long with a save() here,
928 * without breaking its initial sync cycle.
930 * save state only if there's no slave or if it's not yet locked.
932 if (!_slave || !_slave->locked()) {
933 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: requests save\n"));
934 SaveSessionRequested (_current_snapshot_name);
939 /* always try to get rid of this */
941 remove_pending_capture_state ();
943 /* save the current state of things if appropriate */
945 if (did_record && !saved) {
946 SaveSessionRequested (_current_snapshot_name);
949 if (ptw & PostTransportStop) {
951 if (!Config->get_loop_is_mode()) {
956 PositionChanged (_transport_sample); /* EMIT SIGNAL */
957 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC with speed = %1\n", _transport_speed));
958 TransportStateChange (); /* EMIT SIGNAL */
959 AutomationWatch::instance().transport_stop_automation_watches (_transport_sample);
961 /* and start it up again if relevant */
963 if ((ptw & PostTransportLocate) && !config.get_external_sync() && pending_locate_roll) {
964 request_transport_speed (1.0);
967 /* Even if we didn't do a pending locate roll this time, we don't want it hanging
968 around for next time.
970 pending_locate_roll = false;
974 Session::check_declick_out ()
976 bool locate_required = transport_sub_state & PendingLocate;
978 /* this is called after a process() iteration. if PendingDeclickOut was set,
979 it means that we were waiting to declick the output (which has just been
980 done) before maybe doing something else. this is where we do that "something else".
982 note: called from the audio thread.
985 if (transport_sub_state & PendingDeclickOut) {
987 if (locate_required) {
988 start_locate (pending_locate_sample, pending_locate_roll, pending_locate_flush);
989 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
991 if (!(transport_sub_state & StopPendingCapture)) {
992 stop_transport (pending_abort);
993 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
997 } else if (transport_sub_state & PendingLoopDeclickOut) {
998 /* Nothing else to do here; we've declicked, and the loop event will be along shortly */
999 transport_sub_state &= ~PendingLoopDeclickOut;
1004 Session::unset_play_loop ()
1008 clear_events (SessionEvent::AutoLoop);
1009 clear_events (SessionEvent::AutoLoopDeclick);
1010 set_track_loop (false);
1013 if (Config->get_seamless_loop()) {
1014 /* likely need to flush track buffers: this will locate us to wherever we are */
1015 add_post_transport_work (PostTransportLocate);
1016 _butler->schedule_transport_work ();
1022 Session::set_track_loop (bool yn)
1024 Location* loc = _locations->auto_loop_location ();
1030 boost::shared_ptr<RouteList> rl = routes.reader ();
1032 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1033 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1034 if (tr && !tr->is_private_route()) {
1035 tr->set_loop (yn ? loc : 0);
1041 Session::set_play_loop (bool yn, double speed)
1043 /* Called from event-handling context */
1047 if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) {
1048 /* nothing to do, or can't change loop status while recording */
1052 if (yn && Config->get_seamless_loop() && synced_to_engine()) {
1053 warning << string_compose (
1054 _("Seamless looping cannot be supported while %1 is using JACK transport.\n"
1055 "Recommend changing the configured options"), PROGRAM_NAME)
1063 have_looped = false;
1067 unset_play_range ();
1069 if (Config->get_seamless_loop()) {
1070 if (!Config->get_loop_is_mode()) {
1071 /* set all tracks to use internal looping */
1072 set_track_loop (true);
1074 /* we will do this in the locate to the start OR when we hit the end
1075 * of the loop for the first time
1079 /* set all tracks to NOT use internal looping */
1080 set_track_loop (false);
1083 /* Put the delick and loop events in into the event list. The declick event will
1084 cause a de-clicking fade-out just before the end of the loop, and it will also result
1085 in a fade-in when the loop restarts. The AutoLoop event will peform the actual loop.
1090 auto_loop_declick_range (loc, dcp, dcl);
1091 merge_event (new SessionEvent (SessionEvent::AutoLoopDeclick, SessionEvent::Replace, dcp, dcl, 0.0f));
1092 merge_event (new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f));
1094 /* if requested to roll, locate to start of loop and
1095 * roll but ONLY if we're not already rolling.
1097 args: positition, roll=true, flush=true, with_loop=false, force buffer refill if seamless looping
1100 if (Config->get_loop_is_mode()) {
1101 /* loop IS a transport mode: if already
1102 rolling, do not locate to loop start.
1104 if (!transport_rolling() && (speed != 0.0)) {
1105 start_locate (loc->start(), true, true, false, true);
1109 start_locate (loc->start(), true, true, false, true);
1119 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC2 with speed = %1\n", _transport_speed));
1120 TransportStateChange ();
1123 Session::flush_all_inserts ()
1125 boost::shared_ptr<RouteList> r = routes.reader ();
1127 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1128 (*i)->flush_processors ();
1133 Session::start_locate (samplepos_t target_sample, bool with_roll, bool with_flush, bool for_loop_enabled, bool force)
1135 if (target_sample < 0) {
1136 error << _("Locate called for negative sample position - ignored") << endmsg;
1140 if (synced_to_engine()) {
1145 _slave->speed_and_position (sp, pos);
1147 if (target_sample != pos) {
1149 if (config.get_jack_time_master()) {
1150 /* actually locate now, since otherwise jack_timebase_callback
1151 will use the incorrect _transport_sample and report an old
1152 and incorrect time to Jack transport
1154 locate (target_sample, with_roll, with_flush, for_loop_enabled, force);
1157 /* tell JACK to change transport position, and we will
1158 follow along later in ::follow_slave()
1161 _engine.transport_locate (target_sample);
1163 if (sp != 1.0f && with_roll) {
1164 _engine.transport_start ();
1170 locate (target_sample, with_roll, with_flush, for_loop_enabled, force);
1175 Session::worst_latency_preroll () const
1177 return _worst_output_latency + _worst_input_latency;
1181 Session::micro_locate (samplecnt_t distance)
1183 boost::shared_ptr<RouteList> rl = routes.reader();
1184 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1185 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1186 if (tr && !tr->can_internal_playback_seek (distance)) {
1191 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1192 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1194 tr->internal_playback_seek (distance);
1198 _transport_sample += distance;
1202 /** @param with_mmc true to send a MMC locate command when the locate is done */
1204 Session::locate (samplepos_t target_sample, bool with_roll, bool with_flush, bool for_loop_enabled, bool force, bool with_mmc)
1206 bool need_butler = false;
1208 /* Locates for seamless looping are fairly different from other
1209 * locates. They assume that the diskstream buffers for each track
1210 * already have the correct data in them, and thus there is no need to
1211 * actually tell the tracks to locate. What does need to be done,
1212 * though, is all the housekeeping that is associated with non-linear
1213 * changes in the value of _transport_sample.
1216 DEBUG_TRACE (DEBUG::Transport, string_compose ("rt-locate to %1, roll %2 flush %3 loop-enabled %4 force %5 mmc %6\n",
1217 target_sample, with_roll, with_flush, for_loop_enabled, force, with_mmc));
1219 if (!force && _transport_sample == target_sample && !loop_changing && !for_loop_enabled) {
1221 /* already at the desired position. Not forced to locate,
1222 the loop isn't changing, so unless we're told to
1223 start rolling also, there's nothing to do but
1224 tell the world where we are (again).
1228 set_transport_speed (1.0, 0, false);
1230 loop_changing = false;
1231 Located (); /* EMIT SIGNAL */
1235 if (_transport_speed && !(for_loop_enabled && Config->get_seamless_loop())) {
1236 /* Schedule a declick. We'll be called again when its done.
1237 We only do it this way for ordinary locates, not those
1238 due to **seamless** loops.
1241 if (!(transport_sub_state & PendingDeclickOut)) {
1242 transport_sub_state |= (PendingDeclickOut|PendingLocate);
1243 pending_locate_sample = target_sample;
1244 pending_locate_roll = with_roll;
1245 pending_locate_flush = with_flush;
1246 cerr << "Declick scheduled ... back soon\n";
1251 cerr << "... now doing the actual locate\n";
1253 // Update Timecode time
1254 _transport_sample = target_sample;
1255 // Bump seek counter so that any in-process locate in the butler
1256 // thread(s?) can restart.
1257 g_atomic_int_inc (&_seek_counter);
1258 _last_roll_or_reversal_location = target_sample;
1259 _remaining_latency_preroll = worst_latency_preroll ();
1260 timecode_time(_transport_sample, transmitting_timecode_time); // XXX here?
1262 /* do "stopped" stuff if:
1264 * we are rolling AND
1265 * no autoplay in effect AND
1266 * we're not going to keep rolling after the locate AND
1267 * !(playing a loop with JACK sync)
1271 bool transport_was_stopped = !transport_rolling();
1273 if (!transport_was_stopped && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_engine() && play_loop) &&
1274 (!Profile->get_trx() || !(config.get_external_sync() && !synced_to_engine()))) {
1275 realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
1276 transport_was_stopped = true;
1278 /* otherwise tell the world that we located */
1282 if (force || !for_loop_enabled || loop_changing) {
1284 PostTransportWork todo = PostTransportLocate;
1286 if (with_roll && transport_was_stopped) {
1287 todo = PostTransportWork (todo | PostTransportRoll);
1290 add_post_transport_work (todo);
1295 /* this is functionally what clear_clicks() does but with a tentative lock */
1297 Glib::Threads::RWLock::WriterLock clickm (click_lock, Glib::Threads::TRY_LOCK);
1299 if (clickm.locked()) {
1301 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
1310 /* switch from input if we're going to roll */
1311 if (Config->get_monitoring_model() == HardwareMonitoring) {
1312 set_track_monitor_input_status (!config.get_auto_input());
1315 /* otherwise we're going to stop, so do the opposite */
1316 if (Config->get_monitoring_model() == HardwareMonitoring) {
1317 set_track_monitor_input_status (true);
1321 /* cancel looped playback if transport pos outside of loop range */
1324 Location* al = _locations->auto_loop_location();
1327 if (_transport_sample < al->start() || _transport_sample >= al->end()) {
1329 // located outside the loop: cancel looping directly, this is called from event handling context
1331 have_looped = false;
1333 if (!Config->get_loop_is_mode()) {
1334 set_play_loop (false, _transport_speed);
1336 if (Config->get_seamless_loop()) {
1337 /* this will make the non_realtime_locate() in the butler
1338 which then causes seek() in tracks actually do the right
1341 set_track_loop (false);
1345 } else if (_transport_sample == al->start()) {
1347 // located to start of loop - this is looping, basically
1351 if (_last_roll_location != al->start()) {
1352 /* didn't start at loop start - playback must have
1353 * started before loop since we've now hit the loop
1356 add_post_transport_work (PostTransportLocate);
1362 boost::shared_ptr<RouteList> rl = routes.reader();
1364 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1365 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1367 if (tr && tr->rec_enable_control()->get_value()) {
1368 // tell it we've looped, so it can deal with the record state
1369 tr->transport_looped (_transport_sample);
1374 TransportLooped(); // EMIT SIGNAL
1380 _butler->schedule_transport_work ();
1383 loop_changing = false;
1385 _send_timecode_update = true;
1388 send_mmc_locate (_transport_sample);
1391 _last_roll_location = _last_roll_or_reversal_location = _transport_sample;
1392 if (!synced_to_engine () || _transport_sample == _engine.transport_sample ()) {
1393 Located (); /* EMIT SIGNAL */
1397 /** Set the transport speed.
1398 * Called from the process thread.
1399 * @param speed New speed
1402 Session::set_transport_speed (double speed, samplepos_t destination_sample, bool abort, bool clear_state, bool as_default)
1404 DEBUG_TRACE (DEBUG::Transport, string_compose ("@ %5 Set transport speed to %1, abort = %2 clear_state = %3, current = %4 as_default %6\n",
1405 speed, abort, clear_state, _transport_speed, _transport_sample, as_default));
1407 if (_transport_speed == speed) {
1408 if (as_default && speed == 0.0) { // => reset default transport speed. hacky or what?
1409 _default_transport_speed = 1.0;
1414 if (actively_recording() && speed != 1.0 && speed != 0.0) {
1415 /* no varispeed during recording */
1416 DEBUG_TRACE (DEBUG::Transport, string_compose ("No varispeed during recording cur_speed %1, sample %2\n",
1417 _transport_speed, _transport_sample));
1421 _target_transport_speed = fabs(speed);
1423 /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
1424 and user needs. We really need CD-style "skip" playback for ffwd and rewind.
1428 speed = min (8.0, speed);
1429 } else if (speed < 0) {
1430 speed = max (-8.0, speed);
1433 if (transport_rolling() && speed == 0.0) {
1435 /* we are rolling and we want to stop */
1437 if (Config->get_monitoring_model() == HardwareMonitoring) {
1438 set_track_monitor_input_status (true);
1441 if (synced_to_engine ()) {
1443 /* do this here because our response to the slave won't
1446 _play_range = false;
1447 _count_in_once = false;
1450 _engine.transport_stop ();
1452 bool const auto_return_enabled = (!config.get_external_sync() && (Config->get_auto_return_target_list() || abort));
1454 if (!auto_return_enabled) {
1455 _requested_return_sample = destination_sample;
1458 stop_transport (abort);
1461 } else if (transport_stopped() && speed == 1.0) {
1463 _default_transport_speed = speed;
1465 /* we are stopped and we want to start rolling at speed 1 */
1467 if (Config->get_loop_is_mode() && play_loop) {
1469 Location *location = _locations->auto_loop_location();
1471 if (location != 0) {
1472 if (_transport_sample != location->start()) {
1474 if (Config->get_seamless_loop()) {
1475 /* force tracks to do their thing */
1476 set_track_loop (true);
1479 /* jump to start and then roll from there */
1481 request_locate (location->start(), true);
1487 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1488 set_track_monitor_input_status (false);
1491 if (synced_to_engine()) {
1492 _engine.transport_start ();
1493 _count_in_once = false;
1500 /* not zero, not 1.0 ... varispeed */
1502 // TODO handled transport start.. _remaining_latency_preroll
1503 // and reversal of playback direction.
1505 if ((synced_to_engine()) && speed != 0.0 && speed != 1.0) {
1506 warning << string_compose (
1507 _("Global varispeed cannot be supported while %1 is connected to JACK transport control"),
1513 if (actively_recording()) {
1517 if (speed > 0.0 && _transport_sample == current_end_sample()) {
1521 if (speed < 0.0 && _transport_sample == 0) {
1527 /* if we are reversing relative to the current speed, or relative to the speed
1528 before the last stop, then we have to do extra work.
1531 PostTransportWork todo = PostTransportWork (0);
1533 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0 && speed < 0.0)) {
1534 todo = PostTransportWork (todo | PostTransportReverse);
1535 _last_roll_or_reversal_location = _transport_sample;
1538 _last_transport_speed = _transport_speed;
1539 _transport_speed = speed;
1542 _default_transport_speed = speed;
1545 boost::shared_ptr<RouteList> rl = routes.reader();
1546 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1547 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1548 if (tr && tr->realtime_speed_change()) {
1549 todo = PostTransportWork (todo | PostTransportSpeed);
1554 add_post_transport_work (todo);
1555 _butler->schedule_transport_work ();
1558 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC3 with speed = %1\n", _transport_speed));
1560 /* throttle signal emissions.
1561 * when slaved [_last]_transport_speed
1562 * usually changes every cycle (tiny amounts due to DLL).
1563 * Emitting a signal every cycle is overkill and unwarranted.
1565 * Using _last_transport_speed is not acceptable,
1566 * since it allows for large changes over a long period
1567 * of time. Hence we introduce a dedicated variable to keep track
1569 * The 0.2% dead-zone is somewhat arbitrary. Main use-case
1570 * for TransportStateChange() here is the ShuttleControl display.
1572 if (fabs (_signalled_varispeed - speed) > .002
1573 // still, signal hard changes to 1.0 and 0.0:
1574 || ( speed == 1.0 && _signalled_varispeed != 1.0)
1575 || ( speed == 0.0 && _signalled_varispeed != 0.0)
1578 TransportStateChange (); /* EMIT SIGNAL */
1579 _signalled_varispeed = speed;
1585 /** Stop the transport. */
1587 Session::stop_transport (bool abort, bool clear_state)
1589 _count_in_once = false;
1590 if (_transport_speed == 0.0f) {
1594 DEBUG_TRACE (DEBUG::Transport, string_compose ("stop_transport, declick required? %1\n", get_transport_declick_required()));
1596 if (!get_transport_declick_required()) {
1598 /* stop has not yet been scheduled */
1600 boost::shared_ptr<RouteList> rl = routes.reader();
1601 samplepos_t stop_target = audible_sample();
1605 if (actively_recording() && /* we are recording */
1606 worst_input_latency() > current_block_size) { /* input latency exceeds block size, so simple 1 cycle delay before stop is not enough */
1608 /* we need to capture the audio that is still somewhere in the pipeline between
1609 wherever it was generated and the process callback. This means that even though
1610 the user (or something else) has asked us to stop, we have to roll
1611 past this point and then reset the playhead/transport location to
1612 the position at which the stop was requested.
1614 we still need playback to "stop" now, however, which is why we schedule
1618 DEBUG_TRACE (DEBUG::Transport, string_compose ("stop transport requested @ %1, scheduled for + %2 = %3, abort = %4\n",
1619 _transport_sample, _worst_input_latency,
1620 _transport_sample + _worst_input_latency,
1623 SessionEvent *ev = new SessionEvent (SessionEvent::StopOnce, SessionEvent::Replace,
1624 _transport_sample + _worst_input_latency,
1629 /* request a declick at the start of the next process cycle() so that playback ceases.
1630 It will remain silent until we actually stop (at the StopOnce event somewhere in
1631 the future). The extra flag (StopPendingCapture) is set to ensure that check_declick_out()
1632 does not stop the transport too early.
1634 new_bits = SubState (PendingDeclickOut|StopPendingCapture);
1638 /* Not recording, schedule a declick in the next process() cycle and then stop at its end */
1640 new_bits = PendingDeclickOut;
1641 DEBUG_TRACE (DEBUG::Transport, string_compose ("stop scheduled for next process cycle @ %1\n", _transport_sample));
1644 /* we'll be called again after the declick */
1645 transport_sub_state = SubState (transport_sub_state|new_bits);
1646 pending_abort = abort;
1652 DEBUG_TRACE (DEBUG::Transport, "time to actually stop\n");
1654 /* declick was scheduled, but we've been called again, which means it is really time to stop
1656 XXX: we should probably split this off into its own method and call it explicitly.
1659 realtime_stop (abort, clear_state);
1660 _butler->schedule_transport_work ();
1664 /** Called from the process thread */
1666 Session::start_transport ()
1668 DEBUG_TRACE (DEBUG::Transport, "start_transport\n");
1670 _last_roll_location = _transport_sample;
1671 _last_roll_or_reversal_location = _transport_sample;
1672 _remaining_latency_preroll = worst_latency_preroll ();
1674 have_looped = false;
1676 /* if record status is Enabled, move it to Recording. if its
1677 already Recording, move it to Disabled.
1680 switch (record_status()) {
1682 if (!config.get_punch_in() && !preroll_record_punch_enabled()) {
1689 disable_record (false);
1697 transport_sub_state |= PendingDeclickIn;
1699 _transport_speed = _default_transport_speed;
1700 _target_transport_speed = _transport_speed;
1702 boost::shared_ptr<RouteList> rl = routes.reader();
1703 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1704 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1706 tr->realtime_speed_change ();
1710 if (!_engine.freewheeling()) {
1711 Timecode::Time time;
1712 timecode_time_subframes (_transport_sample, time);
1713 if (!dynamic_cast<MTC_Slave*>(_slave)) {
1714 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
1717 if (actively_recording() && click_data && (config.get_count_in () || _count_in_once)) {
1718 _count_in_once = false;
1719 /* calculate count-in duration (in audio samples)
1720 * - use [fixed] tempo/meter at _transport_sample
1721 * - calc duration of 1 bar + time-to-beat before or at transport_sample
1723 const Tempo& tempo = _tempo_map->tempo_at_sample (_transport_sample);
1724 const Meter& meter = _tempo_map->meter_at_sample (_transport_sample);
1726 const double num = meter.divisions_per_bar ();
1727 const double den = meter.note_divisor ();
1728 const double barbeat = _tempo_map->exact_qn_at_sample (_transport_sample, 0) * den / (4. * num);
1729 const double bar_fract = fmod (barbeat, 1.0); // fraction of bar elapsed.
1731 _count_in_samples = meter.samples_per_bar (tempo, _current_sample_rate);
1733 double dt = _count_in_samples / num;
1734 if (bar_fract == 0) {
1735 /* at bar boundary, count-in 2 bars before start. */
1736 _count_in_samples *= 2;
1738 /* beats left after full bar until roll position */
1739 _count_in_samples *= 1. + bar_fract;
1742 if (_count_in_samples > _remaining_latency_preroll) {
1743 _remaining_latency_preroll = _count_in_samples;
1747 samplepos_t cf = _transport_sample - _count_in_samples;
1748 samplecnt_t offset = _click_io->connected_latency (true);
1749 while (cf < _transport_sample + offset) {
1750 add_click (cf, clickbeat == 0);
1752 clickbeat = fmod (clickbeat + 1, num);
1755 if (_count_in_samples < _remaining_latency_preroll) {
1756 _count_in_samples = _remaining_latency_preroll;
1761 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC4 with speed = %1\n", _transport_speed));
1762 TransportStateChange (); /* EMIT SIGNAL */
1765 /** Do any transport work in the audio thread that needs to be done after the
1766 * transport thread is finished. Audio thread, realtime safe.
1769 Session::post_transport ()
1771 PostTransportWork ptw = post_transport_work ();
1773 if (ptw & PostTransportAudition) {
1774 if (auditioner && auditioner->auditioning()) {
1775 process_function = &Session::process_audition;
1777 process_function = &Session::process_with_events;
1781 if (ptw & PostTransportStop) {
1783 transport_sub_state = 0;
1786 if (ptw & PostTransportLocate) {
1788 if (((!config.get_external_sync() && (auto_play_legal && config.get_auto_play())) && !_exporting) || (ptw & PostTransportRoll)) {
1789 _count_in_once = false;
1792 transport_sub_state = 0;
1797 /* XXX is this really safe? shouldn't we just be unsetting the bits that we actually
1800 set_post_transport_work (PostTransportWork (0));
1804 Session::reset_rf_scale (samplecnt_t motion)
1806 cumulative_rf_motion += motion;
1808 if (cumulative_rf_motion < 4 * _current_sample_rate) {
1810 } else if (cumulative_rf_motion < 8 * _current_sample_rate) {
1812 } else if (cumulative_rf_motion < 16 * _current_sample_rate) {
1824 Session::mtc_status_changed (bool yn)
1826 g_atomic_int_set (&_mtc_active, yn);
1827 MTCSyncStateChanged( yn );
1831 Session::ltc_status_changed (bool yn)
1833 g_atomic_int_set (&_ltc_active, yn);
1834 LTCSyncStateChanged( yn );
1838 Session::use_sync_source (Slave* new_slave)
1840 /* Runs in process() context */
1842 bool non_rt_required = false;
1844 /* XXX this deletion is problematic because we're in RT context */
1850 /* slave change, reset any DiskIO block on disk output because it is no
1851 longer valid with a new slave.
1853 DiskReader::set_no_disk_output (false);
1855 MTC_Slave* mtc_slave = dynamic_cast<MTC_Slave*>(_slave);
1857 mtc_slave->ActiveChanged.connect_same_thread (mtc_status_connection, boost::bind (&Session::mtc_status_changed, this, _1));
1858 MTCSyncStateChanged(mtc_slave->locked() );
1860 if (g_atomic_int_get (&_mtc_active) ){
1861 g_atomic_int_set (&_mtc_active, 0);
1862 MTCSyncStateChanged( false );
1864 mtc_status_connection.disconnect ();
1867 LTC_Slave* ltc_slave = dynamic_cast<LTC_Slave*> (_slave);
1869 ltc_slave->ActiveChanged.connect_same_thread (ltc_status_connection, boost::bind (&Session::ltc_status_changed, this, _1));
1870 LTCSyncStateChanged (ltc_slave->locked() );
1872 if (g_atomic_int_get (&_ltc_active) ){
1873 g_atomic_int_set (&_ltc_active, 0);
1874 LTCSyncStateChanged( false );
1876 ltc_status_connection.disconnect ();
1879 DEBUG_TRACE (DEBUG::Slave, string_compose ("set new slave to %1\n", _slave));
1881 // need to queue this for next process() cycle
1882 _send_timecode_update = true;
1884 boost::shared_ptr<RouteList> rl = routes.reader();
1885 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1886 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1887 if (tr && !tr->is_private_route()) {
1888 if (tr->realtime_speed_change()) {
1889 non_rt_required = true;
1891 tr->set_slaved (_slave != 0);
1895 if (non_rt_required) {
1896 add_post_transport_work (PostTransportSpeed);
1897 _butler->schedule_transport_work ();
1904 Session::drop_sync_source ()
1906 request_sync_source (0);
1910 Session::switch_to_sync_source (SyncSource src)
1914 DEBUG_TRACE (DEBUG::Slave, string_compose ("Setting up sync source %1\n", enum_2_string (src)));
1918 if (_slave && dynamic_cast<MTC_Slave*>(_slave)) {
1923 new_slave = new MTC_Slave (*this, *_midi_ports->mtc_input_port());
1926 catch (failed_constructor& err) {
1932 if (_slave && dynamic_cast<LTC_Slave*>(_slave)) {
1937 new_slave = new LTC_Slave (*this);
1940 catch (failed_constructor& err) {
1947 if (_slave && dynamic_cast<MIDIClock_Slave*>(_slave)) {
1952 new_slave = new MIDIClock_Slave (*this, *_midi_ports->midi_clock_input_port(), 24);
1955 catch (failed_constructor& err) {
1961 if (_slave && dynamic_cast<Engine_Slave*>(_slave)) {
1965 if (config.get_video_pullup() != 0.0f) {
1969 new_slave = new Engine_Slave (*AudioEngine::instance());
1977 request_sync_source (new_slave);
1981 Session::unset_play_range ()
1983 _play_range = false;
1984 _clear_event_type (SessionEvent::RangeStop);
1985 _clear_event_type (SessionEvent::RangeLocate);
1989 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1993 /* Called from event-processing context */
1995 unset_play_range ();
1997 if (range.empty()) {
1998 /* _play_range set to false in unset_play_range()
2000 if (!leave_rolling) {
2001 /* stop transport */
2002 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false);
2010 /* cancel loop play */
2013 list<AudioRange>::size_type sz = range.size();
2017 list<AudioRange>::iterator i = range.begin();
2018 list<AudioRange>::iterator next;
2020 while (i != range.end()) {
2025 /* locating/stopping is subject to delays for declicking.
2028 samplepos_t requested_sample = i->end;
2030 if (requested_sample > current_block_size) {
2031 requested_sample -= current_block_size;
2033 requested_sample = 0;
2036 if (next == range.end()) {
2037 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_sample, 0, 0.0f);
2039 ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_sample, (*next).start, 0.0f);
2047 } else if (sz == 1) {
2049 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
2054 /* save range so we can do auto-return etc. */
2056 current_audio_range = range;
2058 /* now start rolling at the right place */
2060 ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
2063 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC5 with speed = %1\n", _transport_speed));
2064 TransportStateChange ();
2068 Session::request_bounded_roll (samplepos_t start, samplepos_t end)
2070 AudioRange ar (start, end, 0);
2071 list<AudioRange> lar;
2074 request_play_range (&lar, true);
2078 Session::set_requested_return_sample (samplepos_t return_to)
2080 _requested_return_sample = return_to;
2084 Session::request_roll_at_and_return (samplepos_t start, samplepos_t return_to)
2086 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
2087 ev->target2_sample = start;
2092 Session::engine_halted ()
2096 /* there will be no more calls to process(), so
2097 we'd better clean up for ourselves, right now.
2099 but first, make sure the butler is out of
2107 realtime_stop (false, true);
2108 non_realtime_stop (false, 0, ignored);
2109 transport_sub_state = 0;
2111 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC6 with speed = %1\n", _transport_speed));
2112 TransportStateChange (); /* EMIT SIGNAL */
2117 Session::xrun_recovery ()
2121 Xrun (_transport_sample); /* EMIT SIGNAL */
2123 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
2125 /* it didn't actually halt, but we need
2126 to handle things in the same way.
2134 Session::route_processors_changed (RouteProcessorChange c)
2136 if (g_atomic_int_get (&_ignore_route_processor_changes) > 0) {
2140 if (c.type == RouteProcessorChange::MeterPointChange) {
2145 if (c.type == RouteProcessorChange::RealTimeChange) {
2150 update_latency_compensation ();
2157 Session::allow_auto_play (bool yn)
2159 auto_play_legal = yn;
2163 Session::maybe_stop (samplepos_t limit)
2165 if ((_transport_speed > 0.0f && _transport_sample >= limit) || (_transport_speed < 0.0f && _transport_sample == 0)) {
2166 if (synced_to_engine () && config.get_jack_time_master ()) {
2167 _engine.transport_stop ();
2168 } else if (!synced_to_engine ()) {
2177 Session::send_mmc_locate (samplepos_t t)
2183 if (!_engine.freewheeling()) {
2184 Timecode::Time time;
2185 timecode_time_subframes (t, time);
2186 send_immediate_mmc (MIDI::MachineControlCommand (time));
2190 /** Ask the transport to not send timecode until further notice. The suspension
2191 * will come into effect some finite time after this call, and timecode_transmission_suspended()
2192 * should be checked by the caller to find out when.
2195 Session::request_suspend_timecode_transmission ()
2197 SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, false);
2202 Session::request_resume_timecode_transmission ()
2204 SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, true);
2209 Session::timecode_transmission_suspended () const
2211 return g_atomic_int_get (&_suspend_timecode_transmission) == 1;