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"
34 #include "midi++/mmc.h"
35 #include "midi++/port.h"
36 #include "midi++/manager.h"
38 #include "ardour/audioengine.h"
39 #include "ardour/auditioner.h"
40 #include "ardour/butler.h"
41 #include "ardour/click.h"
42 #include "ardour/debug.h"
43 #include "ardour/location.h"
44 #include "ardour/session.h"
45 #include "ardour/slave.h"
46 #include "ardour/operations.h"
51 using namespace ARDOUR;
55 Session::add_post_transport_work (PostTransportWork ptw)
57 PostTransportWork oldval;
58 PostTransportWork newval;
62 oldval = (PostTransportWork) g_atomic_int_get (&_post_transport_work);
63 newval = PostTransportWork (oldval | ptw);
64 if (g_atomic_int_compare_and_exchange (&_post_transport_work, oldval, newval)) {
70 error << "Could not set post transport work! Crazy thread madness, call the programmers" << endmsg;
74 Session::request_input_change_handling ()
76 if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
77 SessionEvent* ev = new SessionEvent (SessionEvent::InputConfigurationChange, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
83 Session::request_sync_source (Slave* new_slave)
85 SessionEvent* ev = new SessionEvent (SessionEvent::SetSyncSource, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
88 seamless = Config->get_seamless_loop ();
90 if (dynamic_cast<JACK_Slave*>(new_slave)) {
91 /* JACK cannot support seamless looping at present */
92 Config->set_seamless_loop (false);
94 /* reset to whatever the value was before we last switched slaves */
95 Config->set_seamless_loop (_was_seamless);
98 /* save value of seamless from before the switch */
99 _was_seamless = seamless;
101 ev->slave = new_slave;
102 DEBUG_TRACE (DEBUG::Slave, "sent request for new slave\n");
107 Session::request_transport_speed (double speed, bool as_default)
109 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
110 ev->third_yes_or_no = true;
111 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport speed = %1 as default = %2\n", speed, as_default));
115 /** Request a new transport speed, but if the speed parameter is exactly zero then use
116 * a very small +ve value to prevent the transport actually stopping. This method should
117 * be used by callers who are varying transport speed but don't ever want to stop it.
120 Session::request_transport_speed_nonzero (double speed, bool as_default)
126 request_transport_speed (speed, as_default);
130 Session::request_track_speed (Track* tr, double speed)
132 SessionEvent* ev = new SessionEvent (SessionEvent::SetTrackSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
138 Session::request_stop (bool abort, bool clear_state)
140 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0, abort, clear_state);
141 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport stop, abort = %1, clear state = %2\n", abort, clear_state));
146 Session::request_locate (framepos_t target_frame, bool with_roll)
148 SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, false);
149 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request locate to %1\n", target_frame));
154 Session::force_locate (framepos_t target_frame, bool with_roll)
156 SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, true);
157 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request forced locate to %1\n", target_frame));
162 Session::request_play_loop (bool yn, bool leave_rolling)
165 Location *location = _locations->auto_loop_location();
167 if (location == 0 && yn) {
168 error << _("Cannot loop - no loop range defined")
173 ev = new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn);
174 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request set loop = %1, leave rolling ? %2\n", yn, leave_rolling));
177 if (!leave_rolling && !yn && Config->get_seamless_loop() && transport_rolling()) {
178 // request an immediate locate to refresh the tracks
179 // after disabling looping
180 request_locate (_transport_frame-1, false);
185 Session::request_play_range (list<AudioRange>* range, bool leave_rolling)
187 SessionEvent* ev = new SessionEvent (SessionEvent::SetPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0));
189 ev->audio_range = *range;
191 ev->audio_range.clear ();
193 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request play range, leave rolling ? %1\n", leave_rolling));
198 Session::realtime_stop (bool abort, bool clear_state)
200 DEBUG_TRACE (DEBUG::Transport, string_compose ("realtime stop @ %1\n", _transport_frame));
201 PostTransportWork todo = PostTransportWork (0);
203 /* assume that when we start, we'll be moving forwards */
205 if (_transport_speed < 0.0f) {
206 todo = (PostTransportWork (todo | PostTransportStop | PostTransportReverse));
207 _default_transport_speed = 1.0;
209 todo = PostTransportWork (todo | PostTransportStop);
214 boost::shared_ptr<RouteList> r = routes.reader ();
216 for (RouteList::iterator i = r->begin (); i != r->end(); ++i) {
217 (*i)->realtime_handle_transport_stopped ();
220 if (actively_recording()) {
222 /* move the transport position back to where the
223 request for a stop was noticed. we rolled
224 past that point to pick up delayed input (and/or to delick)
227 if (worst_playback_latency() > current_block_size) {
228 /* we rolled past the stop point to pick up data that had
229 not yet arrived. move back to where the stop occured.
231 decrement_transport_position (current_block_size + (worst_input_latency() - current_block_size));
233 decrement_transport_position (current_block_size);
236 /* the duration change is not guaranteed to have happened, but is likely */
238 todo = PostTransportWork (todo | PostTransportDuration);
242 todo = PostTransportWork (todo | PostTransportAbort);
246 todo = PostTransportWork (todo | PostTransportClearSubstate);
250 add_post_transport_work (todo);
253 _clear_event_type (SessionEvent::StopOnce);
254 _clear_event_type (SessionEvent::RangeStop);
255 _clear_event_type (SessionEvent::RangeLocate);
257 /* if we're going to clear loop state, then force disabling record BUT only if we're not doing latched rec-enable */
258 disable_record (true, (!Config->get_latched_record_enable() && clear_state));
260 reset_slave_state ();
262 _transport_speed = 0;
263 _target_transport_speed = 0;
265 g_atomic_int_set (&_playback_load, 100);
266 g_atomic_int_set (&_capture_load, 100);
268 if (config.get_use_video_sync()) {
269 waiting_for_sync_offset = true;
272 transport_sub_state = 0;
276 Session::realtime_locate ()
278 boost::shared_ptr<RouteList> r = routes.reader ();
279 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
280 (*i)->realtime_locate ();
285 Session::butler_transport_work ()
289 PostTransportWork ptw;
290 boost::shared_ptr<RouteList> r = routes.reader ();
292 int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
294 ptw = post_transport_work();
296 DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler transport work, todo = %1\n", enum_2_string (ptw)));
298 if (ptw & PostTransportAdjustPlaybackBuffering) {
299 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
300 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
302 tr->adjust_playback_buffering ();
303 /* and refill those buffers ... */
305 (*i)->non_realtime_locate (_transport_frame);
310 if (ptw & PostTransportAdjustCaptureBuffering) {
311 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
312 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
314 tr->adjust_capture_buffering ();
319 if (ptw & PostTransportCurveRealloc) {
320 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
321 (*i)->curve_reallocate();
325 if (ptw & PostTransportInputChange) {
326 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
327 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
329 tr->non_realtime_input_change ();
334 if (ptw & PostTransportSpeed) {
335 non_realtime_set_speed ();
338 if (ptw & PostTransportReverse) {
341 cumulative_rf_motion = 0;
344 /* don't seek if locate will take care of that in non_realtime_stop() */
346 if (!(ptw & PostTransportLocate)) {
348 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
349 (*i)->non_realtime_locate (_transport_frame);
351 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
352 /* new request, stop seeking, and start again */
353 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
360 if (ptw & PostTransportLocate) {
361 non_realtime_locate ();
364 if (ptw & PostTransportStop) {
365 non_realtime_stop (ptw & PostTransportAbort, on_entry, finished);
367 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
372 if (ptw & PostTransportOverWrite) {
373 non_realtime_overwrite (on_entry, finished);
375 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
380 if (ptw & PostTransportAudition) {
381 non_realtime_set_audition ();
384 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
386 DEBUG_TRACE (DEBUG::Transport, X_("Butler transport work all done\n"));
387 DEBUG_TRACE (DEBUG::Transport, X_(string_compose ("Frame %1\n", _transport_frame)));
391 Session::non_realtime_set_speed ()
393 boost::shared_ptr<RouteList> rl = routes.reader();
394 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
395 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
397 tr->non_realtime_set_speed ();
403 Session::non_realtime_overwrite (int on_entry, bool& finished)
405 boost::shared_ptr<RouteList> rl = routes.reader();
406 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
407 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
408 if (tr && tr->pending_overwrite ()) {
409 tr->overwrite_existing_buffers ();
411 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
420 Session::non_realtime_locate ()
422 boost::shared_ptr<RouteList> rl = routes.reader();
423 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
424 (*i)->non_realtime_locate (_transport_frame);
427 /* XXX: it would be nice to generate the new clicks here (in the non-RT thread)
428 rather than clearing them so that the RT thread has to spend time constructing
429 them (in Session::click).
436 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
442 PostTransportWork ptw = post_transport_work();
447 boost::shared_ptr<RouteList> rl = routes.reader();
448 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
449 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
450 if (tr && tr->get_captured_frames () != 0) {
456 /* stop and locate are merged here because they share a lot of common stuff */
459 now = localtime (&xnow);
462 auditioner->cancel_audition ();
465 cumulative_rf_motion = 0;
469 begin_reversible_command (Operations::capture);
470 _have_captured = true;
473 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: DS stop\n"));
475 if (abort && did_record) {
476 /* no reason to save the session file when we remove sources
478 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
481 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
482 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
484 tr->transport_stopped_wallclock (*now, xnow, abort);
488 if (abort && did_record) {
489 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
492 boost::shared_ptr<RouteList> r = routes.reader ();
494 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
495 if (!(*i)->is_auditioner()) {
496 (*i)->set_pending_declick (0);
501 commit_reversible_command ();
504 if (_engine.running()) {
505 PostTransportWork ptw = post_transport_work ();
506 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
507 (*i)->nonrealtime_handle_transport_stopped (abort, (ptw & PostTransportLocate), (!(ptw & PostTransportLocate) || pending_locate_flush));
509 update_latency_compensation ();
512 bool const auto_return_enabled =
513 (!config.get_external_sync() && config.get_auto_return());
515 if (auto_return_enabled ||
516 (ptw & PostTransportLocate) ||
517 (_requested_return_frame >= 0) ||
520 if (pending_locate_flush) {
521 flush_all_inserts ();
524 if ((auto_return_enabled || synced_to_jack() || _requested_return_frame >= 0) &&
525 !(ptw & PostTransportLocate)) {
527 /* no explicit locate queued */
529 bool do_locate = false;
531 if (_requested_return_frame >= 0) {
533 /* explicit return request pre-queued in event list. overrides everything else */
535 cerr << "explicit auto-return to " << _requested_return_frame << endl;
537 _transport_frame = _requested_return_frame;
541 if (config.get_auto_return()) {
545 /* don't try to handle loop play when synced to JACK */
547 if (!synced_to_jack()) {
549 Location *location = _locations->auto_loop_location();
552 _transport_frame = location->start();
554 _transport_frame = _last_roll_location;
559 } else if (_play_range) {
561 /* return to start of range */
563 if (!current_audio_range.empty()) {
564 _transport_frame = current_audio_range.front().start;
570 /* regular auto-return */
572 _transport_frame = _last_roll_location;
578 _requested_return_frame = -1;
581 _engine.transport_locate (_transport_frame);
589 /* do this before seeking, because otherwise the tracks will do the wrong thing in seamless loop mode.
592 if (ptw & PostTransportClearSubstate) {
597 /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
599 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: locate\n"));
600 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
601 DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler PTW: locate on %1\n", (*i)->name()));
602 (*i)->non_realtime_locate (_transport_frame);
604 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
606 /* we will be back */
613 if (!_engine.freewheeling()) {
614 send_full_time_code (_transport_frame);
616 if (!dynamic_cast<MTC_Slave*>(_slave)) {
617 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
618 send_mmc_locate (_transport_frame);
622 if ((ptw & PostTransportLocate) && get_record_enabled()) {
623 /* This is scheduled by realtime_stop(), which is also done
624 * when a slave requests /locate/ for an initial sync.
625 * We can't hold up the slave for long with a save() here,
626 * without breaking its initial sync cycle.
628 * save state only if there's no slave or if it's not yet locked.
630 if (!_slave || !_slave->locked()) {
631 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: pending save\n"));
632 /* capture start has been changed, so save pending state */
633 save_state ("", true);
638 /* always try to get rid of this */
640 remove_pending_capture_state ();
642 /* save the current state of things if appropriate */
644 if (did_record && !saved) {
645 save_state (_current_snapshot_name);
648 if (ptw & PostTransportStop) {
653 PositionChanged (_transport_frame); /* EMIT SIGNAL */
654 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC with speed = %1\n", _transport_speed));
655 TransportStateChange (); /* EMIT SIGNAL */
657 /* and start it up again if relevant */
659 if ((ptw & PostTransportLocate) && !config.get_external_sync() && pending_locate_roll) {
660 request_transport_speed (1.0);
663 /* Even if we didn't do a pending locate roll this time, we don't want it hanging
664 around for next time.
666 pending_locate_roll = false;
670 Session::check_declick_out ()
672 bool locate_required = transport_sub_state & PendingLocate;
674 /* this is called after a process() iteration. if PendingDeclickOut was set,
675 it means that we were waiting to declick the output (which has just been
676 done) before maybe doing something else. this is where we do that "something else".
678 note: called from the audio thread.
681 if (transport_sub_state & PendingDeclickOut) {
683 if (locate_required) {
684 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
685 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
687 stop_transport (pending_abort);
688 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
691 } else if (transport_sub_state & PendingLoopDeclickOut) {
692 /* Nothing else to do here; we've declicked, and the loop event will be along shortly */
693 transport_sub_state &= ~PendingLoopDeclickOut;
698 Session::unset_play_loop ()
701 clear_events (SessionEvent::AutoLoop);
702 clear_events (SessionEvent::AutoLoopDeclick);
704 // set all tracks to NOT use internal looping
705 boost::shared_ptr<RouteList> rl = routes.reader ();
706 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
707 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
708 if (tr && !tr->hidden()) {
715 Session::set_play_loop (bool yn)
717 /* Called from event-handling context */
721 if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) {
722 /* nothing to do, or can't change loop status while recording */
726 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
727 warning << string_compose (
728 _("Seamless looping cannot be supported while %1 is using JACK transport.\n"
729 "Recommend changing the configured options"), PROGRAM_NAME)
742 if (Config->get_seamless_loop()) {
743 // set all tracks to use internal looping
744 boost::shared_ptr<RouteList> rl = routes.reader ();
745 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
746 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
747 if (tr && !tr->hidden()) {
753 // set all tracks to NOT use internal looping
754 boost::shared_ptr<RouteList> rl = routes.reader ();
755 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
756 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
757 if (tr && !tr->hidden()) {
763 /* Put the delick and loop events in into the event list. The declick event will
764 cause a de-clicking fade-out just before the end of the loop, and it will also result
765 in a fade-in when the loop restarts. The AutoLoop event will peform the actual loop.
770 auto_loop_declick_range (loc, dcp, dcl);
771 merge_event (new SessionEvent (SessionEvent::AutoLoopDeclick, SessionEvent::Replace, dcp, dcl, 0.0f));
772 merge_event (new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f));
774 /* locate to start of loop and roll.
776 args: positition, roll=true, flush=true, with_loop=false, force buffer refill if seamless looping
779 start_locate (loc->start(), true, true, false, Config->get_seamless_loop());
787 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC2 with speed = %1\n", _transport_speed));
788 TransportStateChange ();
791 Session::flush_all_inserts ()
793 boost::shared_ptr<RouteList> r = routes.reader ();
795 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
796 (*i)->flush_processors ();
801 Session::start_locate (framepos_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
803 if (synced_to_jack()) {
808 _slave->speed_and_position (sp, pos);
810 if (target_frame != pos) {
812 if (config.get_jack_time_master()) {
813 /* actually locate now, since otherwise jack_timebase_callback
814 will use the incorrect _transport_frame and report an old
815 and incorrect time to Jack transport
817 locate (target_frame, with_roll, with_flush, with_loop, force);
820 /* tell JACK to change transport position, and we will
821 follow along later in ::follow_slave()
824 _engine.transport_locate (target_frame);
826 if (sp != 1.0f && with_roll) {
827 _engine.transport_start ();
833 locate (target_frame, with_roll, with_flush, with_loop, force);
838 Session::micro_locate (framecnt_t distance)
840 boost::shared_ptr<RouteList> rl = routes.reader();
841 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
842 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
843 if (tr && !tr->can_internal_playback_seek (distance)) {
848 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
849 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
851 tr->internal_playback_seek (distance);
855 _transport_frame += distance;
859 /** @param with_mmc true to send a MMC locate command when the locate is done */
861 Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool for_seamless_loop, bool force, bool with_mmc)
863 /* Locates for seamless looping are fairly different from other
864 * locates. They assume that the diskstream buffers for each track
865 * already have the correct data in them, and thus there is no need to
866 * actually tell the tracks to locate. What does need to be done,
867 * though, is all the housekeeping that is associated with non-linear
868 * changes in the value of _transport_frame.
871 if (actively_recording() && !for_seamless_loop) {
875 if (!force && _transport_frame == target_frame && !loop_changing && !for_seamless_loop) {
877 set_transport_speed (1.0, false);
879 loop_changing = false;
880 Located (); /* EMIT SIGNAL */
884 if (_transport_speed && !for_seamless_loop) {
885 /* Schedule a declick. We'll be called again when its done.
886 We only do it this way for ordinary locates, not those
887 due to **seamless** loops.
890 if (!(transport_sub_state & PendingDeclickOut)) {
891 transport_sub_state |= (PendingDeclickOut|PendingLocate);
892 pending_locate_frame = target_frame;
893 pending_locate_roll = with_roll;
894 pending_locate_flush = with_flush;
899 // Update Timecode time
900 // [DR] FIXME: find out exactly where this should go below
901 _transport_frame = target_frame;
902 _last_roll_or_reversal_location = target_frame;
903 timecode_time(_transport_frame, transmitting_timecode_time);
904 outbound_mtc_timecode_frame = _transport_frame;
905 next_quarter_frame_to_send = 0;
907 /* do "stopped" stuff if:
910 * no autoplay in effect AND
911 * we're not going to keep rolling after the locate AND
912 * !(playing a loop with JACK sync)
916 bool transport_was_stopped = !transport_rolling();
918 if (transport_was_stopped && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
919 realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
920 transport_was_stopped = true;
922 /* otherwise tell the world that we located */
926 if (force || !for_seamless_loop || loop_changing) {
928 PostTransportWork todo = PostTransportLocate;
930 if (with_roll && transport_was_stopped) {
931 todo = PostTransportWork (todo | PostTransportRoll);
934 add_post_transport_work (todo);
935 _butler->schedule_transport_work ();
939 /* this is functionally what clear_clicks() does but with a tentative lock */
941 Glib::Threads::RWLock::WriterLock clickm (click_lock, Glib::Threads::TRY_LOCK);
943 if (clickm.locked()) {
945 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
954 /* switch from input if we're going to roll */
955 if (Config->get_monitoring_model() == HardwareMonitoring) {
956 set_track_monitor_input_status (!config.get_auto_input());
959 /* otherwise we're going to stop, so do the opposite */
960 if (Config->get_monitoring_model() == HardwareMonitoring) {
961 set_track_monitor_input_status (true);
965 /* cancel looped playback if transport pos outside of loop range */
968 Location* al = _locations->auto_loop_location();
971 if (_transport_frame < al->start() || _transport_frame > al->end()) {
973 // located outside the loop: cancel looping directly, this is called from event handling context
975 set_play_loop (false);
977 } else if (_transport_frame == al->start()) {
979 // located to start of loop - this is looping, basically
981 if (for_seamless_loop) {
983 // this is only necessary for seamless looping
985 boost::shared_ptr<RouteList> rl = routes.reader();
987 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
988 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
990 if (tr && tr->record_enabled ()) {
991 // tell it we've looped, so it can deal with the record state
992 tr->transport_looped (_transport_frame);
998 TransportLooped(); // EMIT SIGNAL
1003 loop_changing = false;
1005 _send_timecode_update = true;
1008 send_mmc_locate (_transport_frame);
1011 _last_roll_location = _last_roll_or_reversal_location = _transport_frame;
1012 Located (); /* EMIT SIGNAL */
1015 /** Set the transport speed.
1016 * Called from the process thread.
1017 * @param speed New speed
1020 Session::set_transport_speed (double speed, bool abort, bool clear_state, bool as_default)
1022 DEBUG_TRACE (DEBUG::Transport, string_compose ("@ %5 Set transport speed to %1, abort = %2 clear_state = %3, current = %4 as_default %6\n",
1023 speed, abort, clear_state, _transport_speed, _transport_frame, as_default));
1025 if (_transport_speed == speed) {
1026 if (as_default && speed == 0.0) { // => reset default transport speed. hacky or what?
1027 _default_transport_speed = 1.0;
1032 if (actively_recording() && speed != 1.0 && speed != 0.0) {
1033 /* no varispeed during recording */
1034 DEBUG_TRACE (DEBUG::Transport, string_compose ("No varispeed during recording cur_speed %1, frame %2\n",
1035 _transport_speed, _transport_frame));
1039 _target_transport_speed = fabs(speed);
1041 /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
1042 and user needs. We really need CD-style "skip" playback for ffwd and rewind.
1046 speed = min (8.0, speed);
1047 } else if (speed < 0) {
1048 speed = max (-8.0, speed);
1051 if (transport_rolling() && speed == 0.0) {
1053 /* we are rolling and we want to stop */
1055 if (Config->get_monitoring_model() == HardwareMonitoring) {
1056 set_track_monitor_input_status (true);
1059 if (synced_to_jack ()) {
1061 /* do this here because our response to the slave won't
1064 _play_range = false;
1067 _engine.transport_stop ();
1069 stop_transport (abort);
1074 } else if (transport_stopped() && speed == 1.0) {
1076 /* we are stopped and we want to start rolling at speed 1 */
1078 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1079 set_track_monitor_input_status (false);
1082 if (synced_to_jack()) {
1083 _engine.transport_start ();
1090 /* not zero, not 1.0 ... varispeed */
1092 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
1093 warning << string_compose (
1094 _("Global varispeed cannot be supported while %1 is connected to JACK transport control"),
1100 if (actively_recording()) {
1104 if (speed > 0.0 && _transport_frame == current_end_frame()) {
1108 if (speed < 0.0 && _transport_frame == 0) {
1114 /* if we are reversing relative to the current speed, or relative to the speed
1115 before the last stop, then we have to do extra work.
1118 PostTransportWork todo = PostTransportWork (0);
1120 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
1121 todo = PostTransportWork (todo | PostTransportReverse);
1122 _last_roll_or_reversal_location = _transport_frame;
1125 _last_transport_speed = _transport_speed;
1126 _transport_speed = speed;
1129 _default_transport_speed = speed;
1132 boost::shared_ptr<RouteList> rl = routes.reader();
1133 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1134 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1135 if (tr && tr->realtime_set_speed (tr->speed(), true)) {
1136 todo = PostTransportWork (todo | PostTransportSpeed);
1141 add_post_transport_work (todo);
1142 _butler->schedule_transport_work ();
1145 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC3 with speed = %1\n", _transport_speed));
1146 TransportStateChange (); /* EMIT SIGNAL */
1151 /** Stop the transport. */
1153 Session::stop_transport (bool abort, bool clear_state)
1155 if (_transport_speed == 0.0f) {
1159 if (actively_recording() && !(transport_sub_state & StopPendingCapture) && worst_input_latency() > current_block_size) {
1161 boost::shared_ptr<RouteList> rl = routes.reader();
1162 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1163 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1165 tr->prepare_to_stop (_transport_frame);
1169 /* we need to capture the audio that has still not yet been received by the system
1170 at the time the stop is requested, so we have to roll past that time.
1172 we want to declick before stopping, so schedule the autostop for one
1173 block before the actual end. we'll declick in the subsequent block,
1174 and then we'll really be stopped.
1177 DEBUG_TRACE (DEBUG::Transport, string_compose ("stop transport requested @ %1, scheduled for + %2 - %3 = %4, abort = %5\n",
1178 _transport_frame, _worst_input_latency, current_block_size,
1179 _transport_frame - _worst_input_latency - current_block_size,
1182 SessionEvent *ev = new SessionEvent (SessionEvent::StopOnce, SessionEvent::Replace,
1183 _transport_frame + _worst_input_latency - current_block_size,
1187 transport_sub_state |= StopPendingCapture;
1188 pending_abort = abort;
1192 if ((transport_sub_state & PendingDeclickOut) == 0) {
1194 if (!(transport_sub_state & StopPendingCapture)) {
1195 boost::shared_ptr<RouteList> rl = routes.reader();
1196 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1197 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1199 tr->prepare_to_stop (_transport_frame);
1204 transport_sub_state |= PendingDeclickOut;
1205 /* we'll be called again after the declick */
1206 pending_abort = abort;
1210 realtime_stop (abort, clear_state);
1211 _butler->schedule_transport_work ();
1214 /** Called from the process thread */
1216 Session::start_transport ()
1218 DEBUG_TRACE (DEBUG::Transport, "start_transport\n");
1220 _last_roll_location = _transport_frame;
1221 _last_roll_or_reversal_location = _transport_frame;
1223 have_looped = false;
1225 /* if record status is Enabled, move it to Recording. if its
1226 already Recording, move it to Disabled.
1229 switch (record_status()) {
1231 if (!config.get_punch_in()) {
1238 disable_record (false);
1246 transport_sub_state |= PendingDeclickIn;
1248 _transport_speed = _default_transport_speed;
1249 _target_transport_speed = _transport_speed;
1251 boost::shared_ptr<RouteList> rl = routes.reader();
1252 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1253 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1255 tr->realtime_set_speed (tr->speed(), true);
1259 if (!_engine.freewheeling()) {
1260 Timecode::Time time;
1261 timecode_time_subframes (_transport_frame, time);
1262 if (!dynamic_cast<MTC_Slave*>(_slave)) {
1263 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
1267 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC4 with speed = %1\n", _transport_speed));
1268 TransportStateChange (); /* EMIT SIGNAL */
1271 /** Do any transport work in the audio thread that needs to be done after the
1272 * transport thread is finished. Audio thread, realtime safe.
1275 Session::post_transport ()
1277 PostTransportWork ptw = post_transport_work ();
1279 if (ptw & PostTransportAudition) {
1280 if (auditioner && auditioner->auditioning()) {
1281 process_function = &Session::process_audition;
1283 process_function = &Session::process_with_events;
1287 if (ptw & PostTransportStop) {
1289 transport_sub_state = 0;
1292 if (ptw & PostTransportLocate) {
1294 if (((!config.get_external_sync() && (auto_play_legal && config.get_auto_play())) && !_exporting) || (ptw & PostTransportRoll)) {
1297 transport_sub_state = 0;
1302 /* XXX is this really safe? shouldn't we just be unsetting the bits that we actually
1305 set_post_transport_work (PostTransportWork (0));
1309 Session::reset_rf_scale (framecnt_t motion)
1311 cumulative_rf_motion += motion;
1313 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1315 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1317 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1329 Session::use_sync_source (Slave* new_slave)
1331 /* Runs in process() context */
1333 bool non_rt_required = false;
1335 /* XXX this deletion is problematic because we're in RT context */
1340 DEBUG_TRACE (DEBUG::Slave, string_compose ("set new slave to %1\n", _slave));
1342 send_full_time_code (_transport_frame);
1344 boost::shared_ptr<RouteList> rl = routes.reader();
1345 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1346 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1347 if (tr && !tr->hidden()) {
1348 if (tr->realtime_set_speed (tr->speed(), true)) {
1349 non_rt_required = true;
1351 tr->set_slaved (_slave != 0);
1355 if (non_rt_required) {
1356 add_post_transport_work (PostTransportSpeed);
1357 _butler->schedule_transport_work ();
1364 Session::drop_sync_source ()
1366 request_sync_source (0);
1370 Session::switch_to_sync_source (SyncSource src)
1374 DEBUG_TRACE (DEBUG::Slave, string_compose ("Setting up sync source %1\n", enum_2_string (src)));
1378 if (_slave && dynamic_cast<MTC_Slave*>(_slave)) {
1383 new_slave = new MTC_Slave (*this, *MIDI::Manager::instance()->mtc_input_port());
1386 catch (failed_constructor& err) {
1392 if (_slave && dynamic_cast<LTC_Slave*>(_slave)) {
1397 new_slave = new LTC_Slave (*this);
1400 catch (failed_constructor& err) {
1407 if (_slave && dynamic_cast<MIDIClock_Slave*>(_slave)) {
1412 new_slave = new MIDIClock_Slave (*this, *MIDI::Manager::instance()->midi_clock_input_port(), 24);
1415 catch (failed_constructor& err) {
1421 if (_slave && dynamic_cast<JACK_Slave*>(_slave)) {
1425 if (config.get_video_pullup() != 0.0f) {
1429 new_slave = new JACK_Slave (_engine.jack());
1437 request_sync_source (new_slave);
1441 Session::set_track_speed (Track* track, double speed)
1443 if (track->realtime_set_speed (speed, false)) {
1444 add_post_transport_work (PostTransportSpeed);
1445 _butler->schedule_transport_work ();
1451 Session::unset_play_range ()
1453 _play_range = false;
1454 _clear_event_type (SessionEvent::RangeStop);
1455 _clear_event_type (SessionEvent::RangeLocate);
1459 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1463 /* Called from event-processing context */
1465 unset_play_range ();
1467 if (range.empty()) {
1468 /* _play_range set to false in unset_play_range()
1470 if (!leave_rolling) {
1471 /* stop transport */
1472 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false);
1480 /* cancel loop play */
1483 list<AudioRange>::size_type sz = range.size();
1487 list<AudioRange>::iterator i = range.begin();
1488 list<AudioRange>::iterator next;
1490 while (i != range.end()) {
1495 /* locating/stopping is subject to delays for declicking.
1498 framepos_t requested_frame = i->end;
1500 if (requested_frame > current_block_size) {
1501 requested_frame -= current_block_size;
1503 requested_frame = 0;
1506 if (next == range.end()) {
1507 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_frame, 0, 0.0f);
1509 ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_frame, (*next).start, 0.0f);
1517 } else if (sz == 1) {
1519 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
1524 /* save range so we can do auto-return etc. */
1526 current_audio_range = range;
1528 /* now start rolling at the right place */
1530 ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
1533 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC5 with speed = %1\n", _transport_speed));
1534 TransportStateChange ();
1538 Session::request_bounded_roll (framepos_t start, framepos_t end)
1540 AudioRange ar (start, end, 0);
1541 list<AudioRange> lar;
1544 request_play_range (&lar, true);
1547 Session::request_roll_at_and_return (framepos_t start, framepos_t return_to)
1549 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
1550 ev->target2_frame = start;
1555 Session::engine_halted ()
1559 /* there will be no more calls to process(), so
1560 we'd better clean up for ourselves, right now.
1562 but first, make sure the butler is out of
1567 g_atomic_int_set (&_butler->should_do_transport_work, 0);
1568 set_post_transport_work (PostTransportWork (0));
1572 realtime_stop (false, true);
1573 non_realtime_stop (false, 0, ignored);
1574 transport_sub_state = 0;
1576 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC6 with speed = %1\n", _transport_speed));
1577 TransportStateChange (); /* EMIT SIGNAL */
1582 Session::xrun_recovery ()
1584 Xrun (_transport_frame); /* EMIT SIGNAL */
1586 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1588 /* it didn't actually halt, but we need
1589 to handle things in the same way.
1597 Session::route_processors_changed (RouteProcessorChange c)
1599 if (ignore_route_processor_changes) {
1603 if (c.type == RouteProcessorChange::MeterPointChange) {
1607 update_latency_compensation ();
1614 Session::allow_auto_play (bool yn)
1616 auto_play_legal = yn;
1620 Session::reset_jack_connection (jack_client_t* jack)
1624 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1625 js->reset_client (jack);
1630 Session::maybe_stop (framepos_t limit)
1632 if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
1633 if (synced_to_jack () && config.get_jack_time_master ()) {
1634 _engine.transport_stop ();
1635 } else if (!synced_to_jack ()) {
1644 Session::send_mmc_locate (framepos_t t)
1646 if (!_engine.freewheeling()) {
1647 Timecode::Time time;
1648 timecode_time_subframes (t, time);
1649 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (time));
1653 /** Ask the transport to not send timecode until further notice. The suspension
1654 * will come into effect some finite time after this call, and timecode_transmission_suspended()
1655 * should be checked by the caller to find out when.
1658 Session::request_suspend_timecode_transmission ()
1660 SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, false);
1665 Session::request_resume_timecode_transmission ()
1667 SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, true);
1672 Session::timecode_transmission_suspended () const
1674 return g_atomic_int_get (&_suspend_timecode_transmission) == 1;