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);
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, bool leave_rolling)
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, (leave_rolling ? 1.0 : 0.0), yn);
126 if (!leave_rolling && !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 if (_transport_speed < 0.0f) {
139 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop | PostTransportReverse);
141 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop);
144 if (actively_recording()) {
146 /* move the transport position back to where the
147 request for a stop was noticed. we rolled
148 past that point to pick up delayed input.
151 #ifndef LEAVE_TRANSPORT_UNADJUSTED
152 decrement_transport_position (_worst_output_latency);
155 /* the duration change is not guaranteed to have happened, but is likely */
157 post_transport_work = PostTransportWork (post_transport_work | PostTransportDuration);
161 post_transport_work = PostTransportWork (post_transport_work | PostTransportAbort);
164 _clear_event_type (Event::StopOnce);
165 _clear_event_type (Event::RangeStop);
166 _clear_event_type (Event::RangeLocate);
168 disable_record (true);
170 reset_slave_state ();
172 _transport_speed = 0;
174 if (Config->get_use_video_sync()) {
175 waiting_for_sync_offset = true;
178 transport_sub_state = ((Config->get_slave_source() == None && Config->get_auto_return()) ? AutoReturning : 0);
182 Session::butler_transport_work ()
186 boost::shared_ptr<RouteList> r = routes.reader ();
187 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
189 int on_entry = g_atomic_int_get (&butler_should_do_transport_work);
192 if (post_transport_work & PostTransportCurveRealloc) {
193 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
194 (*i)->curve_reallocate();
198 if (post_transport_work & PostTransportInputChange) {
199 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
200 (*i)->non_realtime_input_change ();
204 if (post_transport_work & PostTransportSpeed) {
205 non_realtime_set_speed ();
208 if (post_transport_work & PostTransportReverse) {
211 cumulative_rf_motion = 0;
214 /* don't seek if locate will take care of that in non_realtime_stop() */
216 if (!(post_transport_work & PostTransportLocate)) {
218 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
219 if (!(*i)->hidden()) {
220 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
221 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
224 (*i)->seek (_transport_frame);
227 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
228 /* new request, stop seeking, and start again */
229 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
236 if (post_transport_work & (PostTransportStop|PostTransportLocate)) {
237 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
239 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
244 if (post_transport_work & PostTransportOverWrite) {
245 non_realtime_overwrite (on_entry, finished);
247 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
252 if (post_transport_work & PostTransportAudition) {
253 non_realtime_set_audition ();
256 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
260 Session::non_realtime_set_speed ()
262 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
264 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
265 (*i)->non_realtime_set_speed ();
270 Session::non_realtime_overwrite (int on_entry, bool& finished)
272 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
274 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
275 if ((*i)->pending_overwrite) {
276 (*i)->overwrite_existing_buffers ();
278 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
286 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
296 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
298 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
299 if ((*i)->get_captured_frames () != 0) {
305 /* stop and locate are merged here because they share a lot of common stuff */
308 now = localtime (&xnow);
311 auditioner->cancel_audition ();
315 cumulative_rf_motion = 0;
319 begin_reversible_command ("capture");
321 Location* loc = _locations.end_location();
322 bool change_end = false;
324 if (_transport_frame < loc->end()) {
326 /* stopped recording before current end */
328 if (_end_location_is_free) {
330 /* first capture for this session, move end back to where we are */
335 } else if (_transport_frame > loc->end()) {
337 /* stopped recording after the current end, extend it */
343 XMLNode &before = loc->get_state();
344 loc->set_end(_transport_frame);
345 XMLNode &after = loc->get_state();
346 add_command (new MementoCommand<Location>(*loc, &before, &after));
349 _end_location_is_free = false;
350 _have_captured = true;
353 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
354 (*i)->transport_stopped (*now, xnow, abort);
357 boost::shared_ptr<RouteList> r = routes.reader ();
359 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
360 if (!(*i)->hidden()) {
361 (*i)->set_pending_declick (0);
366 commit_reversible_command ();
369 if (_engine.running()) {
370 update_latency_compensation (true, abort);
373 if ((Config->get_slave_source() == None && Config->get_auto_return()) ||
374 (post_transport_work & PostTransportLocate) ||
375 (_requested_return_frame >= 0) ||
378 if (pending_locate_flush) {
379 flush_all_redirects ();
382 if (((Config->get_slave_source() == None && Config->get_auto_return()) ||
384 _requested_return_frame >= 0) &&
385 !(post_transport_work & PostTransportLocate)) {
387 /* no explicit locate queued */
389 bool do_locate = false;
391 if (_requested_return_frame >= 0) {
393 /* explicit return request pre-queued in event list. overrides everything else */
395 cerr << "explicit auto-return to " << _requested_return_frame << endl;
397 _transport_frame = _requested_return_frame;
401 if (Config->get_auto_return()) {
405 /* don't try to handle loop play when synced to JACK */
407 if (!synced_to_jack()) {
409 Location *location = _locations.auto_loop_location();
412 _transport_frame = location->start();
414 _transport_frame = _last_roll_location;
419 } else if (_play_range) {
421 /* return to start of range */
423 if (!current_audio_range.empty()) {
424 _transport_frame = current_audio_range.front().start;
430 /* regular auto-return */
432 _transport_frame = _last_roll_location;
438 _requested_return_frame = -1;
441 _engine.transport_locate (_transport_frame);
447 /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
449 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
450 if (!(*i)->hidden()) {
451 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
452 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
455 (*i)->seek (_transport_frame);
458 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
460 /* we will be back */
467 send_full_time_code ();
468 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
469 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
473 /* XXX its a little odd that we're doing this here
474 when realtime_stop(), which has already executed,
476 JLC - so let's not because it seems unnecessary and breaks loop record
479 if (!Config->get_latched_record_enable()) {
480 g_atomic_int_set (&_record_status, Disabled);
482 g_atomic_int_set (&_record_status, Enabled);
484 RecordStateChanged (); /* emit signal */
488 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
489 /* capture start has been changed, so save pending state */
490 save_state ("", true);
494 /* always try to get rid of this */
496 remove_pending_capture_state ();
498 /* save the current state of things if appropriate */
500 if (did_record && !saved) {
501 save_state (_current_snapshot_name);
504 if (post_transport_work & PostTransportDuration) {
505 DurationChanged (); /* EMIT SIGNAL */
508 if (post_transport_work & PostTransportStop) {
513 nframes_t tf = _transport_frame;
515 PositionChanged (tf); /* EMIT SIGNAL */
516 TransportStateChange (); /* EMIT SIGNAL */
518 /* and start it up again if relevant */
520 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
521 request_transport_speed (1.0);
522 pending_locate_roll = false;
527 Session::check_declick_out ()
529 bool locate_required = transport_sub_state & PendingLocate;
531 /* this is called after a process() iteration. if PendingDeclickOut was set,
532 it means that we were waiting to declick the output (which has just been
533 done) before doing something else. this is where we do that "something else".
535 note: called from the audio thread.
538 if (transport_sub_state & PendingDeclickOut) {
540 if (locate_required) {
541 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
542 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
544 stop_transport (pending_abort);
545 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
551 Session::set_play_loop (bool yn, bool leave_rolling)
553 /* Called from event-handling context */
557 if (yn == play_loop) {
561 if ((actively_recording() && yn) || (loc = _locations.auto_loop_location()) == 0) {
567 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
568 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
569 "Recommend changing the configured options")
574 if ((play_loop = yn)) {
578 set_play_range (false, true);
580 if (Config->get_seamless_loop()) {
581 // set all diskstreams to use internal looping
582 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
583 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
584 if (!(*i)->hidden()) {
585 (*i)->set_loop (loc);
590 // set all diskstreams to NOT use internal looping
591 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
592 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
593 if (!(*i)->hidden()) {
599 /* put the loop event into the event list */
601 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
604 /* locate to start of loop and roll */
605 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
611 clear_events (Event::AutoLoop);
613 // set all diskstreams to NOT use internal looping
614 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
615 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
616 if (!(*i)->hidden()) {
623 TransportStateChange ();
627 Session::flush_all_redirects ()
629 boost::shared_ptr<RouteList> r = routes.reader ();
631 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
632 (*i)->flush_redirects ();
637 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
639 if (synced_to_jack()) {
644 _slave->speed_and_position (sp, pos);
646 if (target_frame != pos) {
648 /* tell JACK to change transport position, and we will
649 follow along later in ::follow_slave()
652 _engine.transport_locate (target_frame);
654 if (sp != 1.0f && with_roll) {
655 _engine.transport_start ();
662 locate (target_frame, with_roll, with_flush, with_loop);
667 Session::micro_locate (nframes_t distance)
669 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
671 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
672 if (!(*i)->can_internal_playback_seek (distance)) {
677 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
678 (*i)->internal_playback_seek (distance);
681 _transport_frame += distance;
686 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
688 if (actively_recording() && !with_loop) {
692 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
694 set_transport_speed (1.0, false);
696 loop_changing = false;
700 _transport_frame = target_frame;
702 if (_transport_speed && (!with_loop || loop_changing)) {
703 /* schedule a declick. we'll be called again when its done */
705 if (!(transport_sub_state & PendingDeclickOut)) {
706 transport_sub_state |= (PendingDeclickOut|PendingLocate);
707 pending_locate_frame = target_frame;
708 pending_locate_roll = with_roll;
709 pending_locate_flush = with_flush;
714 if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
715 realtime_stop (false);
718 if ( !with_loop || loop_changing) {
720 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
723 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
726 schedule_butler_transport_work ();
730 /* this is functionally what clear_clicks() does but with a tentative lock */
732 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
734 if (clickm.locked()) {
736 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
745 /* switch from input if we're going to roll */
746 if (Config->get_monitoring_model() == HardwareMonitoring) {
748 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
750 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
751 if ((*i)->record_enabled ()) {
752 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
753 (*i)->monitor_input (!Config->get_auto_input());
758 /* otherwise we're going to stop, so do the opposite */
759 if (Config->get_monitoring_model() == HardwareMonitoring) {
760 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
762 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
763 if ((*i)->record_enabled ()) {
764 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
765 (*i)->monitor_input (true);
771 /* cancel looped playback if transport pos outside of loop range */
773 Location* al = _locations.auto_loop_location();
775 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
776 // cancel looping directly, this is called from event handling context
777 set_play_loop (false, false);
779 else if (al && _transport_frame == al->start()) {
781 // this is only necessary for seamless looping
783 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
785 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
786 if ((*i)->record_enabled ()) {
787 // tell it we've looped, so it can deal with the record state
788 (*i)->transport_looped(_transport_frame);
793 TransportLooped(); // EMIT SIGNAL
797 loop_changing = false;
799 _send_smpte_update = true;
803 Session::set_transport_speed (float speed, bool abort)
805 if (_transport_speed == speed) {
810 speed = min (8.0f, speed);
811 } else if (speed < 0) {
812 speed = max (-8.0f, speed);
815 if (transport_rolling() && speed == 0.0) {
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 ((*i)->record_enabled ()) {
823 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
824 (*i)->monitor_input (true);
829 if (synced_to_jack ()) {
830 _engine.transport_stop ();
832 stop_transport (abort);
835 } else if (transport_stopped() && speed == 1.0) {
837 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
841 if (Config->get_monitoring_model() == HardwareMonitoring) {
843 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
845 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
846 if (Config->get_auto_input() && (*i)->record_enabled ()) {
847 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
848 (*i)->monitor_input (false);
853 if (synced_to_jack()) {
854 _engine.transport_start ();
861 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
865 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
866 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
871 if (actively_recording()) {
875 if (speed > 0.0f && _transport_frame == current_end_frame()) {
879 if (speed < 0.0f && _transport_frame == 0) {
885 /* if we are reversing relative to the current speed, or relative to the speed
886 before the last stop, then we have to do extra work.
889 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
890 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
891 last_stop_frame = _transport_frame;
894 _last_transport_speed = _transport_speed;
895 _transport_speed = speed;
897 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
898 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
899 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
900 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
904 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
905 schedule_butler_transport_work ();
911 Session::stop_transport (bool abort)
913 if (_transport_speed == 0.0f) {
917 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
918 _worst_output_latency > current_block_size)
921 /* we need to capture the audio that has still not yet been received by the system
922 at the time the stop is requested, so we have to roll past that time.
924 we want to declick before stopping, so schedule the autostop for one
925 block before the actual end. we'll declick in the subsequent block,
926 and then we'll really be stopped.
929 Event *ev = new Event (Event::StopOnce, Event::Replace,
930 _transport_frame + _worst_output_latency - current_block_size,
934 transport_sub_state |= StopPendingCapture;
935 pending_abort = abort;
940 if ((transport_sub_state & PendingDeclickOut) == 0) {
941 transport_sub_state |= PendingDeclickOut;
942 /* we'll be called again after the declick */
943 pending_abort = abort;
947 realtime_stop (abort);
948 schedule_butler_transport_work ();
952 Session::start_transport ()
954 _last_roll_location = _transport_frame;
957 /* if record status is Enabled, move it to Recording. if its
958 already Recording, move it to Disabled.
961 switch (record_status()) {
963 if (!Config->get_punch_in()) {
970 disable_record (false);
978 transport_sub_state |= PendingDeclickIn;
979 _transport_speed = 1.0;
981 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
982 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
983 (*i)->realtime_set_speed ((*i)->speed(), true);
986 send_mmc_in_another_thread (MIDI::MachineControl::cmdDeferredPlay, 0);
988 TransportStateChange (); /* EMIT SIGNAL */
992 Session::post_transport ()
994 if (post_transport_work & PostTransportAudition) {
995 if (auditioner && auditioner->active()) {
996 process_function = &Session::process_audition;
998 process_function = &Session::process_with_events;
1002 if (post_transport_work & PostTransportStop) {
1004 transport_sub_state = 0;
1007 if (post_transport_work & PostTransportLocate) {
1009 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
1013 transport_sub_state = 0;
1019 post_transport_work = PostTransportWork (0);
1023 Session::reset_rf_scale (nframes_t motion)
1025 cumulative_rf_motion += motion;
1027 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1029 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1031 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1043 Session::set_slave_source (SlaveSource src, bool stop_the_transport)
1045 bool reverse = false;
1046 bool non_rt_required = false;
1048 if (_transport_speed) {
1049 error << _("please stop the transport before adjusting slave settings") << endmsg;
1053 // if (src == JACK && Config->get_jack_time_master()) {
1062 if (_transport_speed < 0.0) {
1068 if (stop_the_transport) {
1076 _slave = new MTC_Slave (*this, *_mtc_port);
1079 catch (failed_constructor& err) {
1084 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1087 _desired_transport_speed = _transport_speed;
1091 _slave = new JACK_Slave (_engine.jack());
1092 _desired_transport_speed = _transport_speed;
1096 Config->set_slave_source (src);
1098 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1099 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1100 if (!(*i)->hidden()) {
1101 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1102 non_rt_required = true;
1104 (*i)->set_slaved (_slave);
1109 reverse_diskstream_buffers ();
1112 if (non_rt_required) {
1113 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1114 schedule_butler_transport_work ();
1121 Session::reverse_diskstream_buffers ()
1123 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1124 schedule_butler_transport_work ();
1128 Session::set_diskstream_speed (Diskstream* stream, float speed)
1130 if (stream->realtime_set_speed (speed, false)) {
1131 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1132 schedule_butler_transport_work ();
1138 Session::set_audio_range (list<AudioRange>& range)
1140 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1141 ev->audio_range = range;
1146 Session::request_play_range (bool yn, bool leave_rolling)
1148 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn);
1153 Session::set_play_range (bool yn, bool leave_rolling)
1155 /* Called from event-processing context */
1158 /* cancel loop play */
1159 set_play_loop (false, true);
1166 if (!_play_range && !leave_rolling) {
1167 /* stop transport */
1168 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1172 TransportStateChange ();
1176 Session::setup_auto_play ()
1178 /* Called from event-processing context */
1182 _clear_event_type (Event::RangeStop);
1183 _clear_event_type (Event::RangeLocate);
1189 list<AudioRange>::size_type sz = current_audio_range.size();
1193 list<AudioRange>::iterator i = current_audio_range.begin();
1194 list<AudioRange>::iterator next;
1196 while (i != current_audio_range.end()) {
1201 /* locating/stopping is subject to delays for declicking.
1204 nframes_t requested_frame = (*i).end;
1206 if (requested_frame > current_block_size) {
1207 requested_frame -= current_block_size;
1209 requested_frame = 0;
1212 if (next == current_audio_range.end()) {
1213 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1215 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1223 } else if (sz == 1) {
1225 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1230 /* now start rolling at the right place */
1232 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1237 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1239 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1240 ev->target2_frame = start;
1245 Session::request_bounded_roll (nframes_t start, nframes_t end)
1248 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1250 request_locate (start, true);
1254 Session::engine_halted ()
1258 /* there will be no more calls to process(), so
1259 we'd better clean up for ourselves, right now.
1261 but first, make sure the butler is out of
1265 g_atomic_int_set (&butler_should_do_transport_work, 0);
1266 post_transport_work = PostTransportWork (0);
1269 realtime_stop (false);
1270 non_realtime_stop (false, 0, ignored);
1271 transport_sub_state = 0;
1273 if (synced_to_jack()) {
1274 /* transport is already stopped, hence the second argument */
1275 set_slave_source (None, false);
1278 TransportStateChange (); /* EMIT SIGNAL */
1283 Session::xrun_recovery ()
1285 Xrun (transport_frame()); //EMIT SIGNAL
1287 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1289 /* it didn't actually halt, but we need
1290 to handle things in the same way.
1298 Session::update_latency_compensation (bool with_stop, bool abort)
1300 bool update_jack = false;
1302 if (_state_of_the_state & Deletion) {
1306 _worst_track_latency = 0;
1308 #undef DEBUG_LATENCY
1309 #ifdef DEBUG_LATENCY
1310 cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1313 boost::shared_ptr<RouteList> r = routes.reader ();
1315 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1317 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1318 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1321 nframes_t old_latency = (*i)->signal_latency ();
1322 nframes_t track_latency = (*i)->update_total_latency ();
1324 if (old_latency != track_latency) {
1328 if (!(*i)->hidden() && ((*i)->active())) {
1329 _worst_track_latency = max (_worst_track_latency, track_latency);
1333 #ifdef DEBUG_LATENCY
1334 cerr << "\tworst was " << _worst_track_latency << endl;
1337 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1338 (*i)->set_latency_delay (_worst_track_latency);
1341 /* tell JACK to play catch up */
1344 _engine.update_total_latencies ();
1347 set_worst_io_latencies ();
1349 /* reflect any changes in latencies into capture offsets
1352 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1354 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1355 (*i)->set_capture_offset ();
1360 Session::update_latency_compensation_proxy (void* ignored)
1362 update_latency_compensation (false, false);
1366 Session::allow_auto_play (bool yn)
1368 auto_play_legal = yn;
1372 Session::reset_jack_connection (jack_client_t* jack)
1376 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1377 js->reset_client (jack);