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.
26 #include "pbd/error.h"
27 #include "pbd/enumwriter.h"
28 #include "pbd/pthread_utils.h"
29 #include "pbd/memento_command.h"
31 #include "midi++/mmc.h"
32 #include "midi++/port.h"
34 #include "ardour/ardour.h"
35 #include "ardour/audio_diskstream.h"
36 #include "ardour/audioengine.h"
37 #include "ardour/auditioner.h"
38 #include "ardour/butler.h"
39 #include "ardour/debug.h"
40 #include "ardour/location.h"
41 #include "ardour/session.h"
42 #include "ardour/slave.h"
47 using namespace ARDOUR;
51 Session::add_post_transport_work (PostTransportWork ptw)
53 PostTransportWork oldval;
54 PostTransportWork newval;
58 oldval = (PostTransportWork) g_atomic_int_get (&_post_transport_work);
59 newval = PostTransportWork (oldval | ptw);
60 if (g_atomic_int_compare_and_exchange (&_post_transport_work, oldval, newval)) {
66 error << "Could not set post transport work! Crazy thread madness, call the programmers" << endmsg;
70 Session::request_input_change_handling ()
72 if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
73 SessionEvent* ev = new SessionEvent (SessionEvent::InputConfigurationChange, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
79 Session::request_sync_source (Slave* new_slave)
81 SessionEvent* ev = new SessionEvent (SessionEvent::SetSyncSource, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
84 seamless = Config->get_seamless_loop ();
86 if (dynamic_cast<JACK_Slave*>(new_slave)) {
87 /* JACK cannot support seamless looping at present */
88 Config->set_seamless_loop (false);
90 /* reset to whatever the value was before we last switched slaves */
91 Config->set_seamless_loop (_was_seamless);
94 /* save value of seamless from before the switch */
95 _was_seamless = seamless;
97 ev->slave = new_slave;
102 Session::request_transport_speed (double speed)
104 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
105 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport speed = %1\n", speed));
110 Session::request_diskstream_speed (Diskstream& ds, double speed)
112 SessionEvent* ev = new SessionEvent (SessionEvent::SetDiskstreamSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
118 Session::request_stop (bool abort, bool clear_state)
120 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0, abort, clear_state);
121 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport stop, abort = %1, clear state = %2\n", abort, clear_state));
126 Session::request_locate (nframes_t target_frame, bool with_roll)
128 SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, false);
129 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request locate to %1\n", target_frame));
134 Session::force_locate (nframes64_t target_frame, bool with_roll)
136 SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, true);
137 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request forced locate to %1\n", target_frame));
142 Session::request_play_loop (bool yn, bool leave_rolling)
145 Location *location = _locations.auto_loop_location();
147 if (location == 0 && yn) {
148 error << _("Cannot loop - no loop range defined")
153 ev = new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn);
154 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request set loop = %1, leave rolling ? %2\n", yn, leave_rolling));
157 if (!leave_rolling && !yn && Config->get_seamless_loop() && transport_rolling()) {
158 // request an immediate locate to refresh the diskstreams
159 // after disabling looping
160 request_locate (_transport_frame-1, false);
165 Session::request_play_range (list<AudioRange>* range, bool leave_rolling)
167 SessionEvent* ev = new SessionEvent (SessionEvent::SetPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0));
169 ev->audio_range = *range;
171 ev->audio_range.clear ();
173 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request play range, leave rolling ? %1\n", leave_rolling));
178 Session::realtime_stop (bool abort, bool clear_state)
180 DEBUG_TRACE (DEBUG::Transport, "realtime stop\n");
181 PostTransportWork todo = PostTransportWork (0);
183 /* assume that when we start, we'll be moving forwards */
185 // FIXME: where should this really be? [DR]
186 //send_full_time_code();
187 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
188 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
190 if (_transport_speed < 0.0f) {
191 todo = (PostTransportWork (todo | PostTransportStop | PostTransportReverse));
193 todo = PostTransportWork (todo | PostTransportStop);
196 if (actively_recording()) {
198 /* move the transport position back to where the
199 request for a stop was noticed. we rolled
200 past that point to pick up delayed input.
203 decrement_transport_position (_worst_output_latency);
205 /* the duration change is not guaranteed to have happened, but is likely */
207 todo = PostTransportWork (todo | PostTransportDuration);
211 todo = PostTransportWork (todo | PostTransportAbort);
215 todo = PostTransportWork (todo | PostTransportClearSubstate);
219 add_post_transport_work (todo);
222 _clear_event_type (SessionEvent::StopOnce);
223 _clear_event_type (SessionEvent::RangeStop);
224 _clear_event_type (SessionEvent::RangeLocate);
226 disable_record (true);
228 reset_slave_state ();
230 _transport_speed = 0;
231 _target_transport_speed = 0;
233 if (config.get_use_video_sync()) {
234 waiting_for_sync_offset = true;
237 transport_sub_state = ((!config.get_external_sync()&& config.get_auto_return()) ? AutoReturning : 0);
241 Session::butler_transport_work ()
245 PostTransportWork ptw;
246 boost::shared_ptr<RouteList> r = routes.reader ();
247 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
249 int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
251 ptw = post_transport_work();
253 DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler transport work, todo = %1\n", enum_2_string (ptw)));
255 if (ptw & PostTransportCurveRealloc) {
256 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
257 (*i)->curve_reallocate();
261 if (ptw & PostTransportInputChange) {
262 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
263 (*i)->non_realtime_input_change ();
267 if (ptw & PostTransportSpeed) {
268 non_realtime_set_speed ();
271 if (ptw & PostTransportReverse) {
274 cumulative_rf_motion = 0;
277 /* don't seek if locate will take care of that in non_realtime_stop() */
279 if (!(ptw & PostTransportLocate)) {
281 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
282 if (!(*i)->hidden()) {
283 (*i)->non_realtime_locate (_transport_frame);
285 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
286 /* new request, stop seeking, and start again */
287 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
294 if (ptw & PostTransportLocate) {
295 non_realtime_locate ();
298 if (ptw & PostTransportStop) {
299 non_realtime_stop (ptw & PostTransportAbort, on_entry, finished);
301 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
306 if (ptw & PostTransportOverWrite) {
307 non_realtime_overwrite (on_entry, finished);
309 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
314 if (ptw & PostTransportAudition) {
315 non_realtime_set_audition ();
318 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
322 Session::non_realtime_set_speed ()
324 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
326 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
327 (*i)->non_realtime_set_speed ();
332 Session::non_realtime_overwrite (int on_entry, bool& finished)
334 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
336 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
337 if ((*i)->pending_overwrite) {
338 (*i)->overwrite_existing_buffers ();
340 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
349 Session::non_realtime_locate ()
351 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
353 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
354 (*i)->non_realtime_locate (_transport_frame);
360 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
366 PostTransportWork ptw = post_transport_work();
371 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
373 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
374 if ((*i)->get_captured_frames () != 0) {
380 /* stop and locate are merged here because they share a lot of common stuff */
383 now = localtime (&xnow);
386 auditioner->cancel_audition ();
390 cumulative_rf_motion = 0;
394 begin_reversible_command ("capture");
396 Location* loc = _locations.end_location();
397 bool change_end = false;
399 if (_transport_frame < loc->end()) {
401 /* stopped recording before current end */
403 if (config.get_end_marker_is_free()) {
405 /* first capture for this session, move end back to where we are */
410 } else if (_transport_frame > loc->end()) {
412 /* stopped recording after the current end, extend it */
418 XMLNode &before = loc->get_state();
419 loc->set_end(_transport_frame);
420 XMLNode &after = loc->get_state();
421 add_command (new MementoCommand<Location>(*loc, &before, &after));
424 config.set_end_marker_is_free (false);
425 _have_captured = true;
428 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
429 (*i)->transport_stopped (*now, xnow, abort);
432 boost::shared_ptr<RouteList> r = routes.reader ();
434 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
435 if (!(*i)->is_hidden()) {
436 (*i)->set_pending_declick (0);
441 commit_reversible_command ();
444 if (_engine.running()) {
445 update_latency_compensation (true, abort);
448 bool const auto_return_enabled =
449 (!config.get_external_sync() && config.get_auto_return());
451 if (auto_return_enabled ||
452 (ptw & PostTransportLocate) ||
453 (_requested_return_frame >= 0) ||
456 if (pending_locate_flush) {
457 flush_all_inserts ();
460 if ((auto_return_enabled || synced_to_jack() || _requested_return_frame >= 0) &&
461 !(ptw & PostTransportLocate)) {
463 /* no explicit locate queued */
465 bool do_locate = false;
467 if (_requested_return_frame >= 0) {
469 /* explicit return request pre-queued in event list. overrides everything else */
471 cerr << "explicit auto-return to " << _requested_return_frame << endl;
473 _transport_frame = _requested_return_frame;
477 if (config.get_auto_return()) {
481 /* don't try to handle loop play when synced to JACK */
483 if (!synced_to_jack()) {
485 Location *location = _locations.auto_loop_location();
488 _transport_frame = location->start();
490 _transport_frame = _last_roll_location;
495 } else if (_play_range) {
497 /* return to start of range */
499 if (!current_audio_range.empty()) {
500 _transport_frame = current_audio_range.front().start;
506 /* regular auto-return */
508 _transport_frame = _last_roll_location;
514 _requested_return_frame = -1;
517 _engine.transport_locate (_transport_frame);
523 /* do this before seeking, because otherwise the Diskstreams will do the wrong thing in seamless loop mode.
526 if (ptw & PostTransportClearSubstate) {
531 /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
534 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
535 if (!(*i)->hidden()) {
536 (*i)->non_realtime_locate (_transport_frame);
538 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
540 /* we will be back */
547 send_full_time_code (0);
548 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
549 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
551 if ((ptw & PostTransportLocate) && get_record_enabled()) {
552 /* capture start has been changed, so save pending state */
553 save_state ("", true);
557 /* always try to get rid of this */
559 remove_pending_capture_state ();
561 /* save the current state of things if appropriate */
563 if (did_record && !saved) {
564 save_state (_current_snapshot_name);
567 if (ptw & PostTransportDuration) {
568 DurationChanged (); /* EMIT SIGNAL */
571 if (ptw & PostTransportStop) {
576 // can't cast away volatile so copy and emit that
577 nframes64_t tframe = _transport_frame;
578 PositionChanged (tframe); /* EMIT SIGNAL */
579 TransportStateChange (); /* EMIT SIGNAL */
581 /* and start it up again if relevant */
583 if ((ptw & PostTransportLocate) && !config.get_external_sync() && pending_locate_roll) {
584 request_transport_speed (1.0);
585 pending_locate_roll = false;
590 Session::check_declick_out ()
592 bool locate_required = transport_sub_state & PendingLocate;
594 /* this is called after a process() iteration. if PendingDeclickOut was set,
595 it means that we were waiting to declick the output (which has just been
596 done) before doing something else. this is where we do that "something else".
598 note: called from the audio thread.
601 if (transport_sub_state & PendingDeclickOut) {
603 if (locate_required) {
604 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
605 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
607 stop_transport (pending_abort);
608 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
614 Session::unset_play_loop ()
617 clear_events (SessionEvent::AutoLoop);
619 // set all diskstreams to NOT use internal looping
620 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
621 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
622 if (!(*i)->hidden()) {
629 Session::set_play_loop (bool yn)
631 /* Called from event-handling context */
635 if (yn == play_loop || (actively_recording() && yn) || (loc = _locations.auto_loop_location()) == 0) {
636 /* nothing to do, or can't change loop status while recording */
642 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
643 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
644 "Recommend changing the configured options")
657 if (Config->get_seamless_loop()) {
658 // set all diskstreams to use internal looping
659 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
660 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
661 if (!(*i)->hidden()) {
662 (*i)->set_loop (loc);
667 // set all diskstreams to NOT use internal looping
668 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
669 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
670 if (!(*i)->hidden()) {
676 /* put the loop event into the event list */
678 SessionEvent* event = new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f);
681 /* locate to start of loop and roll. If doing seamless loop, force a
682 locate+buffer refill even if we are positioned there already.
685 start_locate (loc->start(), true, true, false, Config->get_seamless_loop());
693 TransportStateChange ();
696 Session::flush_all_inserts ()
698 boost::shared_ptr<RouteList> r = routes.reader ();
700 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
701 (*i)->flush_processors ();
706 Session::start_locate (nframes64_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
708 if (synced_to_jack()) {
713 _slave->speed_and_position (sp, pos);
715 if (target_frame != pos) {
717 /* tell JACK to change transport position, and we will
718 follow along later in ::follow_slave()
721 _engine.transport_locate (target_frame);
723 if (sp != 1.0f && with_roll) {
724 _engine.transport_start ();
730 locate (target_frame, with_roll, with_flush, with_loop, force);
735 Session::micro_locate (nframes_t distance)
737 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
739 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
740 if (!(*i)->can_internal_playback_seek (distance)) {
745 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
746 (*i)->internal_playback_seek (distance);
749 _transport_frame += distance;
754 Session::locate (nframes64_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
756 if (actively_recording() && !with_loop) {
760 if (!force && _transport_frame == target_frame && !loop_changing && !with_loop) {
762 set_transport_speed (1.0, false);
764 loop_changing = false;
768 // Update Timecode time
769 // [DR] FIXME: find out exactly where this should go below
770 _transport_frame = target_frame;
771 timecode_time(_transport_frame, transmitting_timecode_time);
772 outbound_mtc_timecode_frame = _transport_frame;
773 next_quarter_frame_to_send = 0;
775 if (_transport_speed && (!with_loop || loop_changing)) {
776 /* schedule a declick. we'll be called again when its done */
778 if (!(transport_sub_state & PendingDeclickOut)) {
779 transport_sub_state |= (PendingDeclickOut|PendingLocate);
780 pending_locate_frame = target_frame;
781 pending_locate_roll = with_roll;
782 pending_locate_flush = with_flush;
787 if (transport_rolling() && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
788 realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
791 if (force || !with_loop || loop_changing) {
793 PostTransportWork todo = PostTransportLocate;
796 todo = PostTransportWork (todo | PostTransportRoll);
799 add_post_transport_work (todo);
800 _butler->schedule_transport_work ();
804 /* this is functionally what clear_clicks() does but with a tentative lock */
806 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
808 if (clickm.locked()) {
810 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
819 /* switch from input if we're going to roll */
820 if (Config->get_monitoring_model() == HardwareMonitoring) {
822 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
824 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
825 if ((*i)->record_enabled ()) {
826 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
827 (*i)->monitor_input (!config.get_auto_input());
832 /* otherwise we're going to stop, so do the opposite */
833 if (Config->get_monitoring_model() == HardwareMonitoring) {
834 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
836 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
837 if ((*i)->record_enabled ()) {
838 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
839 (*i)->monitor_input (true);
845 /* cancel looped playback if transport pos outside of loop range */
847 Location* al = _locations.auto_loop_location();
849 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
850 // cancel looping directly, this is called from event handling context
851 set_play_loop (false);
853 else if (al && _transport_frame == al->start()) {
855 // this is only necessary for seamless looping
857 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
859 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
860 if ((*i)->record_enabled ()) {
861 // tell it we've looped, so it can deal with the record state
862 (*i)->transport_looped(_transport_frame);
867 TransportLooped(); // EMIT SIGNAL
871 loop_changing = false;
873 _send_timecode_update = true;
875 Located (); /* EMIT SIGNAL */
878 /** Set the transport speed.
879 * @param speed New speed
883 Session::set_transport_speed (double speed, bool abort, bool clear_state)
885 DEBUG_TRACE (DEBUG::Transport, string_compose ("Set transport speed to %1, abort = %2 clear_state = %3, current = %4\n", speed, abort, clear_state, _transport_speed));
887 if (_transport_speed == speed) {
891 _target_transport_speed = fabs(speed);
893 /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
894 and user needs. We really need CD-style "skip" playback for ffwd and rewind.
898 speed = min (8.0, speed);
899 } else if (speed < 0) {
900 speed = max (-8.0, speed);
903 if (transport_rolling() && speed == 0.0) {
905 /* we are rolling and we want to stop */
907 if (Config->get_monitoring_model() == HardwareMonitoring)
909 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
911 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
912 if ((*i)->record_enabled ()) {
913 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
914 (*i)->monitor_input (true);
919 if (synced_to_jack ()) {
921 /* do this here because our response to the slave won't
927 _engine.transport_stop ();
929 stop_transport (abort);
932 } else if (transport_stopped() && speed == 1.0) {
934 /* we are stopped and we want to start rolling at speed 1 */
936 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
940 if (Config->get_monitoring_model() == HardwareMonitoring) {
942 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
944 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
945 if (config.get_auto_input() && (*i)->record_enabled ()) {
946 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
947 (*i)->monitor_input (false);
952 if (synced_to_jack()) {
953 _engine.transport_start ();
960 /* if not recording, don't roll forward past end if told to stop there */
962 if (!get_record_enabled() && (speed > 0.0 && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame())) {
966 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
967 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
972 if (actively_recording()) {
976 if (speed > 0.0 && _transport_frame == current_end_frame()) {
980 if (speed < 0.0 && _transport_frame == 0) {
986 /* if we are reversing relative to the current speed, or relative to the speed
987 before the last stop, then we have to do extra work.
990 PostTransportWork todo = PostTransportWork (0);
992 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
993 todo = PostTransportWork (todo | PostTransportReverse);
996 _last_transport_speed = _transport_speed;
997 _transport_speed = speed;
999 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1000 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1001 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1002 todo = PostTransportWork (todo | PostTransportSpeed);
1008 add_post_transport_work (todo);
1009 _butler->schedule_transport_work ();
1015 /** Stop the transport. */
1017 Session::stop_transport (bool abort, bool clear_state)
1019 if (_transport_speed == 0.0f) {
1023 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
1024 _worst_output_latency > current_block_size)
1027 /* we need to capture the audio that has still not yet been received by the system
1028 at the time the stop is requested, so we have to roll past that time.
1030 we want to declick before stopping, so schedule the autostop for one
1031 block before the actual end. we'll declick in the subsequent block,
1032 and then we'll really be stopped.
1035 SessionEvent *ev = new SessionEvent (SessionEvent::StopOnce, SessionEvent::Replace,
1036 _transport_frame + _worst_output_latency - current_block_size,
1040 transport_sub_state |= StopPendingCapture;
1041 pending_abort = abort;
1046 if ((transport_sub_state & PendingDeclickOut) == 0) {
1047 transport_sub_state |= PendingDeclickOut;
1048 /* we'll be called again after the declick */
1049 pending_abort = abort;
1053 realtime_stop (abort, clear_state);
1054 _butler->schedule_transport_work ();
1058 Session::start_transport ()
1060 _last_roll_location = _transport_frame;
1061 have_looped = false;
1063 /* if record status is Enabled, move it to Recording. if its
1064 already Recording, move it to Disabled.
1067 switch (record_status()) {
1069 if (!config.get_punch_in()) {
1076 disable_record (false);
1084 transport_sub_state |= PendingDeclickIn;
1086 _transport_speed = 1.0;
1087 _target_transport_speed = 1.0;
1089 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1090 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1091 (*i)->realtime_set_speed ((*i)->speed(), true);
1094 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
1096 TransportStateChange (); /* EMIT SIGNAL */
1099 /** Do any transport work in the audio thread that needs to be done after the
1100 * transport thread is finished. Audio thread, realtime safe.
1103 Session::post_transport ()
1105 PostTransportWork ptw = post_transport_work ();
1107 if (ptw & PostTransportAudition) {
1108 if (auditioner && auditioner->active()) {
1109 process_function = &Session::process_audition;
1111 process_function = &Session::process_with_events;
1115 if (ptw & PostTransportStop) {
1117 transport_sub_state = 0;
1120 if (ptw & PostTransportLocate) {
1122 if (((!config.get_external_sync() && (auto_play_legal && config.get_auto_play())) && !_exporting) || (ptw & PostTransportRoll)) {
1126 transport_sub_state = 0;
1131 /* XXX is this really safe? shouldn't we just be unsetting the bits that we actually
1134 set_post_transport_work (PostTransportWork (0));
1138 Session::reset_rf_scale (nframes_t motion)
1140 cumulative_rf_motion += motion;
1142 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1144 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1146 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1158 Session::use_sync_source (Slave* new_slave)
1160 /* Runs in process() context */
1162 bool non_rt_required = false;
1164 /* XXX this deletion is problematic because we're in RT context */
1169 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1170 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1171 if (!(*i)->hidden()) {
1172 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1173 non_rt_required = true;
1175 (*i)->set_slaved (_slave != 0);
1179 if (non_rt_required) {
1180 add_post_transport_work (PostTransportSpeed);
1181 _butler->schedule_transport_work ();
1188 Session::drop_sync_source ()
1190 request_sync_source (0);
1194 Session::switch_to_sync_source (SyncSource src)
1198 DEBUG_TRACE (DEBUG::Slave, string_compose ("Setting up sync source %1\n", enum_2_string (src)));
1202 if (_slave && dynamic_cast<MTC_Slave*>(_slave)) {
1208 new_slave = new MTC_Slave (*this, *_mtc_port);
1211 catch (failed_constructor& err) {
1216 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1222 if (_slave && dynamic_cast<MIDIClock_Slave*>(_slave)) {
1226 if (_midi_clock_port) {
1228 new_slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24);
1231 catch (failed_constructor& err) {
1236 error << _("No MIDI Clock port defined: MIDI Clock slaving is impossible.") << endmsg;
1242 if (_slave && dynamic_cast<JACK_Slave*>(_slave)) {
1246 new_slave = new JACK_Slave (_engine.jack());
1254 request_sync_source (new_slave);
1258 Session::reverse_diskstream_buffers ()
1260 add_post_transport_work (PostTransportReverse);
1261 _butler->schedule_transport_work ();
1265 Session::set_diskstream_speed (Diskstream* stream, double speed)
1267 if (stream->realtime_set_speed (speed, false)) {
1268 add_post_transport_work (PostTransportSpeed);
1269 _butler->schedule_transport_work ();
1275 Session::unset_play_range ()
1277 _play_range = false;
1278 _clear_event_type (SessionEvent::RangeStop);
1279 _clear_event_type (SessionEvent::RangeLocate);
1283 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1287 /* Called from event-processing context */
1289 unset_play_range ();
1291 if (range.empty()) {
1292 /* _play_range set to false in unset_play_range()
1294 if (!leave_rolling) {
1295 /* stop transport */
1296 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false);
1304 /* cancel loop play */
1307 list<AudioRange>::size_type sz = range.size();
1311 list<AudioRange>::iterator i = range.begin();
1312 list<AudioRange>::iterator next;
1314 while (i != range.end()) {
1319 /* locating/stopping is subject to delays for declicking.
1322 nframes_t requested_frame = (*i).end;
1324 if (requested_frame > current_block_size) {
1325 requested_frame -= current_block_size;
1327 requested_frame = 0;
1330 if (next == range.end()) {
1331 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_frame, 0, 0.0f);
1333 ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_frame, (*next).start, 0.0f);
1341 } else if (sz == 1) {
1343 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
1348 /* save range so we can do auto-return etc. */
1350 current_audio_range = range;
1352 /* now start rolling at the right place */
1354 ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
1357 TransportStateChange ();
1361 Session::request_bounded_roll (nframes_t start, nframes_t end)
1363 AudioRange ar (start, end, 0);
1364 list<AudioRange> lar;
1367 request_play_range (&lar, true);
1370 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1372 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
1373 ev->target2_frame = start;
1378 Session::engine_halted ()
1382 /* there will be no more calls to process(), so
1383 we'd better clean up for ourselves, right now.
1385 but first, make sure the butler is out of
1389 g_atomic_int_set (&_butler->should_do_transport_work, 0);
1390 set_post_transport_work (PostTransportWork (0));
1393 realtime_stop (false, true);
1394 non_realtime_stop (false, 0, ignored);
1395 transport_sub_state = 0;
1397 TransportStateChange (); /* EMIT SIGNAL */
1402 Session::xrun_recovery ()
1404 // can't cast away volatile so copy and emit that
1405 nframes64_t tframe = _transport_frame;
1406 Xrun (tframe); //EMIT SIGNAL
1408 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1410 /* it didn't actually halt, but we need
1411 to handle things in the same way.
1419 Session::route_processors_changed (RouteProcessorChange c)
1421 if (c.type == RouteProcessorChange::MeterPointChange) {
1425 update_latency_compensation (false, false);
1429 Session::update_latency_compensation (bool with_stop, bool abort)
1431 bool update_jack = false;
1432 PostTransportWork ptw;
1434 if (_state_of_the_state & Deletion) {
1438 _worst_track_latency = 0;
1439 ptw = post_transport_work();
1441 #undef DEBUG_LATENCY
1442 #ifdef DEBUG_LATENCY
1443 cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1446 boost::shared_ptr<RouteList> r = routes.reader ();
1448 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1451 (*i)->handle_transport_stopped (abort, (ptw & PostTransportLocate), (!(ptw & PostTransportLocate) || pending_locate_flush));
1454 nframes_t old_latency = (*i)->output()->signal_latency ();
1455 nframes_t track_latency = (*i)->update_total_latency ();
1457 if (old_latency != track_latency) {
1458 (*i)->input()->update_port_total_latencies ();
1459 (*i)->output()->update_port_total_latencies ();
1463 if (!(*i)->is_hidden() && ((*i)->active())) {
1464 _worst_track_latency = max (_worst_track_latency, track_latency);
1469 _engine.update_total_latencies ();
1472 #ifdef DEBUG_LATENCY
1473 cerr << "\tworst was " << _worst_track_latency << endl;
1476 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1477 (*i)->set_latency_delay (_worst_track_latency);
1480 set_worst_io_latencies ();
1482 /* reflect any changes in latencies into capture offsets
1485 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1487 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1488 (*i)->set_capture_offset ();
1493 Session::allow_auto_play (bool yn)
1495 auto_play_legal = yn;
1499 Session::reset_jack_connection (jack_client_t* jack)
1503 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1504 js->reset_client (jack);
1509 Session::maybe_stop (nframes_t limit)
1511 if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
1512 if (synced_to_jack () && config.get_jack_time_master ()) {
1513 _engine.transport_stop ();
1514 } else if (!synced_to_jack ()) {