2 Copyright (C) 1999-2003 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include <sigc++/bind.h>
25 #include <sigc++/retype.h>
28 #include <pbd/error.h>
29 #include <glibmm/thread.h>
30 #include <pbd/pthread_utils.h>
31 #include <pbd/memento_command.h>
33 #include <midi++/mmc.h>
34 #include <midi++/port.h>
36 #include <ardour/ardour.h>
37 #include <ardour/audioengine.h>
38 #include <ardour/session.h>
39 #include <ardour/audio_diskstream.h>
40 #include <ardour/auditioner.h>
41 #include <ardour/slave.h>
42 #include <ardour/location.h>
47 using namespace ARDOUR;
52 Session::request_input_change_handling ()
54 if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
55 Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0);
61 Session::request_slave_source (SlaveSource src)
63 Event* ev = new Event (Event::SetSlaveSource, Event::Add, Event::Immediate, 0, 0.0);
66 /* could set_seamless_loop() be disposed of entirely?*/
67 Config->set_seamless_loop (false);
69 Config->set_seamless_loop (true);
76 Session::request_transport_speed (float speed)
78 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, speed);
83 Session::request_diskstream_speed (Diskstream& ds, float speed)
85 Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed);
91 Session::request_stop (bool abort)
93 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0, abort);
98 Session::request_locate (nframes_t target_frame, bool with_roll)
100 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, false);
105 Session::force_locate (nframes_t target_frame, bool with_roll)
107 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, true);
112 Session::request_play_loop (bool yn)
115 Location *location = _locations.auto_loop_location();
117 if (location == 0 && yn) {
118 error << _("Cannot loop - no loop range defined")
123 ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, 0.0, yn);
126 if (!yn && Config->get_seamless_loop() && transport_rolling()) {
127 // request an immediate locate to refresh the diskstreams
128 // after disabling looping
129 request_locate (_transport_frame-1, false);
134 Session::realtime_stop (bool abort)
136 /* assume that when we start, we'll be moving forwards */
138 // FIXME: where should this really be? [DR]
139 //send_full_time_code();
140 deliver_mmc (MIDI::MachineControl::cmdStop, _transport_frame);
141 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
143 if (_transport_speed < 0.0f) {
144 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop | PostTransportReverse);
146 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop);
149 if (actively_recording()) {
151 /* move the transport position back to where the
152 request for a stop was noticed. we rolled
153 past that point to pick up delayed input.
156 #ifndef LEAVE_TRANSPORT_UNADJUSTED
157 decrement_transport_position (_worst_output_latency);
160 /* the duration change is not guaranteed to have happened, but is likely */
162 post_transport_work = PostTransportWork (post_transport_work | PostTransportDuration);
166 post_transport_work = PostTransportWork (post_transport_work | PostTransportAbort);
169 _clear_event_type (Event::StopOnce);
170 _clear_event_type (Event::RangeStop);
171 _clear_event_type (Event::RangeLocate);
173 disable_record (true);
175 reset_slave_state ();
177 _transport_speed = 0;
179 if (Config->get_use_video_sync()) {
180 waiting_for_sync_offset = true;
183 transport_sub_state = ((Config->get_slave_source() == None && Config->get_auto_return()) ? AutoReturning : 0);
187 Session::butler_transport_work ()
191 boost::shared_ptr<RouteList> r = routes.reader ();
192 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
194 int on_entry = g_atomic_int_get (&butler_should_do_transport_work);
197 if (post_transport_work & PostTransportCurveRealloc) {
198 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
199 (*i)->curve_reallocate();
203 if (post_transport_work & PostTransportInputChange) {
204 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
205 (*i)->non_realtime_input_change ();
209 if (post_transport_work & PostTransportSpeed) {
210 non_realtime_set_speed ();
213 if (post_transport_work & PostTransportReverse) {
217 cumulative_rf_motion = 0;
220 /* don't seek if locate will take care of that in non_realtime_stop() */
222 if (!(post_transport_work & PostTransportLocate)) {
224 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
225 if (!(*i)->hidden()) {
226 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
227 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
230 (*i)->seek (_transport_frame);
233 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
234 /* new request, stop seeking, and start again */
235 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
242 if (post_transport_work & (PostTransportStop|PostTransportLocate)) {
243 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
245 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
250 if (post_transport_work & PostTransportOverWrite) {
251 non_realtime_overwrite (on_entry, finished);
253 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
258 if (post_transport_work & PostTransportAudition) {
259 non_realtime_set_audition ();
262 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
266 Session::non_realtime_set_speed ()
268 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
270 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
271 (*i)->non_realtime_set_speed ();
276 Session::non_realtime_overwrite (int on_entry, bool& finished)
278 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
280 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
281 if ((*i)->pending_overwrite) {
282 (*i)->overwrite_existing_buffers ();
284 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
292 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
302 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
304 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
305 if ((*i)->get_captured_frames () != 0) {
311 /* stop and locate are merged here because they share a lot of common stuff */
314 now = localtime (&xnow);
317 auditioner->cancel_audition ();
321 cumulative_rf_motion = 0;
325 begin_reversible_command ("capture");
327 Location* loc = _locations.end_location();
328 bool change_end = false;
330 if (_transport_frame < loc->end()) {
332 /* stopped recording before current end */
334 if (_end_location_is_free) {
336 /* first capture for this session, move end back to where we are */
341 } else if (_transport_frame > loc->end()) {
343 /* stopped recording after the current end, extend it */
349 XMLNode &before = loc->get_state();
350 loc->set_end(_transport_frame);
351 XMLNode &after = loc->get_state();
352 add_command (new MementoCommand<Location>(*loc, &before, &after));
355 _end_location_is_free = false;
356 _have_captured = true;
359 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
360 (*i)->transport_stopped (*now, xnow, abort);
363 boost::shared_ptr<RouteList> r = routes.reader ();
365 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
366 if (!(*i)->is_hidden()) {
367 (*i)->set_pending_declick (0);
372 commit_reversible_command ();
375 if (_engine.running()) {
376 update_latency_compensation (true, abort);
379 if ((Config->get_slave_source() == None && Config->get_auto_return()) || (post_transport_work & PostTransportLocate) || synced_to_jack()) {
381 if (pending_locate_flush) {
382 flush_all_inserts ();
385 if (((Config->get_slave_source() == None && Config->get_auto_return()) || synced_to_jack()) && !(post_transport_work & PostTransportLocate)) {
387 _transport_frame = last_stop_frame;
389 if (synced_to_jack() && !play_loop) {
390 // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl;
391 _engine.transport_locate (_transport_frame);
395 #ifndef LEAVE_TRANSPORT_UNADJUSTED
399 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
400 if (!(*i)->hidden()) {
401 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
402 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
405 (*i)->seek (_transport_frame);
408 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
410 /* we will be back */
415 #ifdef LEAVE_TRANSPORT_UNADJUSTED
419 last_stop_frame = _transport_frame;
423 /* XXX its a little odd that we're doing this here
424 when realtime_stop(), which has already executed,
426 JLC - so let's not because it seems unnecessary and breaks loop record
429 if (!Config->get_latched_record_enable()) {
430 g_atomic_int_set (&_record_status, Disabled);
432 g_atomic_int_set (&_record_status, Enabled);
434 RecordStateChanged (); /* emit signal */
438 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
439 /* capture start has been changed, so save pending state */
440 save_state ("", true);
444 /* always try to get rid of this */
446 remove_pending_capture_state ();
448 /* save the current state of things if appropriate */
450 if (did_record && !saved) {
451 save_state (_current_snapshot_name);
454 if (post_transport_work & PostTransportDuration) {
455 DurationChanged (); /* EMIT SIGNAL */
458 if (post_transport_work & PostTransportStop) {
461 /* do not turn off autoloop on stop */
465 PositionChanged (_transport_frame); /* EMIT SIGNAL */
466 TransportStateChange (); /* EMIT SIGNAL */
468 /* and start it up again if relevant */
470 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
471 request_transport_speed (1.0);
472 pending_locate_roll = false;
477 Session::check_declick_out ()
479 bool locate_required = transport_sub_state & PendingLocate;
481 /* this is called after a process() iteration. if PendingDeclickOut was set,
482 it means that we were waiting to declick the output (which has just been
483 done) before doing something else. this is where we do that "something else".
485 note: called from the audio thread.
488 if (transport_sub_state & PendingDeclickOut) {
490 if (locate_required) {
491 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
492 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
494 stop_transport (pending_abort);
495 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
501 Session::set_play_loop (bool yn)
503 /* Called from event-handling context */
505 if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
511 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
512 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
513 "Recommend changing the configured options")
519 if ((play_loop = yn)) {
524 if ((loc = _locations.auto_loop_location()) != 0) {
526 if (Config->get_seamless_loop()) {
527 // set all diskstreams to use internal looping
528 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
529 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
530 if (!(*i)->hidden()) {
531 (*i)->set_loop (loc);
536 // set all diskstreams to NOT use internal looping
537 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
538 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
539 if (!(*i)->hidden()) {
545 /* stick in the loop event */
547 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
550 /* locate to start of loop and roll if current pos is outside of the loop range */
551 if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
552 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
556 // locate to current position (+ 1 to force reload)
557 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
565 clear_events (Event::AutoLoop);
567 // set all diskstreams to NOT use internal looping
568 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
569 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
570 if (!(*i)->hidden()) {
579 Session::flush_all_inserts ()
581 boost::shared_ptr<RouteList> r = routes.reader ();
583 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
584 (*i)->flush_processors ();
589 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
591 if (synced_to_jack()) {
596 _slave->speed_and_position (sp, pos);
598 if (target_frame != pos) {
600 /* tell JACK to change transport position, and we will
601 follow along later in ::follow_slave()
604 _engine.transport_locate (target_frame);
606 if (sp != 1.0f && with_roll) {
607 _engine.transport_start ();
614 locate (target_frame, with_roll, with_flush, with_loop);
619 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
621 if (actively_recording() && !with_loop) {
625 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
627 set_transport_speed (1.0, false);
629 loop_changing = false;
634 // [DR] FIXME: find out exactly where this should go below
635 _transport_frame = target_frame;
636 smpte_time(_transport_frame, transmitting_smpte_time);
637 outbound_mtc_smpte_frame = _transport_frame;
638 next_quarter_frame_to_send = 0;
640 if (_transport_speed && (!with_loop || loop_changing)) {
641 /* schedule a declick. we'll be called again when its done */
643 if (!(transport_sub_state & PendingDeclickOut)) {
644 transport_sub_state |= (PendingDeclickOut|PendingLocate);
645 pending_locate_frame = target_frame;
646 pending_locate_roll = with_roll;
647 pending_locate_flush = with_flush;
652 if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
653 realtime_stop (false);
656 if ( !with_loop || loop_changing) {
658 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
661 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
664 schedule_butler_transport_work ();
668 /* this is functionally what clear_clicks() does but with a tentative lock */
670 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
672 if (clickm.locked()) {
674 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
683 /* switch from input if we're going to roll */
684 if (Config->get_monitoring_model() == HardwareMonitoring) {
686 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
688 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
689 if ((*i)->record_enabled ()) {
690 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
691 (*i)->monitor_input (!Config->get_auto_input());
696 /* otherwise we're going to stop, so do the opposite */
697 if (Config->get_monitoring_model() == HardwareMonitoring) {
698 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
700 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
701 if ((*i)->record_enabled ()) {
702 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
703 (*i)->monitor_input (true);
709 /* cancel looped playback if transport pos outside of loop range */
711 Location* al = _locations.auto_loop_location();
713 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
714 // cancel looping directly, this is called from event handling context
715 set_play_loop (false);
717 else if (al && _transport_frame == al->start()) {
719 // this is only necessary for seamless looping
721 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
723 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
724 if ((*i)->record_enabled ()) {
725 // tell it we've looped, so it can deal with the record state
726 (*i)->transport_looped(_transport_frame);
731 TransportLooped(); // EMIT SIGNAL
735 loop_changing = false;
737 _send_smpte_update = true;
740 /** Set the transport speed.
741 * @param speed New speed
745 Session::set_transport_speed (float speed, bool abort)
747 if (_transport_speed == speed) {
752 speed = min (8.0f, speed);
753 } else if (speed < 0) {
754 speed = max (-8.0f, speed);
757 if (transport_rolling() && speed == 0.0) {
759 /* we are rolling and we want to stop */
761 if (Config->get_monitoring_model() == HardwareMonitoring)
763 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
765 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
766 if ((*i)->record_enabled ()) {
767 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
768 (*i)->monitor_input (true);
773 if (synced_to_jack ()) {
774 _engine.transport_stop ();
776 stop_transport (abort);
779 } else if (transport_stopped() && speed == 1.0) {
781 /* we are stopped and we want to start rolling at speed 1 */
783 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
787 if (Config->get_monitoring_model() == HardwareMonitoring) {
789 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
791 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
792 if (Config->get_auto_input() && (*i)->record_enabled ()) {
793 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
794 (*i)->monitor_input (false);
799 if (synced_to_jack()) {
800 _engine.transport_start ();
807 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
811 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
812 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
817 if (actively_recording()) {
821 if (speed > 0.0f && _transport_frame == current_end_frame()) {
825 if (speed < 0.0f && _transport_frame == 0) {
831 /* if we are reversing relative to the current speed, or relative to the speed
832 before the last stop, then we have to do extra work.
835 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
836 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
839 _last_transport_speed = _transport_speed;
840 _transport_speed = speed;
842 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
843 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
844 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
845 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
849 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
850 schedule_butler_transport_work ();
856 /** Stop the transport. */
858 Session::stop_transport (bool abort)
860 if (_transport_speed == 0.0f) {
864 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
865 _worst_output_latency > current_block_size)
868 /* we need to capture the audio that has still not yet been received by the system
869 at the time the stop is requested, so we have to roll past that time.
871 we want to declick before stopping, so schedule the autostop for one
872 block before the actual end. we'll declick in the subsequent block,
873 and then we'll really be stopped.
876 Event *ev = new Event (Event::StopOnce, Event::Replace,
877 _transport_frame + _worst_output_latency - current_block_size,
881 transport_sub_state |= StopPendingCapture;
882 pending_abort = abort;
887 if ((transport_sub_state & PendingDeclickOut) == 0) {
888 transport_sub_state |= PendingDeclickOut;
889 /* we'll be called again after the declick */
890 pending_abort = abort;
894 realtime_stop (abort);
895 schedule_butler_transport_work ();
899 Session::start_transport ()
901 _last_roll_location = _transport_frame;
903 /* if record status is Enabled, move it to Recording. if its
904 already Recording, move it to Disabled.
907 switch (record_status()) {
909 if (!Config->get_punch_in()) {
916 disable_record (false);
924 if (!synced_to_jack() || _exporting) {
925 actually_start_transport ();
927 waiting_to_start = true;
932 Session::actually_start_transport ()
934 waiting_to_start = false;
936 transport_sub_state |= PendingDeclickIn;
937 _transport_speed = 1.0;
939 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
940 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
941 (*i)->realtime_set_speed ((*i)->speed(), true);
944 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
946 TransportStateChange (); /* EMIT SIGNAL */
949 /** Do any transport work in the audio thread that needs to be done after the
950 * transport thread is finished. Audio thread, realtime safe.
953 Session::post_transport ()
955 if (post_transport_work & PostTransportAudition) {
956 if (auditioner && auditioner->active()) {
957 process_function = &Session::process_audition;
959 process_function = &Session::process_with_events;
963 if (post_transport_work & PostTransportStop) {
965 transport_sub_state = 0;
968 if (post_transport_work & PostTransportLocate) {
970 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
974 transport_sub_state = 0;
980 post_transport_work = PostTransportWork (0);
984 Session::reset_rf_scale (nframes_t motion)
986 cumulative_rf_motion += motion;
988 if (cumulative_rf_motion < 4 * _current_frame_rate) {
990 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
992 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1004 Session::set_slave_source (SlaveSource src)
1006 bool reverse = false;
1007 bool non_rt_required = false;
1009 if (_transport_speed) {
1010 error << _("please stop the transport before adjusting slave settings") << endmsg;
1014 // if (src == JACK && Config->get_jack_time_master()) {
1023 if (_transport_speed < 0.0) {
1035 _slave = new MTC_Slave (*this, *_mtc_port);
1038 catch (failed_constructor& err) {
1043 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1046 _desired_transport_speed = _transport_speed;
1050 _slave = new JACK_Slave (_engine.jack());
1051 _desired_transport_speed = _transport_speed;
1055 Config->set_slave_source (src);
1057 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1058 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1059 if (!(*i)->hidden()) {
1060 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1061 non_rt_required = true;
1063 (*i)->set_slaved (_slave);
1068 reverse_diskstream_buffers ();
1071 if (non_rt_required) {
1072 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1073 schedule_butler_transport_work ();
1080 Session::reverse_diskstream_buffers ()
1082 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1083 schedule_butler_transport_work ();
1087 Session::set_diskstream_speed (Diskstream* stream, float speed)
1089 if (stream->realtime_set_speed (speed, false)) {
1090 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1091 schedule_butler_transport_work ();
1097 Session::set_audio_range (list<AudioRange>& range)
1099 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1100 ev->audio_range = range;
1105 Session::request_play_range (bool yn)
1107 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1112 Session::set_play_range (bool yn)
1114 /* Called from event-processing context */
1116 if (_play_range != yn) {
1121 /* stop transport */
1122 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1129 Session::setup_auto_play ()
1131 /* Called from event-processing context */
1135 _clear_event_type (Event::RangeStop);
1136 _clear_event_type (Event::RangeLocate);
1142 list<AudioRange>::size_type sz = current_audio_range.size();
1146 list<AudioRange>::iterator i = current_audio_range.begin();
1147 list<AudioRange>::iterator next;
1149 while (i != current_audio_range.end()) {
1154 /* locating/stopping is subject to delays for declicking.
1157 nframes_t requested_frame = (*i).end;
1159 if (requested_frame > current_block_size) {
1160 requested_frame -= current_block_size;
1162 requested_frame = 0;
1165 if (next == current_audio_range.end()) {
1166 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1168 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1176 } else if (sz == 1) {
1178 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1183 /* now start rolling at the right place */
1185 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1190 Session::request_bounded_roll (nframes_t start, nframes_t end)
1193 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1195 request_locate (start, true);
1199 Session::engine_halted ()
1203 /* there will be no more calls to process(), so
1204 we'd better clean up for ourselves, right now.
1206 but first, make sure the butler is out of
1210 g_atomic_int_set (&butler_should_do_transport_work, 0);
1211 post_transport_work = PostTransportWork (0);
1214 realtime_stop (false);
1215 non_realtime_stop (false, 0, ignored);
1216 transport_sub_state = 0;
1218 TransportStateChange (); /* EMIT SIGNAL */
1223 Session::xrun_recovery ()
1225 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1227 HaltOnXrun (); /* EMIT SIGNAL */
1229 /* it didn't actually halt, but we need
1230 to handle things in the same way.
1238 Session::update_latency_compensation (bool with_stop, bool abort)
1240 bool update_jack = false;
1242 if (_state_of_the_state & Deletion) {
1246 _worst_track_latency = 0;
1248 boost::shared_ptr<RouteList> r = routes.reader ();
1250 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1253 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1254 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1257 nframes_t old_latency = (*i)->signal_latency ();
1258 nframes_t track_latency = (*i)->update_total_latency ();
1260 if (old_latency != track_latency) {
1261 (*i)->update_port_total_latencies ();
1265 if (!(*i)->is_hidden() && ((*i)->active())) {
1266 _worst_track_latency = max (_worst_track_latency, track_latency);
1271 _engine.update_total_latencies ();
1274 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1275 (*i)->set_latency_delay (_worst_track_latency);
1278 set_worst_io_latencies ();
1280 /* reflect any changes in latencies into capture offsets
1283 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1285 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1286 (*i)->set_capture_offset ();
1291 Session::allow_auto_play (bool yn)
1293 auto_play_legal = yn;
1297 Session::reset_jack_connection (jack_client_t* jack)
1301 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1302 js->reset_client (jack);