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 <glibmm/thread.h>
30 #include "pbd/pthread_utils.h"
31 #include "pbd/memento_command.h"
32 #include "pbd/stacktrace.h"
34 #include "midi++/mmc.h"
35 #include "midi++/port.h"
37 #include "ardour/ardour.h"
38 #include "ardour/audio_diskstream.h"
39 #include "ardour/audioengine.h"
40 #include "ardour/auditioner.h"
41 #include "ardour/butler.h"
42 #include "ardour/location.h"
43 #include "ardour/session.h"
44 #include "ardour/slave.h"
49 using namespace ARDOUR;
54 Session::add_post_transport_work (PostTransportWork ptw)
56 PostTransportWork oldval;
57 PostTransportWork newval;
61 oldval = (PostTransportWork) g_atomic_int_get (&_post_transport_work);
62 newval = PostTransportWork (oldval | ptw);
63 if (g_atomic_int_compare_and_exchange (&_post_transport_work, oldval, newval)) {
69 error << "Could not set post transport work! Crazy thread madness, call the programmers" << endmsg;
73 Session::request_input_change_handling ()
75 if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
76 Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0);
82 Session::request_slave_source (SlaveSource src)
84 Event* ev = new Event (Event::SetSlaveSource, Event::Add, Event::Immediate, 0, 0.0);
87 seamless = Config->get_seamless_loop ();
90 /* JACK cannot support seamless looping at present */
91 Config->set_seamless_loop (false);
93 /* reset to whatever the value was before we last switched slaves */
94 Config->set_seamless_loop (_was_seamless);
97 /* save value of seamless from before the switch */
98 _was_seamless = seamless;
105 Session::request_transport_speed (double speed)
107 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, speed);
112 Session::request_diskstream_speed (Diskstream& ds, double speed)
114 Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed);
120 Session::request_stop (bool abort, bool clear_state)
122 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0, abort, clear_state);
127 Session::request_locate (nframes_t target_frame, bool with_roll)
129 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, false);
134 Session::force_locate (nframes64_t target_frame, bool with_roll)
136 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, true);
141 Session::request_play_loop (bool yn, bool leave_rolling)
144 Location *location = _locations.auto_loop_location();
146 if (location == 0 && yn) {
147 error << _("Cannot loop - no loop range defined")
152 ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn);
155 if (!leave_rolling && !yn && Config->get_seamless_loop() && transport_rolling()) {
156 // request an immediate locate to refresh the diskstreams
157 // after disabling looping
158 request_locate (_transport_frame-1, false);
163 Session::request_play_range (list<AudioRange>* range, bool leave_rolling)
165 Event* ev = new Event (Event::SetPlayAudioRange, Event::Add, Event::Immediate, 0, (leave_rolling ? 1.0 : 0.0));
167 ev->audio_range = *range;
169 ev->audio_range.clear ();
175 Session::realtime_stop (bool abort, bool clear_state)
177 PostTransportWork todo = PostTransportWork (0);
179 /* assume that when we start, we'll be moving forwards */
181 // FIXME: where should this really be? [DR]
182 //send_full_time_code();
183 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
184 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
186 if (_transport_speed < 0.0f) {
187 todo = (PostTransportWork (todo | PostTransportStop | PostTransportReverse));
189 todo = PostTransportWork (todo | PostTransportStop);
192 if (actively_recording()) {
194 /* move the transport position back to where the
195 request for a stop was noticed. we rolled
196 past that point to pick up delayed input.
199 decrement_transport_position (_worst_output_latency);
201 /* the duration change is not guaranteed to have happened, but is likely */
203 todo = PostTransportWork (todo | PostTransportDuration);
207 todo = PostTransportWork (todo | PostTransportAbort);
211 todo = PostTransportWork (todo | PostTransportClearSubstate);
215 add_post_transport_work (todo);
218 _clear_event_type (Event::StopOnce);
219 _clear_event_type (Event::RangeStop);
220 _clear_event_type (Event::RangeLocate);
222 disable_record (true);
224 reset_slave_state ();
226 _transport_speed = 0;
227 _target_transport_speed = 0;
229 if (config.get_use_video_sync()) {
230 waiting_for_sync_offset = true;
233 transport_sub_state = ((Config->get_slave_source() == None && config.get_auto_return()) ? AutoReturning : 0);
237 Session::butler_transport_work ()
241 PostTransportWork ptw;
242 boost::shared_ptr<RouteList> r = routes.reader ();
243 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
245 int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
247 ptw = post_transport_work();
248 if (ptw & PostTransportCurveRealloc) {
249 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
250 (*i)->curve_reallocate();
254 if (ptw & PostTransportInputChange) {
255 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
256 (*i)->non_realtime_input_change ();
260 if (ptw & PostTransportSpeed) {
261 non_realtime_set_speed ();
264 if (ptw & PostTransportReverse) {
267 cumulative_rf_motion = 0;
270 /* don't seek if locate will take care of that in non_realtime_stop() */
272 if (!(ptw & PostTransportLocate)) {
274 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
275 if (!(*i)->hidden()) {
276 (*i)->non_realtime_locate (_transport_frame);
278 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
279 /* new request, stop seeking, and start again */
280 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
287 if (ptw & PostTransportLocate) {
288 non_realtime_locate ();
291 if (ptw & PostTransportStop) {
292 non_realtime_stop (ptw & PostTransportAbort, on_entry, finished);
294 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
299 if (ptw & PostTransportOverWrite) {
300 non_realtime_overwrite (on_entry, finished);
302 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
307 if (ptw & PostTransportAudition) {
308 non_realtime_set_audition ();
311 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
315 Session::non_realtime_set_speed ()
317 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
319 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
320 (*i)->non_realtime_set_speed ();
325 Session::non_realtime_overwrite (int on_entry, bool& finished)
327 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
329 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
330 if ((*i)->pending_overwrite) {
331 (*i)->overwrite_existing_buffers ();
333 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
342 Session::non_realtime_locate ()
344 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
346 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
347 (*i)->non_realtime_locate (_transport_frame);
353 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
359 PostTransportWork ptw = post_transport_work();
364 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
366 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
367 if ((*i)->get_captured_frames () != 0) {
373 /* stop and locate are merged here because they share a lot of common stuff */
376 now = localtime (&xnow);
379 auditioner->cancel_audition ();
383 cumulative_rf_motion = 0;
387 begin_reversible_command ("capture");
389 Location* loc = _locations.end_location();
390 bool change_end = false;
392 if (_transport_frame < loc->end()) {
394 /* stopped recording before current end */
396 if (config.get_end_marker_is_free()) {
398 /* first capture for this session, move end back to where we are */
403 } else if (_transport_frame > loc->end()) {
405 /* stopped recording after the current end, extend it */
411 XMLNode &before = loc->get_state();
412 loc->set_end(_transport_frame);
413 XMLNode &after = loc->get_state();
414 add_command (new MementoCommand<Location>(*loc, &before, &after));
417 config.set_end_marker_is_free (false);
418 _have_captured = true;
421 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
422 (*i)->transport_stopped (*now, xnow, abort);
425 boost::shared_ptr<RouteList> r = routes.reader ();
427 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
428 if (!(*i)->is_hidden()) {
429 (*i)->set_pending_declick (0);
434 commit_reversible_command ();
437 if (_engine.running()) {
438 update_latency_compensation (true, abort);
441 bool const auto_return_enabled =
442 (Config->get_slave_source() == None && config.get_auto_return());
444 if (auto_return_enabled ||
445 (ptw & PostTransportLocate) ||
446 (_requested_return_frame >= 0) ||
449 if (pending_locate_flush) {
450 flush_all_inserts ();
453 if ((auto_return_enabled || synced_to_jack() || _requested_return_frame >= 0) &&
454 !(ptw & PostTransportLocate)) {
456 /* no explicit locate queued */
458 bool do_locate = false;
460 if (_requested_return_frame >= 0) {
462 /* explicit return request pre-queued in event list. overrides everything else */
464 cerr << "explicit auto-return to " << _requested_return_frame << endl;
466 _transport_frame = _requested_return_frame;
470 if (config.get_auto_return()) {
474 /* don't try to handle loop play when synced to JACK */
476 if (!synced_to_jack()) {
478 Location *location = _locations.auto_loop_location();
481 _transport_frame = location->start();
483 _transport_frame = _last_roll_location;
488 } else if (_play_range) {
490 /* return to start of range */
492 if (!current_audio_range.empty()) {
493 _transport_frame = current_audio_range.front().start;
499 /* regular auto-return */
501 _transport_frame = _last_roll_location;
507 _requested_return_frame = -1;
510 _engine.transport_locate (_transport_frame);
516 /* do this before seeking, because otherwise the Diskstreams will do the wrong thing in seamless loop mode.
519 if (ptw & PostTransportClearSubstate) {
524 /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
527 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
528 if (!(*i)->hidden()) {
529 (*i)->non_realtime_locate (_transport_frame);
531 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
533 /* we will be back */
540 send_full_time_code (0);
541 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
542 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
544 if ((ptw & PostTransportLocate) && get_record_enabled()) {
545 /* capture start has been changed, so save pending state */
546 save_state ("", true);
550 /* always try to get rid of this */
552 remove_pending_capture_state ();
554 /* save the current state of things if appropriate */
556 if (did_record && !saved) {
557 save_state (_current_snapshot_name);
560 if (ptw & PostTransportDuration) {
561 DurationChanged (); /* EMIT SIGNAL */
564 if (ptw & PostTransportStop) {
569 PositionChanged ((nframes64_t) _transport_frame); /* EMIT SIGNAL */
570 TransportStateChange (); /* EMIT SIGNAL */
572 /* and start it up again if relevant */
574 if ((ptw & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
575 request_transport_speed (1.0);
576 pending_locate_roll = false;
581 Session::check_declick_out ()
583 bool locate_required = transport_sub_state & PendingLocate;
585 /* this is called after a process() iteration. if PendingDeclickOut was set,
586 it means that we were waiting to declick the output (which has just been
587 done) before doing something else. this is where we do that "something else".
589 note: called from the audio thread.
592 if (transport_sub_state & PendingDeclickOut) {
594 if (locate_required) {
595 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
596 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
598 stop_transport (pending_abort);
599 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
605 Session::unset_play_loop ()
608 clear_events (Event::AutoLoop);
610 // set all diskstreams to NOT use internal looping
611 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
612 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
613 if (!(*i)->hidden()) {
620 Session::set_play_loop (bool yn)
622 /* Called from event-handling context */
626 if (yn == play_loop || (actively_recording() && yn) || (loc = _locations.auto_loop_location()) == 0) {
627 /* nothing to do, or can't change loop status while recording */
633 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
634 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
635 "Recommend changing the configured options")
648 if (Config->get_seamless_loop()) {
649 // set all diskstreams to use internal looping
650 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
651 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
652 if (!(*i)->hidden()) {
653 (*i)->set_loop (loc);
658 // set all diskstreams to NOT 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()) {
667 /* put the loop event into the event list */
669 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
672 /* locate to start of loop and roll. If doing seamless loop, force a
673 locate+buffer refill even if we are positioned there already.
676 start_locate (loc->start(), true, true, false, Config->get_seamless_loop());
684 TransportStateChange ();
687 Session::flush_all_inserts ()
689 boost::shared_ptr<RouteList> r = routes.reader ();
691 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
692 (*i)->flush_processors ();
697 Session::start_locate (nframes64_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
699 if (synced_to_jack()) {
704 _slave->speed_and_position (sp, pos);
706 if (target_frame != pos) {
708 /* tell JACK to change transport position, and we will
709 follow along later in ::follow_slave()
712 _engine.transport_locate (target_frame);
714 if (sp != 1.0f && with_roll) {
715 _engine.transport_start ();
721 locate (target_frame, with_roll, with_flush, with_loop, force);
726 Session::micro_locate (nframes_t distance)
728 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
730 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
731 if (!(*i)->can_internal_playback_seek (distance)) {
736 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
737 (*i)->internal_playback_seek (distance);
740 _transport_frame += distance;
745 Session::locate (nframes64_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
747 if (actively_recording() && !with_loop) {
751 if (!force && _transport_frame == target_frame && !loop_changing && !with_loop) {
753 set_transport_speed (1.0, false);
755 loop_changing = false;
759 // Update Timecode time
760 // [DR] FIXME: find out exactly where this should go below
761 _transport_frame = target_frame;
762 timecode_time(_transport_frame, transmitting_timecode_time);
763 outbound_mtc_timecode_frame = _transport_frame;
764 next_quarter_frame_to_send = 0;
766 if (_transport_speed && (!with_loop || loop_changing)) {
767 /* schedule a declick. we'll be called again when its done */
769 if (!(transport_sub_state & PendingDeclickOut)) {
770 transport_sub_state |= (PendingDeclickOut|PendingLocate);
771 pending_locate_frame = target_frame;
772 pending_locate_roll = with_roll;
773 pending_locate_flush = with_flush;
778 if (transport_rolling() && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
779 realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
782 if (force || !with_loop || loop_changing) {
784 PostTransportWork todo = PostTransportLocate;
787 todo = PostTransportWork (todo | PostTransportRoll);
790 add_post_transport_work (todo);
791 _butler->schedule_transport_work ();
795 /* this is functionally what clear_clicks() does but with a tentative lock */
797 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
799 if (clickm.locked()) {
801 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
810 /* switch from input if we're going to roll */
811 if (Config->get_monitoring_model() == HardwareMonitoring) {
813 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
815 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
816 if ((*i)->record_enabled ()) {
817 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
818 (*i)->monitor_input (!config.get_auto_input());
823 /* otherwise we're going to stop, so do the opposite */
824 if (Config->get_monitoring_model() == HardwareMonitoring) {
825 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
827 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
828 if ((*i)->record_enabled ()) {
829 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
830 (*i)->monitor_input (true);
836 /* cancel looped playback if transport pos outside of loop range */
838 Location* al = _locations.auto_loop_location();
840 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
841 // cancel looping directly, this is called from event handling context
842 set_play_loop (false);
844 else if (al && _transport_frame == al->start()) {
846 // this is only necessary for seamless looping
848 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
850 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
851 if ((*i)->record_enabled ()) {
852 // tell it we've looped, so it can deal with the record state
853 (*i)->transport_looped(_transport_frame);
858 TransportLooped(); // EMIT SIGNAL
862 loop_changing = false;
864 _send_timecode_update = true;
866 Located (); /* EMIT SIGNAL */
869 /** Set the transport speed.
870 * @param speed New speed
874 Session::set_transport_speed (double speed, bool abort, bool clear_state)
876 if (_transport_speed == speed) {
880 _target_transport_speed = fabs(speed);
882 /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
883 and user needs. We really need CD-style "skip" playback for ffwd and rewind.
887 speed = min (8.0, speed);
888 } else if (speed < 0) {
889 speed = max (-8.0, speed);
892 if (transport_rolling() && speed == 0.0) {
894 /* we are rolling and we want to stop */
896 if (Config->get_monitoring_model() == HardwareMonitoring)
898 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
900 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
901 if ((*i)->record_enabled ()) {
902 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
903 (*i)->monitor_input (true);
908 if (synced_to_jack ()) {
910 /* do this here because our response to the slave won't
916 _engine.transport_stop ();
918 stop_transport (abort);
921 } else if (transport_stopped() && speed == 1.0) {
923 /* we are stopped and we want to start rolling at speed 1 */
925 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
929 if (Config->get_monitoring_model() == HardwareMonitoring) {
931 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
933 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
934 if (config.get_auto_input() && (*i)->record_enabled ()) {
935 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
936 (*i)->monitor_input (false);
941 if (synced_to_jack()) {
942 _engine.transport_start ();
949 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
953 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
954 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
959 if (actively_recording()) {
963 if (speed > 0.0 && _transport_frame == current_end_frame()) {
967 if (speed < 0.0 && _transport_frame == 0) {
973 /* if we are reversing relative to the current speed, or relative to the speed
974 before the last stop, then we have to do extra work.
977 PostTransportWork todo = PostTransportWork (0);
979 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
980 todo = PostTransportWork (todo | PostTransportReverse);
983 _last_transport_speed = _transport_speed;
984 _transport_speed = speed;
986 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
987 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
988 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
989 todo = PostTransportWork (todo | PostTransportSpeed);
995 add_post_transport_work (todo);
996 _butler->schedule_transport_work ();
1002 /** Stop the transport. */
1004 Session::stop_transport (bool abort, bool clear_state)
1006 if (_transport_speed == 0.0f) {
1010 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
1011 _worst_output_latency > current_block_size)
1014 /* we need to capture the audio that has still not yet been received by the system
1015 at the time the stop is requested, so we have to roll past that time.
1017 we want to declick before stopping, so schedule the autostop for one
1018 block before the actual end. we'll declick in the subsequent block,
1019 and then we'll really be stopped.
1022 Event *ev = new Event (Event::StopOnce, Event::Replace,
1023 _transport_frame + _worst_output_latency - current_block_size,
1027 transport_sub_state |= StopPendingCapture;
1028 pending_abort = abort;
1033 if ((transport_sub_state & PendingDeclickOut) == 0) {
1034 transport_sub_state |= PendingDeclickOut;
1035 /* we'll be called again after the declick */
1036 pending_abort = abort;
1040 realtime_stop (abort, clear_state);
1041 _butler->schedule_transport_work ();
1045 Session::start_transport ()
1047 _last_roll_location = _transport_frame;
1048 have_looped = false;
1050 /* if record status is Enabled, move it to Recording. if its
1051 already Recording, move it to Disabled.
1054 switch (record_status()) {
1056 if (!config.get_punch_in()) {
1063 disable_record (false);
1071 transport_sub_state |= PendingDeclickIn;
1073 _transport_speed = 1.0;
1074 _target_transport_speed = 1.0;
1076 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1077 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1078 (*i)->realtime_set_speed ((*i)->speed(), true);
1081 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
1083 TransportStateChange (); /* EMIT SIGNAL */
1086 /** Do any transport work in the audio thread that needs to be done after the
1087 * transport thread is finished. Audio thread, realtime safe.
1090 Session::post_transport ()
1092 PostTransportWork ptw = post_transport_work ();
1094 if (ptw & PostTransportAudition) {
1095 if (auditioner && auditioner->active()) {
1096 process_function = &Session::process_audition;
1098 process_function = &Session::process_with_events;
1102 if (ptw & PostTransportStop) {
1104 transport_sub_state = 0;
1107 if (ptw & PostTransportLocate) {
1109 if (((Config->get_slave_source() == None && (auto_play_legal && config.get_auto_play())) && !_exporting) || (ptw & PostTransportRoll)) {
1113 transport_sub_state = 0;
1118 /* XXX is this really safe? shouldn't we just be unsetting the bits that we actually
1121 set_post_transport_work (PostTransportWork (0));
1125 Session::reset_rf_scale (nframes_t motion)
1127 cumulative_rf_motion += motion;
1129 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1131 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1133 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1145 Session::set_slave_source (SlaveSource src)
1147 bool reverse = false;
1148 bool non_rt_required = false;
1150 if (_transport_speed) {
1151 error << _("please stop the transport before adjusting slave settings") << endmsg;
1155 // if (src == JACK && Config->get_jack_time_master()) {
1162 if (_transport_speed < 0.0) {
1174 _slave = new MTC_Slave (*this, *_mtc_port);
1177 catch (failed_constructor& err) {
1182 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1188 if (_midi_clock_port) {
1190 _slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24);
1193 catch (failed_constructor& err) {
1198 error << _("No MIDI Clock port defined: MIDI Clock slaving is impossible.") << endmsg;
1204 _slave = new JACK_Slave (_engine.jack());
1209 Config->set_slave_source (src);
1211 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1212 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1213 if (!(*i)->hidden()) {
1214 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1215 non_rt_required = true;
1217 (*i)->set_slaved (_slave);
1222 reverse_diskstream_buffers ();
1225 if (non_rt_required) {
1226 add_post_transport_work (PostTransportSpeed);
1227 _butler->schedule_transport_work ();
1234 Session::reverse_diskstream_buffers ()
1236 add_post_transport_work (PostTransportReverse);
1237 _butler->schedule_transport_work ();
1241 Session::set_diskstream_speed (Diskstream* stream, double speed)
1243 if (stream->realtime_set_speed (speed, false)) {
1244 add_post_transport_work (PostTransportSpeed);
1245 _butler->schedule_transport_work ();
1251 Session::unset_play_range ()
1253 _play_range = false;
1254 _clear_event_type (Event::RangeStop);
1255 _clear_event_type (Event::RangeLocate);
1259 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1263 /* Called from event-processing context */
1265 unset_play_range ();
1267 if (range.empty()) {
1268 /* _play_range set to false in unset_play_range()
1270 if (!leave_rolling) {
1271 /* stop transport */
1272 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1280 /* cancel loop play */
1283 list<AudioRange>::size_type sz = range.size();
1287 list<AudioRange>::iterator i = range.begin();
1288 list<AudioRange>::iterator next;
1290 while (i != range.end()) {
1295 /* locating/stopping is subject to delays for declicking.
1298 nframes_t requested_frame = (*i).end;
1300 if (requested_frame > current_block_size) {
1301 requested_frame -= current_block_size;
1303 requested_frame = 0;
1306 if (next == range.end()) {
1307 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1309 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1317 } else if (sz == 1) {
1319 ev = new Event (Event::RangeStop, Event::Add, range.front().end, 0, 0.0f);
1324 /* save range so we can do auto-return etc. */
1326 current_audio_range = range;
1328 /* now start rolling at the right place */
1330 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, range.front().start, 0.0f, false);
1333 TransportStateChange ();
1337 Session::request_bounded_roll (nframes_t start, nframes_t end)
1339 AudioRange ar (start, end, 0);
1340 list<AudioRange> lar;
1343 request_play_range (&lar, true);
1346 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1348 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1349 ev->target2_frame = start;
1354 Session::engine_halted ()
1358 /* there will be no more calls to process(), so
1359 we'd better clean up for ourselves, right now.
1361 but first, make sure the butler is out of
1365 g_atomic_int_set (&_butler->should_do_transport_work, 0);
1366 set_post_transport_work (PostTransportWork (0));
1369 realtime_stop (false, true);
1370 non_realtime_stop (false, 0, ignored);
1371 transport_sub_state = 0;
1373 TransportStateChange (); /* EMIT SIGNAL */
1378 Session::xrun_recovery ()
1380 Xrun ((nframes64_t)_transport_frame); //EMIT SIGNAL
1382 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1384 /* it didn't actually halt, but we need
1385 to handle things in the same way.
1393 Session::update_latency_compensation (bool with_stop, bool abort)
1395 bool update_jack = false;
1396 PostTransportWork ptw;
1398 if (_state_of_the_state & Deletion) {
1402 _worst_track_latency = 0;
1403 ptw = post_transport_work();
1405 #undef DEBUG_LATENCY
1406 #ifdef DEBUG_LATENCY
1407 cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1410 boost::shared_ptr<RouteList> r = routes.reader ();
1412 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1415 (*i)->handle_transport_stopped (abort, (ptw & PostTransportLocate), (!(ptw & PostTransportLocate) || pending_locate_flush));
1418 nframes_t old_latency = (*i)->output()->signal_latency ();
1419 nframes_t track_latency = (*i)->update_total_latency ();
1421 if (old_latency != track_latency) {
1422 (*i)->input()->update_port_total_latencies ();
1423 (*i)->output()->update_port_total_latencies ();
1427 if (!(*i)->is_hidden() && ((*i)->active())) {
1428 _worst_track_latency = max (_worst_track_latency, track_latency);
1433 _engine.update_total_latencies ();
1436 #ifdef DEBUG_LATENCY
1437 cerr << "\tworst was " << _worst_track_latency << endl;
1440 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1441 (*i)->set_latency_delay (_worst_track_latency);
1444 set_worst_io_latencies ();
1446 /* reflect any changes in latencies into capture offsets
1449 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1451 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1452 (*i)->set_capture_offset ();
1457 Session::allow_auto_play (bool yn)
1459 auto_play_legal = yn;
1463 Session::reset_jack_connection (jack_client_t* jack)
1467 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1468 js->reset_client (jack);
1473 Session::maybe_stop (nframes_t limit)
1475 if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
1476 if (synced_to_jack () && config.get_jack_time_master ()) {
1477 _engine.transport_stop ();
1478 } else if (!synced_to_jack ()) {