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.
24 #include <sigc++/bind.h>
25 #include <sigc++/retype.h>
28 #include "pbd/error.h"
29 #include "pbd/enumwriter.h"
30 #include "pbd/pthread_utils.h"
31 #include "pbd/memento_command.h"
33 #include "midi++/mmc.h"
34 #include "midi++/port.h"
36 #include "ardour/ardour.h"
37 #include "ardour/audio_diskstream.h"
38 #include "ardour/audioengine.h"
39 #include "ardour/auditioner.h"
40 #include "ardour/butler.h"
41 #include "ardour/debug.h"
42 #include "ardour/location.h"
43 #include "ardour/session.h"
44 #include "ardour/slave.h"
49 using namespace ARDOUR;
53 Session::add_post_transport_work (PostTransportWork ptw)
55 PostTransportWork oldval;
56 PostTransportWork newval;
60 oldval = (PostTransportWork) g_atomic_int_get (&_post_transport_work);
61 newval = PostTransportWork (oldval | ptw);
62 if (g_atomic_int_compare_and_exchange (&_post_transport_work, oldval, newval)) {
68 error << "Could not set post transport work! Crazy thread madness, call the programmers" << endmsg;
72 Session::request_input_change_handling ()
74 if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
75 SessionEvent* ev = new SessionEvent (SessionEvent::InputConfigurationChange, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
81 Session::request_sync_source (Slave* new_slave)
83 SessionEvent* ev = new SessionEvent (SessionEvent::SetSyncSource, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
86 seamless = Config->get_seamless_loop ();
88 if (dynamic_cast<JACK_Slave*>(new_slave)) {
89 /* JACK cannot support seamless looping at present */
90 Config->set_seamless_loop (false);
92 /* reset to whatever the value was before we last switched slaves */
93 Config->set_seamless_loop (_was_seamless);
96 /* save value of seamless from before the switch */
97 _was_seamless = seamless;
99 ev->slave = new_slave;
104 Session::request_transport_speed (double speed)
106 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
107 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport speed = %1\n", speed));
112 Session::request_diskstream_speed (Diskstream& ds, double speed)
114 SessionEvent* ev = new SessionEvent (SessionEvent::SetDiskstreamSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
120 Session::request_stop (bool abort, bool clear_state)
122 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0, abort, clear_state);
123 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport stop, abort = %1, clear state = %2\n", abort, clear_state));
128 Session::request_locate (nframes_t target_frame, bool with_roll)
130 SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, false);
131 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request locate to %1\n", target_frame));
136 Session::force_locate (nframes64_t target_frame, bool with_roll)
138 SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, true);
139 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request forced locate to %1\n", target_frame));
144 Session::request_play_loop (bool yn, bool leave_rolling)
147 Location *location = _locations.auto_loop_location();
149 if (location == 0 && yn) {
150 error << _("Cannot loop - no loop range defined")
155 ev = new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn);
156 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request set loop = %1, leave rolling ? %2\n", yn, leave_rolling));
159 if (!leave_rolling && !yn && Config->get_seamless_loop() && transport_rolling()) {
160 // request an immediate locate to refresh the diskstreams
161 // after disabling looping
162 request_locate (_transport_frame-1, false);
167 Session::request_play_range (list<AudioRange>* range, bool leave_rolling)
169 SessionEvent* ev = new SessionEvent (SessionEvent::SetPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0));
171 ev->audio_range = *range;
173 ev->audio_range.clear ();
175 DEBUG_TRACE (DEBUG::Transport, string_compose ("Request play range, leave rolling ? %1\n", leave_rolling));
180 Session::realtime_stop (bool abort, bool clear_state)
182 DEBUG_TRACE (DEBUG::Transport, "realtime stop\n");
183 PostTransportWork todo = PostTransportWork (0);
185 /* assume that when we start, we'll be moving forwards */
187 // FIXME: where should this really be? [DR]
188 //send_full_time_code();
189 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
190 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
192 if (_transport_speed < 0.0f) {
193 todo = (PostTransportWork (todo | PostTransportStop | PostTransportReverse));
195 todo = PostTransportWork (todo | PostTransportStop);
198 if (actively_recording()) {
200 /* move the transport position back to where the
201 request for a stop was noticed. we rolled
202 past that point to pick up delayed input.
205 decrement_transport_position (_worst_output_latency);
207 /* the duration change is not guaranteed to have happened, but is likely */
209 todo = PostTransportWork (todo | PostTransportDuration);
213 todo = PostTransportWork (todo | PostTransportAbort);
217 todo = PostTransportWork (todo | PostTransportClearSubstate);
221 add_post_transport_work (todo);
224 _clear_event_type (SessionEvent::StopOnce);
225 _clear_event_type (SessionEvent::RangeStop);
226 _clear_event_type (SessionEvent::RangeLocate);
228 disable_record (true);
230 reset_slave_state ();
232 _transport_speed = 0;
233 _target_transport_speed = 0;
235 if (config.get_use_video_sync()) {
236 waiting_for_sync_offset = true;
239 transport_sub_state = ((!config.get_external_sync()&& config.get_auto_return()) ? AutoReturning : 0);
243 Session::butler_transport_work ()
247 PostTransportWork ptw;
248 boost::shared_ptr<RouteList> r = routes.reader ();
249 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
251 int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
253 ptw = post_transport_work();
255 DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler transport work, todo = %1\n", enum_2_string (ptw)));
257 if (ptw & PostTransportCurveRealloc) {
258 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
259 (*i)->curve_reallocate();
263 if (ptw & PostTransportInputChange) {
264 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
265 (*i)->non_realtime_input_change ();
269 if (ptw & PostTransportSpeed) {
270 non_realtime_set_speed ();
273 if (ptw & PostTransportReverse) {
276 cumulative_rf_motion = 0;
279 /* don't seek if locate will take care of that in non_realtime_stop() */
281 if (!(ptw & PostTransportLocate)) {
283 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
284 if (!(*i)->hidden()) {
285 (*i)->non_realtime_locate (_transport_frame);
287 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
288 /* new request, stop seeking, and start again */
289 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
296 if (ptw & PostTransportLocate) {
297 non_realtime_locate ();
300 if (ptw & PostTransportStop) {
301 non_realtime_stop (ptw & PostTransportAbort, on_entry, finished);
303 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
308 if (ptw & PostTransportOverWrite) {
309 non_realtime_overwrite (on_entry, finished);
311 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
316 if (ptw & PostTransportAudition) {
317 non_realtime_set_audition ();
320 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
324 Session::non_realtime_set_speed ()
326 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
328 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
329 (*i)->non_realtime_set_speed ();
334 Session::non_realtime_overwrite (int on_entry, bool& finished)
336 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
338 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
339 if ((*i)->pending_overwrite) {
340 (*i)->overwrite_existing_buffers ();
342 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
351 Session::non_realtime_locate ()
353 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
355 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
356 (*i)->non_realtime_locate (_transport_frame);
362 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
368 PostTransportWork ptw = post_transport_work();
373 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
375 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
376 if ((*i)->get_captured_frames () != 0) {
382 /* stop and locate are merged here because they share a lot of common stuff */
385 now = localtime (&xnow);
388 auditioner->cancel_audition ();
392 cumulative_rf_motion = 0;
396 begin_reversible_command ("capture");
398 Location* loc = _locations.end_location();
399 bool change_end = false;
401 if (_transport_frame < loc->end()) {
403 /* stopped recording before current end */
405 if (config.get_end_marker_is_free()) {
407 /* first capture for this session, move end back to where we are */
412 } else if (_transport_frame > loc->end()) {
414 /* stopped recording after the current end, extend it */
420 XMLNode &before = loc->get_state();
421 loc->set_end(_transport_frame);
422 XMLNode &after = loc->get_state();
423 add_command (new MementoCommand<Location>(*loc, &before, &after));
426 config.set_end_marker_is_free (false);
427 _have_captured = true;
430 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
431 (*i)->transport_stopped (*now, xnow, abort);
434 boost::shared_ptr<RouteList> r = routes.reader ();
436 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
437 if (!(*i)->is_hidden()) {
438 (*i)->set_pending_declick (0);
443 commit_reversible_command ();
446 if (_engine.running()) {
447 update_latency_compensation (true, abort);
450 bool const auto_return_enabled =
451 (!config.get_external_sync() && config.get_auto_return());
453 if (auto_return_enabled ||
454 (ptw & PostTransportLocate) ||
455 (_requested_return_frame >= 0) ||
458 if (pending_locate_flush) {
459 flush_all_inserts ();
462 if ((auto_return_enabled || synced_to_jack() || _requested_return_frame >= 0) &&
463 !(ptw & PostTransportLocate)) {
465 /* no explicit locate queued */
467 bool do_locate = false;
469 if (_requested_return_frame >= 0) {
471 /* explicit return request pre-queued in event list. overrides everything else */
473 cerr << "explicit auto-return to " << _requested_return_frame << endl;
475 _transport_frame = _requested_return_frame;
479 if (config.get_auto_return()) {
483 /* don't try to handle loop play when synced to JACK */
485 if (!synced_to_jack()) {
487 Location *location = _locations.auto_loop_location();
490 _transport_frame = location->start();
492 _transport_frame = _last_roll_location;
497 } else if (_play_range) {
499 /* return to start of range */
501 if (!current_audio_range.empty()) {
502 _transport_frame = current_audio_range.front().start;
508 /* regular auto-return */
510 _transport_frame = _last_roll_location;
516 _requested_return_frame = -1;
519 _engine.transport_locate (_transport_frame);
525 /* do this before seeking, because otherwise the Diskstreams will do the wrong thing in seamless loop mode.
528 if (ptw & PostTransportClearSubstate) {
533 /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
536 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
537 if (!(*i)->hidden()) {
538 (*i)->non_realtime_locate (_transport_frame);
540 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
542 /* we will be back */
549 send_full_time_code (0);
550 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
551 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
553 if ((ptw & PostTransportLocate) && get_record_enabled()) {
554 /* capture start has been changed, so save pending state */
555 save_state ("", true);
559 /* always try to get rid of this */
561 remove_pending_capture_state ();
563 /* save the current state of things if appropriate */
565 if (did_record && !saved) {
566 save_state (_current_snapshot_name);
569 if (ptw & PostTransportDuration) {
570 DurationChanged (); /* EMIT SIGNAL */
573 if (ptw & PostTransportStop) {
578 // can't cast away volatile so copy and emit that
579 nframes64_t tframe = _transport_frame;
580 PositionChanged (tframe); /* EMIT SIGNAL */
581 TransportStateChange (); /* EMIT SIGNAL */
583 /* and start it up again if relevant */
585 if ((ptw & PostTransportLocate) && !config.get_external_sync() && pending_locate_roll) {
586 request_transport_speed (1.0);
587 pending_locate_roll = false;
592 Session::check_declick_out ()
594 bool locate_required = transport_sub_state & PendingLocate;
596 /* this is called after a process() iteration. if PendingDeclickOut was set,
597 it means that we were waiting to declick the output (which has just been
598 done) before doing something else. this is where we do that "something else".
600 note: called from the audio thread.
603 if (transport_sub_state & PendingDeclickOut) {
605 if (locate_required) {
606 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
607 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
609 stop_transport (pending_abort);
610 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
616 Session::unset_play_loop ()
619 clear_events (SessionEvent::AutoLoop);
621 // set all diskstreams to NOT use internal looping
622 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
623 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
624 if (!(*i)->hidden()) {
631 Session::set_play_loop (bool yn)
633 /* Called from event-handling context */
637 if (yn == play_loop || (actively_recording() && yn) || (loc = _locations.auto_loop_location()) == 0) {
638 /* nothing to do, or can't change loop status while recording */
644 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
645 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
646 "Recommend changing the configured options")
659 if (Config->get_seamless_loop()) {
660 // set all diskstreams to use internal looping
661 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
662 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
663 if (!(*i)->hidden()) {
664 (*i)->set_loop (loc);
669 // set all diskstreams to NOT use internal looping
670 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
671 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
672 if (!(*i)->hidden()) {
678 /* put the loop event into the event list */
680 SessionEvent* event = new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f);
683 /* locate to start of loop and roll. If doing seamless loop, force a
684 locate+buffer refill even if we are positioned there already.
687 start_locate (loc->start(), true, true, false, Config->get_seamless_loop());
695 TransportStateChange ();
698 Session::flush_all_inserts ()
700 boost::shared_ptr<RouteList> r = routes.reader ();
702 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
703 (*i)->flush_processors ();
708 Session::start_locate (nframes64_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
710 if (synced_to_jack()) {
715 _slave->speed_and_position (sp, pos);
717 if (target_frame != pos) {
719 /* tell JACK to change transport position, and we will
720 follow along later in ::follow_slave()
723 _engine.transport_locate (target_frame);
725 if (sp != 1.0f && with_roll) {
726 _engine.transport_start ();
732 locate (target_frame, with_roll, with_flush, with_loop, force);
737 Session::micro_locate (nframes_t distance)
739 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
741 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
742 if (!(*i)->can_internal_playback_seek (distance)) {
747 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
748 (*i)->internal_playback_seek (distance);
751 _transport_frame += distance;
756 Session::locate (nframes64_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
758 if (actively_recording() && !with_loop) {
762 if (!force && _transport_frame == target_frame && !loop_changing && !with_loop) {
764 set_transport_speed (1.0, false);
766 loop_changing = false;
770 // Update Timecode time
771 // [DR] FIXME: find out exactly where this should go below
772 _transport_frame = target_frame;
773 timecode_time(_transport_frame, transmitting_timecode_time);
774 outbound_mtc_timecode_frame = _transport_frame;
775 next_quarter_frame_to_send = 0;
777 if (_transport_speed && (!with_loop || loop_changing)) {
778 /* schedule a declick. we'll be called again when its done */
780 if (!(transport_sub_state & PendingDeclickOut)) {
781 transport_sub_state |= (PendingDeclickOut|PendingLocate);
782 pending_locate_frame = target_frame;
783 pending_locate_roll = with_roll;
784 pending_locate_flush = with_flush;
789 if (transport_rolling() && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
790 realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
793 if (force || !with_loop || loop_changing) {
795 PostTransportWork todo = PostTransportLocate;
798 todo = PostTransportWork (todo | PostTransportRoll);
801 add_post_transport_work (todo);
802 _butler->schedule_transport_work ();
806 /* this is functionally what clear_clicks() does but with a tentative lock */
808 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
810 if (clickm.locked()) {
812 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
821 /* switch from input if we're going to roll */
822 if (Config->get_monitoring_model() == HardwareMonitoring) {
824 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
826 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
827 if ((*i)->record_enabled ()) {
828 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
829 (*i)->monitor_input (!config.get_auto_input());
834 /* otherwise we're going to stop, so do the opposite */
835 if (Config->get_monitoring_model() == HardwareMonitoring) {
836 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
838 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
839 if ((*i)->record_enabled ()) {
840 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
841 (*i)->monitor_input (true);
847 /* cancel looped playback if transport pos outside of loop range */
849 Location* al = _locations.auto_loop_location();
851 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
852 // cancel looping directly, this is called from event handling context
853 set_play_loop (false);
855 else if (al && _transport_frame == al->start()) {
857 // this is only necessary for seamless looping
859 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
861 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
862 if ((*i)->record_enabled ()) {
863 // tell it we've looped, so it can deal with the record state
864 (*i)->transport_looped(_transport_frame);
869 TransportLooped(); // EMIT SIGNAL
873 loop_changing = false;
875 _send_timecode_update = true;
877 Located (); /* EMIT SIGNAL */
880 /** Set the transport speed.
881 * @param speed New speed
885 Session::set_transport_speed (double speed, bool abort, bool clear_state)
887 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));
889 if (_transport_speed == speed) {
893 _target_transport_speed = fabs(speed);
895 /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
896 and user needs. We really need CD-style "skip" playback for ffwd and rewind.
900 speed = min (8.0, speed);
901 } else if (speed < 0) {
902 speed = max (-8.0, speed);
905 if (transport_rolling() && speed == 0.0) {
907 /* we are rolling and we want to stop */
909 if (Config->get_monitoring_model() == HardwareMonitoring)
911 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
913 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
914 if ((*i)->record_enabled ()) {
915 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
916 (*i)->monitor_input (true);
921 if (synced_to_jack ()) {
923 /* do this here because our response to the slave won't
929 _engine.transport_stop ();
931 stop_transport (abort);
934 } else if (transport_stopped() && speed == 1.0) {
936 /* we are stopped and we want to start rolling at speed 1 */
938 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
942 if (Config->get_monitoring_model() == HardwareMonitoring) {
944 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
946 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
947 if (config.get_auto_input() && (*i)->record_enabled ()) {
948 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
949 (*i)->monitor_input (false);
954 if (synced_to_jack()) {
955 _engine.transport_start ();
962 /* if not recording, don't roll forward past end if told to stop there */
964 if (!get_record_enabled() && (speed > 0.0 && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame())) {
968 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
969 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
974 if (actively_recording()) {
978 if (speed > 0.0 && _transport_frame == current_end_frame()) {
982 if (speed < 0.0 && _transport_frame == 0) {
988 /* if we are reversing relative to the current speed, or relative to the speed
989 before the last stop, then we have to do extra work.
992 PostTransportWork todo = PostTransportWork (0);
994 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
995 todo = PostTransportWork (todo | PostTransportReverse);
998 _last_transport_speed = _transport_speed;
999 _transport_speed = speed;
1001 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1002 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1003 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1004 todo = PostTransportWork (todo | PostTransportSpeed);
1010 add_post_transport_work (todo);
1011 _butler->schedule_transport_work ();
1017 /** Stop the transport. */
1019 Session::stop_transport (bool abort, bool clear_state)
1021 if (_transport_speed == 0.0f) {
1025 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
1026 _worst_output_latency > current_block_size)
1029 /* we need to capture the audio that has still not yet been received by the system
1030 at the time the stop is requested, so we have to roll past that time.
1032 we want to declick before stopping, so schedule the autostop for one
1033 block before the actual end. we'll declick in the subsequent block,
1034 and then we'll really be stopped.
1037 SessionEvent *ev = new SessionEvent (SessionEvent::StopOnce, SessionEvent::Replace,
1038 _transport_frame + _worst_output_latency - current_block_size,
1042 transport_sub_state |= StopPendingCapture;
1043 pending_abort = abort;
1048 if ((transport_sub_state & PendingDeclickOut) == 0) {
1049 transport_sub_state |= PendingDeclickOut;
1050 /* we'll be called again after the declick */
1051 pending_abort = abort;
1055 realtime_stop (abort, clear_state);
1056 _butler->schedule_transport_work ();
1060 Session::start_transport ()
1062 _last_roll_location = _transport_frame;
1063 have_looped = false;
1065 /* if record status is Enabled, move it to Recording. if its
1066 already Recording, move it to Disabled.
1069 switch (record_status()) {
1071 if (!config.get_punch_in()) {
1078 disable_record (false);
1086 transport_sub_state |= PendingDeclickIn;
1088 _transport_speed = 1.0;
1089 _target_transport_speed = 1.0;
1091 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1092 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1093 (*i)->realtime_set_speed ((*i)->speed(), true);
1096 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
1098 TransportStateChange (); /* EMIT SIGNAL */
1101 /** Do any transport work in the audio thread that needs to be done after the
1102 * transport thread is finished. Audio thread, realtime safe.
1105 Session::post_transport ()
1107 PostTransportWork ptw = post_transport_work ();
1109 if (ptw & PostTransportAudition) {
1110 if (auditioner && auditioner->active()) {
1111 process_function = &Session::process_audition;
1113 process_function = &Session::process_with_events;
1117 if (ptw & PostTransportStop) {
1119 transport_sub_state = 0;
1122 if (ptw & PostTransportLocate) {
1124 if (((!config.get_external_sync() && (auto_play_legal && config.get_auto_play())) && !_exporting) || (ptw & PostTransportRoll)) {
1128 transport_sub_state = 0;
1133 /* XXX is this really safe? shouldn't we just be unsetting the bits that we actually
1136 set_post_transport_work (PostTransportWork (0));
1140 Session::reset_rf_scale (nframes_t motion)
1142 cumulative_rf_motion += motion;
1144 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1146 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1148 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1160 Session::use_sync_source (Slave* new_slave)
1162 /* Runs in process() context */
1164 bool non_rt_required = false;
1166 /* XXX this deletion is problematic because we're in RT context */
1171 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1172 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1173 if (!(*i)->hidden()) {
1174 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1175 non_rt_required = true;
1177 (*i)->set_slaved (_slave != 0);
1181 if (non_rt_required) {
1182 add_post_transport_work (PostTransportSpeed);
1183 _butler->schedule_transport_work ();
1190 Session::drop_sync_source ()
1192 request_sync_source (0);
1196 Session::switch_to_sync_source (SyncSource src)
1200 DEBUG_TRACE (DEBUG::Slave, string_compose ("Setting up sync source %1\n", enum_2_string (src)));
1204 if (_slave && dynamic_cast<MTC_Slave*>(_slave)) {
1210 new_slave = new MTC_Slave (*this, *_mtc_port);
1213 catch (failed_constructor& err) {
1218 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1224 if (_slave && dynamic_cast<MIDIClock_Slave*>(_slave)) {
1228 if (_midi_clock_port) {
1230 new_slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24);
1233 catch (failed_constructor& err) {
1238 error << _("No MIDI Clock port defined: MIDI Clock slaving is impossible.") << endmsg;
1244 if (_slave && dynamic_cast<JACK_Slave*>(_slave)) {
1248 new_slave = new JACK_Slave (_engine.jack());
1256 request_sync_source (new_slave);
1260 Session::reverse_diskstream_buffers ()
1262 add_post_transport_work (PostTransportReverse);
1263 _butler->schedule_transport_work ();
1267 Session::set_diskstream_speed (Diskstream* stream, double speed)
1269 if (stream->realtime_set_speed (speed, false)) {
1270 add_post_transport_work (PostTransportSpeed);
1271 _butler->schedule_transport_work ();
1277 Session::unset_play_range ()
1279 _play_range = false;
1280 _clear_event_type (SessionEvent::RangeStop);
1281 _clear_event_type (SessionEvent::RangeLocate);
1285 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1289 /* Called from event-processing context */
1291 unset_play_range ();
1293 if (range.empty()) {
1294 /* _play_range set to false in unset_play_range()
1296 if (!leave_rolling) {
1297 /* stop transport */
1298 SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false);
1306 /* cancel loop play */
1309 list<AudioRange>::size_type sz = range.size();
1313 list<AudioRange>::iterator i = range.begin();
1314 list<AudioRange>::iterator next;
1316 while (i != range.end()) {
1321 /* locating/stopping is subject to delays for declicking.
1324 nframes_t requested_frame = (*i).end;
1326 if (requested_frame > current_block_size) {
1327 requested_frame -= current_block_size;
1329 requested_frame = 0;
1332 if (next == range.end()) {
1333 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_frame, 0, 0.0f);
1335 ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_frame, (*next).start, 0.0f);
1343 } else if (sz == 1) {
1345 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
1350 /* save range so we can do auto-return etc. */
1352 current_audio_range = range;
1354 /* now start rolling at the right place */
1356 ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
1359 TransportStateChange ();
1363 Session::request_bounded_roll (nframes_t start, nframes_t end)
1365 AudioRange ar (start, end, 0);
1366 list<AudioRange> lar;
1369 request_play_range (&lar, true);
1372 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1374 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
1375 ev->target2_frame = start;
1380 Session::engine_halted ()
1384 /* there will be no more calls to process(), so
1385 we'd better clean up for ourselves, right now.
1387 but first, make sure the butler is out of
1391 g_atomic_int_set (&_butler->should_do_transport_work, 0);
1392 set_post_transport_work (PostTransportWork (0));
1395 realtime_stop (false, true);
1396 non_realtime_stop (false, 0, ignored);
1397 transport_sub_state = 0;
1399 TransportStateChange (); /* EMIT SIGNAL */
1404 Session::xrun_recovery ()
1406 // can't cast away volatile so copy and emit that
1407 nframes64_t tframe = _transport_frame;
1408 Xrun (tframe); //EMIT SIGNAL
1410 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1412 /* it didn't actually halt, but we need
1413 to handle things in the same way.
1421 Session::route_processors_changed (RouteProcessorChange c)
1423 if (c.type == RouteProcessorChange::MeterPointChange) {
1427 update_latency_compensation (false, false);
1431 Session::update_latency_compensation (bool with_stop, bool abort)
1433 bool update_jack = false;
1434 PostTransportWork ptw;
1436 if (_state_of_the_state & Deletion) {
1440 _worst_track_latency = 0;
1441 ptw = post_transport_work();
1443 #undef DEBUG_LATENCY
1444 #ifdef DEBUG_LATENCY
1445 cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1448 boost::shared_ptr<RouteList> r = routes.reader ();
1450 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1453 (*i)->handle_transport_stopped (abort, (ptw & PostTransportLocate), (!(ptw & PostTransportLocate) || pending_locate_flush));
1456 nframes_t old_latency = (*i)->output()->signal_latency ();
1457 nframes_t track_latency = (*i)->update_total_latency ();
1459 if (old_latency != track_latency) {
1460 (*i)->input()->update_port_total_latencies ();
1461 (*i)->output()->update_port_total_latencies ();
1465 if (!(*i)->is_hidden() && ((*i)->active())) {
1466 _worst_track_latency = max (_worst_track_latency, track_latency);
1471 _engine.update_total_latencies ();
1474 #ifdef DEBUG_LATENCY
1475 cerr << "\tworst was " << _worst_track_latency << endl;
1478 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1479 (*i)->set_latency_delay (_worst_track_latency);
1482 set_worst_io_latencies ();
1484 /* reflect any changes in latencies into capture offsets
1487 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1489 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1490 (*i)->set_capture_offset ();
1495 Session::allow_auto_play (bool yn)
1497 auto_play_legal = yn;
1501 Session::reset_jack_connection (jack_client_t* jack)
1505 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1506 js->reset_client (jack);
1511 Session::maybe_stop (nframes_t limit)
1513 if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
1514 if (synced_to_jack () && config.get_jack_time_master ()) {
1515 _engine.transport_stop ();
1516 } else if (!synced_to_jack ()) {