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;
777 _send_smpte_update = true;
781 Session::set_transport_speed (float speed, bool abort)
783 if (_transport_speed == speed) {
788 speed = min (8.0f, speed);
789 } else if (speed < 0) {
790 speed = max (-8.0f, speed);
793 if (transport_rolling() && speed == 0.0) {
795 if (Config->get_monitoring_model() == HardwareMonitoring)
797 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
799 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
800 if ((*i)->record_enabled ()) {
801 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
802 (*i)->monitor_input (true);
807 if (synced_to_jack ()) {
808 _engine.transport_stop ();
810 stop_transport (abort);
813 } else if (transport_stopped() && speed == 1.0) {
815 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
819 if (Config->get_monitoring_model() == HardwareMonitoring) {
821 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
823 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
824 if (Config->get_auto_input() && (*i)->record_enabled ()) {
825 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
826 (*i)->monitor_input (false);
831 if (synced_to_jack()) {
832 _engine.transport_start ();
839 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
843 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
844 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
849 if (actively_recording()) {
853 if (speed > 0.0f && _transport_frame == current_end_frame()) {
857 if (speed < 0.0f && _transport_frame == 0) {
863 /* if we are reversing relative to the current speed, or relative to the speed
864 before the last stop, then we have to do extra work.
867 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
868 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
869 last_stop_frame = _transport_frame;
872 _last_transport_speed = _transport_speed;
873 _transport_speed = speed;
875 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
876 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
877 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
878 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
882 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
883 schedule_butler_transport_work ();
889 Session::stop_transport (bool abort)
891 if (_transport_speed == 0.0f) {
895 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
896 _worst_output_latency > current_block_size)
899 /* we need to capture the audio that has still not yet been received by the system
900 at the time the stop is requested, so we have to roll past that time.
902 we want to declick before stopping, so schedule the autostop for one
903 block before the actual end. we'll declick in the subsequent block,
904 and then we'll really be stopped.
907 Event *ev = new Event (Event::StopOnce, Event::Replace,
908 _transport_frame + _worst_output_latency - current_block_size,
912 transport_sub_state |= StopPendingCapture;
913 pending_abort = abort;
918 if ((transport_sub_state & PendingDeclickOut) == 0) {
919 transport_sub_state |= PendingDeclickOut;
920 /* we'll be called again after the declick */
921 pending_abort = abort;
925 realtime_stop (abort);
926 schedule_butler_transport_work ();
930 Session::start_transport ()
932 _last_roll_location = _transport_frame;
935 /* if record status is Enabled, move it to Recording. if its
936 already Recording, move it to Disabled.
939 switch (record_status()) {
941 if (!Config->get_punch_in()) {
948 disable_record (false);
956 transport_sub_state |= PendingDeclickIn;
957 _transport_speed = 1.0;
959 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
960 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
961 (*i)->realtime_set_speed ((*i)->speed(), true);
964 send_mmc_in_another_thread (MIDI::MachineControl::cmdDeferredPlay, 0);
966 TransportStateChange (); /* EMIT SIGNAL */
970 Session::post_transport ()
972 if (post_transport_work & PostTransportAudition) {
973 if (auditioner && auditioner->active()) {
974 process_function = &Session::process_audition;
976 process_function = &Session::process_with_events;
980 if (post_transport_work & PostTransportStop) {
982 transport_sub_state = 0;
985 if (post_transport_work & PostTransportLocate) {
987 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
991 transport_sub_state = 0;
997 post_transport_work = PostTransportWork (0);
1001 Session::reset_rf_scale (nframes_t motion)
1003 cumulative_rf_motion += motion;
1005 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1007 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1009 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1021 Session::set_slave_source (SlaveSource src, bool stop_the_transport)
1023 bool reverse = false;
1024 bool non_rt_required = false;
1026 if (_transport_speed) {
1027 error << _("please stop the transport before adjusting slave settings") << endmsg;
1031 // if (src == JACK && Config->get_jack_time_master()) {
1040 if (_transport_speed < 0.0) {
1046 if (stop_the_transport) {
1054 _slave = new MTC_Slave (*this, *_mtc_port);
1057 catch (failed_constructor& err) {
1062 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1065 _desired_transport_speed = _transport_speed;
1069 _slave = new JACK_Slave (_engine.jack());
1070 _desired_transport_speed = _transport_speed;
1074 Config->set_slave_source (src);
1076 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1077 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1078 if (!(*i)->hidden()) {
1079 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1080 non_rt_required = true;
1082 (*i)->set_slaved (_slave);
1087 reverse_diskstream_buffers ();
1090 if (non_rt_required) {
1091 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1092 schedule_butler_transport_work ();
1099 Session::reverse_diskstream_buffers ()
1101 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1102 schedule_butler_transport_work ();
1106 Session::set_diskstream_speed (Diskstream* stream, float speed)
1108 if (stream->realtime_set_speed (speed, false)) {
1109 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1110 schedule_butler_transport_work ();
1116 Session::set_audio_range (list<AudioRange>& range)
1118 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1119 ev->audio_range = range;
1124 Session::request_play_range (bool yn)
1126 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1131 Session::set_play_range (bool yn)
1133 /* Called from event-processing context */
1135 if (_play_range != yn) {
1140 /* stop transport */
1141 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1148 Session::setup_auto_play ()
1150 /* Called from event-processing context */
1154 _clear_event_type (Event::RangeStop);
1155 _clear_event_type (Event::RangeLocate);
1161 list<AudioRange>::size_type sz = current_audio_range.size();
1165 list<AudioRange>::iterator i = current_audio_range.begin();
1166 list<AudioRange>::iterator next;
1168 while (i != current_audio_range.end()) {
1173 /* locating/stopping is subject to delays for declicking.
1176 nframes_t requested_frame = (*i).end;
1178 if (requested_frame > current_block_size) {
1179 requested_frame -= current_block_size;
1181 requested_frame = 0;
1184 if (next == current_audio_range.end()) {
1185 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1187 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1195 } else if (sz == 1) {
1197 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1202 /* now start rolling at the right place */
1204 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1209 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1211 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1212 ev->target2_frame = start;
1217 Session::request_bounded_roll (nframes_t start, nframes_t end)
1220 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1222 request_locate (start, true);
1226 Session::engine_halted ()
1230 /* there will be no more calls to process(), so
1231 we'd better clean up for ourselves, right now.
1233 but first, make sure the butler is out of
1237 g_atomic_int_set (&butler_should_do_transport_work, 0);
1238 post_transport_work = PostTransportWork (0);
1241 realtime_stop (false);
1242 non_realtime_stop (false, 0, ignored);
1243 transport_sub_state = 0;
1245 if (synced_to_jack()) {
1246 /* transport is already stopped, hence the second argument */
1247 set_slave_source (None, false);
1250 TransportStateChange (); /* EMIT SIGNAL */
1255 Session::xrun_recovery ()
1257 Xrun (transport_frame()); //EMIT SIGNAL
1259 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1261 /* it didn't actually halt, but we need
1262 to handle things in the same way.
1270 Session::update_latency_compensation (bool with_stop, bool abort)
1272 bool update_jack = false;
1274 if (_state_of_the_state & Deletion) {
1278 _worst_track_latency = 0;
1280 #undef DEBUG_LATENCY
1281 #ifdef DEBUG_LATENCY
1282 cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1285 boost::shared_ptr<RouteList> r = routes.reader ();
1287 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1289 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1290 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1293 nframes_t old_latency = (*i)->signal_latency ();
1294 nframes_t track_latency = (*i)->update_total_latency ();
1296 if (old_latency != track_latency) {
1300 if (!(*i)->hidden() && ((*i)->active())) {
1301 _worst_track_latency = max (_worst_track_latency, track_latency);
1305 #ifdef DEBUG_LATENCY
1306 cerr << "\tworst was " << _worst_track_latency << endl;
1309 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1310 (*i)->set_latency_delay (_worst_track_latency);
1313 /* tell JACK to play catch up */
1316 _engine.update_total_latencies ();
1319 set_worst_io_latencies ();
1321 /* reflect any changes in latencies into capture offsets
1324 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1326 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1327 (*i)->set_capture_offset ();
1332 Session::update_latency_compensation_proxy (void* ignored)
1334 update_latency_compensation (false, false);
1338 Session::allow_auto_play (bool yn)
1340 auto_play_legal = yn;
1344 Session::reset_jack_connection (jack_client_t* jack)
1348 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1349 js->reset_client (jack);