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)
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) {
1050 _slave = new MTC_Slave (*this, *_mtc_port);
1053 catch (failed_constructor& err) {
1058 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1061 _desired_transport_speed = _transport_speed;
1065 _slave = new JACK_Slave (_engine.jack());
1066 _desired_transport_speed = _transport_speed;
1070 Config->set_slave_source (src);
1072 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1073 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1074 if (!(*i)->hidden()) {
1075 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1076 non_rt_required = true;
1078 (*i)->set_slaved (_slave);
1083 reverse_diskstream_buffers ();
1086 if (non_rt_required) {
1087 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1088 schedule_butler_transport_work ();
1095 Session::reverse_diskstream_buffers ()
1097 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1098 schedule_butler_transport_work ();
1102 Session::set_diskstream_speed (Diskstream* stream, float speed)
1104 if (stream->realtime_set_speed (speed, false)) {
1105 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1106 schedule_butler_transport_work ();
1112 Session::set_audio_range (list<AudioRange>& range)
1114 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1115 ev->audio_range = range;
1120 Session::request_play_range (bool yn)
1122 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1127 Session::set_play_range (bool yn)
1129 /* Called from event-processing context */
1131 if (_play_range != yn) {
1136 /* stop transport */
1137 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1144 Session::setup_auto_play ()
1146 /* Called from event-processing context */
1150 _clear_event_type (Event::RangeStop);
1151 _clear_event_type (Event::RangeLocate);
1157 list<AudioRange>::size_type sz = current_audio_range.size();
1161 list<AudioRange>::iterator i = current_audio_range.begin();
1162 list<AudioRange>::iterator next;
1164 while (i != current_audio_range.end()) {
1169 /* locating/stopping is subject to delays for declicking.
1172 nframes_t requested_frame = (*i).end;
1174 if (requested_frame > current_block_size) {
1175 requested_frame -= current_block_size;
1177 requested_frame = 0;
1180 if (next == current_audio_range.end()) {
1181 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1183 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1191 } else if (sz == 1) {
1193 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1198 /* now start rolling at the right place */
1200 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1205 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1207 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1208 ev->target2_frame = start;
1213 Session::request_bounded_roll (nframes_t start, nframes_t end)
1216 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1218 request_locate (start, true);
1222 Session::engine_halted ()
1226 /* there will be no more calls to process(), so
1227 we'd better clean up for ourselves, right now.
1229 but first, make sure the butler is out of
1233 g_atomic_int_set (&butler_should_do_transport_work, 0);
1234 post_transport_work = PostTransportWork (0);
1237 realtime_stop (false);
1238 non_realtime_stop (false, 0, ignored);
1239 transport_sub_state = 0;
1241 TransportStateChange (); /* EMIT SIGNAL */
1246 Session::xrun_recovery ()
1248 Xrun (transport_frame()); //EMIT SIGNAL
1250 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1252 /* it didn't actually halt, but we need
1253 to handle things in the same way.
1261 Session::update_latency_compensation (bool with_stop, bool abort)
1263 bool update_jack = false;
1265 if (_state_of_the_state & Deletion) {
1269 _worst_track_latency = 0;
1271 #undef DEBUG_LATENCY
1272 #ifdef DEBUG_LATENCY
1273 cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1276 boost::shared_ptr<RouteList> r = routes.reader ();
1278 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1280 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1281 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1284 nframes_t old_latency = (*i)->signal_latency ();
1285 nframes_t track_latency = (*i)->update_total_latency ();
1287 if (old_latency != track_latency) {
1291 if (!(*i)->hidden() && ((*i)->active())) {
1292 _worst_track_latency = max (_worst_track_latency, track_latency);
1296 #ifdef DEBUG_LATENCY
1297 cerr << "\tworst was " << _worst_track_latency << endl;
1300 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1301 (*i)->set_latency_delay (_worst_track_latency);
1304 /* tell JACK to play catch up */
1307 _engine.update_total_latencies ();
1310 set_worst_io_latencies ();
1312 /* reflect any changes in latencies into capture offsets
1315 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1317 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1318 (*i)->set_capture_offset ();
1323 Session::update_latency_compensation_proxy (void* ignored)
1325 update_latency_compensation (false, false);
1329 Session::allow_auto_play (bool yn)
1331 auto_play_legal = yn;
1335 Session::reset_jack_connection (jack_client_t* jack)
1339 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1340 js->reset_client (jack);