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/butler.h"
41 #include "ardour/click.h"
42 #include "ardour/debug.h"
43 #include "ardour/location.h"
44 #include "ardour/profile.h"
45 #include "ardour/scene_changer.h"
46 #include "ardour/session.h"
47 #include "ardour/slave.h"
48 #include "ardour/operations.h"
53 using namespace ARDOUR;
57 Session::add_post_transport_work (PostTransportWork ptw)
59 PostTransportWork oldval;
60 PostTransportWork newval;
64 oldval = (PostTransportWork) g_atomic_int_get (&_post_transport_work);
65 newval = PostTransportWork (oldval | ptw);
66 if (g_atomic_int_compare_and_exchange (&_post_transport_work, oldval, newval)) {
72 error << "Could not set post transport work! Crazy thread madness, call the programmers" << endmsg;
76 Session::request_input_change_handling ()
78 if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
79 SessionEvent* ev = new SessionEvent (SessionEvent::InputConfigurationChange, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
85 Session::request_sync_source (Slave* new_slave)
87 SessionEvent* ev = new SessionEvent (SessionEvent::SetSyncSource, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
90 seamless = Config->get_seamless_loop ();
92 if (dynamic_cast<Engine_Slave*>(new_slave)) {
93 /* JACK cannot support seamless looping at present */
94 Config->set_seamless_loop (false);
96 /* reset to whatever the value was before we last switched slaves */
97 Config->set_seamless_loop (_was_seamless);
100 /* save value of seamless from before the switch */
101 _was_seamless = seamless;
103 ev->slave = new_slave;
104 DEBUG_TRACE (DEBUG::Slave, "sent request for new slave\n");
109 Session::request_transport_speed (double speed, bool as_default)
111 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
112 ev->third_yes_or_no = true;
113 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport speed = %1 as default = %2\n", speed, as_default));
117 /** Request a new transport speed, but if the speed parameter is exactly zero then use
118 * a very small +ve value to prevent the transport actually stopping. This method should
119 * be used by callers who are varying transport speed but don't ever want to stop it.
122 Session::request_transport_speed_nonzero (double speed, bool as_default)
128 request_transport_speed (speed, as_default);
132 Session::request_track_speed (Track* tr, double speed)
134 SessionEvent* ev = new SessionEvent (SessionEvent::SetTrackSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
140 Session::request_stop (bool abort, bool clear_state)
142 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0, abort, clear_state);
143 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport stop, abort = %1, clear state = %2\n", abort, clear_state));
148 Session::request_locate (framepos_t target_frame, bool with_roll)
150 SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, false);
151 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request locate to %1\n", target_frame));
156 Session::force_locate (framepos_t target_frame, bool with_roll)
158 SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, true);
159 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request forced locate to %1\n", target_frame));
164 Session::request_play_loop (bool yn, bool change_transport_roll)
167 Location *location = _locations->auto_loop_location();
170 if (location == 0 && yn) {
171 error << _("Cannot loop - no loop range defined")
176 if (change_transport_roll) {
177 if (transport_rolling()) {
178 /* start looping at current speed */
179 target_speed = transport_speed ();
181 /* currently stopped */
183 /* start looping at normal speed */
190 /* leave the speed alone */
191 target_speed = transport_speed ();
194 ev = new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, target_speed, yn);
195 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request set loop = %1, change roll state ? %2\n", yn, change_transport_roll));
199 if (!change_transport_roll) {
200 if (!transport_rolling()) {
201 /* we're not changing transport state, but we do want
202 to set up position for the new loop. Don't
203 do this if we're rolling already.
205 request_locate (location->start(), false);
209 if (!change_transport_roll && Config->get_seamless_loop() && transport_rolling()) {
210 // request an immediate locate to refresh the tracks
211 // after disabling looping
212 request_locate (_transport_frame-1, false);
218 Session::request_play_range (list<AudioRange>* range, bool leave_rolling)
220 SessionEvent* ev = new SessionEvent (SessionEvent::SetPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0));
222 ev->audio_range = *range;
224 ev->audio_range.clear ();
226 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request play range, leave rolling ? %1\n", leave_rolling));
231 Session::request_cancel_play_range ()
233 SessionEvent* ev = new SessionEvent (SessionEvent::CancelPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, 0);
239 Session::realtime_stop (bool abort, bool clear_state)
241 DEBUG_TRACE (DEBUG::Transport, string_compose ("realtime stop @ %1\n", _transport_frame));
242 PostTransportWork todo = PostTransportWork (0);
244 /* assume that when we start, we'll be moving forwards */
246 if (_transport_speed < 0.0f) {
247 todo = (PostTransportWork (todo | PostTransportStop | PostTransportReverse));
248 _default_transport_speed = 1.0;
250 todo = PostTransportWork (todo | PostTransportStop);
255 boost::shared_ptr<RouteList> r = routes.reader ();
257 for (RouteList::iterator i = r->begin (); i != r->end(); ++i) {
258 (*i)->realtime_handle_transport_stopped ();
261 if (actively_recording()) {
263 /* move the transport position back to where the
264 request for a stop was noticed. we rolled
265 past that point to pick up delayed input (and/or to delick)
268 if (worst_playback_latency() > current_block_size) {
269 /* we rolled past the stop point to pick up data that had
270 not yet arrived. move back to where the stop occured.
272 decrement_transport_position (current_block_size + (worst_input_latency() - current_block_size));
274 decrement_transport_position (current_block_size);
277 /* the duration change is not guaranteed to have happened, but is likely */
279 todo = PostTransportWork (todo | PostTransportDuration);
283 todo = PostTransportWork (todo | PostTransportAbort);
287 todo = PostTransportWork (todo | PostTransportClearSubstate);
291 add_post_transport_work (todo);
294 _clear_event_type (SessionEvent::StopOnce);
295 _clear_event_type (SessionEvent::RangeStop);
296 _clear_event_type (SessionEvent::RangeLocate);
298 /* if we're going to clear loop state, then force disabling record BUT only if we're not doing latched rec-enable */
299 disable_record (true, (!Config->get_latched_record_enable() && clear_state));
301 reset_slave_state ();
303 _transport_speed = 0;
304 _target_transport_speed = 0;
306 g_atomic_int_set (&_playback_load, 100);
307 g_atomic_int_set (&_capture_load, 100);
309 if (config.get_use_video_sync()) {
310 waiting_for_sync_offset = true;
313 transport_sub_state = 0;
317 Session::realtime_locate ()
319 boost::shared_ptr<RouteList> r = routes.reader ();
320 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
321 (*i)->realtime_locate ();
326 Session::butler_transport_work ()
330 PostTransportWork ptw;
331 boost::shared_ptr<RouteList> r = routes.reader ();
333 int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
335 ptw = post_transport_work();
337 DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler transport work, todo = %1\n", enum_2_string (ptw)));
339 if (ptw & PostTransportAdjustPlaybackBuffering) {
340 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
341 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
343 tr->adjust_playback_buffering ();
344 /* and refill those buffers ... */
346 (*i)->non_realtime_locate (_transport_frame);
351 if (ptw & PostTransportAdjustCaptureBuffering) {
352 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
353 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
355 tr->adjust_capture_buffering ();
360 if (ptw & PostTransportCurveRealloc) {
361 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
362 (*i)->curve_reallocate();
366 if (ptw & PostTransportInputChange) {
367 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
368 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
370 tr->non_realtime_input_change ();
375 if (ptw & PostTransportSpeed) {
376 non_realtime_set_speed ();
379 if (ptw & PostTransportReverse) {
382 cumulative_rf_motion = 0;
385 /* don't seek if locate will take care of that in non_realtime_stop() */
387 if (!(ptw & PostTransportLocate)) {
389 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
390 (*i)->non_realtime_locate (_transport_frame);
392 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
393 /* new request, stop seeking, and start again */
394 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
401 if (ptw & PostTransportLocate) {
402 non_realtime_locate ();
405 if (ptw & PostTransportStop) {
406 non_realtime_stop (ptw & PostTransportAbort, on_entry, finished);
408 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
413 if (ptw & PostTransportOverWrite) {
414 non_realtime_overwrite (on_entry, finished);
416 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
421 if (ptw & PostTransportAudition) {
422 non_realtime_set_audition ();
425 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
427 DEBUG_TRACE (DEBUG::Transport, X_("Butler transport work all done\n"));
428 DEBUG_TRACE (DEBUG::Transport, X_(string_compose ("Frame %1\n", _transport_frame)));
432 Session::non_realtime_set_speed ()
434 boost::shared_ptr<RouteList> rl = routes.reader();
435 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
436 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
438 tr->non_realtime_set_speed ();
444 Session::non_realtime_overwrite (int on_entry, bool& finished)
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->pending_overwrite ()) {
450 tr->overwrite_existing_buffers ();
452 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
461 Session::non_realtime_locate ()
463 boost::shared_ptr<RouteList> rl = routes.reader();
464 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
465 (*i)->non_realtime_locate (_transport_frame);
468 _scene_changer->locate (_transport_frame);
470 /* XXX: it would be nice to generate the new clicks here (in the non-RT thread)
471 rather than clearing them so that the RT thread has to spend time constructing
472 them (in Session::click).
479 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
485 PostTransportWork ptw = post_transport_work();
490 boost::shared_ptr<RouteList> rl = routes.reader();
491 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
492 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
493 if (tr && tr->get_captured_frames () != 0) {
499 /* stop and locate are merged here because they share a lot of common stuff */
502 now = localtime (&xnow);
505 auditioner->cancel_audition ();
508 cumulative_rf_motion = 0;
512 begin_reversible_command (Operations::capture);
513 _have_captured = true;
516 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: DS stop\n"));
518 if (abort && did_record) {
519 /* no reason to save the session file when we remove sources
521 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
524 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
525 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
527 tr->transport_stopped_wallclock (*now, xnow, abort);
531 if (abort && did_record) {
532 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
535 boost::shared_ptr<RouteList> r = routes.reader ();
537 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
538 if (!(*i)->is_auditioner()) {
539 (*i)->set_pending_declick (0);
544 commit_reversible_command ();
545 /* increase take name */
546 if (config.get_track_name_take () && !config.get_take_name ().empty()) {
547 string newname = config.get_take_name();
548 config.set_take_name(bump_name_number (newname));
552 if (_engine.running()) {
553 PostTransportWork ptw = post_transport_work ();
554 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
555 (*i)->nonrealtime_handle_transport_stopped (abort, (ptw & PostTransportLocate), (!(ptw & PostTransportLocate) || pending_locate_flush));
557 update_latency_compensation ();
560 bool const auto_return_enabled =
561 (!config.get_external_sync() && (config.get_auto_return() || abort));
563 if (auto_return_enabled ||
564 (ptw & PostTransportLocate) ||
565 (_requested_return_frame >= 0) ||
566 synced_to_engine()) {
568 if (pending_locate_flush) {
569 flush_all_inserts ();
572 if ((auto_return_enabled || synced_to_engine() || _requested_return_frame >= 0) &&
573 !(ptw & PostTransportLocate)) {
575 /* no explicit locate queued */
577 bool do_locate = false;
579 if (_requested_return_frame >= 0) {
581 /* explicit return request pre-queued in event list. overrides everything else */
583 _transport_frame = _requested_return_frame;
587 if (config.get_auto_return()) {
591 /* don't try to handle loop play when synced to JACK */
593 if (!synced_to_engine()) {
595 Location *location = _locations->auto_loop_location();
598 _transport_frame = location->start();
600 _transport_frame = _last_roll_location;
605 } else if (_play_range) {
607 /* return to start of range */
609 if (!current_audio_range.empty()) {
610 _transport_frame = current_audio_range.front().start;
616 /* regular auto-return */
618 _transport_frame = _last_roll_location;
623 _transport_frame = _last_roll_location;
628 _requested_return_frame = -1;
631 _engine.transport_locate (_transport_frame);
639 /* do this before seeking, because otherwise the tracks will do the wrong thing in seamless loop mode.
642 if (ptw & PostTransportClearSubstate) {
644 if (!Config->get_loop_is_mode()) {
649 /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
651 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: locate\n"));
652 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
653 DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler PTW: locate on %1\n", (*i)->name()));
654 (*i)->non_realtime_locate (_transport_frame);
656 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
658 /* we will be back */
665 /* don't bother with this stuff if we're disconnected from the engine,
666 because there will be no process callbacks to deliver stuff from
669 if (_engine.connected() && !_engine.freewheeling()) {
670 // need to queue this in the next RT cycle
671 _send_timecode_update = true;
673 if (!dynamic_cast<MTC_Slave*>(_slave)) {
674 _mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
676 /* This (::non_realtime_stop()) gets called by main
677 process thread, which will lead to confusion
678 when calling AsyncMIDIPort::write().
680 Something must be done. XXX
682 send_mmc_locate (_transport_frame);
686 if ((ptw & PostTransportLocate) && get_record_enabled()) {
687 /* This is scheduled by realtime_stop(), which is also done
688 * when a slave requests /locate/ for an initial sync.
689 * We can't hold up the slave for long with a save() here,
690 * without breaking its initial sync cycle.
692 * save state only if there's no slave or if it's not yet locked.
694 if (!_slave || !_slave->locked()) {
695 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: pending save\n"));
696 /* capture start has been changed, so save pending state */
697 save_state ("", true);
702 /* always try to get rid of this */
704 remove_pending_capture_state ();
706 /* save the current state of things if appropriate */
708 if (did_record && !saved) {
709 save_state (_current_snapshot_name);
712 if (ptw & PostTransportStop) {
714 if (!Config->get_loop_is_mode()) {
719 PositionChanged (_transport_frame); /* EMIT SIGNAL */
720 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC with speed = %1\n", _transport_speed));
721 TransportStateChange (); /* EMIT SIGNAL */
723 /* and start it up again if relevant */
725 if ((ptw & PostTransportLocate) && !config.get_external_sync() && pending_locate_roll) {
726 request_transport_speed (1.0);
729 /* Even if we didn't do a pending locate roll this time, we don't want it hanging
730 around for next time.
732 pending_locate_roll = false;
736 Session::check_declick_out ()
738 bool locate_required = transport_sub_state & PendingLocate;
740 /* this is called after a process() iteration. if PendingDeclickOut was set,
741 it means that we were waiting to declick the output (which has just been
742 done) before maybe doing something else. this is where we do that "something else".
744 note: called from the audio thread.
747 if (transport_sub_state & PendingDeclickOut) {
749 if (locate_required) {
750 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
751 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
753 stop_transport (pending_abort);
754 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
757 } else if (transport_sub_state & PendingLoopDeclickOut) {
758 /* Nothing else to do here; we've declicked, and the loop event will be along shortly */
759 transport_sub_state &= ~PendingLoopDeclickOut;
764 Session::unset_play_loop ()
767 clear_events (SessionEvent::AutoLoop);
768 clear_events (SessionEvent::AutoLoopDeclick);
770 // set all tracks to NOT use internal looping
771 boost::shared_ptr<RouteList> rl = routes.reader ();
772 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
773 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
774 if (tr && !tr->hidden()) {
781 Session::set_play_loop (bool yn, double speed)
783 /* Called from event-handling context */
787 if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) {
788 /* nothing to do, or can't change loop status while recording */
792 if (yn && Config->get_seamless_loop() && synced_to_engine()) {
793 warning << string_compose (
794 _("Seamless looping cannot be supported while %1 is using JACK transport.\n"
795 "Recommend changing the configured options"), PROGRAM_NAME)
808 if (Config->get_seamless_loop()) {
809 // set all tracks to use internal looping
810 boost::shared_ptr<RouteList> rl = routes.reader ();
811 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
812 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
813 if (tr && !tr->hidden()) {
819 // set all tracks to NOT use internal looping
820 boost::shared_ptr<RouteList> rl = routes.reader ();
821 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
822 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
823 if (tr && !tr->hidden()) {
829 /* Put the delick and loop events in into the event list. The declick event will
830 cause a de-clicking fade-out just before the end of the loop, and it will also result
831 in a fade-in when the loop restarts. The AutoLoop event will peform the actual loop.
836 auto_loop_declick_range (loc, dcp, dcl);
837 merge_event (new SessionEvent (SessionEvent::AutoLoopDeclick, SessionEvent::Replace, dcp, dcl, 0.0f));
838 merge_event (new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f));
840 /* if requested to roll, locate to start of loop and
841 * roll but ONLY if we're not already rolling.
843 args: positition, roll=true, flush=true, with_loop=false, force buffer refill if seamless looping
846 if (Config->get_loop_is_mode()) {
847 /* loop IS a transport mode: if already
848 rolling, do not locate to loop start.
850 if (!transport_rolling() && (speed != 0.0)) {
851 start_locate (loc->start(), true, true, false, Config->get_seamless_loop());
855 start_locate (loc->start(), true, true, false, Config->get_seamless_loop());
865 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC2 with speed = %1\n", _transport_speed));
866 TransportStateChange ();
869 Session::flush_all_inserts ()
871 boost::shared_ptr<RouteList> r = routes.reader ();
873 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
874 (*i)->flush_processors ();
879 Session::start_locate (framepos_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
881 if (synced_to_engine()) {
886 _slave->speed_and_position (sp, pos);
888 if (target_frame != pos) {
890 if (config.get_jack_time_master()) {
891 /* actually locate now, since otherwise jack_timebase_callback
892 will use the incorrect _transport_frame and report an old
893 and incorrect time to Jack transport
895 locate (target_frame, with_roll, with_flush, with_loop, force);
898 /* tell JACK to change transport position, and we will
899 follow along later in ::follow_slave()
902 _engine.transport_locate (target_frame);
904 if (sp != 1.0f && with_roll) {
905 _engine.transport_start ();
911 locate (target_frame, with_roll, with_flush, with_loop, force);
916 Session::micro_locate (framecnt_t distance)
918 boost::shared_ptr<RouteList> rl = routes.reader();
919 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
920 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
921 if (tr && !tr->can_internal_playback_seek (distance)) {
926 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
927 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
929 tr->internal_playback_seek (distance);
933 _transport_frame += distance;
937 /** @param with_mmc true to send a MMC locate command when the locate is done */
939 Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool for_seamless_loop, bool force, bool with_mmc)
941 /* Locates for seamless looping are fairly different from other
942 * locates. They assume that the diskstream buffers for each track
943 * already have the correct data in them, and thus there is no need to
944 * actually tell the tracks to locate. What does need to be done,
945 * though, is all the housekeeping that is associated with non-linear
946 * changes in the value of _transport_frame.
949 if (actively_recording() && !for_seamless_loop) {
953 if (!force && _transport_frame == target_frame && !loop_changing && !for_seamless_loop) {
955 set_transport_speed (1.0, false);
957 loop_changing = false;
958 Located (); /* EMIT SIGNAL */
962 if (_transport_speed && !for_seamless_loop) {
963 /* Schedule a declick. We'll be called again when its done.
964 We only do it this way for ordinary locates, not those
965 due to **seamless** loops.
968 if (!(transport_sub_state & PendingDeclickOut)) {
969 transport_sub_state |= (PendingDeclickOut|PendingLocate);
970 pending_locate_frame = target_frame;
971 pending_locate_roll = with_roll;
972 pending_locate_flush = with_flush;
977 // Update Timecode time
978 // [DR] FIXME: find out exactly where this should go below
979 _transport_frame = target_frame;
980 _last_roll_or_reversal_location = target_frame;
981 timecode_time(_transport_frame, transmitting_timecode_time);
982 outbound_mtc_timecode_frame = _transport_frame;
983 next_quarter_frame_to_send = 0;
985 /* do "stopped" stuff if:
988 * no autoplay in effect AND
989 * we're not going to keep rolling after the locate AND
990 * !(playing a loop with JACK sync)
994 bool transport_was_stopped = !transport_rolling();
996 if (transport_was_stopped && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_engine() && play_loop)) {
997 realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
998 transport_was_stopped = true;
1000 /* otherwise tell the world that we located */
1004 if (force || !for_seamless_loop || loop_changing) {
1006 PostTransportWork todo = PostTransportLocate;
1008 if (with_roll && transport_was_stopped) {
1009 todo = PostTransportWork (todo | PostTransportRoll);
1012 add_post_transport_work (todo);
1013 _butler->schedule_transport_work ();
1017 /* this is functionally what clear_clicks() does but with a tentative lock */
1019 Glib::Threads::RWLock::WriterLock clickm (click_lock, Glib::Threads::TRY_LOCK);
1021 if (clickm.locked()) {
1023 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
1032 /* switch from input if we're going to roll */
1033 if (Config->get_monitoring_model() == HardwareMonitoring) {
1034 set_track_monitor_input_status (!config.get_auto_input());
1037 /* otherwise we're going to stop, so do the opposite */
1038 if (Config->get_monitoring_model() == HardwareMonitoring) {
1039 set_track_monitor_input_status (true);
1043 /* cancel looped playback if transport pos outside of loop range */
1046 Location* al = _locations->auto_loop_location();
1049 if (_transport_frame < al->start() || _transport_frame > al->end()) {
1051 // located outside the loop: cancel looping directly, this is called from event handling context
1053 if (!Config->get_loop_is_mode()) {
1054 set_play_loop (false, _transport_speed);
1057 } else if (_transport_frame == al->start()) {
1059 // located to start of loop - this is looping, basically
1061 if (for_seamless_loop) {
1063 // this is only necessary for seamless looping
1065 boost::shared_ptr<RouteList> rl = routes.reader();
1067 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1068 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1070 if (tr && tr->record_enabled ()) {
1071 // tell it we've looped, so it can deal with the record state
1072 tr->transport_looped (_transport_frame);
1078 TransportLooped(); // EMIT SIGNAL
1083 loop_changing = false;
1085 _send_timecode_update = true;
1088 send_mmc_locate (_transport_frame);
1091 _last_roll_location = _last_roll_or_reversal_location = _transport_frame;
1092 Located (); /* EMIT SIGNAL */
1095 /** Set the transport speed.
1096 * Called from the process thread.
1097 * @param speed New speed
1100 Session::set_transport_speed (double speed, bool abort, bool clear_state, bool as_default)
1102 DEBUG_TRACE (DEBUG::Transport, string_compose ("@ %5 Set transport speed to %1, abort = %2 clear_state = %3, current = %4 as_default %6\n",
1103 speed, abort, clear_state, _transport_speed, _transport_frame, as_default));
1105 if (_transport_speed == speed) {
1106 if (as_default && speed == 0.0) { // => reset default transport speed. hacky or what?
1107 _default_transport_speed = 1.0;
1112 if (actively_recording() && speed != 1.0 && speed != 0.0) {
1113 /* no varispeed during recording */
1114 DEBUG_TRACE (DEBUG::Transport, string_compose ("No varispeed during recording cur_speed %1, frame %2\n",
1115 _transport_speed, _transport_frame));
1119 _target_transport_speed = fabs(speed);
1121 /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
1122 and user needs. We really need CD-style "skip" playback for ffwd and rewind.
1126 speed = min (8.0, speed);
1127 } else if (speed < 0) {
1128 speed = max (-8.0, speed);
1131 if (transport_rolling() && speed == 0.0) {
1133 /* we are rolling and we want to stop */
1135 if (Config->get_monitoring_model() == HardwareMonitoring) {
1136 set_track_monitor_input_status (true);
1139 if (synced_to_engine ()) {
1141 /* do this here because our response to the slave won't
1144 _play_range = false;
1147 _engine.transport_stop ();
1149 stop_transport (abort);
1152 if (!Config->get_loop_is_mode()) {
1156 } else if (transport_stopped() && speed == 1.0) {
1158 /* we are stopped and we want to start rolling at speed 1 */
1160 if (Config->get_loop_is_mode() && play_loop) {
1162 Location *location = _locations->auto_loop_location();
1164 if (location != 0) {
1165 if (_transport_frame != location->start()) {
1166 /* jump to start and then roll from there */
1167 request_locate (location->start(), true);
1173 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1174 set_track_monitor_input_status (false);
1177 if (synced_to_engine()) {
1178 _engine.transport_start ();
1185 /* not zero, not 1.0 ... varispeed */
1187 if ((synced_to_engine()) && speed != 0.0 && speed != 1.0) {
1188 warning << string_compose (
1189 _("Global varispeed cannot be supported while %1 is connected to JACK transport control"),
1195 if (actively_recording()) {
1199 if (speed > 0.0 && _transport_frame == current_end_frame()) {
1203 if (speed < 0.0 && _transport_frame == 0) {
1209 /* if we are reversing relative to the current speed, or relative to the speed
1210 before the last stop, then we have to do extra work.
1213 PostTransportWork todo = PostTransportWork (0);
1215 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
1216 todo = PostTransportWork (todo | PostTransportReverse);
1217 _last_roll_or_reversal_location = _transport_frame;
1220 _last_transport_speed = _transport_speed;
1221 _transport_speed = speed;
1224 _default_transport_speed = speed;
1227 boost::shared_ptr<RouteList> rl = routes.reader();
1228 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1229 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1230 if (tr && tr->realtime_set_speed (tr->speed(), true)) {
1231 todo = PostTransportWork (todo | PostTransportSpeed);
1236 add_post_transport_work (todo);
1237 _butler->schedule_transport_work ();
1240 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC3 with speed = %1\n", _transport_speed));
1241 TransportStateChange (); /* EMIT SIGNAL */
1246 /** Stop the transport. */
1248 Session::stop_transport (bool abort, bool clear_state)
1250 if (_transport_speed == 0.0f) {
1254 if (actively_recording() && !(transport_sub_state & StopPendingCapture) && worst_input_latency() > current_block_size) {
1256 boost::shared_ptr<RouteList> rl = routes.reader();
1257 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1258 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1260 tr->prepare_to_stop (_transport_frame);
1264 /* we need to capture the audio that has still not yet been received by the system
1265 at the time the stop is requested, so we have to roll past that time.
1267 we want to declick before stopping, so schedule the autostop for one
1268 block before the actual end. we'll declick in the subsequent block,
1269 and then we'll really be stopped.
1272 DEBUG_TRACE (DEBUG::Transport, string_compose ("stop transport requested @ %1, scheduled for + %2 - %3 = %4, abort = %5\n",
1273 _transport_frame, _worst_input_latency, current_block_size,
1274 _transport_frame - _worst_input_latency - current_block_size,
1277 SessionEvent *ev = new SessionEvent (SessionEvent::StopOnce, SessionEvent::Replace,
1278 _transport_frame + _worst_input_latency - current_block_size,
1282 transport_sub_state |= StopPendingCapture;
1283 pending_abort = abort;
1287 if ((transport_sub_state & PendingDeclickOut) == 0) {
1289 if (!(transport_sub_state & StopPendingCapture)) {
1290 boost::shared_ptr<RouteList> rl = routes.reader();
1291 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1292 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1294 tr->prepare_to_stop (_transport_frame);
1299 transport_sub_state |= PendingDeclickOut;
1300 /* we'll be called again after the declick */
1301 pending_abort = abort;
1305 realtime_stop (abort, clear_state);
1306 _butler->schedule_transport_work ();
1309 /** Called from the process thread */
1311 Session::start_transport ()
1313 DEBUG_TRACE (DEBUG::Transport, "start_transport\n");
1315 _last_roll_location = _transport_frame;
1316 _last_roll_or_reversal_location = _transport_frame;
1318 have_looped = false;
1320 /* if record status is Enabled, move it to Recording. if its
1321 already Recording, move it to Disabled.
1324 switch (record_status()) {
1326 if (!config.get_punch_in()) {
1333 disable_record (false);
1341 transport_sub_state |= PendingDeclickIn;
1343 _transport_speed = _default_transport_speed;
1344 _target_transport_speed = _transport_speed;
1346 boost::shared_ptr<RouteList> rl = routes.reader();
1347 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1348 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1350 tr->realtime_set_speed (tr->speed(), true);
1354 if (!_engine.freewheeling()) {
1355 Timecode::Time time;
1356 timecode_time_subframes (_transport_frame, time);
1357 if (!dynamic_cast<MTC_Slave*>(_slave)) {
1358 _mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
1362 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC4 with speed = %1\n", _transport_speed));
1363 TransportStateChange (); /* EMIT SIGNAL */
1366 /** Do any transport work in the audio thread that needs to be done after the
1367 * transport thread is finished. Audio thread, realtime safe.
1370 Session::post_transport ()
1372 PostTransportWork ptw = post_transport_work ();
1374 if (ptw & PostTransportAudition) {
1375 if (auditioner && auditioner->auditioning()) {
1376 process_function = &Session::process_audition;
1378 process_function = &Session::process_with_events;
1382 if (ptw & PostTransportStop) {
1384 transport_sub_state = 0;
1387 if (ptw & PostTransportLocate) {
1389 if (((!config.get_external_sync() && (auto_play_legal && config.get_auto_play())) && !_exporting) || (ptw & PostTransportRoll)) {
1392 transport_sub_state = 0;
1397 /* XXX is this really safe? shouldn't we just be unsetting the bits that we actually
1400 set_post_transport_work (PostTransportWork (0));
1404 Session::reset_rf_scale (framecnt_t motion)
1406 cumulative_rf_motion += motion;
1408 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1410 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1412 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1424 Session::use_sync_source (Slave* new_slave)
1426 /* Runs in process() context */
1428 bool non_rt_required = false;
1430 /* XXX this deletion is problematic because we're in RT context */
1435 DEBUG_TRACE (DEBUG::Slave, string_compose ("set new slave to %1\n", _slave));
1437 // need to queue this for next process() cycle
1438 _send_timecode_update = true;
1440 boost::shared_ptr<RouteList> rl = routes.reader();
1441 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1442 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1443 if (tr && !tr->hidden()) {
1444 if (tr->realtime_set_speed (tr->speed(), true)) {
1445 non_rt_required = true;
1447 tr->set_slaved (_slave != 0);
1451 if (non_rt_required) {
1452 add_post_transport_work (PostTransportSpeed);
1453 _butler->schedule_transport_work ();
1460 Session::drop_sync_source ()
1462 request_sync_source (0);
1466 Session::switch_to_sync_source (SyncSource src)
1470 DEBUG_TRACE (DEBUG::Slave, string_compose ("Setting up sync source %1\n", enum_2_string (src)));
1474 if (_slave && dynamic_cast<MTC_Slave*>(_slave)) {
1479 new_slave = new MTC_Slave (*this, *_midi_ports->mtc_input_port());
1482 catch (failed_constructor& err) {
1488 if (_slave && dynamic_cast<LTC_Slave*>(_slave)) {
1493 new_slave = new LTC_Slave (*this);
1496 catch (failed_constructor& err) {
1503 if (_slave && dynamic_cast<MIDIClock_Slave*>(_slave)) {
1508 new_slave = new MIDIClock_Slave (*this, *_midi_ports->midi_clock_input_port(), 24);
1511 catch (failed_constructor& err) {
1517 if (_slave && dynamic_cast<Engine_Slave*>(_slave)) {
1521 if (config.get_video_pullup() != 0.0f) {
1525 new_slave = new Engine_Slave (*AudioEngine::instance());
1533 request_sync_source (new_slave);
1537 Session::set_track_speed (Track* track, double speed)
1539 if (track->realtime_set_speed (speed, false)) {
1540 add_post_transport_work (PostTransportSpeed);
1541 _butler->schedule_transport_work ();
1547 Session::unset_play_range ()
1549 _play_range = false;
1550 _clear_event_type (SessionEvent::RangeStop);
1551 _clear_event_type (SessionEvent::RangeLocate);
1555 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1559 /* Called from event-processing context */
1561 unset_play_range ();
1563 if (range.empty()) {
1564 /* _play_range set to false in unset_play_range()
1566 if (!leave_rolling) {
1567 /* stop transport */
1568 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false);
1576 /* cancel loop play */
1579 list<AudioRange>::size_type sz = range.size();
1583 list<AudioRange>::iterator i = range.begin();
1584 list<AudioRange>::iterator next;
1586 while (i != range.end()) {
1591 /* locating/stopping is subject to delays for declicking.
1594 framepos_t requested_frame = i->end;
1596 if (requested_frame > current_block_size) {
1597 requested_frame -= current_block_size;
1599 requested_frame = 0;
1602 if (next == range.end()) {
1603 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_frame, 0, 0.0f);
1605 ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_frame, (*next).start, 0.0f);
1613 } else if (sz == 1) {
1615 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
1620 /* save range so we can do auto-return etc. */
1622 current_audio_range = range;
1624 /* now start rolling at the right place */
1626 ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
1629 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC5 with speed = %1\n", _transport_speed));
1630 TransportStateChange ();
1634 Session::request_bounded_roll (framepos_t start, framepos_t end)
1636 AudioRange ar (start, end, 0);
1637 list<AudioRange> lar;
1640 request_play_range (&lar, true);
1644 Session::set_requested_return_frame (framepos_t return_to)
1646 _requested_return_frame = return_to;
1650 Session::request_roll_at_and_return (framepos_t start, framepos_t return_to)
1652 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
1653 ev->target2_frame = start;
1658 Session::engine_halted ()
1662 /* there will be no more calls to process(), so
1663 we'd better clean up for ourselves, right now.
1665 but first, make sure the butler is out of
1670 g_atomic_int_set (&_butler->should_do_transport_work, 0);
1671 set_post_transport_work (PostTransportWork (0));
1675 realtime_stop (false, true);
1676 non_realtime_stop (false, 0, ignored);
1677 transport_sub_state = 0;
1679 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC6 with speed = %1\n", _transport_speed));
1680 TransportStateChange (); /* EMIT SIGNAL */
1685 Session::xrun_recovery ()
1687 Xrun (_transport_frame); /* EMIT SIGNAL */
1689 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1691 /* it didn't actually halt, but we need
1692 to handle things in the same way.
1700 Session::route_processors_changed (RouteProcessorChange c)
1702 if (ignore_route_processor_changes) {
1706 if (c.type == RouteProcessorChange::MeterPointChange) {
1710 update_latency_compensation ();
1717 Session::allow_auto_play (bool yn)
1719 auto_play_legal = yn;
1723 Session::maybe_stop (framepos_t limit)
1725 if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
1726 if (synced_to_engine () && config.get_jack_time_master ()) {
1727 _engine.transport_stop ();
1728 } else if (!synced_to_engine ()) {
1737 Session::send_mmc_locate (framepos_t t)
1739 if (!_engine.freewheeling()) {
1740 Timecode::Time time;
1741 timecode_time_subframes (t, time);
1742 _mmc->send (MIDI::MachineControlCommand (time));
1746 /** Ask the transport to not send timecode until further notice. The suspension
1747 * will come into effect some finite time after this call, and timecode_transmission_suspended()
1748 * should be checked by the caller to find out when.
1751 Session::request_suspend_timecode_transmission ()
1753 SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, false);
1758 Session::request_resume_timecode_transmission ()
1760 SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, true);
1765 Session::timecode_transmission_suspended () const
1767 return g_atomic_int_get (&_suspend_timecode_transmission) == 1;