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>
33 #include <midi++/mmc.h>
34 #include <midi++/port.h>
36 #include <ardour/ardour.h>
37 #include <ardour/audioengine.h>
38 #include <ardour/session.h>
39 #include <ardour/audio_diskstream.h>
40 #include <ardour/auditioner.h>
41 #include <ardour/slave.h>
42 #include <ardour/location.h>
47 using namespace ARDOUR;
52 Session::request_input_change_handling ()
54 if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
55 Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0);
61 Session::request_slave_source (SlaveSource src)
63 Event* ev = new Event (Event::SetSlaveSource, Event::Add, Event::Immediate, 0, 0.0);
66 /* could set_seamless_loop() be disposed of entirely?*/
67 Config->set_seamless_loop (false);
69 Config->set_seamless_loop (true);
76 Session::request_transport_speed (float speed)
78 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, speed);
83 Session::request_diskstream_speed (Diskstream& ds, float speed)
85 Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed);
91 Session::request_stop (bool abort)
93 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0, abort);
98 Session::request_locate (nframes_t target_frame, bool with_roll)
100 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, false);
105 Session::force_locate (nframes_t target_frame, bool with_roll)
107 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, true);
112 Session::request_play_loop (bool yn)
115 Location *location = _locations.auto_loop_location();
117 if (location == 0 && yn) {
118 error << _("Cannot loop - no loop range defined")
123 ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, 0.0, yn);
126 if (!yn && Config->get_seamless_loop() && transport_rolling()) {
127 // request an immediate locate to refresh the diskstreams
128 // after disabling looping
129 request_locate (_transport_frame-1, false);
134 Session::realtime_stop (bool abort)
136 /* assume that when we start, we'll be moving forwards */
138 // FIXME: where should this really be? [DR]
139 //send_full_time_code();
140 deliver_mmc (MIDI::MachineControl::cmdStop, _transport_frame);
141 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
143 if (_transport_speed < 0.0f) {
144 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop | PostTransportReverse);
146 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop);
149 if (actively_recording()) {
151 /* move the transport position back to where the
152 request for a stop was noticed. we rolled
153 past that point to pick up delayed input.
156 #ifndef LEAVE_TRANSPORT_UNADJUSTED
157 decrement_transport_position (_worst_output_latency);
160 /* the duration change is not guaranteed to have happened, but is likely */
162 post_transport_work = PostTransportWork (post_transport_work | PostTransportDuration);
166 post_transport_work = PostTransportWork (post_transport_work | PostTransportAbort);
169 _clear_event_type (Event::StopOnce);
170 _clear_event_type (Event::RangeStop);
171 _clear_event_type (Event::RangeLocate);
173 disable_record (true);
175 reset_slave_state ();
177 _transport_speed = 0;
179 if (Config->get_use_video_sync()) {
180 waiting_for_sync_offset = true;
183 transport_sub_state = ((Config->get_slave_source() == None && Config->get_auto_return()) ? AutoReturning : 0);
187 Session::butler_transport_work ()
191 boost::shared_ptr<RouteList> r = routes.reader ();
192 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
194 int on_entry = g_atomic_int_get (&butler_should_do_transport_work);
197 if (post_transport_work & PostTransportCurveRealloc) {
198 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
199 (*i)->curve_reallocate();
203 if (post_transport_work & PostTransportInputChange) {
204 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
205 (*i)->non_realtime_input_change ();
209 if (post_transport_work & PostTransportSpeed) {
210 non_realtime_set_speed ();
213 if (post_transport_work & PostTransportReverse) {
217 cumulative_rf_motion = 0;
220 /* don't seek if locate will take care of that in non_realtime_stop() */
222 if (!(post_transport_work & PostTransportLocate)) {
224 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
225 if (!(*i)->hidden()) {
226 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
227 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
230 (*i)->seek (_transport_frame);
233 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
234 /* new request, stop seeking, and start again */
235 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
242 if (post_transport_work & PostTransportLocate) {
243 non_realtime_locate ();
246 if (post_transport_work & PostTransportStop) {
247 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
249 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
254 if (post_transport_work & PostTransportOverWrite) {
255 non_realtime_overwrite (on_entry, finished);
257 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
262 if (post_transport_work & PostTransportAudition) {
263 non_realtime_set_audition ();
266 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
270 Session::non_realtime_set_speed ()
272 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
274 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
275 (*i)->non_realtime_set_speed ();
280 Session::non_realtime_overwrite (int on_entry, bool& finished)
282 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
284 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
285 if ((*i)->pending_overwrite) {
286 (*i)->overwrite_existing_buffers ();
288 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
297 Session::non_realtime_locate ()
299 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
301 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
302 (*i)->non_realtime_locate (_transport_frame);
308 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
318 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
320 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
321 if ((*i)->get_captured_frames () != 0) {
327 /* stop and locate are merged here because they share a lot of common stuff */
330 now = localtime (&xnow);
333 auditioner->cancel_audition ();
337 cumulative_rf_motion = 0;
341 begin_reversible_command ("capture");
343 Location* loc = _locations.end_location();
344 bool change_end = false;
346 if (_transport_frame < loc->end()) {
348 /* stopped recording before current end */
350 if (_end_location_is_free) {
352 /* first capture for this session, move end back to where we are */
357 } else if (_transport_frame > loc->end()) {
359 /* stopped recording after the current end, extend it */
365 XMLNode &before = loc->get_state();
366 loc->set_end(_transport_frame);
367 XMLNode &after = loc->get_state();
368 add_command (new MementoCommand<Location>(*loc, &before, &after));
371 _end_location_is_free = false;
372 _have_captured = true;
375 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
376 (*i)->transport_stopped (*now, xnow, abort);
379 boost::shared_ptr<RouteList> r = routes.reader ();
381 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
382 if (!(*i)->is_hidden()) {
383 (*i)->set_pending_declick (0);
388 commit_reversible_command ();
391 if (_engine.running()) {
392 update_latency_compensation (true, abort);
395 if ((Config->get_slave_source() == None && Config->get_auto_return()) || (post_transport_work & PostTransportLocate) || synced_to_jack()) {
397 if (pending_locate_flush) {
398 flush_all_inserts ();
401 if (((Config->get_slave_source() == None && Config->get_auto_return()) || synced_to_jack()) && !(post_transport_work & PostTransportLocate)) {
403 _transport_frame = last_stop_frame;
405 if (synced_to_jack() && !play_loop) {
406 // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl;
407 _engine.transport_locate (_transport_frame);
411 #ifndef LEAVE_TRANSPORT_UNADJUSTED
415 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
416 if (!(*i)->hidden()) {
417 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
418 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
421 (*i)->seek (_transport_frame);
424 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
426 /* we will be back */
431 #ifdef LEAVE_TRANSPORT_UNADJUSTED
435 last_stop_frame = _transport_frame;
439 /* XXX its a little odd that we're doing this here
440 when realtime_stop(), which has already executed,
442 JLC - so let's not because it seems unnecessary and breaks loop record
445 if (!Config->get_latched_record_enable()) {
446 g_atomic_int_set (&_record_status, Disabled);
448 g_atomic_int_set (&_record_status, Enabled);
450 RecordStateChanged (); /* emit signal */
454 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
455 /* capture start has been changed, so save pending state */
456 save_state ("", true);
460 /* always try to get rid of this */
462 remove_pending_capture_state ();
464 /* save the current state of things if appropriate */
466 if (did_record && !saved) {
467 save_state (_current_snapshot_name);
470 if (post_transport_work & PostTransportDuration) {
471 DurationChanged (); /* EMIT SIGNAL */
474 if (post_transport_work & PostTransportStop) {
477 /* do not turn off autoloop on stop */
481 PositionChanged (_transport_frame); /* EMIT SIGNAL */
482 TransportStateChange (); /* EMIT SIGNAL */
484 /* and start it up again if relevant */
486 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
487 request_transport_speed (1.0);
488 pending_locate_roll = false;
493 Session::check_declick_out ()
495 bool locate_required = transport_sub_state & PendingLocate;
497 /* this is called after a process() iteration. if PendingDeclickOut was set,
498 it means that we were waiting to declick the output (which has just been
499 done) before doing something else. this is where we do that "something else".
501 note: called from the audio thread.
504 if (transport_sub_state & PendingDeclickOut) {
506 if (locate_required) {
507 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
508 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
510 stop_transport (pending_abort);
511 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
517 Session::set_play_loop (bool yn)
519 /* Called from event-handling context */
521 if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
527 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
528 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
529 "Recommend changing the configured options")
535 if ((play_loop = yn)) {
540 if ((loc = _locations.auto_loop_location()) != 0) {
542 if (Config->get_seamless_loop()) {
543 // set all diskstreams to use internal looping
544 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
545 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
546 if (!(*i)->hidden()) {
547 (*i)->set_loop (loc);
552 // set all diskstreams to NOT use internal looping
553 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
554 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
555 if (!(*i)->hidden()) {
561 /* stick in the loop event */
563 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
566 /* locate to start of loop and roll if current pos is outside of the loop range */
567 if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
568 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
572 // locate to current position (+ 1 to force reload)
573 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
581 clear_events (Event::AutoLoop);
583 // set all diskstreams to NOT use internal looping
584 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
585 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
586 if (!(*i)->hidden()) {
595 Session::flush_all_inserts ()
597 boost::shared_ptr<RouteList> r = routes.reader ();
599 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
600 (*i)->flush_processors ();
605 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
607 if (synced_to_jack()) {
612 _slave->speed_and_position (sp, pos);
614 if (target_frame != pos) {
616 /* tell JACK to change transport position, and we will
617 follow along later in ::follow_slave()
620 _engine.transport_locate (target_frame);
622 if (sp != 1.0f && with_roll) {
623 _engine.transport_start ();
630 locate (target_frame, with_roll, with_flush, with_loop);
635 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
637 if (actively_recording() && !with_loop) {
641 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
643 set_transport_speed (1.0, false);
645 loop_changing = false;
650 // [DR] FIXME: find out exactly where this should go below
651 _transport_frame = target_frame;
652 smpte_time(_transport_frame, transmitting_smpte_time);
653 outbound_mtc_smpte_frame = _transport_frame;
654 next_quarter_frame_to_send = 0;
656 if (_transport_speed && (!with_loop || loop_changing)) {
657 /* schedule a declick. we'll be called again when its done */
659 if (!(transport_sub_state & PendingDeclickOut)) {
660 transport_sub_state |= (PendingDeclickOut|PendingLocate);
661 pending_locate_frame = target_frame;
662 pending_locate_roll = with_roll;
663 pending_locate_flush = with_flush;
668 if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
669 realtime_stop (false);
672 if ( !with_loop || loop_changing) {
674 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
677 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
680 schedule_butler_transport_work ();
684 /* this is functionally what clear_clicks() does but with a tentative lock */
686 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
688 if (clickm.locked()) {
690 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
699 /* switch from input if we're going to roll */
700 if (Config->get_monitoring_model() == HardwareMonitoring) {
702 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
704 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
705 if ((*i)->record_enabled ()) {
706 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
707 (*i)->monitor_input (!Config->get_auto_input());
712 /* otherwise we're going to stop, so do the opposite */
713 if (Config->get_monitoring_model() == HardwareMonitoring) {
714 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
716 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
717 if ((*i)->record_enabled ()) {
718 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
719 (*i)->monitor_input (true);
725 /* cancel looped playback if transport pos outside of loop range */
727 Location* al = _locations.auto_loop_location();
729 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
730 // cancel looping directly, this is called from event handling context
731 set_play_loop (false);
733 else if (al && _transport_frame == al->start()) {
735 // this is only necessary for seamless looping
737 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
739 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
740 if ((*i)->record_enabled ()) {
741 // tell it we've looped, so it can deal with the record state
742 (*i)->transport_looped(_transport_frame);
747 TransportLooped(); // EMIT SIGNAL
751 loop_changing = false;
753 _send_smpte_update = true;
756 /** Set the transport speed.
757 * @param speed New speed
761 Session::set_transport_speed (float speed, bool abort)
763 if (_transport_speed == speed) {
768 speed = min (8.0f, speed);
769 } else if (speed < 0) {
770 speed = max (-8.0f, speed);
773 if (transport_rolling() && speed == 0.0) {
775 /* we are rolling and we want to stop */
777 if (Config->get_monitoring_model() == HardwareMonitoring)
779 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
781 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
782 if ((*i)->record_enabled ()) {
783 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
784 (*i)->monitor_input (true);
789 if (synced_to_jack ()) {
790 _engine.transport_stop ();
792 stop_transport (abort);
795 } else if (transport_stopped() && speed == 1.0) {
797 /* we are stopped and we want to start rolling at speed 1 */
799 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
803 if (Config->get_monitoring_model() == HardwareMonitoring) {
805 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
807 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
808 if (Config->get_auto_input() && (*i)->record_enabled ()) {
809 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
810 (*i)->monitor_input (false);
815 if (synced_to_jack()) {
816 _engine.transport_start ();
823 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
827 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
828 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
833 if (actively_recording()) {
837 if (speed > 0.0f && _transport_frame == current_end_frame()) {
841 if (speed < 0.0f && _transport_frame == 0) {
847 /* if we are reversing relative to the current speed, or relative to the speed
848 before the last stop, then we have to do extra work.
851 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
852 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
855 _last_transport_speed = _transport_speed;
856 _transport_speed = speed;
858 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
859 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
860 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
861 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
865 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
866 schedule_butler_transport_work ();
872 /** Stop the transport. */
874 Session::stop_transport (bool abort)
876 if (_transport_speed == 0.0f) {
880 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
881 _worst_output_latency > current_block_size)
884 /* we need to capture the audio that has still not yet been received by the system
885 at the time the stop is requested, so we have to roll past that time.
887 we want to declick before stopping, so schedule the autostop for one
888 block before the actual end. we'll declick in the subsequent block,
889 and then we'll really be stopped.
892 Event *ev = new Event (Event::StopOnce, Event::Replace,
893 _transport_frame + _worst_output_latency - current_block_size,
897 transport_sub_state |= StopPendingCapture;
898 pending_abort = abort;
903 if ((transport_sub_state & PendingDeclickOut) == 0) {
904 transport_sub_state |= PendingDeclickOut;
905 /* we'll be called again after the declick */
906 pending_abort = abort;
910 realtime_stop (abort);
911 schedule_butler_transport_work ();
915 Session::start_transport ()
917 _last_roll_location = _transport_frame;
919 /* if record status is Enabled, move it to Recording. if its
920 already Recording, move it to Disabled.
923 switch (record_status()) {
925 if (!Config->get_punch_in()) {
932 disable_record (false);
940 if (!synced_to_jack() || _exporting) {
941 actually_start_transport ();
943 waiting_to_start = true;
948 Session::actually_start_transport ()
950 waiting_to_start = false;
952 transport_sub_state |= PendingDeclickIn;
953 _transport_speed = 1.0;
955 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
956 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
957 (*i)->realtime_set_speed ((*i)->speed(), true);
960 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
962 TransportStateChange (); /* EMIT SIGNAL */
965 /** Do any transport work in the audio thread that needs to be done after the
966 * transport thread is finished. Audio thread, realtime safe.
969 Session::post_transport ()
971 if (post_transport_work & PostTransportAudition) {
972 if (auditioner && auditioner->active()) {
973 process_function = &Session::process_audition;
975 process_function = &Session::process_with_events;
979 if (post_transport_work & PostTransportStop) {
981 transport_sub_state = 0;
984 if (post_transport_work & PostTransportLocate) {
986 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
990 transport_sub_state = 0;
996 post_transport_work = PostTransportWork (0);
1000 Session::reset_rf_scale (nframes_t motion)
1002 cumulative_rf_motion += motion;
1004 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1006 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1008 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1020 Session::set_slave_source (SlaveSource src)
1022 bool reverse = false;
1023 bool non_rt_required = false;
1025 if (_transport_speed) {
1026 error << _("please stop the transport before adjusting slave settings") << endmsg;
1030 // if (src == JACK && Config->get_jack_time_master()) {
1039 if (_transport_speed < 0.0) {
1051 _slave = new MTC_Slave (*this, *_mtc_port);
1054 catch (failed_constructor& err) {
1059 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1062 _desired_transport_speed = _transport_speed;
1066 _slave = new JACK_Slave (_engine.jack());
1067 _desired_transport_speed = _transport_speed;
1071 Config->set_slave_source (src);
1073 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1074 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1075 if (!(*i)->hidden()) {
1076 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1077 non_rt_required = true;
1079 (*i)->set_slaved (_slave);
1084 reverse_diskstream_buffers ();
1087 if (non_rt_required) {
1088 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1089 schedule_butler_transport_work ();
1096 Session::reverse_diskstream_buffers ()
1098 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1099 schedule_butler_transport_work ();
1103 Session::set_diskstream_speed (Diskstream* stream, float speed)
1105 if (stream->realtime_set_speed (speed, false)) {
1106 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1107 schedule_butler_transport_work ();
1113 Session::set_audio_range (list<AudioRange>& range)
1115 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1116 ev->audio_range = range;
1121 Session::request_play_range (bool yn)
1123 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1128 Session::set_play_range (bool yn)
1130 /* Called from event-processing context */
1132 if (_play_range != yn) {
1137 /* stop transport */
1138 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1145 Session::setup_auto_play ()
1147 /* Called from event-processing context */
1151 _clear_event_type (Event::RangeStop);
1152 _clear_event_type (Event::RangeLocate);
1158 list<AudioRange>::size_type sz = current_audio_range.size();
1162 list<AudioRange>::iterator i = current_audio_range.begin();
1163 list<AudioRange>::iterator next;
1165 while (i != current_audio_range.end()) {
1170 /* locating/stopping is subject to delays for declicking.
1173 nframes_t requested_frame = (*i).end;
1175 if (requested_frame > current_block_size) {
1176 requested_frame -= current_block_size;
1178 requested_frame = 0;
1181 if (next == current_audio_range.end()) {
1182 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1184 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1192 } else if (sz == 1) {
1194 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1199 /* now start rolling at the right place */
1201 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1206 Session::request_bounded_roll (nframes_t start, nframes_t end)
1209 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1211 request_locate (start, true);
1215 Session::engine_halted ()
1219 /* there will be no more calls to process(), so
1220 we'd better clean up for ourselves, right now.
1222 but first, make sure the butler is out of
1226 g_atomic_int_set (&butler_should_do_transport_work, 0);
1227 post_transport_work = PostTransportWork (0);
1230 realtime_stop (false);
1231 non_realtime_stop (false, 0, ignored);
1232 transport_sub_state = 0;
1234 TransportStateChange (); /* EMIT SIGNAL */
1239 Session::xrun_recovery ()
1241 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1243 HaltOnXrun (); /* EMIT SIGNAL */
1245 /* it didn't actually halt, but we need
1246 to handle things in the same way.
1254 Session::update_latency_compensation (bool with_stop, bool abort)
1256 bool update_jack = false;
1258 if (_state_of_the_state & Deletion) {
1262 _worst_track_latency = 0;
1264 boost::shared_ptr<RouteList> r = routes.reader ();
1266 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1269 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1270 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1273 nframes_t old_latency = (*i)->signal_latency ();
1274 nframes_t track_latency = (*i)->update_total_latency ();
1276 if (old_latency != track_latency) {
1277 (*i)->update_port_total_latencies ();
1281 if (!(*i)->is_hidden() && ((*i)->active())) {
1282 _worst_track_latency = max (_worst_track_latency, track_latency);
1287 _engine.update_total_latencies ();
1290 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1291 (*i)->set_latency_delay (_worst_track_latency);
1294 set_worst_io_latencies ();
1296 /* reflect any changes in latencies into capture offsets
1299 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1301 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1302 (*i)->set_capture_offset ();
1307 Session::allow_auto_play (bool yn)
1309 auto_play_legal = yn;
1313 Session::reset_jack_connection (jack_client_t* jack)
1317 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1318 js->reset_client (jack);