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/audioengine.h>
39 #include <ardour/session.h>
40 #include <ardour/audio_diskstream.h>
41 #include <ardour/auditioner.h>
42 #include <ardour/slave.h>
43 #include <ardour/location.h>
48 using namespace ARDOUR;
53 Session::request_input_change_handling ()
55 if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
56 Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0);
62 Session::request_slave_source (SlaveSource src)
64 Event* ev = new Event (Event::SetSlaveSource, Event::Add, Event::Immediate, 0, 0.0);
67 /* could set_seamless_loop() be disposed of entirely?*/
68 Config->set_seamless_loop (false);
70 Config->set_seamless_loop (true);
77 Session::request_transport_speed (float speed)
79 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, speed);
84 Session::request_diskstream_speed (Diskstream& ds, float speed)
86 Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed);
92 Session::request_stop (bool abort)
94 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0, abort);
99 Session::request_locate (nframes_t target_frame, bool with_roll)
101 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, false);
106 Session::force_locate (nframes_t target_frame, bool with_roll)
108 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, true);
113 Session::request_play_loop (bool yn)
116 Location *location = _locations.auto_loop_location();
118 if (location == 0 && yn) {
119 error << _("Cannot loop - no loop range defined")
124 ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, 0.0, yn);
127 if (!yn && Config->get_seamless_loop() && transport_rolling()) {
128 // request an immediate locate to refresh the diskstreams
129 // after disabling looping
130 request_locate (_transport_frame-1, false);
135 Session::realtime_stop (bool abort)
137 /* assume that when we start, we'll be moving forwards */
139 // FIXME: where should this really be? [DR]
140 //send_full_time_code();
141 deliver_mmc (MIDI::MachineControl::cmdStop, _transport_frame);
142 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
144 if (_transport_speed < 0.0f) {
145 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop | PostTransportReverse);
147 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop);
150 if (actively_recording()) {
152 /* move the transport position back to where the
153 request for a stop was noticed. we rolled
154 past that point to pick up delayed input.
157 #ifndef LEAVE_TRANSPORT_UNADJUSTED
158 decrement_transport_position (_worst_output_latency);
161 /* the duration change is not guaranteed to have happened, but is likely */
163 post_transport_work = PostTransportWork (post_transport_work | PostTransportDuration);
167 post_transport_work = PostTransportWork (post_transport_work | PostTransportAbort);
170 _clear_event_type (Event::StopOnce);
171 _clear_event_type (Event::RangeStop);
172 _clear_event_type (Event::RangeLocate);
174 disable_record (true);
176 reset_slave_state ();
178 _transport_speed = 0;
180 if (Config->get_use_video_sync()) {
181 waiting_for_sync_offset = true;
184 transport_sub_state = ((Config->get_slave_source() == None && Config->get_auto_return()) ? AutoReturning : 0);
188 Session::butler_transport_work ()
192 boost::shared_ptr<RouteList> r = routes.reader ();
193 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
195 int on_entry = g_atomic_int_get (&butler_should_do_transport_work);
198 if (post_transport_work & PostTransportCurveRealloc) {
199 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
200 (*i)->curve_reallocate();
204 if (post_transport_work & PostTransportInputChange) {
205 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
206 (*i)->non_realtime_input_change ();
210 if (post_transport_work & PostTransportSpeed) {
211 non_realtime_set_speed ();
214 if (post_transport_work & PostTransportReverse) {
218 cumulative_rf_motion = 0;
221 /* don't seek if locate will take care of that in non_realtime_stop() */
223 if (!(post_transport_work & PostTransportLocate)) {
225 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
226 if (!(*i)->hidden()) {
227 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
228 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
231 (*i)->seek (_transport_frame);
234 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
235 /* new request, stop seeking, and start again */
236 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
243 if (post_transport_work & PostTransportLocate) {
244 non_realtime_locate ();
247 if (post_transport_work & PostTransportStop) {
248 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
250 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
255 if (post_transport_work & PostTransportOverWrite) {
256 non_realtime_overwrite (on_entry, finished);
258 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
263 if (post_transport_work & PostTransportAudition) {
264 non_realtime_set_audition ();
267 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
271 Session::non_realtime_set_speed ()
273 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
275 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
276 (*i)->non_realtime_set_speed ();
281 Session::non_realtime_overwrite (int on_entry, bool& finished)
283 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
285 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
286 if ((*i)->pending_overwrite) {
287 (*i)->overwrite_existing_buffers ();
289 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
298 Session::non_realtime_locate ()
300 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
302 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
303 (*i)->non_realtime_locate (_transport_frame);
309 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
319 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
321 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
322 if ((*i)->get_captured_frames () != 0) {
328 /* stop and locate are merged here because they share a lot of common stuff */
331 now = localtime (&xnow);
334 auditioner->cancel_audition ();
338 cumulative_rf_motion = 0;
342 begin_reversible_command ("capture");
344 Location* loc = _locations.end_location();
345 bool change_end = false;
347 if (_transport_frame < loc->end()) {
349 /* stopped recording before current end */
351 if (_end_location_is_free) {
353 /* first capture for this session, move end back to where we are */
358 } else if (_transport_frame > loc->end()) {
360 /* stopped recording after the current end, extend it */
366 XMLNode &before = loc->get_state();
367 loc->set_end(_transport_frame);
368 XMLNode &after = loc->get_state();
369 add_command (new MementoCommand<Location>(*loc, &before, &after));
372 _end_location_is_free = false;
373 _have_captured = true;
376 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
377 (*i)->transport_stopped (*now, xnow, abort);
380 boost::shared_ptr<RouteList> r = routes.reader ();
382 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
383 if (!(*i)->is_hidden()) {
384 (*i)->set_pending_declick (0);
389 commit_reversible_command ();
392 if (_engine.running()) {
393 update_latency_compensation (true, abort);
396 if ((Config->get_slave_source() == None && Config->get_auto_return()) ||
397 (post_transport_work & PostTransportLocate) ||
398 (_requested_return_frame >= 0) ||
401 if (pending_locate_flush) {
402 flush_all_inserts ();
405 if (((Config->get_slave_source() == None && Config->get_auto_return()) ||
407 _requested_return_frame >= 0) &&
408 !(post_transport_work & PostTransportLocate)) {
410 bool do_locate = false;
412 if (_requested_return_frame >= 0) {
413 _transport_frame = _requested_return_frame;
414 _requested_return_frame = -1;
417 _transport_frame = last_stop_frame;
420 if (synced_to_jack() && !play_loop) {
425 // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl;
426 _engine.transport_locate (_transport_frame);
430 #ifndef LEAVE_TRANSPORT_UNADJUSTED
434 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
435 if (!(*i)->hidden()) {
436 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
437 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
440 (*i)->seek (_transport_frame);
443 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
445 /* we will be back */
450 #ifdef LEAVE_TRANSPORT_UNADJUSTED
454 last_stop_frame = _transport_frame;
458 /* XXX its a little odd that we're doing this here
459 when realtime_stop(), which has already executed,
461 JLC - so let's not because it seems unnecessary and breaks loop record
464 if (!Config->get_latched_record_enable()) {
465 g_atomic_int_set (&_record_status, Disabled);
467 g_atomic_int_set (&_record_status, Enabled);
469 RecordStateChanged (); /* emit signal */
473 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
474 /* capture start has been changed, so save pending state */
475 save_state ("", true);
479 /* always try to get rid of this */
481 remove_pending_capture_state ();
483 /* save the current state of things if appropriate */
485 if (did_record && !saved) {
486 save_state (_current_snapshot_name);
489 if (post_transport_work & PostTransportDuration) {
490 DurationChanged (); /* EMIT SIGNAL */
493 if (post_transport_work & PostTransportStop) {
496 /* do not turn off autoloop on stop */
500 nframes_t tf = _transport_frame;
502 PositionChanged (tf); /* EMIT SIGNAL */
503 TransportStateChange (); /* EMIT SIGNAL */
505 /* and start it up again if relevant */
507 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
508 request_transport_speed (1.0);
509 pending_locate_roll = false;
514 Session::check_declick_out ()
516 bool locate_required = transport_sub_state & PendingLocate;
518 /* this is called after a process() iteration. if PendingDeclickOut was set,
519 it means that we were waiting to declick the output (which has just been
520 done) before doing something else. this is where we do that "something else".
522 note: called from the audio thread.
525 if (transport_sub_state & PendingDeclickOut) {
527 if (locate_required) {
528 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
529 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
531 stop_transport (pending_abort);
532 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
538 Session::set_play_loop (bool yn)
540 /* Called from event-handling context */
542 if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
548 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
549 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
550 "Recommend changing the configured options")
556 if ((play_loop = yn)) {
561 if ((loc = _locations.auto_loop_location()) != 0) {
563 if (Config->get_seamless_loop()) {
564 // set all diskstreams to use internal looping
565 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
566 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
567 if (!(*i)->hidden()) {
568 (*i)->set_loop (loc);
573 // set all diskstreams to NOT use internal looping
574 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
575 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
576 if (!(*i)->hidden()) {
582 /* stick in the loop event */
584 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
587 /* locate to start of loop and roll if current pos is outside of the loop range */
588 if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
589 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
593 // locate to current position (+ 1 to force reload)
594 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
602 clear_events (Event::AutoLoop);
604 // set all diskstreams to NOT use internal looping
605 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
606 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
607 if (!(*i)->hidden()) {
616 Session::flush_all_inserts ()
618 boost::shared_ptr<RouteList> r = routes.reader ();
620 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
621 (*i)->flush_processors ();
626 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
628 if (synced_to_jack()) {
633 _slave->speed_and_position (sp, pos);
635 if (target_frame != pos) {
637 /* tell JACK to change transport position, and we will
638 follow along later in ::follow_slave()
641 _engine.transport_locate (target_frame);
643 if (sp != 1.0f && with_roll) {
644 _engine.transport_start ();
651 locate (target_frame, with_roll, with_flush, with_loop);
656 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
658 if (actively_recording() && !with_loop) {
662 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
664 set_transport_speed (1.0, false);
666 loop_changing = false;
671 // [DR] FIXME: find out exactly where this should go below
672 _transport_frame = target_frame;
673 smpte_time(_transport_frame, transmitting_smpte_time);
674 outbound_mtc_smpte_frame = _transport_frame;
675 next_quarter_frame_to_send = 0;
677 if (_transport_speed && (!with_loop || loop_changing)) {
678 /* schedule a declick. we'll be called again when its done */
680 if (!(transport_sub_state & PendingDeclickOut)) {
681 transport_sub_state |= (PendingDeclickOut|PendingLocate);
682 pending_locate_frame = target_frame;
683 pending_locate_roll = with_roll;
684 pending_locate_flush = with_flush;
689 if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
690 realtime_stop (false);
693 if ( !with_loop || loop_changing) {
695 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
698 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
701 schedule_butler_transport_work ();
705 /* this is functionally what clear_clicks() does but with a tentative lock */
707 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
709 if (clickm.locked()) {
711 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
720 /* switch from input if we're going to roll */
721 if (Config->get_monitoring_model() == HardwareMonitoring) {
723 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
725 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
726 if ((*i)->record_enabled ()) {
727 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
728 (*i)->monitor_input (!Config->get_auto_input());
733 /* otherwise we're going to stop, so do the opposite */
734 if (Config->get_monitoring_model() == HardwareMonitoring) {
735 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
737 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
738 if ((*i)->record_enabled ()) {
739 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
740 (*i)->monitor_input (true);
746 /* cancel looped playback if transport pos outside of loop range */
748 Location* al = _locations.auto_loop_location();
750 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
751 // cancel looping directly, this is called from event handling context
752 set_play_loop (false);
754 else if (al && _transport_frame == al->start()) {
756 // this is only necessary for seamless looping
758 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
760 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
761 if ((*i)->record_enabled ()) {
762 // tell it we've looped, so it can deal with the record state
763 (*i)->transport_looped(_transport_frame);
768 TransportLooped(); // EMIT SIGNAL
772 loop_changing = false;
774 _send_smpte_update = true;
777 /** Set the transport speed.
778 * @param speed New speed
782 Session::set_transport_speed (float speed, bool abort)
784 if (_transport_speed == speed) {
789 speed = min (8.0f, speed);
790 } else if (speed < 0) {
791 speed = max (-8.0f, speed);
794 if (transport_rolling() && speed == 0.0) {
796 /* we are rolling and we want to stop */
798 if (Config->get_monitoring_model() == HardwareMonitoring)
800 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
802 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
803 if ((*i)->record_enabled ()) {
804 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
805 (*i)->monitor_input (true);
810 if (synced_to_jack ()) {
811 _engine.transport_stop ();
813 stop_transport (abort);
816 } else if (transport_stopped() && speed == 1.0) {
818 /* we are stopped and we want to start rolling at speed 1 */
820 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
824 if (Config->get_monitoring_model() == HardwareMonitoring) {
826 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
828 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
829 if (Config->get_auto_input() && (*i)->record_enabled ()) {
830 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
831 (*i)->monitor_input (false);
836 if (synced_to_jack()) {
837 _engine.transport_start ();
844 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
848 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
849 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
854 if (actively_recording()) {
858 if (speed > 0.0f && _transport_frame == current_end_frame()) {
862 if (speed < 0.0f && _transport_frame == 0) {
868 /* if we are reversing relative to the current speed, or relative to the speed
869 before the last stop, then we have to do extra work.
872 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
873 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
876 _last_transport_speed = _transport_speed;
877 _transport_speed = speed;
879 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
880 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
881 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
882 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
886 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
887 schedule_butler_transport_work ();
893 /** Stop the transport. */
895 Session::stop_transport (bool abort)
897 if (_transport_speed == 0.0f) {
901 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
902 _worst_output_latency > current_block_size)
905 /* we need to capture the audio that has still not yet been received by the system
906 at the time the stop is requested, so we have to roll past that time.
908 we want to declick before stopping, so schedule the autostop for one
909 block before the actual end. we'll declick in the subsequent block,
910 and then we'll really be stopped.
913 Event *ev = new Event (Event::StopOnce, Event::Replace,
914 _transport_frame + _worst_output_latency - current_block_size,
918 transport_sub_state |= StopPendingCapture;
919 pending_abort = abort;
924 if ((transport_sub_state & PendingDeclickOut) == 0) {
925 transport_sub_state |= PendingDeclickOut;
926 /* we'll be called again after the declick */
927 pending_abort = abort;
931 realtime_stop (abort);
932 schedule_butler_transport_work ();
936 Session::start_transport ()
938 _last_roll_location = _transport_frame;
940 /* if record status is Enabled, move it to Recording. if its
941 already Recording, move it to Disabled.
944 switch (record_status()) {
946 if (!Config->get_punch_in()) {
953 disable_record (false);
961 if (!synced_to_jack() || _exporting) {
962 actually_start_transport ();
964 waiting_to_start = true;
969 Session::actually_start_transport ()
971 waiting_to_start = false;
973 transport_sub_state |= PendingDeclickIn;
974 _transport_speed = 1.0;
976 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
977 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
978 (*i)->realtime_set_speed ((*i)->speed(), true);
981 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
983 TransportStateChange (); /* EMIT SIGNAL */
986 /** Do any transport work in the audio thread that needs to be done after the
987 * transport thread is finished. Audio thread, realtime safe.
990 Session::post_transport ()
992 if (post_transport_work & PostTransportAudition) {
993 if (auditioner && auditioner->active()) {
994 process_function = &Session::process_audition;
996 process_function = &Session::process_with_events;
1000 if (post_transport_work & PostTransportStop) {
1002 transport_sub_state = 0;
1005 if (post_transport_work & PostTransportLocate) {
1007 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
1011 transport_sub_state = 0;
1017 post_transport_work = PostTransportWork (0);
1021 Session::reset_rf_scale (nframes_t motion)
1023 cumulative_rf_motion += motion;
1025 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1027 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1029 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1041 Session::set_slave_source (SlaveSource src)
1043 bool reverse = false;
1044 bool non_rt_required = false;
1046 if (_transport_speed) {
1047 error << _("please stop the transport before adjusting slave settings") << endmsg;
1051 // if (src == JACK && Config->get_jack_time_master()) {
1060 if (_transport_speed < 0.0) {
1072 _slave = new MTC_Slave (*this, *_mtc_port);
1075 catch (failed_constructor& err) {
1080 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1083 _desired_transport_speed = _transport_speed;
1087 _slave = new JACK_Slave (_engine.jack());
1088 _desired_transport_speed = _transport_speed;
1092 Config->set_slave_source (src);
1094 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1095 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1096 if (!(*i)->hidden()) {
1097 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1098 non_rt_required = true;
1100 (*i)->set_slaved (_slave);
1105 reverse_diskstream_buffers ();
1108 if (non_rt_required) {
1109 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1110 schedule_butler_transport_work ();
1117 Session::reverse_diskstream_buffers ()
1119 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1120 schedule_butler_transport_work ();
1124 Session::set_diskstream_speed (Diskstream* stream, float speed)
1126 if (stream->realtime_set_speed (speed, false)) {
1127 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1128 schedule_butler_transport_work ();
1134 Session::set_audio_range (list<AudioRange>& range)
1136 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1137 ev->audio_range = range;
1142 Session::request_play_range (bool yn)
1144 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1149 Session::set_play_range (bool yn)
1151 /* Called from event-processing context */
1153 if (_play_range != yn) {
1158 /* stop transport */
1159 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1166 Session::setup_auto_play ()
1168 /* Called from event-processing context */
1172 _clear_event_type (Event::RangeStop);
1173 _clear_event_type (Event::RangeLocate);
1179 list<AudioRange>::size_type sz = current_audio_range.size();
1183 list<AudioRange>::iterator i = current_audio_range.begin();
1184 list<AudioRange>::iterator next;
1186 while (i != current_audio_range.end()) {
1191 /* locating/stopping is subject to delays for declicking.
1194 nframes_t requested_frame = (*i).end;
1196 if (requested_frame > current_block_size) {
1197 requested_frame -= current_block_size;
1199 requested_frame = 0;
1202 if (next == current_audio_range.end()) {
1203 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1205 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1213 } else if (sz == 1) {
1215 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1220 /* now start rolling at the right place */
1222 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1227 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1229 request_locate (start, false);
1230 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1235 Session::request_bounded_roll (nframes_t start, nframes_t end)
1238 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1240 request_locate (start, true);
1244 Session::engine_halted ()
1248 /* there will be no more calls to process(), so
1249 we'd better clean up for ourselves, right now.
1251 but first, make sure the butler is out of
1255 g_atomic_int_set (&butler_should_do_transport_work, 0);
1256 post_transport_work = PostTransportWork (0);
1259 realtime_stop (false);
1260 non_realtime_stop (false, 0, ignored);
1261 transport_sub_state = 0;
1263 TransportStateChange (); /* EMIT SIGNAL */
1268 Session::xrun_recovery ()
1270 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1272 HaltOnXrun (); /* EMIT SIGNAL */
1274 /* it didn't actually halt, but we need
1275 to handle things in the same way.
1283 Session::update_latency_compensation (bool with_stop, bool abort)
1285 bool update_jack = false;
1287 if (_state_of_the_state & Deletion) {
1291 _worst_track_latency = 0;
1293 boost::shared_ptr<RouteList> r = routes.reader ();
1295 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1298 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1299 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1302 nframes_t old_latency = (*i)->signal_latency ();
1303 nframes_t track_latency = (*i)->update_total_latency ();
1305 if (old_latency != track_latency) {
1306 (*i)->update_port_total_latencies ();
1310 if (!(*i)->is_hidden() && ((*i)->active())) {
1311 _worst_track_latency = max (_worst_track_latency, track_latency);
1316 _engine.update_total_latencies ();
1319 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1320 (*i)->set_latency_delay (_worst_track_latency);
1323 set_worst_io_latencies ();
1325 /* reflect any changes in latencies into capture offsets
1328 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1330 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1331 (*i)->set_capture_offset ();
1336 Session::allow_auto_play (bool yn)
1338 auto_play_legal = yn;
1342 Session::reset_jack_connection (jack_client_t* jack)
1346 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1347 js->reset_client (jack);