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, 0);
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 (*i)->non_realtime_locate (_transport_frame);
229 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
230 /* new request, stop seeking, and start again */
231 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
238 if (post_transport_work & PostTransportLocate) {
239 non_realtime_locate ();
242 if (post_transport_work & PostTransportStop) {
243 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
245 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
250 if (post_transport_work & PostTransportOverWrite) {
251 non_realtime_overwrite (on_entry, finished);
253 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
258 if (post_transport_work & PostTransportAudition) {
259 non_realtime_set_audition ();
262 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
266 Session::non_realtime_set_speed ()
268 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
270 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
271 (*i)->non_realtime_set_speed ();
276 Session::non_realtime_overwrite (int on_entry, bool& finished)
278 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
280 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
281 if ((*i)->pending_overwrite) {
282 (*i)->overwrite_existing_buffers ();
284 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
293 Session::non_realtime_locate ()
295 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
297 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
298 (*i)->non_realtime_locate (_transport_frame);
304 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
314 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
316 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
317 if ((*i)->get_captured_frames () != 0) {
323 /* stop and locate are merged here because they share a lot of common stuff */
326 now = localtime (&xnow);
329 auditioner->cancel_audition ();
333 cumulative_rf_motion = 0;
337 begin_reversible_command ("capture");
339 Location* loc = _locations.end_location();
340 bool change_end = false;
342 if (_transport_frame < loc->end()) {
344 /* stopped recording before current end */
346 if (_end_location_is_free) {
348 /* first capture for this session, move end back to where we are */
353 } else if (_transport_frame > loc->end()) {
355 /* stopped recording after the current end, extend it */
361 XMLNode &before = loc->get_state();
362 loc->set_end(_transport_frame);
363 XMLNode &after = loc->get_state();
364 add_command (new MementoCommand<Location>(*loc, &before, &after));
367 _end_location_is_free = false;
368 _have_captured = true;
371 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
372 (*i)->transport_stopped (*now, xnow, abort);
375 boost::shared_ptr<RouteList> r = routes.reader ();
377 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
378 if (!(*i)->is_hidden()) {
379 (*i)->set_pending_declick (0);
384 commit_reversible_command ();
387 if (_engine.running()) {
388 update_latency_compensation (true, abort);
391 if ((Config->get_slave_source() == None && Config->get_auto_return()) ||
392 (post_transport_work & PostTransportLocate) ||
393 (_requested_return_frame >= 0) ||
396 if (pending_locate_flush) {
397 flush_all_inserts ();
400 if (((Config->get_slave_source() == None && Config->get_auto_return()) ||
402 _requested_return_frame >= 0) &&
403 !(post_transport_work & PostTransportLocate)) {
405 bool do_locate = false;
407 if (_requested_return_frame >= 0) {
408 _transport_frame = _requested_return_frame;
409 _requested_return_frame = -1;
412 _transport_frame = last_stop_frame;
413 _requested_return_frame = -1;
416 if (synced_to_jack() && !play_loop) {
421 // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl;
422 _engine.transport_locate (_transport_frame);
426 #ifndef LEAVE_TRANSPORT_UNADJUSTED
430 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
431 if (!(*i)->hidden()) {
432 (*i)->non_realtime_locate (_transport_frame);
434 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
436 /* we will be back */
441 #ifdef LEAVE_TRANSPORT_UNADJUSTED
445 if (_requested_return_frame < 0) {
446 last_stop_frame = _transport_frame;
448 last_stop_frame = _requested_return_frame;
449 _requested_return_frame = -1;
454 /* XXX its a little odd that we're doing this here
455 when realtime_stop(), which has already executed,
457 JLC - so let's not because it seems unnecessary and breaks loop record
460 if (!Config->get_latched_record_enable()) {
461 g_atomic_int_set (&_record_status, Disabled);
463 g_atomic_int_set (&_record_status, Enabled);
465 RecordStateChanged (); /* emit signal */
469 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
470 /* capture start has been changed, so save pending state */
471 save_state ("", true);
475 /* always try to get rid of this */
477 remove_pending_capture_state ();
479 /* save the current state of things if appropriate */
481 if (did_record && !saved) {
482 save_state (_current_snapshot_name);
485 if (post_transport_work & PostTransportDuration) {
486 DurationChanged (); /* EMIT SIGNAL */
489 if (post_transport_work & PostTransportStop) {
492 /* do not turn off autoloop on stop */
496 nframes_t tf = _transport_frame;
498 PositionChanged (tf); /* EMIT SIGNAL */
499 TransportStateChange (); /* EMIT SIGNAL */
501 /* and start it up again if relevant */
503 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
504 request_transport_speed (1.0);
505 pending_locate_roll = false;
510 Session::check_declick_out ()
512 bool locate_required = transport_sub_state & PendingLocate;
514 /* this is called after a process() iteration. if PendingDeclickOut was set,
515 it means that we were waiting to declick the output (which has just been
516 done) before doing something else. this is where we do that "something else".
518 note: called from the audio thread.
521 if (transport_sub_state & PendingDeclickOut) {
523 if (locate_required) {
524 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
525 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
527 stop_transport (pending_abort);
528 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
534 Session::set_play_loop (bool yn)
536 /* Called from event-handling context */
538 if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
544 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
545 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
546 "Recommend changing the configured options")
552 if ((play_loop = yn)) {
557 if ((loc = _locations.auto_loop_location()) != 0) {
559 if (Config->get_seamless_loop()) {
560 // set all diskstreams to use internal looping
561 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
562 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
563 if (!(*i)->hidden()) {
564 (*i)->set_loop (loc);
569 // set all diskstreams to NOT use internal looping
570 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
571 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
572 if (!(*i)->hidden()) {
578 /* stick in the loop event */
580 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
583 /* locate to start of loop and roll if current pos is outside of the loop range */
584 if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
585 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
589 // locate to current position (+ 1 to force reload)
590 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
598 clear_events (Event::AutoLoop);
600 // set all diskstreams to NOT use internal looping
601 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
602 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
603 if (!(*i)->hidden()) {
612 Session::flush_all_inserts ()
614 boost::shared_ptr<RouteList> r = routes.reader ();
616 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
617 (*i)->flush_processors ();
622 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
624 if (synced_to_jack()) {
629 _slave->speed_and_position (sp, pos);
631 if (target_frame != pos) {
633 /* tell JACK to change transport position, and we will
634 follow along later in ::follow_slave()
637 _engine.transport_locate (target_frame);
639 if (sp != 1.0f && with_roll) {
640 _engine.transport_start ();
647 locate (target_frame, with_roll, with_flush, with_loop);
652 Session::micro_locate (nframes_t distance)
654 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
656 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
657 if (!(*i)->can_internal_playback_seek (distance)) {
662 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
663 (*i)->internal_playback_seek (distance);
666 _transport_frame += distance;
671 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
673 if (actively_recording() && !with_loop) {
677 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
679 set_transport_speed (1.0, false);
681 loop_changing = false;
686 // [DR] FIXME: find out exactly where this should go below
687 _transport_frame = target_frame;
688 smpte_time(_transport_frame, transmitting_smpte_time);
689 outbound_mtc_smpte_frame = _transport_frame;
690 next_quarter_frame_to_send = 0;
692 if (_transport_speed && (!with_loop || loop_changing)) {
693 /* schedule a declick. we'll be called again when its done */
695 if (!(transport_sub_state & PendingDeclickOut)) {
696 transport_sub_state |= (PendingDeclickOut|PendingLocate);
697 pending_locate_frame = target_frame;
698 pending_locate_roll = with_roll;
699 pending_locate_flush = with_flush;
704 if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
705 realtime_stop (false);
708 if ( !with_loop || loop_changing) {
710 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
713 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
716 schedule_butler_transport_work ();
720 /* this is functionally what clear_clicks() does but with a tentative lock */
722 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
724 if (clickm.locked()) {
726 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
735 /* switch from input if we're going to roll */
736 if (Config->get_monitoring_model() == HardwareMonitoring) {
738 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
740 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
741 if ((*i)->record_enabled ()) {
742 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
743 (*i)->monitor_input (!Config->get_auto_input());
748 /* otherwise we're going to stop, so do the opposite */
749 if (Config->get_monitoring_model() == HardwareMonitoring) {
750 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
752 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
753 if ((*i)->record_enabled ()) {
754 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
755 (*i)->monitor_input (true);
761 /* cancel looped playback if transport pos outside of loop range */
763 Location* al = _locations.auto_loop_location();
765 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
766 // cancel looping directly, this is called from event handling context
767 set_play_loop (false);
769 else if (al && _transport_frame == al->start()) {
771 // this is only necessary for seamless looping
773 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
775 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
776 if ((*i)->record_enabled ()) {
777 // tell it we've looped, so it can deal with the record state
778 (*i)->transport_looped(_transport_frame);
783 TransportLooped(); // EMIT SIGNAL
787 loop_changing = false;
789 _send_smpte_update = true;
792 /** Set the transport speed.
793 * @param speed New speed
797 Session::set_transport_speed (float speed, bool abort)
799 if (_transport_speed == speed) {
804 speed = min (8.0f, speed);
805 } else if (speed < 0) {
806 speed = max (-8.0f, speed);
809 if (transport_rolling() && speed == 0.0) {
811 /* we are rolling and we want to stop */
813 if (Config->get_monitoring_model() == HardwareMonitoring)
815 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
817 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
818 if ((*i)->record_enabled ()) {
819 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
820 (*i)->monitor_input (true);
825 if (synced_to_jack ()) {
826 _engine.transport_stop ();
828 stop_transport (abort);
831 } else if (transport_stopped() && speed == 1.0) {
833 /* we are stopped and we want to start rolling at speed 1 */
835 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
839 if (Config->get_monitoring_model() == HardwareMonitoring) {
841 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
843 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
844 if (Config->get_auto_input() && (*i)->record_enabled ()) {
845 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
846 (*i)->monitor_input (false);
851 if (synced_to_jack()) {
852 _engine.transport_start ();
859 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
863 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
864 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
869 if (actively_recording()) {
873 if (speed > 0.0f && _transport_frame == current_end_frame()) {
877 if (speed < 0.0f && _transport_frame == 0) {
883 /* if we are reversing relative to the current speed, or relative to the speed
884 before the last stop, then we have to do extra work.
887 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
888 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
891 _last_transport_speed = _transport_speed;
892 _transport_speed = speed;
894 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
895 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
896 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
897 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
901 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
902 schedule_butler_transport_work ();
908 /** Stop the transport. */
910 Session::stop_transport (bool abort)
912 if (_transport_speed == 0.0f) {
916 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
917 _worst_output_latency > current_block_size)
920 /* we need to capture the audio that has still not yet been received by the system
921 at the time the stop is requested, so we have to roll past that time.
923 we want to declick before stopping, so schedule the autostop for one
924 block before the actual end. we'll declick in the subsequent block,
925 and then we'll really be stopped.
928 Event *ev = new Event (Event::StopOnce, Event::Replace,
929 _transport_frame + _worst_output_latency - current_block_size,
933 transport_sub_state |= StopPendingCapture;
934 pending_abort = abort;
939 if ((transport_sub_state & PendingDeclickOut) == 0) {
940 transport_sub_state |= PendingDeclickOut;
941 /* we'll be called again after the declick */
942 pending_abort = abort;
946 realtime_stop (abort);
947 schedule_butler_transport_work ();
951 Session::start_transport ()
953 _last_roll_location = _transport_frame;
955 /* if record status is Enabled, move it to Recording. if its
956 already Recording, move it to Disabled.
959 switch (record_status()) {
961 if (!Config->get_punch_in()) {
968 disable_record (false);
976 if (!synced_to_jack() || _exporting) {
977 actually_start_transport ();
979 waiting_to_start = true;
984 Session::actually_start_transport ()
986 waiting_to_start = false;
988 transport_sub_state |= PendingDeclickIn;
989 _transport_speed = 1.0;
991 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
992 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
993 (*i)->realtime_set_speed ((*i)->speed(), true);
996 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
998 TransportStateChange (); /* EMIT SIGNAL */
1001 /** Do any transport work in the audio thread that needs to be done after the
1002 * transport thread is finished. Audio thread, realtime safe.
1005 Session::post_transport ()
1007 if (post_transport_work & PostTransportAudition) {
1008 if (auditioner && auditioner->active()) {
1009 process_function = &Session::process_audition;
1011 process_function = &Session::process_with_events;
1015 if (post_transport_work & PostTransportStop) {
1017 transport_sub_state = 0;
1020 if (post_transport_work & PostTransportLocate) {
1022 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
1026 transport_sub_state = 0;
1032 post_transport_work = PostTransportWork (0);
1036 Session::reset_rf_scale (nframes_t motion)
1038 cumulative_rf_motion += motion;
1040 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1042 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1044 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1056 Session::set_slave_source (SlaveSource src)
1058 bool reverse = false;
1059 bool non_rt_required = false;
1061 if (_transport_speed) {
1062 error << _("please stop the transport before adjusting slave settings") << endmsg;
1066 // if (src == JACK && Config->get_jack_time_master()) {
1075 if (_transport_speed < 0.0) {
1087 _slave = new MTC_Slave (*this, *_mtc_port);
1090 catch (failed_constructor& err) {
1095 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1098 _desired_transport_speed = _transport_speed;
1102 if (_midi_clock_port) {
1104 _slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24);
1107 catch (failed_constructor& err) {
1112 error << _("No MIDI Clock port defined: MIDI Clock slaving is impossible.") << endmsg;
1115 _desired_transport_speed = _transport_speed;
1119 _slave = new JACK_Slave (_engine.jack());
1120 _desired_transport_speed = _transport_speed;
1125 Config->set_slave_source (src);
1127 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1128 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1129 if (!(*i)->hidden()) {
1130 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1131 non_rt_required = true;
1133 (*i)->set_slaved (_slave);
1138 reverse_diskstream_buffers ();
1141 if (non_rt_required) {
1142 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1143 schedule_butler_transport_work ();
1150 Session::reverse_diskstream_buffers ()
1152 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1153 schedule_butler_transport_work ();
1157 Session::set_diskstream_speed (Diskstream* stream, float speed)
1159 if (stream->realtime_set_speed (speed, false)) {
1160 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1161 schedule_butler_transport_work ();
1167 Session::set_audio_range (list<AudioRange>& range)
1169 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1170 ev->audio_range = range;
1175 Session::request_play_range (bool yn)
1177 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1182 Session::set_play_range (bool yn)
1184 /* Called from event-processing context */
1186 if (_play_range != yn) {
1191 /* stop transport */
1192 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1199 Session::setup_auto_play ()
1201 /* Called from event-processing context */
1205 _clear_event_type (Event::RangeStop);
1206 _clear_event_type (Event::RangeLocate);
1212 list<AudioRange>::size_type sz = current_audio_range.size();
1216 list<AudioRange>::iterator i = current_audio_range.begin();
1217 list<AudioRange>::iterator next;
1219 while (i != current_audio_range.end()) {
1224 /* locating/stopping is subject to delays for declicking.
1227 nframes_t requested_frame = (*i).end;
1229 if (requested_frame > current_block_size) {
1230 requested_frame -= current_block_size;
1232 requested_frame = 0;
1235 if (next == current_audio_range.end()) {
1236 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1238 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1246 } else if (sz == 1) {
1248 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1253 /* now start rolling at the right place */
1255 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1260 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1262 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1263 ev->target2_frame = start;
1268 Session::request_bounded_roll (nframes_t start, nframes_t end)
1271 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1273 request_locate (start, true);
1277 Session::engine_halted ()
1281 /* there will be no more calls to process(), so
1282 we'd better clean up for ourselves, right now.
1284 but first, make sure the butler is out of
1288 g_atomic_int_set (&butler_should_do_transport_work, 0);
1289 post_transport_work = PostTransportWork (0);
1292 realtime_stop (false);
1293 non_realtime_stop (false, 0, ignored);
1294 transport_sub_state = 0;
1296 TransportStateChange (); /* EMIT SIGNAL */
1301 Session::xrun_recovery ()
1303 Xrun (transport_frame()); //EMIT SIGNAL
1305 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1307 /* it didn't actually halt, but we need
1308 to handle things in the same way.
1316 Session::update_latency_compensation (bool with_stop, bool abort)
1318 bool update_jack = false;
1320 if (_state_of_the_state & Deletion) {
1324 _worst_track_latency = 0;
1326 #undef DEBUG_LATENCY
1327 #ifdef DEBUG_LATENCY
1328 cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1331 boost::shared_ptr<RouteList> r = routes.reader ();
1333 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1336 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1337 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1340 nframes_t old_latency = (*i)->signal_latency ();
1341 nframes_t track_latency = (*i)->update_total_latency ();
1343 if (old_latency != track_latency) {
1344 (*i)->update_port_total_latencies ();
1348 if (!(*i)->is_hidden() && ((*i)->active())) {
1349 _worst_track_latency = max (_worst_track_latency, track_latency);
1354 _engine.update_total_latencies ();
1357 #ifdef DEBUG_LATENCY
1358 cerr << "\tworst was " << _worst_track_latency << endl;
1361 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1362 (*i)->set_latency_delay (_worst_track_latency);
1365 set_worst_io_latencies ();
1367 /* reflect any changes in latencies into capture offsets
1370 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1372 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1373 (*i)->set_capture_offset ();
1378 Session::allow_auto_play (bool yn)
1380 auto_play_legal = yn;
1384 Session::reset_jack_connection (jack_client_t* jack)
1388 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1389 js->reset_client (jack);