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"));
390 Session::non_realtime_set_speed ()
392 boost::shared_ptr<RouteList> rl = routes.reader();
393 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
394 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
396 tr->non_realtime_set_speed ();
402 Session::non_realtime_overwrite (int on_entry, bool& finished)
404 boost::shared_ptr<RouteList> rl = routes.reader();
405 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
406 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
407 if (tr && tr->pending_overwrite ()) {
408 tr->overwrite_existing_buffers ();
410 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
419 Session::non_realtime_locate ()
421 boost::shared_ptr<RouteList> rl = routes.reader();
422 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
423 (*i)->non_realtime_locate (_transport_frame);
426 /* XXX: it would be nice to generate the new clicks here (in the non-RT thread)
427 rather than clearing them so that the RT thread has to spend time constructing
428 them (in Session::click).
435 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
441 PostTransportWork ptw = post_transport_work();
446 boost::shared_ptr<RouteList> rl = routes.reader();
447 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
448 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
449 if (tr && tr->get_captured_frames () != 0) {
455 /* stop and locate are merged here because they share a lot of common stuff */
458 now = localtime (&xnow);
461 auditioner->cancel_audition ();
464 cumulative_rf_motion = 0;
468 begin_reversible_command (Operations::capture);
469 _have_captured = true;
472 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: DS stop\n"));
474 if (abort && did_record) {
475 /* no reason to save the session file when we remove sources
477 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
480 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
481 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
483 tr->transport_stopped_wallclock (*now, xnow, abort);
487 if (abort && did_record) {
488 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
491 boost::shared_ptr<RouteList> r = routes.reader ();
493 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
494 if (!(*i)->is_hidden()) {
495 (*i)->set_pending_declick (0);
500 commit_reversible_command ();
503 if (_engine.running()) {
504 PostTransportWork ptw = post_transport_work ();
505 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
506 (*i)->nonrealtime_handle_transport_stopped (abort, (ptw & PostTransportLocate), (!(ptw & PostTransportLocate) || pending_locate_flush));
508 update_latency_compensation ();
511 bool const auto_return_enabled =
512 (!config.get_external_sync() && config.get_auto_return());
514 if (auto_return_enabled ||
515 (ptw & PostTransportLocate) ||
516 (_requested_return_frame >= 0) ||
519 if (pending_locate_flush) {
520 flush_all_inserts ();
523 if ((auto_return_enabled || synced_to_jack() || _requested_return_frame >= 0) &&
524 !(ptw & PostTransportLocate)) {
526 /* no explicit locate queued */
528 bool do_locate = false;
530 if (_requested_return_frame >= 0) {
532 /* explicit return request pre-queued in event list. overrides everything else */
534 cerr << "explicit auto-return to " << _requested_return_frame << endl;
536 _transport_frame = _requested_return_frame;
540 if (config.get_auto_return()) {
544 /* don't try to handle loop play when synced to JACK */
546 if (!synced_to_jack()) {
548 Location *location = _locations->auto_loop_location();
551 _transport_frame = location->start();
553 _transport_frame = _last_roll_location;
558 } else if (_play_range) {
560 /* return to start of range */
562 if (!current_audio_range.empty()) {
563 _transport_frame = current_audio_range.front().start;
569 /* regular auto-return */
571 _transport_frame = _last_roll_location;
577 _requested_return_frame = -1;
580 _engine.transport_locate (_transport_frame);
588 /* do this before seeking, because otherwise the tracks will do the wrong thing in seamless loop mode.
591 if (ptw & PostTransportClearSubstate) {
596 /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
598 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: locate\n"));
599 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
600 DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler PTW: locate on %1\n", (*i)->name()));
601 (*i)->non_realtime_locate (_transport_frame);
603 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
605 /* we will be back */
612 if (!_engine.freewheeling()) {
613 send_full_time_code (_transport_frame);
615 if (!dynamic_cast<MTC_Slave*>(_slave)) {
616 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
617 send_mmc_locate (_transport_frame);
621 if ((ptw & PostTransportLocate) && get_record_enabled()) {
622 /* This is scheduled by realtime_stop(), which is also done
623 * when a slave requests /locate/ for an initial sync.
624 * We can't hold up the slave for long with a save() here,
625 * without breaking its initial sync cycle.
627 * save state only if there's no slave or if it's not yet locked.
629 if (!_slave || !_slave->locked()) {
630 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: pending save\n"));
631 /* capture start has been changed, so save pending state */
632 save_state ("", true);
637 /* always try to get rid of this */
639 remove_pending_capture_state ();
641 /* save the current state of things if appropriate */
643 if (did_record && !saved) {
644 save_state (_current_snapshot_name);
647 if (ptw & PostTransportStop) {
652 PositionChanged (_transport_frame); /* EMIT SIGNAL */
653 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC with speed = %1\n", _transport_speed));
654 TransportStateChange (); /* EMIT SIGNAL */
656 /* and start it up again if relevant */
658 if ((ptw & PostTransportLocate) && !config.get_external_sync() && pending_locate_roll) {
659 request_transport_speed (1.0);
662 /* Even if we didn't do a pending locate roll this time, we don't want it hanging
663 around for next time.
665 pending_locate_roll = false;
669 Session::check_declick_out ()
671 bool locate_required = transport_sub_state & PendingLocate;
673 /* this is called after a process() iteration. if PendingDeclickOut was set,
674 it means that we were waiting to declick the output (which has just been
675 done) before maybe doing something else. this is where we do that "something else".
677 note: called from the audio thread.
680 if (transport_sub_state & PendingDeclickOut) {
682 if (locate_required) {
683 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
684 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
686 stop_transport (pending_abort);
687 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
690 } else if (transport_sub_state & PendingLoopDeclickOut) {
691 /* Nothing else to do here; we've declicked, and the loop event will be along shortly */
692 transport_sub_state &= ~PendingLoopDeclickOut;
697 Session::unset_play_loop ()
700 clear_events (SessionEvent::AutoLoop);
701 clear_events (SessionEvent::AutoLoopDeclick);
703 // set all tracks to NOT use internal looping
704 boost::shared_ptr<RouteList> rl = routes.reader ();
705 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
706 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
707 if (tr && !tr->hidden()) {
714 Session::set_play_loop (bool yn)
716 /* Called from event-handling context */
720 if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) {
721 /* nothing to do, or can't change loop status while recording */
725 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
726 warning << string_compose (
727 _("Seamless looping cannot be supported while %1 is using JACK transport.\n"
728 "Recommend changing the configured options"), PROGRAM_NAME)
741 if (Config->get_seamless_loop()) {
742 // set all tracks to use internal looping
743 boost::shared_ptr<RouteList> rl = routes.reader ();
744 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
745 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
746 if (tr && !tr->hidden()) {
752 // set all tracks to NOT use internal looping
753 boost::shared_ptr<RouteList> rl = routes.reader ();
754 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
755 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
756 if (tr && !tr->hidden()) {
762 /* Put the delick and loop events in into the event list. The declick event will
763 cause a de-clicking fade-out just before the end of the loop, and it will also result
764 in a fade-in when the loop restarts. The AutoLoop event will peform the actual loop.
769 auto_loop_declick_range (loc, dcp, dcl);
770 merge_event (new SessionEvent (SessionEvent::AutoLoopDeclick, SessionEvent::Replace, dcp, dcl, 0.0f));
771 merge_event (new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f));
773 /* locate to start of loop and roll.
775 args: positition, roll=true, flush=true, with_loop=false, force buffer refill if seamless looping
778 start_locate (loc->start(), true, true, false, Config->get_seamless_loop());
786 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC2 with speed = %1\n", _transport_speed));
787 TransportStateChange ();
790 Session::flush_all_inserts ()
792 boost::shared_ptr<RouteList> r = routes.reader ();
794 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
795 (*i)->flush_processors ();
800 Session::start_locate (framepos_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
802 if (synced_to_jack()) {
807 _slave->speed_and_position (sp, pos);
809 if (target_frame != pos) {
811 if (config.get_jack_time_master()) {
812 /* actually locate now, since otherwise jack_timebase_callback
813 will use the incorrect _transport_frame and report an old
814 and incorrect time to Jack transport
816 locate (target_frame, with_roll, with_flush, with_loop, force);
819 /* tell JACK to change transport position, and we will
820 follow along later in ::follow_slave()
823 _engine.transport_locate (target_frame);
825 if (sp != 1.0f && with_roll) {
826 _engine.transport_start ();
832 locate (target_frame, with_roll, with_flush, with_loop, force);
837 Session::micro_locate (framecnt_t distance)
839 boost::shared_ptr<RouteList> rl = routes.reader();
840 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
841 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
842 if (tr && !tr->can_internal_playback_seek (distance)) {
847 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
848 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
850 tr->internal_playback_seek (distance);
854 _transport_frame += distance;
858 /** @param with_mmc true to send a MMC locate command when the locate is done */
860 Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool for_seamless_loop, bool force, bool with_mmc)
862 /* Locates for seamless looping are fairly different from other
863 * locates. They assume that the diskstream buffers for each track
864 * already have the correct data in them, and thus there is no need to
865 * actually tell the tracks to locate. What does need to be done,
866 * though, is all the housekeeping that is associated with non-linear
867 * changes in the value of _transport_frame.
870 if (actively_recording() && !for_seamless_loop) {
874 if (!force && _transport_frame == target_frame && !loop_changing && !for_seamless_loop) {
876 set_transport_speed (1.0, false);
878 loop_changing = false;
879 Located (); /* EMIT SIGNAL */
883 if (_transport_speed && !for_seamless_loop) {
884 /* Schedule a declick. We'll be called again when its done.
885 We only do it this way for ordinary locates, not those
886 due to **seamless** loops.
889 if (!(transport_sub_state & PendingDeclickOut)) {
890 transport_sub_state |= (PendingDeclickOut|PendingLocate);
891 pending_locate_frame = target_frame;
892 pending_locate_roll = with_roll;
893 pending_locate_flush = with_flush;
898 // Update Timecode time
899 // [DR] FIXME: find out exactly where this should go below
900 _transport_frame = target_frame;
901 _last_roll_or_reversal_location = target_frame;
902 timecode_time(_transport_frame, transmitting_timecode_time);
903 outbound_mtc_timecode_frame = _transport_frame;
904 next_quarter_frame_to_send = 0;
906 /* do "stopped" stuff if:
909 * no autoplay in effect AND
910 * we're not going to keep rolling after the locate AND
911 * !(playing a loop with JACK sync)
915 bool transport_was_stopped = !transport_rolling();
917 if (transport_was_stopped && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
918 realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
919 transport_was_stopped = true;
921 /* otherwise tell the world that we located */
925 if (force || !for_seamless_loop || loop_changing) {
927 PostTransportWork todo = PostTransportLocate;
929 if (with_roll && transport_was_stopped) {
930 todo = PostTransportWork (todo | PostTransportRoll);
933 add_post_transport_work (todo);
934 _butler->schedule_transport_work ();
938 /* this is functionally what clear_clicks() does but with a tentative lock */
940 Glib::Threads::RWLock::WriterLock clickm (click_lock, Glib::Threads::TRY_LOCK);
942 if (clickm.locked()) {
944 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
953 /* switch from input if we're going to roll */
954 if (Config->get_monitoring_model() == HardwareMonitoring) {
955 set_track_monitor_input_status (!config.get_auto_input());
958 /* otherwise we're going to stop, so do the opposite */
959 if (Config->get_monitoring_model() == HardwareMonitoring) {
960 set_track_monitor_input_status (true);
964 /* cancel looped playback if transport pos outside of loop range */
967 Location* al = _locations->auto_loop_location();
970 if (_transport_frame < al->start() || _transport_frame > al->end()) {
972 // located outside the loop: cancel looping directly, this is called from event handling context
974 set_play_loop (false);
976 } else if (_transport_frame == al->start()) {
978 // located to start of loop - this is looping, basically
980 if (for_seamless_loop) {
982 // this is only necessary for seamless looping
984 boost::shared_ptr<RouteList> rl = routes.reader();
986 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
987 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
989 if (tr && tr->record_enabled ()) {
990 // tell it we've looped, so it can deal with the record state
991 tr->transport_looped (_transport_frame);
997 TransportLooped(); // EMIT SIGNAL
1002 loop_changing = false;
1004 _send_timecode_update = true;
1007 send_mmc_locate (_transport_frame);
1010 Located (); /* EMIT SIGNAL */
1013 /** Set the transport speed.
1014 * Called from the process thread.
1015 * @param speed New speed
1018 Session::set_transport_speed (double speed, bool abort, bool clear_state, bool as_default)
1020 DEBUG_TRACE (DEBUG::Transport, string_compose ("@ %5 Set transport speed to %1, abort = %2 clear_state = %3, current = %4 as_default %6\n",
1021 speed, abort, clear_state, _transport_speed, _transport_frame, as_default));
1023 if (_transport_speed == speed) {
1024 if (as_default && speed == 0.0) { // => reset default transport speed. hacky or what?
1025 _default_transport_speed = 1.0;
1030 if (actively_recording() && speed != 1.0 && speed != 0.0) {
1031 /* no varispeed during recording */
1032 DEBUG_TRACE (DEBUG::Transport, string_compose ("No varispeed during recording cur_speed %1, frame %2\n",
1033 _transport_speed, _transport_frame));
1037 _target_transport_speed = fabs(speed);
1039 /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
1040 and user needs. We really need CD-style "skip" playback for ffwd and rewind.
1044 speed = min (8.0, speed);
1045 } else if (speed < 0) {
1046 speed = max (-8.0, speed);
1049 if (transport_rolling() && speed == 0.0) {
1051 /* we are rolling and we want to stop */
1053 if (Config->get_monitoring_model() == HardwareMonitoring) {
1054 set_track_monitor_input_status (true);
1057 if (synced_to_jack ()) {
1059 /* do this here because our response to the slave won't
1062 _play_range = false;
1065 _engine.transport_stop ();
1067 stop_transport (abort);
1072 } else if (transport_stopped() && speed == 1.0) {
1074 /* we are stopped and we want to start rolling at speed 1 */
1076 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1077 set_track_monitor_input_status (false);
1080 if (synced_to_jack()) {
1081 _engine.transport_start ();
1088 /* not zero, not 1.0 ... varispeed */
1090 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
1091 warning << string_compose (
1092 _("Global varispeed cannot be supported while %1 is connected to JACK transport control"),
1098 if (actively_recording()) {
1102 if (speed > 0.0 && _transport_frame == current_end_frame()) {
1106 if (speed < 0.0 && _transport_frame == 0) {
1112 /* if we are reversing relative to the current speed, or relative to the speed
1113 before the last stop, then we have to do extra work.
1116 PostTransportWork todo = PostTransportWork (0);
1118 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
1119 todo = PostTransportWork (todo | PostTransportReverse);
1120 _last_roll_or_reversal_location = _transport_frame;
1123 _last_transport_speed = _transport_speed;
1124 _transport_speed = speed;
1127 _default_transport_speed = speed;
1130 boost::shared_ptr<RouteList> rl = routes.reader();
1131 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1132 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1133 if (tr && tr->realtime_set_speed (tr->speed(), true)) {
1134 todo = PostTransportWork (todo | PostTransportSpeed);
1139 add_post_transport_work (todo);
1140 _butler->schedule_transport_work ();
1143 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC3 with speed = %1\n", _transport_speed));
1144 TransportStateChange (); /* EMIT SIGNAL */
1149 /** Stop the transport. */
1151 Session::stop_transport (bool abort, bool clear_state)
1153 if (_transport_speed == 0.0f) {
1157 if (actively_recording() && !(transport_sub_state & StopPendingCapture) && worst_input_latency() > current_block_size) {
1159 boost::shared_ptr<RouteList> rl = routes.reader();
1160 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1161 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1163 tr->prepare_to_stop (_transport_frame);
1167 /* we need to capture the audio that has still not yet been received by the system
1168 at the time the stop is requested, so we have to roll past that time.
1170 we want to declick before stopping, so schedule the autostop for one
1171 block before the actual end. we'll declick in the subsequent block,
1172 and then we'll really be stopped.
1175 DEBUG_TRACE (DEBUG::Transport, string_compose ("stop transport requested @ %1, scheduled for + %2 - %3 = %4, abort = %5\n",
1176 _transport_frame, _worst_input_latency, current_block_size,
1177 _transport_frame - _worst_input_latency - current_block_size,
1180 SessionEvent *ev = new SessionEvent (SessionEvent::StopOnce, SessionEvent::Replace,
1181 _transport_frame + _worst_input_latency - current_block_size,
1185 transport_sub_state |= StopPendingCapture;
1186 pending_abort = abort;
1190 if ((transport_sub_state & PendingDeclickOut) == 0) {
1192 if (!(transport_sub_state & StopPendingCapture)) {
1193 boost::shared_ptr<RouteList> rl = routes.reader();
1194 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1195 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1197 tr->prepare_to_stop (_transport_frame);
1202 transport_sub_state |= PendingDeclickOut;
1203 /* we'll be called again after the declick */
1204 pending_abort = abort;
1208 realtime_stop (abort, clear_state);
1209 _butler->schedule_transport_work ();
1212 /** Called from the process thread */
1214 Session::start_transport ()
1216 DEBUG_TRACE (DEBUG::Transport, "start_transport\n");
1218 _last_roll_location = _transport_frame;
1219 _last_roll_or_reversal_location = _transport_frame;
1221 have_looped = false;
1223 /* if record status is Enabled, move it to Recording. if its
1224 already Recording, move it to Disabled.
1227 switch (record_status()) {
1229 if (!config.get_punch_in()) {
1236 disable_record (false);
1244 transport_sub_state |= PendingDeclickIn;
1246 _transport_speed = _default_transport_speed;
1247 _target_transport_speed = _transport_speed;
1249 boost::shared_ptr<RouteList> rl = routes.reader();
1250 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1251 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1253 tr->realtime_set_speed (tr->speed(), true);
1257 if (!_engine.freewheeling()) {
1258 Timecode::Time time;
1259 timecode_time_subframes (_transport_frame, time);
1260 if (!dynamic_cast<MTC_Slave*>(_slave)) {
1261 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
1265 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC4 with speed = %1\n", _transport_speed));
1266 TransportStateChange (); /* EMIT SIGNAL */
1269 /** Do any transport work in the audio thread that needs to be done after the
1270 * transport thread is finished. Audio thread, realtime safe.
1273 Session::post_transport ()
1275 PostTransportWork ptw = post_transport_work ();
1277 if (ptw & PostTransportAudition) {
1278 if (auditioner && auditioner->auditioning()) {
1279 process_function = &Session::process_audition;
1281 process_function = &Session::process_with_events;
1285 if (ptw & PostTransportStop) {
1287 transport_sub_state = 0;
1290 if (ptw & PostTransportLocate) {
1292 if (((!config.get_external_sync() && (auto_play_legal && config.get_auto_play())) && !_exporting) || (ptw & PostTransportRoll)) {
1295 transport_sub_state = 0;
1300 /* XXX is this really safe? shouldn't we just be unsetting the bits that we actually
1303 set_post_transport_work (PostTransportWork (0));
1307 Session::reset_rf_scale (framecnt_t motion)
1309 cumulative_rf_motion += motion;
1311 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1313 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1315 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1327 Session::use_sync_source (Slave* new_slave)
1329 /* Runs in process() context */
1331 bool non_rt_required = false;
1333 /* XXX this deletion is problematic because we're in RT context */
1338 DEBUG_TRACE (DEBUG::Slave, string_compose ("set new slave to %1\n", _slave));
1340 send_full_time_code (_transport_frame);
1342 boost::shared_ptr<RouteList> rl = routes.reader();
1343 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1344 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1345 if (tr && !tr->hidden()) {
1346 if (tr->realtime_set_speed (tr->speed(), true)) {
1347 non_rt_required = true;
1349 tr->set_slaved (_slave != 0);
1353 if (non_rt_required) {
1354 add_post_transport_work (PostTransportSpeed);
1355 _butler->schedule_transport_work ();
1362 Session::drop_sync_source ()
1364 request_sync_source (0);
1368 Session::switch_to_sync_source (SyncSource src)
1372 DEBUG_TRACE (DEBUG::Slave, string_compose ("Setting up sync source %1\n", enum_2_string (src)));
1376 if (_slave && dynamic_cast<MTC_Slave*>(_slave)) {
1381 new_slave = new MTC_Slave (*this, *MIDI::Manager::instance()->mtc_input_port());
1384 catch (failed_constructor& err) {
1390 if (_slave && dynamic_cast<LTC_Slave*>(_slave)) {
1395 new_slave = new LTC_Slave (*this);
1398 catch (failed_constructor& err) {
1405 if (_slave && dynamic_cast<MIDIClock_Slave*>(_slave)) {
1410 new_slave = new MIDIClock_Slave (*this, *MIDI::Manager::instance()->midi_clock_input_port(), 24);
1413 catch (failed_constructor& err) {
1419 if (_slave && dynamic_cast<JACK_Slave*>(_slave)) {
1423 if (config.get_video_pullup() != 0.0f) {
1427 new_slave = new JACK_Slave (_engine.jack());
1435 request_sync_source (new_slave);
1439 Session::set_track_speed (Track* track, double speed)
1441 if (track->realtime_set_speed (speed, false)) {
1442 add_post_transport_work (PostTransportSpeed);
1443 _butler->schedule_transport_work ();
1449 Session::unset_play_range ()
1451 _play_range = false;
1452 _clear_event_type (SessionEvent::RangeStop);
1453 _clear_event_type (SessionEvent::RangeLocate);
1457 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1461 /* Called from event-processing context */
1463 unset_play_range ();
1465 if (range.empty()) {
1466 /* _play_range set to false in unset_play_range()
1468 if (!leave_rolling) {
1469 /* stop transport */
1470 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false);
1478 /* cancel loop play */
1481 list<AudioRange>::size_type sz = range.size();
1485 list<AudioRange>::iterator i = range.begin();
1486 list<AudioRange>::iterator next;
1488 while (i != range.end()) {
1493 /* locating/stopping is subject to delays for declicking.
1496 framepos_t requested_frame = i->end;
1498 if (requested_frame > current_block_size) {
1499 requested_frame -= current_block_size;
1501 requested_frame = 0;
1504 if (next == range.end()) {
1505 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_frame, 0, 0.0f);
1507 ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_frame, (*next).start, 0.0f);
1515 } else if (sz == 1) {
1517 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
1522 /* save range so we can do auto-return etc. */
1524 current_audio_range = range;
1526 /* now start rolling at the right place */
1528 ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
1531 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC5 with speed = %1\n", _transport_speed));
1532 TransportStateChange ();
1536 Session::request_bounded_roll (framepos_t start, framepos_t end)
1538 AudioRange ar (start, end, 0);
1539 list<AudioRange> lar;
1542 request_play_range (&lar, true);
1545 Session::request_roll_at_and_return (framepos_t start, framepos_t return_to)
1547 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
1548 ev->target2_frame = start;
1553 Session::engine_halted ()
1557 /* there will be no more calls to process(), so
1558 we'd better clean up for ourselves, right now.
1560 but first, make sure the butler is out of
1565 g_atomic_int_set (&_butler->should_do_transport_work, 0);
1566 set_post_transport_work (PostTransportWork (0));
1570 realtime_stop (false, true);
1571 non_realtime_stop (false, 0, ignored);
1572 transport_sub_state = 0;
1574 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC6 with speed = %1\n", _transport_speed));
1575 TransportStateChange (); /* EMIT SIGNAL */
1580 Session::xrun_recovery ()
1582 Xrun (_transport_frame); /* EMIT SIGNAL */
1584 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1586 /* it didn't actually halt, but we need
1587 to handle things in the same way.
1595 Session::route_processors_changed (RouteProcessorChange c)
1597 if (ignore_route_processor_changes) {
1601 if (c.type == RouteProcessorChange::MeterPointChange) {
1605 update_latency_compensation ();
1612 Session::allow_auto_play (bool yn)
1614 auto_play_legal = yn;
1618 Session::reset_jack_connection (jack_client_t* jack)
1622 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1623 js->reset_client (jack);
1628 Session::maybe_stop (framepos_t limit)
1630 if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
1631 if (synced_to_jack () && config.get_jack_time_master ()) {
1632 _engine.transport_stop ();
1633 } else if (!synced_to_jack ()) {
1642 Session::send_mmc_locate (framepos_t t)
1644 if (!_engine.freewheeling()) {
1645 Timecode::Time time;
1646 timecode_time_subframes (t, time);
1647 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (time));
1651 /** Ask the transport to not send timecode until further notice. The suspension
1652 * will come into effect some finite time after this call, and timecode_transmission_suspended()
1653 * should be checked by the caller to find out when.
1656 Session::request_suspend_timecode_transmission ()
1658 SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, false);
1663 Session::request_resume_timecode_transmission ()
1665 SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, true);
1670 Session::timecode_transmission_suspended () const
1672 return g_atomic_int_get (&_suspend_timecode_transmission) == 1;