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 if (speed != 0.0 && speed != 1.0) {
80 cerr << "odd speed requested\n";
81 stacktrace (cerr, 20);
83 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, speed);
88 Session::request_diskstream_speed (Diskstream& ds, float speed)
90 Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed);
96 Session::request_stop (bool abort)
98 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0, abort);
103 Session::request_locate (nframes_t target_frame, bool with_roll)
105 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, false);
110 Session::force_locate (nframes_t target_frame, bool with_roll)
112 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, true);
117 Session::request_play_loop (bool yn)
120 Location *location = _locations.auto_loop_location();
122 if (location == 0 && yn) {
123 error << _("Cannot loop - no loop range defined")
128 ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, 0.0, yn);
131 if (!yn && Config->get_seamless_loop() && transport_rolling()) {
132 // request an immediate locate to refresh the diskstreams
133 // after disabling looping
134 request_locate (_transport_frame-1, false);
139 Session::realtime_stop (bool abort)
141 /* assume that when we start, we'll be moving forwards */
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)->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()) ||
380 (post_transport_work & PostTransportLocate) ||
381 (_requested_return_frame >= 0) ||
384 if (pending_locate_flush) {
385 flush_all_redirects ();
388 if (((Config->get_slave_source() == None && Config->get_auto_return()) ||
390 _requested_return_frame >= 0) &&
391 !(post_transport_work & PostTransportLocate)) {
393 bool do_locate = false;
395 if (_requested_return_frame >= 0) {
396 _transport_frame = _requested_return_frame;
397 _requested_return_frame = -1;
400 _transport_frame = last_stop_frame;
403 if (synced_to_jack() && !play_loop) {
408 // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl;
409 _engine.transport_locate (_transport_frame);
413 #ifndef LEAVE_TRANSPORT_UNADJUSTED
417 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
418 if (!(*i)->hidden()) {
419 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
420 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
423 (*i)->seek (_transport_frame);
426 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
428 /* we will be back */
432 #ifdef LEAVE_TRANSPORT_UNADJUSTED
436 last_stop_frame = _transport_frame;
438 send_full_time_code ();
439 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
440 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
444 /* XXX its a little odd that we're doing this here
445 when realtime_stop(), which has already executed,
447 JLC - so let's not because it seems unnecessary and breaks loop record
450 if (!Config->get_latched_record_enable()) {
451 g_atomic_int_set (&_record_status, Disabled);
453 g_atomic_int_set (&_record_status, Enabled);
455 RecordStateChanged (); /* emit signal */
459 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
460 /* capture start has been changed, so save pending state */
461 save_state ("", true);
465 /* always try to get rid of this */
467 remove_pending_capture_state ();
469 /* save the current state of things if appropriate */
471 if (did_record && !saved) {
472 save_state (_current_snapshot_name);
475 if (post_transport_work & PostTransportDuration) {
476 DurationChanged (); /* EMIT SIGNAL */
479 if (post_transport_work & PostTransportStop) {
482 /* do not turn off autoloop on stop */
486 nframes_t tf = _transport_frame;
488 PositionChanged (tf); /* EMIT SIGNAL */
489 TransportStateChange (); /* EMIT SIGNAL */
491 /* and start it up again if relevant */
493 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
494 request_transport_speed (1.0);
495 pending_locate_roll = false;
500 Session::check_declick_out ()
502 bool locate_required = transport_sub_state & PendingLocate;
504 /* this is called after a process() iteration. if PendingDeclickOut was set,
505 it means that we were waiting to declick the output (which has just been
506 done) before doing something else. this is where we do that "something else".
508 note: called from the audio thread.
511 if (transport_sub_state & PendingDeclickOut) {
513 if (locate_required) {
514 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
515 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
517 stop_transport (pending_abort);
518 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
524 Session::set_play_loop (bool yn)
526 /* Called from event-handling context */
528 if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
534 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
535 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
536 "Recommend changing the configured options")
542 if ((play_loop = yn)) {
547 if ((loc = _locations.auto_loop_location()) != 0) {
549 if (Config->get_seamless_loop()) {
550 // set all diskstreams to use internal looping
551 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
552 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
553 if (!(*i)->hidden()) {
554 (*i)->set_loop (loc);
559 // set all diskstreams to NOT use internal looping
560 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
561 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
562 if (!(*i)->hidden()) {
568 /* stick in the loop event */
570 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
573 /* locate to start of loop and roll if current pos is outside of the loop range */
574 if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
575 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
579 // locate to current position (+ 1 to force reload)
580 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
588 clear_events (Event::AutoLoop);
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()) {
602 Session::flush_all_redirects ()
604 boost::shared_ptr<RouteList> r = routes.reader ();
606 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
607 (*i)->flush_redirects ();
612 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
614 if (synced_to_jack()) {
619 _slave->speed_and_position (sp, pos);
621 if (target_frame != pos) {
623 /* tell JACK to change transport position, and we will
624 follow along later in ::follow_slave()
627 _engine.transport_locate (target_frame);
629 if (sp != 1.0f && with_roll) {
630 _engine.transport_start ();
637 locate (target_frame, with_roll, with_flush, with_loop);
642 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
644 if (actively_recording() && !with_loop) {
648 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
650 set_transport_speed (1.0, false);
652 loop_changing = false;
656 _transport_frame = target_frame;
658 if (_transport_speed && (!with_loop || loop_changing)) {
659 /* schedule a declick. we'll be called again when its done */
661 if (!(transport_sub_state & PendingDeclickOut)) {
662 transport_sub_state |= (PendingDeclickOut|PendingLocate);
663 pending_locate_frame = target_frame;
664 pending_locate_roll = with_roll;
665 pending_locate_flush = with_flush;
670 if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
671 realtime_stop (false);
674 if ( !with_loop || loop_changing) {
676 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
679 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
682 schedule_butler_transport_work ();
686 /* this is functionally what clear_clicks() does but with a tentative lock */
688 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
690 if (clickm.locked()) {
692 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
701 /* switch from input if we're going to roll */
702 if (Config->get_monitoring_model() == HardwareMonitoring) {
704 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
706 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
707 if ((*i)->record_enabled ()) {
708 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
709 (*i)->monitor_input (!Config->get_auto_input());
714 /* otherwise we're going to stop, so do the opposite */
715 if (Config->get_monitoring_model() == HardwareMonitoring) {
716 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
718 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
719 if ((*i)->record_enabled ()) {
720 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
721 (*i)->monitor_input (true);
727 /* cancel looped playback if transport pos outside of loop range */
729 Location* al = _locations.auto_loop_location();
731 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
732 // cancel looping directly, this is called from event handling context
733 set_play_loop (false);
735 else if (al && _transport_frame == al->start()) {
737 // this is only necessary for seamless looping
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 // tell it we've looped, so it can deal with the record state
744 (*i)->transport_looped(_transport_frame);
749 TransportLooped(); // EMIT SIGNAL
753 loop_changing = false;
757 Session::set_transport_speed (float speed, bool abort)
759 cerr << "Session::set_transport_speed " << speed << " abort capture ? " << abort << endl;
761 if (_transport_speed == speed) {
766 speed = min (8.0f, speed);
767 } else if (speed < 0) {
768 speed = max (-8.0f, speed);
771 if (transport_rolling() && speed == 0.0) {
773 if (Config->get_monitoring_model() == HardwareMonitoring)
775 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
777 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
778 if ((*i)->record_enabled ()) {
779 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
780 (*i)->monitor_input (true);
785 if (synced_to_jack ()) {
786 _engine.transport_stop ();
788 stop_transport (abort);
791 } else if (transport_stopped() && speed == 1.0) {
793 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
797 if (Config->get_monitoring_model() == HardwareMonitoring) {
799 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
801 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
802 if (Config->get_auto_input() && (*i)->record_enabled ()) {
803 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
804 (*i)->monitor_input (false);
809 if (synced_to_jack()) {
810 _engine.transport_start ();
817 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
821 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
822 cerr << "synced to jack and speed == " << speed << endl;
823 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
828 if (actively_recording()) {
832 if (speed > 0.0f && _transport_frame == current_end_frame()) {
836 if (speed < 0.0f && _transport_frame == 0) {
842 /* if we are reversing relative to the current speed, or relative to the speed
843 before the last stop, then we have to do extra work.
846 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
847 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
850 _last_transport_speed = _transport_speed;
851 _transport_speed = speed;
853 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
854 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
855 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
856 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
860 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
861 schedule_butler_transport_work ();
867 Session::stop_transport (bool abort)
869 if (_transport_speed == 0.0f) {
873 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
874 _worst_output_latency > current_block_size)
877 /* we need to capture the audio that has still not yet been received by the system
878 at the time the stop is requested, so we have to roll past that time.
880 we want to declick before stopping, so schedule the autostop for one
881 block before the actual end. we'll declick in the subsequent block,
882 and then we'll really be stopped.
885 Event *ev = new Event (Event::StopOnce, Event::Replace,
886 _transport_frame + _worst_output_latency - current_block_size,
890 transport_sub_state |= StopPendingCapture;
891 pending_abort = abort;
896 if ((transport_sub_state & PendingDeclickOut) == 0) {
897 transport_sub_state |= PendingDeclickOut;
898 /* we'll be called again after the declick */
899 pending_abort = abort;
903 realtime_stop (abort);
904 schedule_butler_transport_work ();
908 Session::start_transport ()
910 _last_roll_location = _transport_frame;
912 /* if record status is Enabled, move it to Recording. if its
913 already Recording, move it to Disabled.
916 switch (record_status()) {
918 if (!Config->get_punch_in()) {
925 disable_record (false);
933 if (!synced_to_jack() || _exporting) {
934 actually_start_transport ();
936 waiting_to_start = true;
941 Session::actually_start_transport ()
943 waiting_to_start = false;
945 transport_sub_state |= PendingDeclickIn;
946 _transport_speed = 1.0;
948 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
949 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
950 (*i)->realtime_set_speed ((*i)->speed(), true);
953 send_mmc_in_another_thread (MIDI::MachineControl::cmdDeferredPlay, 0);
955 TransportStateChange (); /* EMIT SIGNAL */
959 Session::post_transport ()
961 if (post_transport_work & PostTransportAudition) {
962 if (auditioner && auditioner->active()) {
963 process_function = &Session::process_audition;
965 process_function = &Session::process_with_events;
969 if (post_transport_work & PostTransportStop) {
971 transport_sub_state = 0;
974 if (post_transport_work & PostTransportLocate) {
976 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
980 transport_sub_state = 0;
986 post_transport_work = PostTransportWork (0);
990 Session::reset_rf_scale (nframes_t motion)
992 cumulative_rf_motion += motion;
994 if (cumulative_rf_motion < 4 * _current_frame_rate) {
996 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
998 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1010 Session::set_slave_source (SlaveSource src)
1012 bool reverse = false;
1013 bool non_rt_required = false;
1015 if (_transport_speed) {
1016 error << _("please stop the transport before adjusting slave settings") << endmsg;
1020 // if (src == JACK && Config->get_jack_time_master()) {
1029 if (_transport_speed < 0.0) {
1041 _slave = new MTC_Slave (*this, *_mtc_port);
1044 catch (failed_constructor& err) {
1049 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1052 _desired_transport_speed = _transport_speed;
1056 _slave = new JACK_Slave (_engine.jack());
1057 _desired_transport_speed = _transport_speed;
1061 Config->set_slave_source (src);
1063 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1064 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1065 if (!(*i)->hidden()) {
1066 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1067 non_rt_required = true;
1069 (*i)->set_slaved (_slave);
1074 reverse_diskstream_buffers ();
1077 if (non_rt_required) {
1078 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1079 schedule_butler_transport_work ();
1086 Session::reverse_diskstream_buffers ()
1088 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1089 schedule_butler_transport_work ();
1093 Session::set_diskstream_speed (Diskstream* stream, float speed)
1095 if (stream->realtime_set_speed (speed, false)) {
1096 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1097 schedule_butler_transport_work ();
1103 Session::set_audio_range (list<AudioRange>& range)
1105 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1106 ev->audio_range = range;
1111 Session::request_play_range (bool yn)
1113 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1118 Session::set_play_range (bool yn)
1120 /* Called from event-processing context */
1122 if (_play_range != yn) {
1127 /* stop transport */
1128 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1135 Session::setup_auto_play ()
1137 /* Called from event-processing context */
1141 _clear_event_type (Event::RangeStop);
1142 _clear_event_type (Event::RangeLocate);
1148 list<AudioRange>::size_type sz = current_audio_range.size();
1152 list<AudioRange>::iterator i = current_audio_range.begin();
1153 list<AudioRange>::iterator next;
1155 while (i != current_audio_range.end()) {
1160 /* locating/stopping is subject to delays for declicking.
1163 nframes_t requested_frame = (*i).end;
1165 if (requested_frame > current_block_size) {
1166 requested_frame -= current_block_size;
1168 requested_frame = 0;
1171 if (next == current_audio_range.end()) {
1172 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1174 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1182 } else if (sz == 1) {
1184 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1189 /* now start rolling at the right place */
1191 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1196 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1198 request_locate (start, false);
1199 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1204 Session::request_bounded_roll (nframes_t start, nframes_t end)
1207 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1209 request_locate (start, true);
1213 Session::engine_halted ()
1217 /* there will be no more calls to process(), so
1218 we'd better clean up for ourselves, right now.
1220 but first, make sure the butler is out of
1224 g_atomic_int_set (&butler_should_do_transport_work, 0);
1225 post_transport_work = PostTransportWork (0);
1228 realtime_stop (false);
1229 non_realtime_stop (false, 0, ignored);
1230 transport_sub_state = 0;
1232 TransportStateChange (); /* EMIT SIGNAL */
1237 Session::xrun_recovery ()
1239 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1241 HaltOnXrun (); /* EMIT SIGNAL */
1243 /* it didn't actually halt, but we need
1244 to handle things in the same way.
1252 Session::update_latency_compensation (bool with_stop, bool abort)
1254 bool update_jack = false;
1256 if (_state_of_the_state & Deletion) {
1260 _worst_track_latency = 0;
1262 boost::shared_ptr<RouteList> r = routes.reader ();
1264 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1266 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1267 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1270 nframes_t old_latency = (*i)->signal_latency ();
1271 nframes_t track_latency = (*i)->update_total_latency ();
1273 if (old_latency != track_latency) {
1277 if (!(*i)->hidden() && ((*i)->active())) {
1278 _worst_track_latency = max (_worst_track_latency, track_latency);
1282 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1283 (*i)->set_latency_delay (_worst_track_latency);
1286 /* tell JACK to play catch up */
1289 _engine.update_total_latencies ();
1292 set_worst_io_latencies ();
1294 /* reflect any changes in latencies into capture offsets
1297 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1299 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1300 (*i)->set_capture_offset ();
1305 Session::update_latency_compensation_proxy (void* ignored)
1307 update_latency_compensation (false, false);
1311 Session::allow_auto_play (bool yn)
1313 auto_play_legal = yn;
1317 Session::reset_jack_connection (jack_client_t* jack)
1321 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1322 js->reset_client (jack);