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());
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;
624 _requested_return_frame = -1;
627 _engine.transport_locate (_transport_frame);
635 /* do this before seeking, because otherwise the tracks will do the wrong thing in seamless loop mode.
638 if (ptw & PostTransportClearSubstate) {
640 if (!Config->get_loop_is_mode()) {
645 /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
647 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: locate\n"));
648 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
649 DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler PTW: locate on %1\n", (*i)->name()));
650 (*i)->non_realtime_locate (_transport_frame);
652 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
654 /* we will be back */
661 /* don't bother with this stuff if we're disconnected from the engine,
662 because there will be no process callbacks to deliver stuff from
665 if (_engine.connected() && !_engine.freewheeling()) {
666 // need to queue this in the next RT cycle
667 _send_timecode_update = true;
669 if (!dynamic_cast<MTC_Slave*>(_slave)) {
670 _mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
672 /* This (::non_realtime_stop()) gets called by main
673 process thread, which will lead to confusion
674 when calling AsyncMIDIPort::write().
676 Something must be done. XXX
678 send_mmc_locate (_transport_frame);
682 if ((ptw & PostTransportLocate) && get_record_enabled()) {
683 /* This is scheduled by realtime_stop(), which is also done
684 * when a slave requests /locate/ for an initial sync.
685 * We can't hold up the slave for long with a save() here,
686 * without breaking its initial sync cycle.
688 * save state only if there's no slave or if it's not yet locked.
690 if (!_slave || !_slave->locked()) {
691 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: pending save\n"));
692 /* capture start has been changed, so save pending state */
693 save_state ("", true);
698 /* always try to get rid of this */
700 remove_pending_capture_state ();
702 /* save the current state of things if appropriate */
704 if (did_record && !saved) {
705 save_state (_current_snapshot_name);
708 if (ptw & PostTransportStop) {
710 if (!Config->get_loop_is_mode()) {
715 PositionChanged (_transport_frame); /* EMIT SIGNAL */
716 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC with speed = %1\n", _transport_speed));
717 TransportStateChange (); /* EMIT SIGNAL */
719 /* and start it up again if relevant */
721 if ((ptw & PostTransportLocate) && !config.get_external_sync() && pending_locate_roll) {
722 request_transport_speed (1.0);
725 /* Even if we didn't do a pending locate roll this time, we don't want it hanging
726 around for next time.
728 pending_locate_roll = false;
732 Session::check_declick_out ()
734 bool locate_required = transport_sub_state & PendingLocate;
736 /* this is called after a process() iteration. if PendingDeclickOut was set,
737 it means that we were waiting to declick the output (which has just been
738 done) before maybe doing something else. this is where we do that "something else".
740 note: called from the audio thread.
743 if (transport_sub_state & PendingDeclickOut) {
745 if (locate_required) {
746 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
747 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
749 stop_transport (pending_abort);
750 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
753 } else if (transport_sub_state & PendingLoopDeclickOut) {
754 /* Nothing else to do here; we've declicked, and the loop event will be along shortly */
755 transport_sub_state &= ~PendingLoopDeclickOut;
760 Session::unset_play_loop ()
763 clear_events (SessionEvent::AutoLoop);
764 clear_events (SessionEvent::AutoLoopDeclick);
766 // set all tracks to NOT use internal looping
767 boost::shared_ptr<RouteList> rl = routes.reader ();
768 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
769 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
770 if (tr && !tr->hidden()) {
777 Session::set_play_loop (bool yn, double speed)
779 /* Called from event-handling context */
783 if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) {
784 /* nothing to do, or can't change loop status while recording */
788 if (yn && Config->get_seamless_loop() && synced_to_engine()) {
789 warning << string_compose (
790 _("Seamless looping cannot be supported while %1 is using JACK transport.\n"
791 "Recommend changing the configured options"), PROGRAM_NAME)
804 if (Config->get_seamless_loop()) {
805 // set all tracks to use internal looping
806 boost::shared_ptr<RouteList> rl = routes.reader ();
807 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
808 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
809 if (tr && !tr->hidden()) {
815 // set all tracks to NOT use internal looping
816 boost::shared_ptr<RouteList> rl = routes.reader ();
817 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
818 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
819 if (tr && !tr->hidden()) {
825 /* Put the delick and loop events in into the event list. The declick event will
826 cause a de-clicking fade-out just before the end of the loop, and it will also result
827 in a fade-in when the loop restarts. The AutoLoop event will peform the actual loop.
832 auto_loop_declick_range (loc, dcp, dcl);
833 merge_event (new SessionEvent (SessionEvent::AutoLoopDeclick, SessionEvent::Replace, dcp, dcl, 0.0f));
834 merge_event (new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f));
836 /* if requested to roll, locate to start of loop and
837 * roll but ONLY if we're not already rolling.
839 args: positition, roll=true, flush=true, with_loop=false, force buffer refill if seamless looping
842 if (Config->get_loop_is_mode()) {
843 /* loop IS a transport mode: if already
844 rolling, do not locate to loop start.
846 if (!transport_rolling() && (speed != 0.0)) {
847 start_locate (loc->start(), true, true, false, Config->get_seamless_loop());
851 start_locate (loc->start(), true, true, false, Config->get_seamless_loop());
861 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC2 with speed = %1\n", _transport_speed));
862 TransportStateChange ();
865 Session::flush_all_inserts ()
867 boost::shared_ptr<RouteList> r = routes.reader ();
869 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
870 (*i)->flush_processors ();
875 Session::start_locate (framepos_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
877 if (synced_to_engine()) {
882 _slave->speed_and_position (sp, pos);
884 if (target_frame != pos) {
886 if (config.get_jack_time_master()) {
887 /* actually locate now, since otherwise jack_timebase_callback
888 will use the incorrect _transport_frame and report an old
889 and incorrect time to Jack transport
891 locate (target_frame, with_roll, with_flush, with_loop, force);
894 /* tell JACK to change transport position, and we will
895 follow along later in ::follow_slave()
898 _engine.transport_locate (target_frame);
900 if (sp != 1.0f && with_roll) {
901 _engine.transport_start ();
907 locate (target_frame, with_roll, with_flush, with_loop, force);
912 Session::micro_locate (framecnt_t distance)
914 boost::shared_ptr<RouteList> rl = routes.reader();
915 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
916 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
917 if (tr && !tr->can_internal_playback_seek (distance)) {
922 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
923 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
925 tr->internal_playback_seek (distance);
929 _transport_frame += distance;
933 /** @param with_mmc true to send a MMC locate command when the locate is done */
935 Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool for_seamless_loop, bool force, bool with_mmc)
937 /* Locates for seamless looping are fairly different from other
938 * locates. They assume that the diskstream buffers for each track
939 * already have the correct data in them, and thus there is no need to
940 * actually tell the tracks to locate. What does need to be done,
941 * though, is all the housekeeping that is associated with non-linear
942 * changes in the value of _transport_frame.
945 if (actively_recording() && !for_seamless_loop) {
949 if (!force && _transport_frame == target_frame && !loop_changing && !for_seamless_loop) {
951 set_transport_speed (1.0, false);
953 loop_changing = false;
954 Located (); /* EMIT SIGNAL */
958 if (_transport_speed && !for_seamless_loop) {
959 /* Schedule a declick. We'll be called again when its done.
960 We only do it this way for ordinary locates, not those
961 due to **seamless** loops.
964 if (!(transport_sub_state & PendingDeclickOut)) {
965 transport_sub_state |= (PendingDeclickOut|PendingLocate);
966 pending_locate_frame = target_frame;
967 pending_locate_roll = with_roll;
968 pending_locate_flush = with_flush;
973 // Update Timecode time
974 // [DR] FIXME: find out exactly where this should go below
975 _transport_frame = target_frame;
976 _last_roll_or_reversal_location = target_frame;
977 timecode_time(_transport_frame, transmitting_timecode_time);
978 outbound_mtc_timecode_frame = _transport_frame;
979 next_quarter_frame_to_send = 0;
981 /* do "stopped" stuff if:
984 * no autoplay in effect AND
985 * we're not going to keep rolling after the locate AND
986 * !(playing a loop with JACK sync)
990 bool transport_was_stopped = !transport_rolling();
992 if (transport_was_stopped && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_engine() && play_loop)) {
993 realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
994 transport_was_stopped = true;
996 /* otherwise tell the world that we located */
1000 if (force || !for_seamless_loop || loop_changing) {
1002 PostTransportWork todo = PostTransportLocate;
1004 if (with_roll && transport_was_stopped) {
1005 todo = PostTransportWork (todo | PostTransportRoll);
1008 add_post_transport_work (todo);
1009 _butler->schedule_transport_work ();
1013 /* this is functionally what clear_clicks() does but with a tentative lock */
1015 Glib::Threads::RWLock::WriterLock clickm (click_lock, Glib::Threads::TRY_LOCK);
1017 if (clickm.locked()) {
1019 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
1028 /* switch from input if we're going to roll */
1029 if (Config->get_monitoring_model() == HardwareMonitoring) {
1030 set_track_monitor_input_status (!config.get_auto_input());
1033 /* otherwise we're going to stop, so do the opposite */
1034 if (Config->get_monitoring_model() == HardwareMonitoring) {
1035 set_track_monitor_input_status (true);
1039 /* cancel looped playback if transport pos outside of loop range */
1042 Location* al = _locations->auto_loop_location();
1045 if (_transport_frame < al->start() || _transport_frame > al->end()) {
1047 // located outside the loop: cancel looping directly, this is called from event handling context
1049 if (!Config->get_loop_is_mode()) {
1050 set_play_loop (false, _transport_speed);
1053 } else if (_transport_frame == al->start()) {
1055 // located to start of loop - this is looping, basically
1057 if (for_seamless_loop) {
1059 // this is only necessary for seamless looping
1061 boost::shared_ptr<RouteList> rl = routes.reader();
1063 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1064 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1066 if (tr && tr->record_enabled ()) {
1067 // tell it we've looped, so it can deal with the record state
1068 tr->transport_looped (_transport_frame);
1074 TransportLooped(); // EMIT SIGNAL
1079 loop_changing = false;
1081 _send_timecode_update = true;
1084 send_mmc_locate (_transport_frame);
1087 _last_roll_location = _last_roll_or_reversal_location = _transport_frame;
1088 Located (); /* EMIT SIGNAL */
1091 /** Set the transport speed.
1092 * Called from the process thread.
1093 * @param speed New speed
1096 Session::set_transport_speed (double speed, bool abort, bool clear_state, bool as_default)
1098 DEBUG_TRACE (DEBUG::Transport, string_compose ("@ %5 Set transport speed to %1, abort = %2 clear_state = %3, current = %4 as_default %6\n",
1099 speed, abort, clear_state, _transport_speed, _transport_frame, as_default));
1101 if (_transport_speed == speed) {
1102 if (as_default && speed == 0.0) { // => reset default transport speed. hacky or what?
1103 _default_transport_speed = 1.0;
1108 if (actively_recording() && speed != 1.0 && speed != 0.0) {
1109 /* no varispeed during recording */
1110 DEBUG_TRACE (DEBUG::Transport, string_compose ("No varispeed during recording cur_speed %1, frame %2\n",
1111 _transport_speed, _transport_frame));
1115 _target_transport_speed = fabs(speed);
1117 /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
1118 and user needs. We really need CD-style "skip" playback for ffwd and rewind.
1122 speed = min (8.0, speed);
1123 } else if (speed < 0) {
1124 speed = max (-8.0, speed);
1127 if (transport_rolling() && speed == 0.0) {
1129 /* we are rolling and we want to stop */
1131 if (Config->get_monitoring_model() == HardwareMonitoring) {
1132 set_track_monitor_input_status (true);
1135 if (synced_to_engine ()) {
1137 /* do this here because our response to the slave won't
1140 _play_range = false;
1143 _engine.transport_stop ();
1145 stop_transport (abort);
1148 if (!Config->get_loop_is_mode()) {
1152 } else if (transport_stopped() && speed == 1.0) {
1154 /* we are stopped and we want to start rolling at speed 1 */
1156 if (Config->get_loop_is_mode() && play_loop) {
1158 Location *location = _locations->auto_loop_location();
1160 if (location != 0) {
1161 if (_transport_frame != location->start()) {
1162 /* jump to start and then roll from there */
1163 request_locate (location->start(), true);
1169 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1170 set_track_monitor_input_status (false);
1173 if (synced_to_engine()) {
1174 _engine.transport_start ();
1181 /* not zero, not 1.0 ... varispeed */
1183 if ((synced_to_engine()) && speed != 0.0 && speed != 1.0) {
1184 warning << string_compose (
1185 _("Global varispeed cannot be supported while %1 is connected to JACK transport control"),
1191 if (actively_recording()) {
1195 if (speed > 0.0 && _transport_frame == current_end_frame()) {
1199 if (speed < 0.0 && _transport_frame == 0) {
1205 /* if we are reversing relative to the current speed, or relative to the speed
1206 before the last stop, then we have to do extra work.
1209 PostTransportWork todo = PostTransportWork (0);
1211 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
1212 todo = PostTransportWork (todo | PostTransportReverse);
1213 _last_roll_or_reversal_location = _transport_frame;
1216 _last_transport_speed = _transport_speed;
1217 _transport_speed = speed;
1220 _default_transport_speed = speed;
1223 boost::shared_ptr<RouteList> rl = routes.reader();
1224 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1225 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1226 if (tr && tr->realtime_set_speed (tr->speed(), true)) {
1227 todo = PostTransportWork (todo | PostTransportSpeed);
1232 add_post_transport_work (todo);
1233 _butler->schedule_transport_work ();
1236 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC3 with speed = %1\n", _transport_speed));
1237 TransportStateChange (); /* EMIT SIGNAL */
1242 /** Stop the transport. */
1244 Session::stop_transport (bool abort, bool clear_state)
1246 if (_transport_speed == 0.0f) {
1250 if (actively_recording() && !(transport_sub_state & StopPendingCapture) && worst_input_latency() > current_block_size) {
1252 boost::shared_ptr<RouteList> rl = routes.reader();
1253 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1254 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1256 tr->prepare_to_stop (_transport_frame);
1260 /* we need to capture the audio that has still not yet been received by the system
1261 at the time the stop is requested, so we have to roll past that time.
1263 we want to declick before stopping, so schedule the autostop for one
1264 block before the actual end. we'll declick in the subsequent block,
1265 and then we'll really be stopped.
1268 DEBUG_TRACE (DEBUG::Transport, string_compose ("stop transport requested @ %1, scheduled for + %2 - %3 = %4, abort = %5\n",
1269 _transport_frame, _worst_input_latency, current_block_size,
1270 _transport_frame - _worst_input_latency - current_block_size,
1273 SessionEvent *ev = new SessionEvent (SessionEvent::StopOnce, SessionEvent::Replace,
1274 _transport_frame + _worst_input_latency - current_block_size,
1278 transport_sub_state |= StopPendingCapture;
1279 pending_abort = abort;
1283 if ((transport_sub_state & PendingDeclickOut) == 0) {
1285 if (!(transport_sub_state & StopPendingCapture)) {
1286 boost::shared_ptr<RouteList> rl = routes.reader();
1287 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1288 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1290 tr->prepare_to_stop (_transport_frame);
1295 transport_sub_state |= PendingDeclickOut;
1296 /* we'll be called again after the declick */
1297 pending_abort = abort;
1301 realtime_stop (abort, clear_state);
1302 _butler->schedule_transport_work ();
1305 /** Called from the process thread */
1307 Session::start_transport ()
1309 DEBUG_TRACE (DEBUG::Transport, "start_transport\n");
1311 _last_roll_location = _transport_frame;
1312 _last_roll_or_reversal_location = _transport_frame;
1314 have_looped = false;
1316 /* if record status is Enabled, move it to Recording. if its
1317 already Recording, move it to Disabled.
1320 switch (record_status()) {
1322 if (!config.get_punch_in()) {
1329 disable_record (false);
1337 transport_sub_state |= PendingDeclickIn;
1339 _transport_speed = _default_transport_speed;
1340 _target_transport_speed = _transport_speed;
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);
1346 tr->realtime_set_speed (tr->speed(), true);
1350 if (!_engine.freewheeling()) {
1351 Timecode::Time time;
1352 timecode_time_subframes (_transport_frame, time);
1353 if (!dynamic_cast<MTC_Slave*>(_slave)) {
1354 _mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
1358 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC4 with speed = %1\n", _transport_speed));
1359 TransportStateChange (); /* EMIT SIGNAL */
1362 /** Do any transport work in the audio thread that needs to be done after the
1363 * transport thread is finished. Audio thread, realtime safe.
1366 Session::post_transport ()
1368 PostTransportWork ptw = post_transport_work ();
1370 if (ptw & PostTransportAudition) {
1371 if (auditioner && auditioner->auditioning()) {
1372 process_function = &Session::process_audition;
1374 process_function = &Session::process_with_events;
1378 if (ptw & PostTransportStop) {
1380 transport_sub_state = 0;
1383 if (ptw & PostTransportLocate) {
1385 if (((!config.get_external_sync() && (auto_play_legal && config.get_auto_play())) && !_exporting) || (ptw & PostTransportRoll)) {
1388 transport_sub_state = 0;
1393 /* XXX is this really safe? shouldn't we just be unsetting the bits that we actually
1396 set_post_transport_work (PostTransportWork (0));
1400 Session::reset_rf_scale (framecnt_t motion)
1402 cumulative_rf_motion += motion;
1404 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1406 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1408 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1420 Session::use_sync_source (Slave* new_slave)
1422 /* Runs in process() context */
1424 bool non_rt_required = false;
1426 /* XXX this deletion is problematic because we're in RT context */
1431 DEBUG_TRACE (DEBUG::Slave, string_compose ("set new slave to %1\n", _slave));
1433 // need to queue this for next process() cycle
1434 _send_timecode_update = true;
1436 boost::shared_ptr<RouteList> rl = routes.reader();
1437 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1438 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1439 if (tr && !tr->hidden()) {
1440 if (tr->realtime_set_speed (tr->speed(), true)) {
1441 non_rt_required = true;
1443 tr->set_slaved (_slave != 0);
1447 if (non_rt_required) {
1448 add_post_transport_work (PostTransportSpeed);
1449 _butler->schedule_transport_work ();
1456 Session::drop_sync_source ()
1458 request_sync_source (0);
1462 Session::switch_to_sync_source (SyncSource src)
1466 DEBUG_TRACE (DEBUG::Slave, string_compose ("Setting up sync source %1\n", enum_2_string (src)));
1470 if (_slave && dynamic_cast<MTC_Slave*>(_slave)) {
1475 new_slave = new MTC_Slave (*this, *_midi_ports->mtc_input_port());
1478 catch (failed_constructor& err) {
1484 if (_slave && dynamic_cast<LTC_Slave*>(_slave)) {
1489 new_slave = new LTC_Slave (*this);
1492 catch (failed_constructor& err) {
1499 if (_slave && dynamic_cast<MIDIClock_Slave*>(_slave)) {
1504 new_slave = new MIDIClock_Slave (*this, *_midi_ports->midi_clock_input_port(), 24);
1507 catch (failed_constructor& err) {
1513 if (_slave && dynamic_cast<Engine_Slave*>(_slave)) {
1517 if (config.get_video_pullup() != 0.0f) {
1521 new_slave = new Engine_Slave (*AudioEngine::instance());
1529 request_sync_source (new_slave);
1533 Session::set_track_speed (Track* track, double speed)
1535 if (track->realtime_set_speed (speed, false)) {
1536 add_post_transport_work (PostTransportSpeed);
1537 _butler->schedule_transport_work ();
1543 Session::unset_play_range ()
1545 _play_range = false;
1546 _clear_event_type (SessionEvent::RangeStop);
1547 _clear_event_type (SessionEvent::RangeLocate);
1551 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1555 /* Called from event-processing context */
1557 unset_play_range ();
1559 if (range.empty()) {
1560 /* _play_range set to false in unset_play_range()
1562 if (!leave_rolling) {
1563 /* stop transport */
1564 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false);
1572 /* cancel loop play */
1575 list<AudioRange>::size_type sz = range.size();
1579 list<AudioRange>::iterator i = range.begin();
1580 list<AudioRange>::iterator next;
1582 while (i != range.end()) {
1587 /* locating/stopping is subject to delays for declicking.
1590 framepos_t requested_frame = i->end;
1592 if (requested_frame > current_block_size) {
1593 requested_frame -= current_block_size;
1595 requested_frame = 0;
1598 if (next == range.end()) {
1599 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_frame, 0, 0.0f);
1601 ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_frame, (*next).start, 0.0f);
1609 } else if (sz == 1) {
1611 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
1616 /* save range so we can do auto-return etc. */
1618 current_audio_range = range;
1620 /* now start rolling at the right place */
1622 ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
1625 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC5 with speed = %1\n", _transport_speed));
1626 TransportStateChange ();
1630 Session::request_bounded_roll (framepos_t start, framepos_t end)
1632 AudioRange ar (start, end, 0);
1633 list<AudioRange> lar;
1636 request_play_range (&lar, true);
1639 Session::request_roll_at_and_return (framepos_t start, framepos_t return_to)
1641 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
1642 ev->target2_frame = start;
1647 Session::engine_halted ()
1651 /* there will be no more calls to process(), so
1652 we'd better clean up for ourselves, right now.
1654 but first, make sure the butler is out of
1659 g_atomic_int_set (&_butler->should_do_transport_work, 0);
1660 set_post_transport_work (PostTransportWork (0));
1664 realtime_stop (false, true);
1665 non_realtime_stop (false, 0, ignored);
1666 transport_sub_state = 0;
1668 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC6 with speed = %1\n", _transport_speed));
1669 TransportStateChange (); /* EMIT SIGNAL */
1674 Session::xrun_recovery ()
1676 Xrun (_transport_frame); /* EMIT SIGNAL */
1678 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1680 /* it didn't actually halt, but we need
1681 to handle things in the same way.
1689 Session::route_processors_changed (RouteProcessorChange c)
1691 if (ignore_route_processor_changes) {
1695 if (c.type == RouteProcessorChange::MeterPointChange) {
1699 update_latency_compensation ();
1706 Session::allow_auto_play (bool yn)
1708 auto_play_legal = yn;
1712 Session::maybe_stop (framepos_t limit)
1714 if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
1715 if (synced_to_engine () && config.get_jack_time_master ()) {
1716 _engine.transport_stop ();
1717 } else if (!synced_to_engine ()) {
1726 Session::send_mmc_locate (framepos_t t)
1728 if (!_engine.freewheeling()) {
1729 Timecode::Time time;
1730 timecode_time_subframes (t, time);
1731 _mmc->send (MIDI::MachineControlCommand (time));
1735 /** Ask the transport to not send timecode until further notice. The suspension
1736 * will come into effect some finite time after this call, and timecode_transmission_suspended()
1737 * should be checked by the caller to find out when.
1740 Session::request_suspend_timecode_transmission ()
1742 SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, false);
1747 Session::request_resume_timecode_transmission ()
1749 SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, true);
1754 Session::timecode_transmission_suspended () const
1756 return g_atomic_int_get (&_suspend_timecode_transmission) == 1;