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;
722 Session::set_transport_speed (float speed, bool abort)
724 if (_transport_speed == speed) {
729 speed = min (8.0f, speed);
730 } else if (speed < 0) {
731 speed = max (-8.0f, speed);
734 if (transport_rolling() && speed == 0.0) {
736 if (Config->get_monitoring_model() == HardwareMonitoring)
738 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
740 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
741 if ((*i)->record_enabled ()) {
742 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
743 (*i)->monitor_input (true);
748 if (synced_to_jack ()) {
749 _engine.transport_stop ();
751 stop_transport (abort);
754 } else if (transport_stopped() && speed == 1.0) {
756 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
760 if (Config->get_monitoring_model() == HardwareMonitoring) {
762 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
764 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
765 if (Config->get_auto_input() && (*i)->record_enabled ()) {
766 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
767 (*i)->monitor_input (false);
772 if (synced_to_jack()) {
773 _engine.transport_start ();
780 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
784 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
785 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
790 if (actively_recording()) {
794 if (speed > 0.0f && _transport_frame == current_end_frame()) {
798 if (speed < 0.0f && _transport_frame == 0) {
804 /* if we are reversing relative to the current speed, or relative to the speed
805 before the last stop, then we have to do extra work.
808 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
809 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
812 _last_transport_speed = _transport_speed;
813 _transport_speed = speed;
815 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
816 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
817 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
818 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
822 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
823 schedule_butler_transport_work ();
829 Session::stop_transport (bool abort)
831 if (_transport_speed == 0.0f) {
835 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
836 _worst_output_latency > current_block_size)
839 /* we need to capture the audio that has still not yet been received by the system
840 at the time the stop is requested, so we have to roll past that time.
842 we want to declick before stopping, so schedule the autostop for one
843 block before the actual end. we'll declick in the subsequent block,
844 and then we'll really be stopped.
847 Event *ev = new Event (Event::StopOnce, Event::Replace,
848 _transport_frame + _worst_output_latency - current_block_size,
852 transport_sub_state |= StopPendingCapture;
853 pending_abort = abort;
858 if ((transport_sub_state & PendingDeclickOut) == 0) {
859 transport_sub_state |= PendingDeclickOut;
860 /* we'll be called again after the declick */
861 pending_abort = abort;
865 realtime_stop (abort);
866 schedule_butler_transport_work ();
870 Session::start_transport ()
872 _last_roll_location = _transport_frame;
874 /* if record status is Enabled, move it to Recording. if its
875 already Recording, move it to Disabled.
878 switch (record_status()) {
880 if (!Config->get_punch_in()) {
886 disable_record (false);
893 if (!synced_to_jack() || _exporting) {
894 actually_start_transport ();
896 waiting_to_start = true;
901 Session::actually_start_transport ()
903 waiting_to_start = false;
905 transport_sub_state |= PendingDeclickIn;
906 _transport_speed = 1.0;
908 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
909 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
910 (*i)->realtime_set_speed ((*i)->speed(), true);
913 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
915 TransportStateChange (); /* EMIT SIGNAL */
918 /** Do any transport work in the audio thread that needs to be done after the
919 * transport thread is finished. Audio thread, realtime safe.
922 Session::post_transport ()
924 if (post_transport_work & PostTransportAudition) {
925 if (auditioner && auditioner->active()) {
926 process_function = &Session::process_audition;
928 process_function = &Session::process_with_events;
932 if (post_transport_work & PostTransportStop) {
934 transport_sub_state = 0;
937 if (post_transport_work & PostTransportLocate) {
939 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
943 transport_sub_state = 0;
949 post_transport_work = PostTransportWork (0);
953 Session::reset_rf_scale (nframes_t motion)
955 cumulative_rf_motion += motion;
957 if (cumulative_rf_motion < 4 * _current_frame_rate) {
959 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
961 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
973 Session::set_slave_source (SlaveSource src)
975 bool reverse = false;
976 bool non_rt_required = false;
978 if (_transport_speed) {
979 error << _("please stop the transport before adjusting slave settings") << endmsg;
983 // if (src == JACK && Config->get_jack_time_master()) {
992 if (_transport_speed < 0.0) {
1004 _slave = new MTC_Slave (*this, *_mtc_port);
1007 catch (failed_constructor& err) {
1012 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1015 _desired_transport_speed = _transport_speed;
1019 _slave = new JACK_Slave (_engine.jack());
1020 _desired_transport_speed = _transport_speed;
1024 Config->set_slave_source (src);
1026 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1027 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1028 if (!(*i)->hidden()) {
1029 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1030 non_rt_required = true;
1032 (*i)->set_slaved (_slave);
1037 reverse_diskstream_buffers ();
1040 if (non_rt_required) {
1041 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1042 schedule_butler_transport_work ();
1049 Session::reverse_diskstream_buffers ()
1051 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1052 schedule_butler_transport_work ();
1056 Session::set_diskstream_speed (Diskstream* stream, float speed)
1058 if (stream->realtime_set_speed (speed, false)) {
1059 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1060 schedule_butler_transport_work ();
1066 Session::set_audio_range (list<AudioRange>& range)
1068 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1069 ev->audio_range = range;
1074 Session::request_play_range (bool yn)
1076 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1081 Session::set_play_range (bool yn)
1083 /* Called from event-processing context */
1085 if (_play_range != yn) {
1090 /* stop transport */
1091 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1098 Session::setup_auto_play ()
1100 /* Called from event-processing context */
1104 _clear_event_type (Event::RangeStop);
1105 _clear_event_type (Event::RangeLocate);
1111 list<AudioRange>::size_type sz = current_audio_range.size();
1115 list<AudioRange>::iterator i = current_audio_range.begin();
1116 list<AudioRange>::iterator next;
1118 while (i != current_audio_range.end()) {
1123 /* locating/stopping is subject to delays for declicking.
1126 nframes_t requested_frame = (*i).end;
1128 if (requested_frame > current_block_size) {
1129 requested_frame -= current_block_size;
1131 requested_frame = 0;
1134 if (next == current_audio_range.end()) {
1135 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1137 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1145 } else if (sz == 1) {
1147 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1152 /* now start rolling at the right place */
1154 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1159 Session::request_bounded_roll (nframes_t start, nframes_t end)
1162 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1164 request_locate (start, true);
1168 Session::engine_halted ()
1172 /* there will be no more calls to process(), so
1173 we'd better clean up for ourselves, right now.
1175 but first, make sure the butler is out of
1179 g_atomic_int_set (&butler_should_do_transport_work, 0);
1180 post_transport_work = PostTransportWork (0);
1183 realtime_stop (false);
1184 non_realtime_stop (false, 0, ignored);
1185 transport_sub_state = 0;
1187 TransportStateChange (); /* EMIT SIGNAL */
1192 Session::xrun_recovery ()
1194 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1196 HaltOnXrun (); /* EMIT SIGNAL */
1198 /* it didn't actually halt, but we need
1199 to handle things in the same way.
1207 Session::update_latency_compensation (bool with_stop, bool abort)
1209 bool update_jack = false;
1211 if (_state_of_the_state & Deletion) {
1215 _worst_track_latency = 0;
1217 boost::shared_ptr<RouteList> r = routes.reader ();
1219 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1221 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1222 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1225 nframes_t old_latency = (*i)->signal_latency ();
1226 nframes_t track_latency = (*i)->update_total_latency ();
1228 if (old_latency != track_latency) {
1232 if (!(*i)->hidden() && ((*i)->active())) {
1233 _worst_track_latency = max (_worst_track_latency, track_latency);
1237 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1238 (*i)->set_latency_delay (_worst_track_latency);
1241 /* tell JACK to play catch up */
1244 _engine.update_total_latencies ();
1247 set_worst_io_latencies ();
1249 /* reflect any changes in latencies into capture offsets
1252 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1254 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1255 (*i)->set_capture_offset ();
1260 Session::update_latency_compensation_proxy (void* ignored)
1262 update_latency_compensation (false, false);
1266 Session::allow_auto_play (bool yn)
1268 auto_play_legal = yn;
1272 Session::reset_jack_connection (jack_client_t* jack)
1276 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1277 js->reset_client (jack);