2 Copyright (C) 1999-2009 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 if (_transport_speed < 0.0f) {
140 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop | PostTransportReverse);
142 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop);
145 if (actively_recording()) {
147 /* move the transport position back to where the
148 request for a stop was noticed. we rolled
149 past that point to pick up delayed input.
152 #ifndef LEAVE_TRANSPORT_UNADJUSTED
153 decrement_transport_position (_worst_output_latency);
156 /* the duration change is not guaranteed to have happened, but is likely */
158 post_transport_work = PostTransportWork (post_transport_work | PostTransportDuration);
162 post_transport_work = PostTransportWork (post_transport_work | PostTransportAbort);
165 _clear_event_type (Event::StopOnce);
166 _clear_event_type (Event::RangeStop);
167 _clear_event_type (Event::RangeLocate);
169 disable_record (true);
171 reset_slave_state ();
173 _transport_speed = 0;
175 if (Config->get_use_video_sync()) {
176 waiting_for_sync_offset = true;
179 transport_sub_state = ((Config->get_slave_source() == None && Config->get_auto_return()) ? AutoReturning : 0);
183 Session::butler_transport_work ()
187 boost::shared_ptr<RouteList> r = routes.reader ();
188 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
190 int on_entry = g_atomic_int_get (&butler_should_do_transport_work);
193 if (post_transport_work & PostTransportCurveRealloc) {
194 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
195 (*i)->curve_reallocate();
199 if (post_transport_work & PostTransportInputChange) {
200 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
201 (*i)->non_realtime_input_change ();
205 if (post_transport_work & PostTransportSpeed) {
206 non_realtime_set_speed ();
209 if (post_transport_work & PostTransportReverse) {
212 cumulative_rf_motion = 0;
215 /* don't seek if locate will take care of that in non_realtime_stop() */
217 if (!(post_transport_work & PostTransportLocate)) {
219 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
220 if (!(*i)->hidden()) {
221 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
222 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
225 (*i)->seek (_transport_frame);
228 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
229 /* new request, stop seeking, and start again */
230 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
237 if (post_transport_work & (PostTransportStop|PostTransportLocate)) {
238 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
240 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
245 if (post_transport_work & PostTransportOverWrite) {
246 non_realtime_overwrite (on_entry, finished);
248 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
253 if (post_transport_work & PostTransportAudition) {
254 non_realtime_set_audition ();
257 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
261 Session::non_realtime_set_speed ()
263 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
265 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
266 (*i)->non_realtime_set_speed ();
271 Session::non_realtime_overwrite (int on_entry, bool& finished)
273 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
275 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
276 if ((*i)->pending_overwrite) {
277 (*i)->overwrite_existing_buffers ();
279 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
287 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
297 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
299 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
300 if ((*i)->get_captured_frames () != 0) {
306 /* stop and locate are merged here because they share a lot of common stuff */
309 now = localtime (&xnow);
312 auditioner->cancel_audition ();
316 cumulative_rf_motion = 0;
320 begin_reversible_command ("capture");
322 Location* loc = _locations.end_location();
323 bool change_end = false;
325 if (_transport_frame < loc->end()) {
327 /* stopped recording before current end */
329 if (_end_location_is_free) {
331 /* first capture for this session, move end back to where we are */
336 } else if (_transport_frame > loc->end()) {
338 /* stopped recording after the current end, extend it */
344 XMLNode &before = loc->get_state();
345 loc->set_end(_transport_frame);
346 XMLNode &after = loc->get_state();
347 add_command (new MementoCommand<Location>(*loc, &before, &after));
350 _end_location_is_free = false;
351 _have_captured = true;
354 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
355 (*i)->transport_stopped (*now, xnow, abort);
358 boost::shared_ptr<RouteList> r = routes.reader ();
360 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
361 if (!(*i)->hidden()) {
362 (*i)->set_pending_declick (0);
367 commit_reversible_command ();
370 if (_engine.running()) {
371 update_latency_compensation (true, abort);
374 if ((Config->get_slave_source() == None && Config->get_auto_return()) ||
375 (post_transport_work & PostTransportLocate) ||
376 (_requested_return_frame >= 0) ||
379 if (pending_locate_flush) {
380 flush_all_redirects ();
383 if (((Config->get_slave_source() == None && Config->get_auto_return()) ||
385 _requested_return_frame >= 0) &&
386 !(post_transport_work & PostTransportLocate)) {
388 bool do_locate = false;
390 if (_requested_return_frame >= 0) {
391 _transport_frame = _requested_return_frame;
392 _requested_return_frame = -1;
395 _transport_frame = last_stop_frame;
396 _requested_return_frame = -1;
399 if (synced_to_jack() && !play_loop) {
404 // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl;
405 _engine.transport_locate (_transport_frame);
409 #ifndef LEAVE_TRANSPORT_UNADJUSTED
413 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
414 if (!(*i)->hidden()) {
415 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
416 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
419 (*i)->seek (_transport_frame);
422 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
424 /* we will be back */
428 #ifdef LEAVE_TRANSPORT_UNADJUSTED
432 if (_requested_return_frame < 0) {
433 last_stop_frame = _transport_frame;
435 last_stop_frame = _requested_return_frame;
436 _requested_return_frame = -1;
441 send_full_time_code ();
442 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
443 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
447 /* XXX its a little odd that we're doing this here
448 when realtime_stop(), which has already executed,
450 JLC - so let's not because it seems unnecessary and breaks loop record
453 if (!Config->get_latched_record_enable()) {
454 g_atomic_int_set (&_record_status, Disabled);
456 g_atomic_int_set (&_record_status, Enabled);
458 RecordStateChanged (); /* emit signal */
462 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
463 /* capture start has been changed, so save pending state */
464 save_state ("", true);
468 /* always try to get rid of this */
470 remove_pending_capture_state ();
472 /* save the current state of things if appropriate */
474 if (did_record && !saved) {
475 save_state (_current_snapshot_name);
478 if (post_transport_work & PostTransportDuration) {
479 DurationChanged (); /* EMIT SIGNAL */
482 if (post_transport_work & PostTransportStop) {
485 /* do not turn off autoloop on stop */
489 nframes_t tf = _transport_frame;
491 PositionChanged (tf); /* EMIT SIGNAL */
492 TransportStateChange (); /* EMIT SIGNAL */
494 /* and start it up again if relevant */
496 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
497 request_transport_speed (1.0);
498 pending_locate_roll = false;
503 Session::check_declick_out ()
505 bool locate_required = transport_sub_state & PendingLocate;
507 /* this is called after a process() iteration. if PendingDeclickOut was set,
508 it means that we were waiting to declick the output (which has just been
509 done) before doing something else. this is where we do that "something else".
511 note: called from the audio thread.
514 if (transport_sub_state & PendingDeclickOut) {
516 if (locate_required) {
517 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
518 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
520 stop_transport (pending_abort);
521 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
527 Session::set_play_loop (bool yn)
529 /* Called from event-handling context */
531 if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
537 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
538 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
539 "Recommend changing the configured options")
545 if ((play_loop = yn)) {
550 if ((loc = _locations.auto_loop_location()) != 0) {
552 if (Config->get_seamless_loop()) {
553 // set all diskstreams to use internal looping
554 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
555 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
556 if (!(*i)->hidden()) {
557 (*i)->set_loop (loc);
562 // set all diskstreams to NOT use internal looping
563 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
564 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
565 if (!(*i)->hidden()) {
571 /* stick in the loop event */
573 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
576 /* locate to start of loop and roll if current pos is outside of the loop range */
577 if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
578 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
582 // locate to current position (+ 1 to force reload)
583 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
591 clear_events (Event::AutoLoop);
593 // set all diskstreams to NOT use internal looping
594 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
595 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
596 if (!(*i)->hidden()) {
605 Session::flush_all_redirects ()
607 boost::shared_ptr<RouteList> r = routes.reader ();
609 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
610 (*i)->flush_redirects ();
615 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
617 if (synced_to_jack()) {
622 _slave->speed_and_position (sp, pos);
624 if (target_frame != pos) {
626 /* tell JACK to change transport position, and we will
627 follow along later in ::follow_slave()
630 _engine.transport_locate (target_frame);
632 if (sp != 1.0f && with_roll) {
633 _engine.transport_start ();
640 locate (target_frame, with_roll, with_flush, with_loop);
645 Session::micro_locate (nframes_t distance)
647 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
649 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
650 if (!(*i)->can_internal_playback_seek (distance)) {
655 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
656 (*i)->internal_playback_seek (distance);
659 _transport_frame += distance;
664 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
666 if (actively_recording() && !with_loop) {
670 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
672 set_transport_speed (1.0, false);
674 loop_changing = false;
678 _transport_frame = target_frame;
680 if (_transport_speed && (!with_loop || loop_changing)) {
681 /* schedule a declick. we'll be called again when its done */
683 if (!(transport_sub_state & PendingDeclickOut)) {
684 transport_sub_state |= (PendingDeclickOut|PendingLocate);
685 pending_locate_frame = target_frame;
686 pending_locate_roll = with_roll;
687 pending_locate_flush = with_flush;
692 if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
693 realtime_stop (false);
696 if ( !with_loop || loop_changing) {
698 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
701 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
704 schedule_butler_transport_work ();
708 /* this is functionally what clear_clicks() does but with a tentative lock */
710 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
712 if (clickm.locked()) {
714 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
723 /* switch from input if we're going to roll */
724 if (Config->get_monitoring_model() == HardwareMonitoring) {
726 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
728 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
729 if ((*i)->record_enabled ()) {
730 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
731 (*i)->monitor_input (!Config->get_auto_input());
736 /* otherwise we're going to stop, so do the opposite */
737 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 to input" << __FILE__ << __LINE__ << endl << endl;
743 (*i)->monitor_input (true);
749 /* cancel looped playback if transport pos outside of loop range */
751 Location* al = _locations.auto_loop_location();
753 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
754 // cancel looping directly, this is called from event handling context
755 set_play_loop (false);
757 else if (al && _transport_frame == al->start()) {
759 // this is only necessary for seamless looping
761 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
763 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
764 if ((*i)->record_enabled ()) {
765 // tell it we've looped, so it can deal with the record state
766 (*i)->transport_looped(_transport_frame);
771 TransportLooped(); // EMIT SIGNAL
775 loop_changing = false;
779 Session::set_transport_speed (float speed, bool abort)
781 if (_transport_speed == speed) {
786 speed = min (8.0f, speed);
787 } else if (speed < 0) {
788 speed = max (-8.0f, speed);
791 if (transport_rolling() && speed == 0.0) {
793 if (Config->get_monitoring_model() == HardwareMonitoring)
795 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
797 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
798 if ((*i)->record_enabled ()) {
799 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
800 (*i)->monitor_input (true);
805 if (synced_to_jack ()) {
806 _engine.transport_stop ();
808 stop_transport (abort);
811 } else if (transport_stopped() && speed == 1.0) {
813 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
817 if (Config->get_monitoring_model() == HardwareMonitoring) {
819 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
821 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
822 if (Config->get_auto_input() && (*i)->record_enabled ()) {
823 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
824 (*i)->monitor_input (false);
829 if (synced_to_jack()) {
830 _engine.transport_start ();
837 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
841 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
842 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
847 if (actively_recording()) {
851 if (speed > 0.0f && _transport_frame == current_end_frame()) {
855 if (speed < 0.0f && _transport_frame == 0) {
861 /* if we are reversing relative to the current speed, or relative to the speed
862 before the last stop, then we have to do extra work.
865 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
866 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
867 last_stop_frame = _transport_frame;
870 _last_transport_speed = _transport_speed;
871 _transport_speed = speed;
873 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
874 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
875 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
876 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
880 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
881 schedule_butler_transport_work ();
887 Session::stop_transport (bool abort)
889 if (_transport_speed == 0.0f) {
893 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
894 _worst_output_latency > current_block_size)
897 /* we need to capture the audio that has still not yet been received by the system
898 at the time the stop is requested, so we have to roll past that time.
900 we want to declick before stopping, so schedule the autostop for one
901 block before the actual end. we'll declick in the subsequent block,
902 and then we'll really be stopped.
905 Event *ev = new Event (Event::StopOnce, Event::Replace,
906 _transport_frame + _worst_output_latency - current_block_size,
910 transport_sub_state |= StopPendingCapture;
911 pending_abort = abort;
916 if ((transport_sub_state & PendingDeclickOut) == 0) {
917 transport_sub_state |= PendingDeclickOut;
918 /* we'll be called again after the declick */
919 pending_abort = abort;
923 realtime_stop (abort);
924 schedule_butler_transport_work ();
928 Session::start_transport ()
930 _last_roll_location = _transport_frame;
933 /* if record status is Enabled, move it to Recording. if its
934 already Recording, move it to Disabled.
937 switch (record_status()) {
939 if (!Config->get_punch_in()) {
946 disable_record (false);
954 transport_sub_state |= PendingDeclickIn;
955 _transport_speed = 1.0;
957 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
958 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
959 (*i)->realtime_set_speed ((*i)->speed(), true);
962 send_mmc_in_another_thread (MIDI::MachineControl::cmdDeferredPlay, 0);
964 TransportStateChange (); /* EMIT SIGNAL */
968 Session::post_transport ()
970 if (post_transport_work & PostTransportAudition) {
971 if (auditioner && auditioner->active()) {
972 process_function = &Session::process_audition;
974 process_function = &Session::process_with_events;
978 if (post_transport_work & PostTransportStop) {
980 transport_sub_state = 0;
983 if (post_transport_work & PostTransportLocate) {
985 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
989 transport_sub_state = 0;
995 post_transport_work = PostTransportWork (0);
999 Session::reset_rf_scale (nframes_t motion)
1001 cumulative_rf_motion += motion;
1003 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1005 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1007 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1019 Session::set_slave_source (SlaveSource src, bool stop_the_transport)
1021 bool reverse = false;
1022 bool non_rt_required = false;
1024 if (_transport_speed) {
1025 error << _("please stop the transport before adjusting slave settings") << endmsg;
1029 // if (src == JACK && Config->get_jack_time_master()) {
1038 if (_transport_speed < 0.0) {
1044 if (stop_the_transport) {
1052 _slave = new MTC_Slave (*this, *_mtc_port);
1055 catch (failed_constructor& err) {
1060 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1063 _desired_transport_speed = _transport_speed;
1067 _slave = new JACK_Slave (_engine.jack());
1068 _desired_transport_speed = _transport_speed;
1072 Config->set_slave_source (src);
1074 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1075 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1076 if (!(*i)->hidden()) {
1077 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1078 non_rt_required = true;
1080 (*i)->set_slaved (_slave);
1085 reverse_diskstream_buffers ();
1088 if (non_rt_required) {
1089 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1090 schedule_butler_transport_work ();
1097 Session::reverse_diskstream_buffers ()
1099 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1100 schedule_butler_transport_work ();
1104 Session::set_diskstream_speed (Diskstream* stream, float speed)
1106 if (stream->realtime_set_speed (speed, false)) {
1107 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1108 schedule_butler_transport_work ();
1114 Session::set_audio_range (list<AudioRange>& range)
1116 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1117 ev->audio_range = range;
1122 Session::request_play_range (bool yn)
1124 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1129 Session::set_play_range (bool yn)
1131 /* Called from event-processing context */
1133 if (_play_range != yn) {
1138 /* stop transport */
1139 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1146 Session::setup_auto_play ()
1148 /* Called from event-processing context */
1152 _clear_event_type (Event::RangeStop);
1153 _clear_event_type (Event::RangeLocate);
1159 list<AudioRange>::size_type sz = current_audio_range.size();
1163 list<AudioRange>::iterator i = current_audio_range.begin();
1164 list<AudioRange>::iterator next;
1166 while (i != current_audio_range.end()) {
1171 /* locating/stopping is subject to delays for declicking.
1174 nframes_t requested_frame = (*i).end;
1176 if (requested_frame > current_block_size) {
1177 requested_frame -= current_block_size;
1179 requested_frame = 0;
1182 if (next == current_audio_range.end()) {
1183 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1185 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1193 } else if (sz == 1) {
1195 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1200 /* now start rolling at the right place */
1202 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1207 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1209 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1210 ev->target2_frame = start;
1215 Session::request_bounded_roll (nframes_t start, nframes_t end)
1218 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1220 request_locate (start, true);
1224 Session::engine_halted ()
1228 /* there will be no more calls to process(), so
1229 we'd better clean up for ourselves, right now.
1231 but first, make sure the butler is out of
1235 g_atomic_int_set (&butler_should_do_transport_work, 0);
1236 post_transport_work = PostTransportWork (0);
1239 realtime_stop (false);
1240 non_realtime_stop (false, 0, ignored);
1241 transport_sub_state = 0;
1243 if (synced_to_jack()) {
1244 /* transport is already stopped, hence the second argument */
1245 set_slave_source (None, false);
1248 TransportStateChange (); /* EMIT SIGNAL */
1253 Session::xrun_recovery ()
1255 Xrun (transport_frame()); //EMIT SIGNAL
1257 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1259 /* it didn't actually halt, but we need
1260 to handle things in the same way.
1268 Session::update_latency_compensation (bool with_stop, bool abort)
1270 bool update_jack = false;
1272 if (_state_of_the_state & Deletion) {
1276 _worst_track_latency = 0;
1278 #undef DEBUG_LATENCY
1279 #ifdef DEBUG_LATENCY
1280 cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1283 boost::shared_ptr<RouteList> r = routes.reader ();
1285 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1287 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1288 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1291 nframes_t old_latency = (*i)->signal_latency ();
1292 nframes_t track_latency = (*i)->update_total_latency ();
1294 if (old_latency != track_latency) {
1298 if (!(*i)->hidden() && ((*i)->active())) {
1299 _worst_track_latency = max (_worst_track_latency, track_latency);
1303 #ifdef DEBUG_LATENCY
1304 cerr << "\tworst was " << _worst_track_latency << endl;
1307 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1308 (*i)->set_latency_delay (_worst_track_latency);
1311 /* tell JACK to play catch up */
1314 _engine.update_total_latencies ();
1317 set_worst_io_latencies ();
1319 /* reflect any changes in latencies into capture offsets
1322 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1324 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1325 (*i)->set_capture_offset ();
1330 Session::update_latency_compensation_proxy (void* ignored)
1332 update_latency_compensation (false, false);
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);