2 Copyright (C) 1999-2003 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include <sigc++/bind.h>
25 #include <sigc++/retype.h>
28 #include <pbd/error.h>
29 #include <glibmm/thread.h>
30 #include <pbd/pthread_utils.h>
31 #include <pbd/memento_command.h>
33 #include <midi++/mmc.h>
34 #include <midi++/port.h>
36 #include <ardour/ardour.h>
37 #include <ardour/audioengine.h>
38 #include <ardour/session.h>
39 #include <ardour/audio_diskstream.h>
40 #include <ardour/auditioner.h>
41 #include <ardour/slave.h>
42 #include <ardour/location.h>
47 using namespace ARDOUR;
52 Session::request_input_change_handling ()
54 if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
55 Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0);
61 Session::request_slave_source (SlaveSource src)
63 Event* ev = new Event (Event::SetSlaveSource, Event::Add, Event::Immediate, 0, 0.0);
66 /* could set_seamless_loop() be disposed of entirely?*/
67 Config->set_seamless_loop (false);
69 Config->set_seamless_loop (true);
76 Session::request_transport_speed (float speed)
78 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, speed);
83 Session::request_diskstream_speed (Diskstream& ds, float speed)
85 Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed);
91 Session::request_stop (bool abort)
93 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0, abort);
98 Session::request_locate (nframes_t target_frame, bool with_roll)
100 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, false);
105 Session::force_locate (nframes_t target_frame, bool with_roll)
107 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, true);
112 Session::request_play_loop (bool yn)
115 Location *location = _locations.auto_loop_location();
117 if (location == 0 && yn) {
118 error << _("Cannot loop - no loop range defined")
123 ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, 0.0, yn);
126 if (!yn && Config->get_seamless_loop() && transport_rolling()) {
127 // request an immediate locate to refresh the diskstreams
128 // after disabling looping
129 request_locate (_transport_frame-1, false);
134 Session::realtime_stop (bool abort)
136 /* assume that when we start, we'll be moving forwards */
138 // FIXME: where should this really be? [DR]
139 //send_full_time_code();
140 deliver_mmc (MIDI::MachineControl::cmdStop, _transport_frame);
141 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
143 if (_transport_speed < 0.0f) {
144 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop | PostTransportReverse);
146 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop);
149 if (actively_recording()) {
151 /* move the transport position back to where the
152 request for a stop was noticed. we rolled
153 past that point to pick up delayed input.
156 #ifndef LEAVE_TRANSPORT_UNADJUSTED
157 decrement_transport_position (_worst_output_latency);
160 /* the duration change is not guaranteed to have happened, but is likely */
162 post_transport_work = PostTransportWork (post_transport_work | PostTransportDuration);
166 post_transport_work = PostTransportWork (post_transport_work | PostTransportAbort);
169 _clear_event_type (Event::StopOnce);
170 _clear_event_type (Event::RangeStop);
171 _clear_event_type (Event::RangeLocate);
173 disable_record (true);
175 reset_slave_state ();
177 _transport_speed = 0;
179 if (Config->get_use_video_sync()) {
180 waiting_for_sync_offset = true;
183 transport_sub_state = ((Config->get_slave_source() == None && Config->get_auto_return()) ? AutoReturning : 0);
187 Session::butler_transport_work ()
191 boost::shared_ptr<RouteList> r = routes.reader ();
192 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
194 int on_entry = g_atomic_int_get (&butler_should_do_transport_work);
197 if (post_transport_work & PostTransportCurveRealloc) {
198 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
199 (*i)->curve_reallocate();
203 if (post_transport_work & PostTransportInputChange) {
204 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
205 (*i)->non_realtime_input_change ();
209 if (post_transport_work & PostTransportSpeed) {
210 non_realtime_set_speed ();
213 if (post_transport_work & PostTransportReverse) {
217 cumulative_rf_motion = 0;
220 /* don't seek if locate will take care of that in non_realtime_stop() */
222 if (!(post_transport_work & PostTransportLocate)) {
224 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
225 if (!(*i)->hidden()) {
226 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
227 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
230 (*i)->seek (_transport_frame);
233 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
234 /* new request, stop seeking, and start again */
235 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
242 if (post_transport_work & (PostTransportStop|PostTransportLocate)) {
243 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
245 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
250 if (post_transport_work & PostTransportOverWrite) {
251 non_realtime_overwrite (on_entry, finished);
253 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
258 if (post_transport_work & PostTransportAudition) {
259 non_realtime_set_audition ();
262 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
266 Session::non_realtime_set_speed ()
268 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
270 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
271 (*i)->non_realtime_set_speed ();
276 Session::non_realtime_overwrite (int on_entry, bool& finished)
278 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
280 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
281 if ((*i)->pending_overwrite) {
282 (*i)->overwrite_existing_buffers ();
284 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
292 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
302 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
304 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
305 if ((*i)->get_captured_frames () != 0) {
311 /* stop and locate are merged here because they share a lot of common stuff */
314 now = localtime (&xnow);
317 auditioner->cancel_audition ();
321 cumulative_rf_motion = 0;
325 begin_reversible_command ("capture");
327 Location* loc = _locations.end_location();
328 bool change_end = false;
330 if (_transport_frame < loc->end()) {
332 /* stopped recording before current end */
334 if (_end_location_is_free) {
336 /* first capture for this session, move end back to where we are */
341 } else if (_transport_frame > loc->end()) {
343 /* stopped recording after the current end, extend it */
349 XMLNode &before = loc->get_state();
350 loc->set_end(_transport_frame);
351 XMLNode &after = loc->get_state();
352 add_command (new MementoCommand<Location>(*loc, &before, &after));
355 _end_location_is_free = false;
356 _have_captured = true;
359 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
360 (*i)->transport_stopped (*now, xnow, abort);
363 boost::shared_ptr<RouteList> r = routes.reader ();
365 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
366 if (!(*i)->hidden()) {
367 (*i)->set_pending_declick (0);
372 commit_reversible_command ();
375 if (_engine.running()) {
376 update_latency_compensation (true, abort);
379 if ((Config->get_slave_source() == None && Config->get_auto_return()) || (post_transport_work & PostTransportLocate) || synced_to_jack()) {
381 if (pending_locate_flush) {
382 flush_all_redirects ();
385 if (((Config->get_slave_source() == None && Config->get_auto_return()) || synced_to_jack()) && !(post_transport_work & PostTransportLocate)) {
387 _transport_frame = last_stop_frame;
389 if (synced_to_jack()) {
390 _engine.transport_locate (_transport_frame);
394 #ifndef LEAVE_TRANSPORT_UNADJUSTED
398 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
399 if (!(*i)->hidden()) {
400 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
401 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
404 (*i)->seek (_transport_frame);
407 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
409 /* we will be back */
414 #ifdef LEAVE_TRANSPORT_UNADJUSTED
418 last_stop_frame = _transport_frame;
422 /* XXX its a little odd that we're doing this here
423 when realtime_stop(), which has already executed,
427 if (!Config->get_latched_record_enable()) {
428 g_atomic_int_set (&_record_status, Disabled);
430 g_atomic_int_set (&_record_status, Enabled);
432 RecordStateChanged (); /* emit signal */
435 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
436 /* capture start has been changed, so save pending state */
437 save_state ("", true);
441 /* always try to get rid of this */
443 remove_pending_capture_state ();
445 /* save the current state of things if appropriate */
447 if (did_record && !saved) {
448 save_state (_current_snapshot_name);
451 if (post_transport_work & PostTransportDuration) {
452 DurationChanged (); /* EMIT SIGNAL */
455 if (post_transport_work & PostTransportStop) {
458 /* do not turn off autoloop on stop */
462 PositionChanged (_transport_frame); /* EMIT SIGNAL */
463 TransportStateChange (); /* EMIT SIGNAL */
465 /* and start it up again if relevant */
467 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
468 request_transport_speed (1.0);
469 pending_locate_roll = false;
474 Session::check_declick_out ()
476 bool locate_required = transport_sub_state & PendingLocate;
478 /* this is called after a process() iteration. if PendingDeclickOut was set,
479 it means that we were waiting to declick the output (which has just been
480 done) before doing something else. this is where we do that "something else".
482 note: called from the audio thread.
485 if (transport_sub_state & PendingDeclickOut) {
487 if (locate_required) {
488 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
489 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
491 stop_transport (pending_abort);
492 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
498 Session::set_play_loop (bool yn)
500 /* Called from event-handling context */
502 if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
508 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
509 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
510 "Recommend changing the configured options")
516 if ((play_loop = yn)) {
521 if ((loc = _locations.auto_loop_location()) != 0) {
523 if (Config->get_seamless_loop()) {
524 // set all diskstreams to use internal looping
525 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
526 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
527 if (!(*i)->hidden()) {
528 (*i)->set_loop (loc);
533 // set all diskstreams to NOT use internal looping
534 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
535 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
536 if (!(*i)->hidden()) {
542 /* stick in the loop event */
544 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
547 /* locate to start of loop and roll if current pos is outside of the loop range */
548 if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
549 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
553 // locate to current position (+ 1 to force reload)
554 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
562 clear_events (Event::AutoLoop);
564 // set all diskstreams to NOT use internal looping
565 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
566 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
567 if (!(*i)->hidden()) {
576 Session::flush_all_redirects ()
578 boost::shared_ptr<RouteList> r = routes.reader ();
580 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
581 (*i)->flush_redirects ();
586 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
588 if (synced_to_jack()) {
593 _slave->speed_and_position (sp, pos);
595 if (target_frame != pos) {
597 /* tell JACK to change transport position, and we will
598 follow along later in ::follow_slave()
601 _engine.transport_locate (target_frame);
603 if (sp != 1.0f && with_roll) {
604 _engine.transport_start ();
611 locate (target_frame, with_roll, with_flush, with_loop);
616 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
618 if (actively_recording()) {
622 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
624 set_transport_speed (1.0, false);
626 loop_changing = false;
631 // [DR] FIXME: find out exactly where this should go below
632 _transport_frame = target_frame;
633 smpte_time(_transport_frame, transmitting_smpte_time);
634 outbound_mtc_smpte_frame = _transport_frame;
635 next_quarter_frame_to_send = 0;
637 if (_transport_speed && (!with_loop || loop_changing)) {
638 /* schedule a declick. we'll be called again when its done */
640 if (!(transport_sub_state & PendingDeclickOut)) {
641 transport_sub_state |= (PendingDeclickOut|PendingLocate);
642 pending_locate_frame = target_frame;
643 pending_locate_roll = with_roll;
644 pending_locate_flush = with_flush;
649 if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
650 realtime_stop (false);
653 if ( !with_loop || loop_changing) {
655 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
658 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
661 schedule_butler_transport_work ();
665 /* this is functionally what clear_clicks() does but with a tentative lock */
667 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
669 if (clickm.locked()) {
671 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
680 /* switch from input if we're going to roll */
681 if (Config->get_monitoring_model() == HardwareMonitoring) {
683 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
685 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
686 if ((*i)->record_enabled ()) {
687 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
688 (*i)->monitor_input (!Config->get_auto_input());
693 /* otherwise we're going to stop, so do the opposite */
694 if (Config->get_monitoring_model() == HardwareMonitoring) {
695 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
697 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
698 if ((*i)->record_enabled ()) {
699 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
700 (*i)->monitor_input (true);
706 /* cancel looped playback if transport pos outside of loop range */
708 Location* al = _locations.auto_loop_location();
710 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
711 // cancel looping directly, this is called from event handling context
712 set_play_loop (false);
716 loop_changing = false;
718 _send_smpte_update = true;
721 /** Set the transport speed.
722 * @param speed New speed
726 Session::set_transport_speed (float speed, bool abort)
728 if (_transport_speed == speed) {
733 speed = min (8.0f, speed);
734 } else if (speed < 0) {
735 speed = max (-8.0f, speed);
738 if (transport_rolling() && speed == 0.0) {
740 /* we are rolling and we want to stop */
742 if (Config->get_monitoring_model() == HardwareMonitoring)
744 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
746 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
747 if ((*i)->record_enabled ()) {
748 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
749 (*i)->monitor_input (true);
754 if (synced_to_jack ()) {
755 _engine.transport_stop ();
757 stop_transport (abort);
760 } else if (transport_stopped() && speed == 1.0) {
762 /* we are stopped and we want to start rolling at speed 1 */
764 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
768 if (Config->get_monitoring_model() == HardwareMonitoring) {
770 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
772 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
773 if (Config->get_auto_input() && (*i)->record_enabled ()) {
774 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
775 (*i)->monitor_input (false);
780 if (synced_to_jack()) {
781 _engine.transport_start ();
788 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
792 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
793 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
798 if (actively_recording()) {
802 if (speed > 0.0f && _transport_frame == current_end_frame()) {
806 if (speed < 0.0f && _transport_frame == 0) {
812 /* if we are reversing relative to the current speed, or relative to the speed
813 before the last stop, then we have to do extra work.
816 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
817 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
820 _last_transport_speed = _transport_speed;
821 _transport_speed = speed;
823 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
824 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
825 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
826 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
830 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
831 schedule_butler_transport_work ();
837 /** Stop the transport. */
839 Session::stop_transport (bool abort)
841 if (_transport_speed == 0.0f) {
845 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
846 _worst_output_latency > current_block_size)
849 /* we need to capture the audio that has still not yet been received by the system
850 at the time the stop is requested, so we have to roll past that time.
852 we want to declick before stopping, so schedule the autostop for one
853 block before the actual end. we'll declick in the subsequent block,
854 and then we'll really be stopped.
857 Event *ev = new Event (Event::StopOnce, Event::Replace,
858 _transport_frame + _worst_output_latency - current_block_size,
862 transport_sub_state |= StopPendingCapture;
863 pending_abort = abort;
868 if ((transport_sub_state & PendingDeclickOut) == 0) {
869 transport_sub_state |= PendingDeclickOut;
870 /* we'll be called again after the declick */
871 pending_abort = abort;
875 realtime_stop (abort);
876 schedule_butler_transport_work ();
880 Session::start_transport ()
882 _last_roll_location = _transport_frame;
884 /* if record status is Enabled, move it to Recording. if its
885 already Recording, move it to Disabled.
888 switch (record_status()) {
890 if (!Config->get_punch_in()) {
896 disable_record (false);
903 if (!synced_to_jack() || _exporting) {
904 actually_start_transport ();
906 waiting_to_start = true;
911 Session::actually_start_transport ()
913 waiting_to_start = false;
915 transport_sub_state |= PendingDeclickIn;
916 _transport_speed = 1.0;
918 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
919 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
920 (*i)->realtime_set_speed ((*i)->speed(), true);
923 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
925 TransportStateChange (); /* EMIT SIGNAL */
928 /** Do any transport work in the audio thread that needs to be done after the
929 * transport thread is finished. Audio thread, realtime safe.
932 Session::post_transport ()
934 if (post_transport_work & PostTransportAudition) {
935 if (auditioner && auditioner->active()) {
936 process_function = &Session::process_audition;
938 process_function = &Session::process_with_events;
942 if (post_transport_work & PostTransportStop) {
944 transport_sub_state = 0;
947 if (post_transport_work & PostTransportLocate) {
949 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
953 transport_sub_state = 0;
959 post_transport_work = PostTransportWork (0);
963 Session::reset_rf_scale (nframes_t motion)
965 cumulative_rf_motion += motion;
967 if (cumulative_rf_motion < 4 * _current_frame_rate) {
969 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
971 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
983 Session::set_slave_source (SlaveSource src)
985 bool reverse = false;
986 bool non_rt_required = false;
988 if (_transport_speed) {
989 error << _("please stop the transport before adjusting slave settings") << endmsg;
993 // if (src == JACK && Config->get_jack_time_master()) {
1002 if (_transport_speed < 0.0) {
1014 _slave = new MTC_Slave (*this, *_mtc_port);
1017 catch (failed_constructor& err) {
1022 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1025 _desired_transport_speed = _transport_speed;
1029 _slave = new JACK_Slave (_engine.jack());
1030 _desired_transport_speed = _transport_speed;
1034 Config->set_slave_source (src);
1036 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1037 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1038 if (!(*i)->hidden()) {
1039 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1040 non_rt_required = true;
1042 (*i)->set_slaved (_slave);
1047 reverse_diskstream_buffers ();
1050 if (non_rt_required) {
1051 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1052 schedule_butler_transport_work ();
1059 Session::reverse_diskstream_buffers ()
1061 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1062 schedule_butler_transport_work ();
1066 Session::set_diskstream_speed (Diskstream* stream, float speed)
1068 if (stream->realtime_set_speed (speed, false)) {
1069 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1070 schedule_butler_transport_work ();
1076 Session::set_audio_range (list<AudioRange>& range)
1078 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1079 ev->audio_range = range;
1084 Session::request_play_range (bool yn)
1086 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1091 Session::set_play_range (bool yn)
1093 /* Called from event-processing context */
1095 if (_play_range != yn) {
1100 /* stop transport */
1101 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1108 Session::setup_auto_play ()
1110 /* Called from event-processing context */
1114 _clear_event_type (Event::RangeStop);
1115 _clear_event_type (Event::RangeLocate);
1121 list<AudioRange>::size_type sz = current_audio_range.size();
1125 list<AudioRange>::iterator i = current_audio_range.begin();
1126 list<AudioRange>::iterator next;
1128 while (i != current_audio_range.end()) {
1133 /* locating/stopping is subject to delays for declicking.
1136 nframes_t requested_frame = (*i).end;
1138 if (requested_frame > current_block_size) {
1139 requested_frame -= current_block_size;
1141 requested_frame = 0;
1144 if (next == current_audio_range.end()) {
1145 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1147 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1155 } else if (sz == 1) {
1157 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1162 /* now start rolling at the right place */
1164 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1169 Session::request_bounded_roll (nframes_t start, nframes_t end)
1172 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1174 request_locate (start, true);
1178 Session::engine_halted ()
1182 /* there will be no more calls to process(), so
1183 we'd better clean up for ourselves, right now.
1185 but first, make sure the butler is out of
1189 g_atomic_int_set (&butler_should_do_transport_work, 0);
1190 post_transport_work = PostTransportWork (0);
1193 realtime_stop (false);
1194 non_realtime_stop (false, 0, ignored);
1195 transport_sub_state = 0;
1197 TransportStateChange (); /* EMIT SIGNAL */
1202 Session::xrun_recovery ()
1204 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1206 HaltOnXrun (); /* EMIT SIGNAL */
1208 /* it didn't actually halt, but we need
1209 to handle things in the same way.
1217 Session::update_latency_compensation (bool with_stop, bool abort)
1219 bool update_jack = false;
1221 if (_state_of_the_state & Deletion) {
1225 _worst_track_latency = 0;
1227 boost::shared_ptr<RouteList> r = routes.reader ();
1229 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1231 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1232 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1235 nframes_t old_latency = (*i)->signal_latency ();
1236 nframes_t track_latency = (*i)->update_total_latency ();
1238 if (old_latency != track_latency) {
1242 if (!(*i)->hidden() && ((*i)->active())) {
1243 _worst_track_latency = max (_worst_track_latency, track_latency);
1247 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1248 (*i)->set_latency_delay (_worst_track_latency);
1251 /* tell JACK to play catch up */
1254 _engine.update_total_latencies ();
1257 set_worst_io_latencies ();
1259 /* reflect any changes in latencies into capture offsets
1262 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1264 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1265 (*i)->set_capture_offset ();
1270 Session::update_latency_compensation_proxy (void* ignored)
1272 update_latency_compensation (false, false);
1276 Session::allow_auto_play (bool yn)
1278 auto_play_legal = yn;
1282 Session::reset_jack_connection (jack_client_t* jack)
1286 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1287 js->reset_client (jack);