2 Copyright (C) 1999-2003 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include <sigc++/bind.h>
25 #include <sigc++/retype.h>
28 #include <pbd/error.h>
29 #include <glibmm/thread.h>
30 #include <pbd/pthread_utils.h>
31 #include <pbd/memento_command.h>
32 #include <pbd/stacktrace.h>
34 #include <midi++/mmc.h>
35 #include <midi++/port.h>
37 #include <ardour/ardour.h>
38 #include <ardour/audioengine.h>
39 #include <ardour/session.h>
40 #include <ardour/audio_diskstream.h>
41 #include <ardour/auditioner.h>
42 #include <ardour/slave.h>
43 #include <ardour/location.h>
48 using namespace ARDOUR;
53 Session::request_input_change_handling ()
55 if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
56 Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0);
62 Session::request_slave_source (SlaveSource src)
64 Event* ev = new Event (Event::SetSlaveSource, Event::Add, Event::Immediate, 0, 0.0);
67 /* could set_seamless_loop() be disposed of entirely?*/
68 Config->set_seamless_loop (false);
70 Config->set_seamless_loop (true);
77 Session::request_transport_speed (float speed)
79 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, speed);
84 Session::request_diskstream_speed (Diskstream& ds, float speed)
86 Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed);
92 Session::request_stop (bool abort)
94 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0, abort);
99 Session::request_locate (nframes_t target_frame, bool with_roll)
101 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, false);
106 Session::force_locate (nframes_t target_frame, bool with_roll)
108 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, true);
113 Session::request_play_loop (bool yn)
116 Location *location = _locations.auto_loop_location();
118 if (location == 0 && yn) {
119 error << _("Cannot loop - no loop range defined")
124 ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, 0.0, yn);
127 if (!yn && Config->get_seamless_loop() && transport_rolling()) {
128 // request an immediate locate to refresh the diskstreams
129 // after disabling looping
130 request_locate (_transport_frame-1, false);
135 Session::realtime_stop (bool abort)
137 /* assume that when we start, we'll be moving forwards */
139 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) {
213 cumulative_rf_motion = 0;
216 /* don't seek if locate will take care of that in non_realtime_stop() */
218 if (!(post_transport_work & PostTransportLocate)) {
220 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
221 if (!(*i)->hidden()) {
222 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
223 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
226 (*i)->seek (_transport_frame);
229 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
230 /* new request, stop seeking, and start again */
231 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
238 if (post_transport_work & (PostTransportStop|PostTransportLocate)) {
239 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
241 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
246 if (post_transport_work & PostTransportOverWrite) {
247 non_realtime_overwrite (on_entry, finished);
249 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
254 if (post_transport_work & PostTransportAudition) {
255 non_realtime_set_audition ();
258 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
262 Session::non_realtime_set_speed ()
264 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
266 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
267 (*i)->non_realtime_set_speed ();
272 Session::non_realtime_overwrite (int on_entry, bool& finished)
274 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
276 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
277 if ((*i)->pending_overwrite) {
278 (*i)->overwrite_existing_buffers ();
280 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
288 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
298 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
300 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
301 if ((*i)->get_captured_frames () != 0) {
307 /* stop and locate are merged here because they share a lot of common stuff */
310 now = localtime (&xnow);
313 auditioner->cancel_audition ();
317 cumulative_rf_motion = 0;
321 begin_reversible_command ("capture");
323 Location* loc = _locations.end_location();
324 bool change_end = false;
326 if (_transport_frame < loc->end()) {
328 /* stopped recording before current end */
330 if (_end_location_is_free) {
332 /* first capture for this session, move end back to where we are */
337 } else if (_transport_frame > loc->end()) {
339 /* stopped recording after the current end, extend it */
345 XMLNode &before = loc->get_state();
346 loc->set_end(_transport_frame);
347 XMLNode &after = loc->get_state();
348 add_command (new MementoCommand<Location>(*loc, &before, &after));
351 _end_location_is_free = false;
352 _have_captured = true;
355 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
356 (*i)->transport_stopped (*now, xnow, abort);
359 boost::shared_ptr<RouteList> r = routes.reader ();
361 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
362 if (!(*i)->hidden()) {
363 (*i)->set_pending_declick (0);
368 commit_reversible_command ();
371 if (_engine.running()) {
372 update_latency_compensation (true, abort);
375 if ((Config->get_slave_source() == None && Config->get_auto_return()) ||
376 (post_transport_work & PostTransportLocate) ||
377 (_requested_return_frame >= 0) ||
380 if (pending_locate_flush) {
381 flush_all_redirects ();
384 if (((Config->get_slave_source() == None && Config->get_auto_return()) ||
386 _requested_return_frame >= 0) &&
387 !(post_transport_work & PostTransportLocate)) {
389 bool do_locate = false;
391 if (_requested_return_frame >= 0) {
392 _transport_frame = _requested_return_frame;
393 _requested_return_frame = -1;
396 _transport_frame = last_stop_frame;
397 _requested_return_frame = -1;
400 if (synced_to_jack() && !play_loop) {
405 // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl;
406 _engine.transport_locate (_transport_frame);
410 #ifndef LEAVE_TRANSPORT_UNADJUSTED
414 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
415 if (!(*i)->hidden()) {
416 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
417 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
420 (*i)->seek (_transport_frame);
423 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
425 /* we will be back */
429 #ifdef LEAVE_TRANSPORT_UNADJUSTED
433 if (_requested_return_frame < 0) {
434 last_stop_frame = _transport_frame;
436 last_stop_frame = _requested_return_frame;
437 _requested_return_frame = -1;
442 send_full_time_code ();
443 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
444 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
448 /* XXX its a little odd that we're doing this here
449 when realtime_stop(), which has already executed,
451 JLC - so let's not because it seems unnecessary and breaks loop record
454 if (!Config->get_latched_record_enable()) {
455 g_atomic_int_set (&_record_status, Disabled);
457 g_atomic_int_set (&_record_status, Enabled);
459 RecordStateChanged (); /* emit signal */
463 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
464 /* capture start has been changed, so save pending state */
465 save_state ("", true);
469 /* always try to get rid of this */
471 remove_pending_capture_state ();
473 /* save the current state of things if appropriate */
475 if (did_record && !saved) {
476 save_state (_current_snapshot_name);
479 if (post_transport_work & PostTransportDuration) {
480 DurationChanged (); /* EMIT SIGNAL */
483 if (post_transport_work & PostTransportStop) {
486 /* do not turn off autoloop on stop */
490 nframes_t tf = _transport_frame;
492 PositionChanged (tf); /* EMIT SIGNAL */
493 TransportStateChange (); /* EMIT SIGNAL */
495 /* and start it up again if relevant */
497 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
498 request_transport_speed (1.0);
499 pending_locate_roll = false;
504 Session::check_declick_out ()
506 bool locate_required = transport_sub_state & PendingLocate;
508 /* this is called after a process() iteration. if PendingDeclickOut was set,
509 it means that we were waiting to declick the output (which has just been
510 done) before doing something else. this is where we do that "something else".
512 note: called from the audio thread.
515 if (transport_sub_state & PendingDeclickOut) {
517 if (locate_required) {
518 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
519 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
521 stop_transport (pending_abort);
522 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
528 Session::set_play_loop (bool yn)
530 /* Called from event-handling context */
532 if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
538 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
539 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
540 "Recommend changing the configured options")
546 if ((play_loop = yn)) {
551 if ((loc = _locations.auto_loop_location()) != 0) {
553 if (Config->get_seamless_loop()) {
554 // set all diskstreams to use internal looping
555 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
556 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
557 if (!(*i)->hidden()) {
558 (*i)->set_loop (loc);
563 // set all diskstreams to NOT use internal looping
564 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
565 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
566 if (!(*i)->hidden()) {
572 /* stick in the loop event */
574 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
577 /* locate to start of loop and roll if current pos is outside of the loop range */
578 if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
579 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
583 // locate to current position (+ 1 to force reload)
584 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
592 clear_events (Event::AutoLoop);
594 // set all diskstreams to NOT use internal looping
595 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
596 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
597 if (!(*i)->hidden()) {
606 Session::flush_all_redirects ()
608 boost::shared_ptr<RouteList> r = routes.reader ();
610 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
611 (*i)->flush_redirects ();
616 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
618 if (synced_to_jack()) {
623 _slave->speed_and_position (sp, pos);
625 if (target_frame != pos) {
627 /* tell JACK to change transport position, and we will
628 follow along later in ::follow_slave()
631 _engine.transport_locate (target_frame);
633 if (sp != 1.0f && with_roll) {
634 _engine.transport_start ();
641 locate (target_frame, with_roll, with_flush, with_loop);
646 Session::micro_locate (nframes_t distance)
648 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
650 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
651 if (!(*i)->can_internal_playback_seek (distance)) {
656 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
657 (*i)->internal_playback_seek (distance);
660 _transport_frame += distance;
665 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
667 if (actively_recording() && !with_loop) {
671 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
673 set_transport_speed (1.0, false);
675 loop_changing = false;
679 _transport_frame = target_frame;
681 if (_transport_speed && (!with_loop || loop_changing)) {
682 /* schedule a declick. we'll be called again when its done */
684 if (!(transport_sub_state & PendingDeclickOut)) {
685 transport_sub_state |= (PendingDeclickOut|PendingLocate);
686 pending_locate_frame = target_frame;
687 pending_locate_roll = with_roll;
688 pending_locate_flush = with_flush;
693 if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
694 realtime_stop (false);
697 if ( !with_loop || loop_changing) {
699 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
702 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
705 schedule_butler_transport_work ();
709 /* this is functionally what clear_clicks() does but with a tentative lock */
711 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
713 if (clickm.locked()) {
715 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
724 /* switch from input if we're going to roll */
725 if (Config->get_monitoring_model() == HardwareMonitoring) {
727 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
729 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
730 if ((*i)->record_enabled ()) {
731 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
732 (*i)->monitor_input (!Config->get_auto_input());
737 /* otherwise we're going to stop, so do the opposite */
738 if (Config->get_monitoring_model() == HardwareMonitoring) {
739 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
741 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
742 if ((*i)->record_enabled ()) {
743 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
744 (*i)->monitor_input (true);
750 /* cancel looped playback if transport pos outside of loop range */
752 Location* al = _locations.auto_loop_location();
754 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
755 // cancel looping directly, this is called from event handling context
756 set_play_loop (false);
758 else if (al && _transport_frame == al->start()) {
760 // this is only necessary for seamless looping
762 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
764 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
765 if ((*i)->record_enabled ()) {
766 // tell it we've looped, so it can deal with the record state
767 (*i)->transport_looped(_transport_frame);
772 TransportLooped(); // EMIT SIGNAL
776 loop_changing = false;
780 Session::set_transport_speed (float speed, bool abort)
782 if (_transport_speed == speed) {
787 speed = min (8.0f, speed);
788 } else if (speed < 0) {
789 speed = max (-8.0f, speed);
792 if (transport_rolling() && speed == 0.0) {
794 if (Config->get_monitoring_model() == HardwareMonitoring)
796 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
798 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
799 if ((*i)->record_enabled ()) {
800 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
801 (*i)->monitor_input (true);
806 if (synced_to_jack ()) {
807 _engine.transport_stop ();
809 stop_transport (abort);
812 } else if (transport_stopped() && speed == 1.0) {
814 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
818 if (Config->get_monitoring_model() == HardwareMonitoring) {
820 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
822 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
823 if (Config->get_auto_input() && (*i)->record_enabled ()) {
824 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
825 (*i)->monitor_input (false);
830 if (synced_to_jack()) {
831 _engine.transport_start ();
838 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
842 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
843 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
848 if (actively_recording()) {
852 if (speed > 0.0f && _transport_frame == current_end_frame()) {
856 if (speed < 0.0f && _transport_frame == 0) {
862 /* if we are reversing relative to the current speed, or relative to the speed
863 before the last stop, then we have to do extra work.
866 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
867 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
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);