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;
399 if (synced_to_jack() && !play_loop) {
404 // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl;
405 _engine.transport_locate (_transport_frame);
409 #ifndef LEAVE_TRANSPORT_UNADJUSTED
413 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
414 if (!(*i)->hidden()) {
415 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
416 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
419 (*i)->seek (_transport_frame);
422 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
424 /* we will be back */
428 #ifdef LEAVE_TRANSPORT_UNADJUSTED
432 last_stop_frame = _transport_frame;
434 send_full_time_code ();
435 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
436 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
440 /* XXX its a little odd that we're doing this here
441 when realtime_stop(), which has already executed,
443 JLC - so let's not because it seems unnecessary and breaks loop record
446 if (!Config->get_latched_record_enable()) {
447 g_atomic_int_set (&_record_status, Disabled);
449 g_atomic_int_set (&_record_status, Enabled);
451 RecordStateChanged (); /* emit signal */
455 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
456 /* capture start has been changed, so save pending state */
457 save_state ("", true);
461 /* always try to get rid of this */
463 remove_pending_capture_state ();
465 /* save the current state of things if appropriate */
467 if (did_record && !saved) {
468 save_state (_current_snapshot_name);
471 if (post_transport_work & PostTransportDuration) {
472 DurationChanged (); /* EMIT SIGNAL */
475 if (post_transport_work & PostTransportStop) {
478 /* do not turn off autoloop on stop */
482 nframes_t tf = _transport_frame;
484 PositionChanged (tf); /* EMIT SIGNAL */
485 TransportStateChange (); /* EMIT SIGNAL */
487 /* and start it up again if relevant */
489 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
490 request_transport_speed (1.0);
491 pending_locate_roll = false;
496 Session::check_declick_out ()
498 bool locate_required = transport_sub_state & PendingLocate;
500 /* this is called after a process() iteration. if PendingDeclickOut was set,
501 it means that we were waiting to declick the output (which has just been
502 done) before doing something else. this is where we do that "something else".
504 note: called from the audio thread.
507 if (transport_sub_state & PendingDeclickOut) {
509 if (locate_required) {
510 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
511 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
513 stop_transport (pending_abort);
514 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
520 Session::set_play_loop (bool yn)
522 /* Called from event-handling context */
524 if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
530 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
531 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
532 "Recommend changing the configured options")
538 if ((play_loop = yn)) {
543 if ((loc = _locations.auto_loop_location()) != 0) {
545 if (Config->get_seamless_loop()) {
546 // set all diskstreams to use internal looping
547 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
548 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
549 if (!(*i)->hidden()) {
550 (*i)->set_loop (loc);
555 // set all diskstreams to NOT use internal looping
556 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
557 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
558 if (!(*i)->hidden()) {
564 /* stick in the loop event */
566 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
569 /* locate to start of loop and roll if current pos is outside of the loop range */
570 if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
571 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
575 // locate to current position (+ 1 to force reload)
576 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
584 clear_events (Event::AutoLoop);
586 // set all diskstreams to NOT use internal looping
587 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
588 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
589 if (!(*i)->hidden()) {
598 Session::flush_all_redirects ()
600 boost::shared_ptr<RouteList> r = routes.reader ();
602 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
603 (*i)->flush_redirects ();
608 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
610 if (synced_to_jack()) {
615 _slave->speed_and_position (sp, pos);
617 if (target_frame != pos) {
619 /* tell JACK to change transport position, and we will
620 follow along later in ::follow_slave()
623 _engine.transport_locate (target_frame);
625 if (sp != 1.0f && with_roll) {
626 _engine.transport_start ();
633 locate (target_frame, with_roll, with_flush, with_loop);
638 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
640 if (actively_recording() && !with_loop) {
644 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
646 set_transport_speed (1.0, false);
648 loop_changing = false;
652 _transport_frame = target_frame;
654 if (_transport_speed && (!with_loop || loop_changing)) {
655 /* schedule a declick. we'll be called again when its done */
657 if (!(transport_sub_state & PendingDeclickOut)) {
658 transport_sub_state |= (PendingDeclickOut|PendingLocate);
659 pending_locate_frame = target_frame;
660 pending_locate_roll = with_roll;
661 pending_locate_flush = with_flush;
666 if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
667 realtime_stop (false);
670 if ( !with_loop || loop_changing) {
672 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
675 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
678 schedule_butler_transport_work ();
682 /* this is functionally what clear_clicks() does but with a tentative lock */
684 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
686 if (clickm.locked()) {
688 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
697 /* switch from input if we're going to roll */
698 if (Config->get_monitoring_model() == HardwareMonitoring) {
700 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
702 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
703 if ((*i)->record_enabled ()) {
704 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
705 (*i)->monitor_input (!Config->get_auto_input());
710 /* otherwise we're going to stop, so do the opposite */
711 if (Config->get_monitoring_model() == HardwareMonitoring) {
712 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
714 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
715 if ((*i)->record_enabled ()) {
716 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
717 (*i)->monitor_input (true);
723 /* cancel looped playback if transport pos outside of loop range */
725 Location* al = _locations.auto_loop_location();
727 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
728 // cancel looping directly, this is called from event handling context
729 set_play_loop (false);
731 else if (al && _transport_frame == al->start()) {
733 // this is only necessary for seamless looping
735 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
737 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
738 if ((*i)->record_enabled ()) {
739 // tell it we've looped, so it can deal with the record state
740 (*i)->transport_looped(_transport_frame);
745 TransportLooped(); // EMIT SIGNAL
749 loop_changing = false;
753 Session::set_transport_speed (float speed, bool abort)
755 cerr << "Session::set_transport_speed " << speed << " abort capture ? " << abort << endl;
757 if (_transport_speed == speed) {
762 speed = min (8.0f, speed);
763 } else if (speed < 0) {
764 speed = max (-8.0f, speed);
767 if (transport_rolling() && speed == 0.0) {
769 if (Config->get_monitoring_model() == HardwareMonitoring)
771 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
773 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
774 if ((*i)->record_enabled ()) {
775 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
776 (*i)->monitor_input (true);
781 if (synced_to_jack ()) {
782 _engine.transport_stop ();
784 stop_transport (abort);
787 } else if (transport_stopped() && speed == 1.0) {
789 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
793 if (Config->get_monitoring_model() == HardwareMonitoring) {
795 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
797 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
798 if (Config->get_auto_input() && (*i)->record_enabled ()) {
799 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
800 (*i)->monitor_input (false);
805 if (synced_to_jack()) {
806 _engine.transport_start ();
813 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
817 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
818 cerr << "synced to jack and speed == " << speed << endl;
819 stacktrace (cerr, 20);
820 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
825 if (actively_recording()) {
829 if (speed > 0.0f && _transport_frame == current_end_frame()) {
833 if (speed < 0.0f && _transport_frame == 0) {
839 /* if we are reversing relative to the current speed, or relative to the speed
840 before the last stop, then we have to do extra work.
843 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
844 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
847 _last_transport_speed = _transport_speed;
848 _transport_speed = speed;
850 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
851 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
852 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
853 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
857 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
858 schedule_butler_transport_work ();
864 Session::stop_transport (bool abort)
866 if (_transport_speed == 0.0f) {
870 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
871 _worst_output_latency > current_block_size)
874 /* we need to capture the audio that has still not yet been received by the system
875 at the time the stop is requested, so we have to roll past that time.
877 we want to declick before stopping, so schedule the autostop for one
878 block before the actual end. we'll declick in the subsequent block,
879 and then we'll really be stopped.
882 Event *ev = new Event (Event::StopOnce, Event::Replace,
883 _transport_frame + _worst_output_latency - current_block_size,
887 transport_sub_state |= StopPendingCapture;
888 pending_abort = abort;
893 if ((transport_sub_state & PendingDeclickOut) == 0) {
894 transport_sub_state |= PendingDeclickOut;
895 /* we'll be called again after the declick */
896 pending_abort = abort;
900 realtime_stop (abort);
901 schedule_butler_transport_work ();
905 Session::start_transport ()
907 _last_roll_location = _transport_frame;
909 /* if record status is Enabled, move it to Recording. if its
910 already Recording, move it to Disabled.
913 switch (record_status()) {
915 if (!Config->get_punch_in()) {
922 disable_record (false);
930 if (!synced_to_jack() || _exporting) {
931 actually_start_transport ();
933 waiting_to_start = true;
938 Session::actually_start_transport ()
940 waiting_to_start = false;
942 transport_sub_state |= PendingDeclickIn;
943 _transport_speed = 1.0;
945 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
946 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
947 (*i)->realtime_set_speed ((*i)->speed(), true);
950 send_mmc_in_another_thread (MIDI::MachineControl::cmdDeferredPlay, 0);
952 TransportStateChange (); /* EMIT SIGNAL */
956 Session::post_transport ()
958 if (post_transport_work & PostTransportAudition) {
959 if (auditioner && auditioner->active()) {
960 process_function = &Session::process_audition;
962 process_function = &Session::process_with_events;
966 if (post_transport_work & PostTransportStop) {
968 transport_sub_state = 0;
971 if (post_transport_work & PostTransportLocate) {
973 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
977 transport_sub_state = 0;
983 post_transport_work = PostTransportWork (0);
987 Session::reset_rf_scale (nframes_t motion)
989 cumulative_rf_motion += motion;
991 if (cumulative_rf_motion < 4 * _current_frame_rate) {
993 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
995 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1007 Session::set_slave_source (SlaveSource src)
1009 bool reverse = false;
1010 bool non_rt_required = false;
1012 if (_transport_speed) {
1013 error << _("please stop the transport before adjusting slave settings") << endmsg;
1017 // if (src == JACK && Config->get_jack_time_master()) {
1026 if (_transport_speed < 0.0) {
1038 _slave = new MTC_Slave (*this, *_mtc_port);
1041 catch (failed_constructor& err) {
1046 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1049 _desired_transport_speed = _transport_speed;
1053 _slave = new JACK_Slave (_engine.jack());
1054 _desired_transport_speed = _transport_speed;
1058 Config->set_slave_source (src);
1060 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1061 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1062 if (!(*i)->hidden()) {
1063 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1064 non_rt_required = true;
1066 (*i)->set_slaved (_slave);
1071 reverse_diskstream_buffers ();
1074 if (non_rt_required) {
1075 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1076 schedule_butler_transport_work ();
1083 Session::reverse_diskstream_buffers ()
1085 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1086 schedule_butler_transport_work ();
1090 Session::set_diskstream_speed (Diskstream* stream, float speed)
1092 if (stream->realtime_set_speed (speed, false)) {
1093 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1094 schedule_butler_transport_work ();
1100 Session::set_audio_range (list<AudioRange>& range)
1102 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1103 ev->audio_range = range;
1108 Session::request_play_range (bool yn)
1110 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1115 Session::set_play_range (bool yn)
1117 /* Called from event-processing context */
1119 if (_play_range != yn) {
1124 /* stop transport */
1125 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1132 Session::setup_auto_play ()
1134 /* Called from event-processing context */
1138 _clear_event_type (Event::RangeStop);
1139 _clear_event_type (Event::RangeLocate);
1145 list<AudioRange>::size_type sz = current_audio_range.size();
1149 list<AudioRange>::iterator i = current_audio_range.begin();
1150 list<AudioRange>::iterator next;
1152 while (i != current_audio_range.end()) {
1157 /* locating/stopping is subject to delays for declicking.
1160 nframes_t requested_frame = (*i).end;
1162 if (requested_frame > current_block_size) {
1163 requested_frame -= current_block_size;
1165 requested_frame = 0;
1168 if (next == current_audio_range.end()) {
1169 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1171 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1179 } else if (sz == 1) {
1181 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1186 /* now start rolling at the right place */
1188 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1193 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1195 request_locate (start, false);
1196 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1201 Session::request_bounded_roll (nframes_t start, nframes_t end)
1204 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1206 request_locate (start, true);
1210 Session::engine_halted ()
1214 /* there will be no more calls to process(), so
1215 we'd better clean up for ourselves, right now.
1217 but first, make sure the butler is out of
1221 g_atomic_int_set (&butler_should_do_transport_work, 0);
1222 post_transport_work = PostTransportWork (0);
1225 realtime_stop (false);
1226 non_realtime_stop (false, 0, ignored);
1227 transport_sub_state = 0;
1229 TransportStateChange (); /* EMIT SIGNAL */
1234 Session::xrun_recovery ()
1236 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1238 HaltOnXrun (); /* EMIT SIGNAL */
1240 /* it didn't actually halt, but we need
1241 to handle things in the same way.
1249 Session::update_latency_compensation (bool with_stop, bool abort)
1251 bool update_jack = false;
1253 if (_state_of_the_state & Deletion) {
1257 _worst_track_latency = 0;
1259 boost::shared_ptr<RouteList> r = routes.reader ();
1261 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1263 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1264 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1267 nframes_t old_latency = (*i)->signal_latency ();
1268 nframes_t track_latency = (*i)->update_total_latency ();
1270 if (old_latency != track_latency) {
1274 if (!(*i)->hidden() && ((*i)->active())) {
1275 _worst_track_latency = max (_worst_track_latency, track_latency);
1279 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1280 (*i)->set_latency_delay (_worst_track_latency);
1283 /* tell JACK to play catch up */
1286 _engine.update_total_latencies ();
1289 set_worst_io_latencies ();
1291 /* reflect any changes in latencies into capture offsets
1294 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1296 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1297 (*i)->set_capture_offset ();
1302 Session::update_latency_compensation_proxy (void* ignored)
1304 update_latency_compensation (false, false);
1308 Session::allow_auto_play (bool yn)
1310 auto_play_legal = yn;
1314 Session::reset_jack_connection (jack_client_t* jack)
1318 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1319 js->reset_client (jack);