2 Copyright (C) 1999-2003 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include <sigc++/bind.h>
25 #include <sigc++/retype.h>
28 #include <pbd/error.h>
29 #include <glibmm/thread.h>
30 #include <pbd/pthread_utils.h>
31 #include <pbd/memento_command.h>
32 #include <pbd/stacktrace.h>
34 #include <midi++/mmc.h>
35 #include <midi++/port.h>
37 #include <ardour/ardour.h>
38 #include <ardour/audioengine.h>
39 #include <ardour/session.h>
40 #include <ardour/audio_diskstream.h>
41 #include <ardour/auditioner.h>
42 #include <ardour/slave.h>
43 #include <ardour/location.h>
48 using namespace ARDOUR;
53 Session::request_input_change_handling ()
55 if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
56 Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0);
62 Session::request_slave_source (SlaveSource src)
64 Event* ev = new Event (Event::SetSlaveSource, Event::Add, Event::Immediate, 0, 0.0);
67 /* could set_seamless_loop() be disposed of entirely?*/
68 Config->set_seamless_loop (false);
70 Config->set_seamless_loop (true);
77 Session::request_transport_speed (float speed)
79 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, speed);
84 Session::request_diskstream_speed (Diskstream& ds, float speed)
86 Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed);
92 Session::request_stop (bool abort)
94 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0, abort);
99 Session::request_locate (nframes_t target_frame, bool with_roll)
101 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, false);
106 Session::force_locate (nframes_t target_frame, bool with_roll)
108 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, true);
113 Session::request_play_loop (bool yn)
116 Location *location = _locations.auto_loop_location();
118 if (location == 0 && yn) {
119 error << _("Cannot loop - no loop range defined")
124 ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, 0.0, yn);
127 if (!yn && Config->get_seamless_loop() && transport_rolling()) {
128 // request an immediate locate to refresh the diskstreams
129 // after disabling looping
130 request_locate (_transport_frame-1, false);
135 Session::realtime_stop (bool abort)
137 /* assume that when we start, we'll be moving forwards */
139 if (_transport_speed < 0.0f) {
140 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop | PostTransportReverse);
142 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop);
145 if (actively_recording()) {
147 /* move the transport position back to where the
148 request for a stop was noticed. we rolled
149 past that point to pick up delayed input.
152 #ifndef LEAVE_TRANSPORT_UNADJUSTED
153 decrement_transport_position (_worst_output_latency);
156 /* the duration change is not guaranteed to have happened, but is likely */
158 post_transport_work = PostTransportWork (post_transport_work | PostTransportDuration);
162 post_transport_work = PostTransportWork (post_transport_work | PostTransportAbort);
165 _clear_event_type (Event::StopOnce);
166 _clear_event_type (Event::RangeStop);
167 _clear_event_type (Event::RangeLocate);
169 disable_record (true);
171 reset_slave_state ();
173 _transport_speed = 0;
175 if (Config->get_use_video_sync()) {
176 waiting_for_sync_offset = true;
179 transport_sub_state = ((Config->get_slave_source() == None && Config->get_auto_return()) ? AutoReturning : 0);
183 Session::butler_transport_work ()
187 boost::shared_ptr<RouteList> r = routes.reader ();
188 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
190 int on_entry = g_atomic_int_get (&butler_should_do_transport_work);
193 if (post_transport_work & PostTransportCurveRealloc) {
194 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
195 (*i)->curve_reallocate();
199 if (post_transport_work & PostTransportInputChange) {
200 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
201 (*i)->non_realtime_input_change ();
205 if (post_transport_work & PostTransportSpeed) {
206 non_realtime_set_speed ();
209 if (post_transport_work & PostTransportReverse) {
213 cumulative_rf_motion = 0;
216 /* don't seek if locate will take care of that in non_realtime_stop() */
218 if (!(post_transport_work & PostTransportLocate)) {
220 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
221 if (!(*i)->hidden()) {
222 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
223 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
226 (*i)->seek (_transport_frame);
229 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
230 /* new request, stop seeking, and start again */
231 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
238 if (post_transport_work & (PostTransportStop|PostTransportLocate)) {
239 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
241 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
246 if (post_transport_work & PostTransportOverWrite) {
247 non_realtime_overwrite (on_entry, finished);
249 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
254 if (post_transport_work & PostTransportAudition) {
255 non_realtime_set_audition ();
258 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
262 Session::non_realtime_set_speed ()
264 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
266 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
267 (*i)->non_realtime_set_speed ();
272 Session::non_realtime_overwrite (int on_entry, bool& finished)
274 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
276 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
277 if ((*i)->pending_overwrite) {
278 (*i)->overwrite_existing_buffers ();
280 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
288 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
298 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
300 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
301 if ((*i)->get_captured_frames () != 0) {
307 /* stop and locate are merged here because they share a lot of common stuff */
310 now = localtime (&xnow);
313 auditioner->cancel_audition ();
317 cumulative_rf_motion = 0;
321 begin_reversible_command ("capture");
323 Location* loc = _locations.end_location();
324 bool change_end = false;
326 if (_transport_frame < loc->end()) {
328 /* stopped recording before current end */
330 if (_end_location_is_free) {
332 /* first capture for this session, move end back to where we are */
337 } else if (_transport_frame > loc->end()) {
339 /* stopped recording after the current end, extend it */
345 XMLNode &before = loc->get_state();
346 loc->set_end(_transport_frame);
347 XMLNode &after = loc->get_state();
348 add_command (new MementoCommand<Location>(*loc, &before, &after));
351 _end_location_is_free = false;
352 _have_captured = true;
355 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
356 (*i)->transport_stopped (*now, xnow, abort);
359 boost::shared_ptr<RouteList> r = routes.reader ();
361 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
362 if (!(*i)->hidden()) {
363 (*i)->set_pending_declick (0);
368 commit_reversible_command ();
371 if (_engine.running()) {
372 update_latency_compensation (true, abort);
375 if ((Config->get_slave_source() == None && Config->get_auto_return()) ||
376 (post_transport_work & PostTransportLocate) ||
377 (_requested_return_frame >= 0) ||
380 if (pending_locate_flush) {
381 flush_all_redirects ();
384 if (((Config->get_slave_source() == None && Config->get_auto_return()) ||
386 _requested_return_frame >= 0) &&
387 !(post_transport_work & PostTransportLocate)) {
389 bool do_locate = false;
391 if (_requested_return_frame >= 0) {
392 _transport_frame = _requested_return_frame;
393 _requested_return_frame = -1;
396 _transport_frame = last_stop_frame;
397 _requested_return_frame = -1;
400 if (synced_to_jack() && !play_loop) {
405 // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl;
406 _engine.transport_locate (_transport_frame);
410 #ifndef LEAVE_TRANSPORT_UNADJUSTED
414 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
415 if (!(*i)->hidden()) {
416 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
417 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
420 (*i)->seek (_transport_frame);
423 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
425 /* we will be back */
429 #ifdef LEAVE_TRANSPORT_UNADJUSTED
433 if (_requested_return_frame < 0) {
434 last_stop_frame = _transport_frame;
436 last_stop_frame = _requested_return_frame;
437 _requested_return_frame = -1;
440 send_full_time_code ();
441 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
442 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
446 /* XXX its a little odd that we're doing this here
447 when realtime_stop(), which has already executed,
449 JLC - so let's not because it seems unnecessary and breaks loop record
452 if (!Config->get_latched_record_enable()) {
453 g_atomic_int_set (&_record_status, Disabled);
455 g_atomic_int_set (&_record_status, Enabled);
457 RecordStateChanged (); /* emit signal */
461 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
462 /* capture start has been changed, so save pending state */
463 save_state ("", true);
467 /* always try to get rid of this */
469 remove_pending_capture_state ();
471 /* save the current state of things if appropriate */
473 if (did_record && !saved) {
474 save_state (_current_snapshot_name);
477 if (post_transport_work & PostTransportDuration) {
478 DurationChanged (); /* EMIT SIGNAL */
481 if (post_transport_work & PostTransportStop) {
484 /* do not turn off autoloop on stop */
488 nframes_t tf = _transport_frame;
490 PositionChanged (tf); /* EMIT SIGNAL */
491 TransportStateChange (); /* EMIT SIGNAL */
493 /* and start it up again if relevant */
495 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
496 request_transport_speed (1.0);
497 pending_locate_roll = false;
502 Session::check_declick_out ()
504 bool locate_required = transport_sub_state & PendingLocate;
506 /* this is called after a process() iteration. if PendingDeclickOut was set,
507 it means that we were waiting to declick the output (which has just been
508 done) before doing something else. this is where we do that "something else".
510 note: called from the audio thread.
513 if (transport_sub_state & PendingDeclickOut) {
515 if (locate_required) {
516 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
517 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
519 stop_transport (pending_abort);
520 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
526 Session::set_play_loop (bool yn)
528 /* Called from event-handling context */
530 if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
536 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
537 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
538 "Recommend changing the configured options")
544 if ((play_loop = yn)) {
549 if ((loc = _locations.auto_loop_location()) != 0) {
551 if (Config->get_seamless_loop()) {
552 // set all diskstreams to use internal looping
553 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
554 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
555 if (!(*i)->hidden()) {
556 (*i)->set_loop (loc);
561 // set all diskstreams to NOT use internal looping
562 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
563 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
564 if (!(*i)->hidden()) {
570 /* stick in the loop event */
572 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
575 /* locate to start of loop and roll if current pos is outside of the loop range */
576 if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
577 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
581 // locate to current position (+ 1 to force reload)
582 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
590 clear_events (Event::AutoLoop);
592 // set all diskstreams to NOT use internal looping
593 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
594 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
595 if (!(*i)->hidden()) {
604 Session::flush_all_redirects ()
606 boost::shared_ptr<RouteList> r = routes.reader ();
608 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
609 (*i)->flush_redirects ();
614 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
616 if (synced_to_jack()) {
621 _slave->speed_and_position (sp, pos);
623 if (target_frame != pos) {
625 /* tell JACK to change transport position, and we will
626 follow along later in ::follow_slave()
629 _engine.transport_locate (target_frame);
631 if (sp != 1.0f && with_roll) {
632 _engine.transport_start ();
639 locate (target_frame, with_roll, with_flush, with_loop);
644 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
646 if (actively_recording() && !with_loop) {
650 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
652 set_transport_speed (1.0, false);
654 loop_changing = false;
658 _transport_frame = target_frame;
660 if (_transport_speed && (!with_loop || loop_changing)) {
661 /* schedule a declick. we'll be called again when its done */
663 if (!(transport_sub_state & PendingDeclickOut)) {
664 transport_sub_state |= (PendingDeclickOut|PendingLocate);
665 pending_locate_frame = target_frame;
666 pending_locate_roll = with_roll;
667 pending_locate_flush = with_flush;
672 if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
673 realtime_stop (false);
676 if ( !with_loop || loop_changing) {
678 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
681 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
684 schedule_butler_transport_work ();
688 /* this is functionally what clear_clicks() does but with a tentative lock */
690 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
692 if (clickm.locked()) {
694 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
703 /* switch from input if we're going to roll */
704 if (Config->get_monitoring_model() == HardwareMonitoring) {
706 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
708 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
709 if ((*i)->record_enabled ()) {
710 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
711 (*i)->monitor_input (!Config->get_auto_input());
716 /* otherwise we're going to stop, so do the opposite */
717 if (Config->get_monitoring_model() == HardwareMonitoring) {
718 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
720 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
721 if ((*i)->record_enabled ()) {
722 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
723 (*i)->monitor_input (true);
729 /* cancel looped playback if transport pos outside of loop range */
731 Location* al = _locations.auto_loop_location();
733 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
734 // cancel looping directly, this is called from event handling context
735 set_play_loop (false);
737 else if (al && _transport_frame == al->start()) {
739 // this is only necessary for seamless looping
741 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
743 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
744 if ((*i)->record_enabled ()) {
745 // tell it we've looped, so it can deal with the record state
746 (*i)->transport_looped(_transport_frame);
751 TransportLooped(); // EMIT SIGNAL
755 loop_changing = false;
759 Session::set_transport_speed (float speed, bool abort)
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 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
827 if (actively_recording()) {
831 if (speed > 0.0f && _transport_frame == current_end_frame()) {
835 if (speed < 0.0f && _transport_frame == 0) {
841 /* if we are reversing relative to the current speed, or relative to the speed
842 before the last stop, then we have to do extra work.
845 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
846 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
849 _last_transport_speed = _transport_speed;
850 _transport_speed = speed;
852 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
853 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
854 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
855 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
859 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
860 schedule_butler_transport_work ();
866 Session::stop_transport (bool abort)
868 if (_transport_speed == 0.0f) {
872 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
873 _worst_output_latency > current_block_size)
876 /* we need to capture the audio that has still not yet been received by the system
877 at the time the stop is requested, so we have to roll past that time.
879 we want to declick before stopping, so schedule the autostop for one
880 block before the actual end. we'll declick in the subsequent block,
881 and then we'll really be stopped.
884 Event *ev = new Event (Event::StopOnce, Event::Replace,
885 _transport_frame + _worst_output_latency - current_block_size,
889 transport_sub_state |= StopPendingCapture;
890 pending_abort = abort;
895 if ((transport_sub_state & PendingDeclickOut) == 0) {
896 transport_sub_state |= PendingDeclickOut;
897 /* we'll be called again after the declick */
898 pending_abort = abort;
902 realtime_stop (abort);
903 schedule_butler_transport_work ();
907 Session::start_transport ()
909 _last_roll_location = _transport_frame;
911 /* if record status is Enabled, move it to Recording. if its
912 already Recording, move it to Disabled.
915 switch (record_status()) {
917 if (!Config->get_punch_in()) {
924 disable_record (false);
932 if (!synced_to_jack() || _exporting) {
933 actually_start_transport ();
935 waiting_to_start = true;
940 Session::actually_start_transport ()
942 waiting_to_start = false;
944 transport_sub_state |= PendingDeclickIn;
945 _transport_speed = 1.0;
947 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
948 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
949 (*i)->realtime_set_speed ((*i)->speed(), true);
952 send_mmc_in_another_thread (MIDI::MachineControl::cmdDeferredPlay, 0);
954 TransportStateChange (); /* EMIT SIGNAL */
958 Session::post_transport ()
960 if (post_transport_work & PostTransportAudition) {
961 if (auditioner && auditioner->active()) {
962 process_function = &Session::process_audition;
964 process_function = &Session::process_with_events;
968 if (post_transport_work & PostTransportStop) {
970 transport_sub_state = 0;
973 if (post_transport_work & PostTransportLocate) {
975 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
979 transport_sub_state = 0;
985 post_transport_work = PostTransportWork (0);
989 Session::reset_rf_scale (nframes_t motion)
991 cumulative_rf_motion += motion;
993 if (cumulative_rf_motion < 4 * _current_frame_rate) {
995 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
997 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1009 Session::set_slave_source (SlaveSource src)
1011 bool reverse = false;
1012 bool non_rt_required = false;
1014 if (_transport_speed) {
1015 error << _("please stop the transport before adjusting slave settings") << endmsg;
1019 // if (src == JACK && Config->get_jack_time_master()) {
1028 if (_transport_speed < 0.0) {
1040 _slave = new MTC_Slave (*this, *_mtc_port);
1043 catch (failed_constructor& err) {
1048 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1051 _desired_transport_speed = _transport_speed;
1055 _slave = new JACK_Slave (_engine.jack());
1056 _desired_transport_speed = _transport_speed;
1060 Config->set_slave_source (src);
1062 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1063 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1064 if (!(*i)->hidden()) {
1065 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1066 non_rt_required = true;
1068 (*i)->set_slaved (_slave);
1073 reverse_diskstream_buffers ();
1076 if (non_rt_required) {
1077 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1078 schedule_butler_transport_work ();
1085 Session::reverse_diskstream_buffers ()
1087 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1088 schedule_butler_transport_work ();
1092 Session::set_diskstream_speed (Diskstream* stream, float speed)
1094 if (stream->realtime_set_speed (speed, false)) {
1095 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1096 schedule_butler_transport_work ();
1102 Session::set_audio_range (list<AudioRange>& range)
1104 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1105 ev->audio_range = range;
1110 Session::request_play_range (bool yn)
1112 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1117 Session::set_play_range (bool yn)
1119 /* Called from event-processing context */
1121 if (_play_range != yn) {
1126 /* stop transport */
1127 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1134 Session::setup_auto_play ()
1136 /* Called from event-processing context */
1140 _clear_event_type (Event::RangeStop);
1141 _clear_event_type (Event::RangeLocate);
1147 list<AudioRange>::size_type sz = current_audio_range.size();
1151 list<AudioRange>::iterator i = current_audio_range.begin();
1152 list<AudioRange>::iterator next;
1154 while (i != current_audio_range.end()) {
1159 /* locating/stopping is subject to delays for declicking.
1162 nframes_t requested_frame = (*i).end;
1164 if (requested_frame > current_block_size) {
1165 requested_frame -= current_block_size;
1167 requested_frame = 0;
1170 if (next == current_audio_range.end()) {
1171 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1173 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1181 } else if (sz == 1) {
1183 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1188 /* now start rolling at the right place */
1190 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1195 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1197 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1198 ev->target2_frame = start;
1203 Session::request_bounded_roll (nframes_t start, nframes_t end)
1206 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1208 request_locate (start, true);
1212 Session::engine_halted ()
1216 /* there will be no more calls to process(), so
1217 we'd better clean up for ourselves, right now.
1219 but first, make sure the butler is out of
1223 g_atomic_int_set (&butler_should_do_transport_work, 0);
1224 post_transport_work = PostTransportWork (0);
1227 realtime_stop (false);
1228 non_realtime_stop (false, 0, ignored);
1229 transport_sub_state = 0;
1231 TransportStateChange (); /* EMIT SIGNAL */
1236 Session::xrun_recovery ()
1238 Xrun (transport_frame()); //EMIT SIGNAL
1240 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1242 /* it didn't actually halt, but we need
1243 to handle things in the same way.
1251 Session::update_latency_compensation (bool with_stop, bool abort)
1253 bool update_jack = false;
1255 if (_state_of_the_state & Deletion) {
1259 _worst_track_latency = 0;
1261 boost::shared_ptr<RouteList> r = routes.reader ();
1263 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1265 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1266 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1269 nframes_t old_latency = (*i)->signal_latency ();
1270 nframes_t track_latency = (*i)->update_total_latency ();
1272 if (old_latency != track_latency) {
1276 if (!(*i)->hidden() && ((*i)->active())) {
1277 _worst_track_latency = max (_worst_track_latency, track_latency);
1281 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1282 (*i)->set_latency_delay (_worst_track_latency);
1285 /* tell JACK to play catch up */
1288 _engine.update_total_latencies ();
1291 set_worst_io_latencies ();
1293 /* reflect any changes in latencies into capture offsets
1296 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1298 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1299 (*i)->set_capture_offset ();
1304 Session::update_latency_compensation_proxy (void* ignored)
1306 update_latency_compensation (false, false);
1310 Session::allow_auto_play (bool yn)
1312 auto_play_legal = yn;
1316 Session::reset_jack_connection (jack_client_t* jack)
1320 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1321 js->reset_client (jack);