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 (double speed)
79 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, speed);
84 Session::request_diskstream_speed (Diskstream& ds, double 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 // FIXME: where should this really be? [DR]
140 //send_full_time_code();
141 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
142 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
144 if (_transport_speed < 0.0f) {
145 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop | PostTransportReverse);
147 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop);
150 if (actively_recording()) {
152 /* move the transport position back to where the
153 request for a stop was noticed. we rolled
154 past that point to pick up delayed input.
157 #ifndef LEAVE_TRANSPORT_UNADJUSTED
158 decrement_transport_position (_worst_output_latency);
161 /* the duration change is not guaranteed to have happened, but is likely */
163 post_transport_work = PostTransportWork (post_transport_work | PostTransportDuration);
167 post_transport_work = PostTransportWork (post_transport_work | PostTransportAbort);
170 _clear_event_type (Event::StopOnce);
171 _clear_event_type (Event::RangeStop);
172 _clear_event_type (Event::RangeLocate);
174 disable_record (true);
176 reset_slave_state ();
178 _transport_speed = 0;
180 if (Config->get_use_video_sync()) {
181 waiting_for_sync_offset = true;
184 transport_sub_state = ((Config->get_slave_source() == None && Config->get_auto_return()) ? AutoReturning : 0);
188 Session::butler_transport_work ()
192 boost::shared_ptr<RouteList> r = routes.reader ();
193 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
195 int on_entry = g_atomic_int_get (&butler_should_do_transport_work);
198 if (post_transport_work & PostTransportCurveRealloc) {
199 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
200 (*i)->curve_reallocate();
204 if (post_transport_work & PostTransportInputChange) {
205 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
206 (*i)->non_realtime_input_change ();
210 if (post_transport_work & PostTransportSpeed) {
211 non_realtime_set_speed ();
214 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 (*i)->non_realtime_locate (_transport_frame);
228 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
229 /* new request, stop seeking, and start again */
230 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
237 if (post_transport_work & PostTransportLocate) {
238 non_realtime_locate ();
241 if (post_transport_work & PostTransportStop) {
242 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
244 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
249 if (post_transport_work & PostTransportOverWrite) {
250 non_realtime_overwrite (on_entry, finished);
252 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
257 if (post_transport_work & PostTransportAudition) {
258 non_realtime_set_audition ();
261 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
265 Session::non_realtime_set_speed ()
267 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
269 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
270 (*i)->non_realtime_set_speed ();
275 Session::non_realtime_overwrite (int on_entry, bool& finished)
277 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
279 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
280 if ((*i)->pending_overwrite) {
281 (*i)->overwrite_existing_buffers ();
283 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
292 Session::non_realtime_locate ()
294 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
296 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
297 (*i)->non_realtime_locate (_transport_frame);
303 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
313 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
315 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
316 if ((*i)->get_captured_frames () != 0) {
322 /* stop and locate are merged here because they share a lot of common stuff */
325 now = localtime (&xnow);
328 auditioner->cancel_audition ();
332 cumulative_rf_motion = 0;
336 begin_reversible_command ("capture");
338 Location* loc = _locations.end_location();
339 bool change_end = false;
341 if (_transport_frame < loc->end()) {
343 /* stopped recording before current end */
345 if (_end_location_is_free) {
347 /* first capture for this session, move end back to where we are */
352 } else if (_transport_frame > loc->end()) {
354 /* stopped recording after the current end, extend it */
360 XMLNode &before = loc->get_state();
361 loc->set_end(_transport_frame);
362 XMLNode &after = loc->get_state();
363 add_command (new MementoCommand<Location>(*loc, &before, &after));
366 _end_location_is_free = false;
367 _have_captured = true;
370 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
371 (*i)->transport_stopped (*now, xnow, abort);
374 boost::shared_ptr<RouteList> r = routes.reader ();
376 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
377 if (!(*i)->is_hidden()) {
378 (*i)->set_pending_declick (0);
383 commit_reversible_command ();
386 if (_engine.running()) {
387 update_latency_compensation (true, abort);
390 if ((Config->get_slave_source() == None && Config->get_auto_return()) ||
391 (post_transport_work & PostTransportLocate) ||
392 (_requested_return_frame >= 0) ||
395 if (pending_locate_flush) {
396 flush_all_inserts ();
399 if (((Config->get_slave_source() == None && Config->get_auto_return()) ||
401 _requested_return_frame >= 0) &&
402 !(post_transport_work & PostTransportLocate)) {
404 bool do_locate = false;
406 if (_requested_return_frame >= 0) {
407 _transport_frame = _requested_return_frame;
408 _requested_return_frame = -1;
411 _transport_frame = last_stop_frame;
412 _requested_return_frame = -1;
415 if (synced_to_jack() && !play_loop) {
420 // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl;
421 _engine.transport_locate (_transport_frame);
425 #ifndef LEAVE_TRANSPORT_UNADJUSTED
429 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
430 if (!(*i)->hidden()) {
431 (*i)->non_realtime_locate (_transport_frame);
433 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
435 /* we will be back */
440 #ifdef LEAVE_TRANSPORT_UNADJUSTED
444 if (_requested_return_frame < 0) {
445 last_stop_frame = _transport_frame;
447 last_stop_frame = _requested_return_frame;
448 _requested_return_frame = -1;
453 send_full_time_code (0);
454 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
455 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
459 /* XXX its a little odd that we're doing this here
460 when realtime_stop(), which has already executed,
462 JLC - so let's not because it seems unnecessary and breaks loop record
465 if (!Config->get_latched_record_enable()) {
466 g_atomic_int_set (&_record_status, Disabled);
468 g_atomic_int_set (&_record_status, Enabled);
470 RecordStateChanged (); /* emit signal */
474 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
475 /* capture start has been changed, so save pending state */
476 save_state ("", true);
480 /* always try to get rid of this */
482 remove_pending_capture_state ();
484 /* save the current state of things if appropriate */
486 if (did_record && !saved) {
487 save_state (_current_snapshot_name);
490 if (post_transport_work & PostTransportDuration) {
491 DurationChanged (); /* EMIT SIGNAL */
494 if (post_transport_work & PostTransportStop) {
497 /* do not turn off autoloop on stop */
501 nframes_t tf = _transport_frame;
503 PositionChanged (tf); /* EMIT SIGNAL */
504 TransportStateChange (); /* EMIT SIGNAL */
506 /* and start it up again if relevant */
508 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
509 request_transport_speed (1.0);
510 pending_locate_roll = false;
515 Session::check_declick_out ()
517 bool locate_required = transport_sub_state & PendingLocate;
519 /* this is called after a process() iteration. if PendingDeclickOut was set,
520 it means that we were waiting to declick the output (which has just been
521 done) before doing something else. this is where we do that "something else".
523 note: called from the audio thread.
526 if (transport_sub_state & PendingDeclickOut) {
528 if (locate_required) {
529 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
530 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
532 stop_transport (pending_abort);
533 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
539 Session::set_play_loop (bool yn)
541 /* Called from event-handling context */
543 if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
549 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
550 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
551 "Recommend changing the configured options")
557 if ((play_loop = yn)) {
562 if ((loc = _locations.auto_loop_location()) != 0) {
564 if (Config->get_seamless_loop()) {
565 // set all diskstreams to use internal looping
566 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
567 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
568 if (!(*i)->hidden()) {
569 (*i)->set_loop (loc);
574 // set all diskstreams to NOT use internal looping
575 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
576 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
577 if (!(*i)->hidden()) {
583 /* stick in the loop event */
585 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
588 /* locate to start of loop and roll if current pos is outside of the loop range */
589 if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
590 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
594 // locate to current position (+ 1 to force reload)
595 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
603 clear_events (Event::AutoLoop);
605 // set all diskstreams to NOT use internal looping
606 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
607 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
608 if (!(*i)->hidden()) {
617 Session::flush_all_inserts ()
619 boost::shared_ptr<RouteList> r = routes.reader ();
621 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
622 (*i)->flush_processors ();
627 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
629 if (synced_to_jack()) {
634 _slave->speed_and_position (sp, pos);
636 if (target_frame != pos) {
638 /* tell JACK to change transport position, and we will
639 follow along later in ::follow_slave()
642 _engine.transport_locate (target_frame);
644 if (sp != 1.0f && with_roll) {
645 _engine.transport_start ();
652 locate (target_frame, with_roll, with_flush, with_loop);
657 Session::micro_locate (nframes_t distance)
659 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
661 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
662 if (!(*i)->can_internal_playback_seek (distance)) {
667 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
668 (*i)->internal_playback_seek (distance);
671 _transport_frame += distance;
676 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
678 if (actively_recording() && !with_loop) {
682 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
684 set_transport_speed (1.0, false);
686 loop_changing = false;
691 // [DR] FIXME: find out exactly where this should go below
692 _transport_frame = target_frame;
693 smpte_time(_transport_frame, transmitting_smpte_time);
694 outbound_mtc_smpte_frame = _transport_frame;
695 next_quarter_frame_to_send = 0;
697 if (_transport_speed && (!with_loop || loop_changing)) {
698 /* schedule a declick. we'll be called again when its done */
700 if (!(transport_sub_state & PendingDeclickOut)) {
701 transport_sub_state |= (PendingDeclickOut|PendingLocate);
702 pending_locate_frame = target_frame;
703 pending_locate_roll = with_roll;
704 pending_locate_flush = with_flush;
709 if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
710 realtime_stop (false);
713 if ( !with_loop || loop_changing) {
715 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
718 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
721 schedule_butler_transport_work ();
725 /* this is functionally what clear_clicks() does but with a tentative lock */
727 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
729 if (clickm.locked()) {
731 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
740 /* switch from input if we're going to roll */
741 if (Config->get_monitoring_model() == HardwareMonitoring) {
743 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
745 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
746 if ((*i)->record_enabled ()) {
747 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
748 (*i)->monitor_input (!Config->get_auto_input());
753 /* otherwise we're going to stop, so do the opposite */
754 if (Config->get_monitoring_model() == HardwareMonitoring) {
755 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
757 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
758 if ((*i)->record_enabled ()) {
759 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
760 (*i)->monitor_input (true);
766 /* cancel looped playback if transport pos outside of loop range */
768 Location* al = _locations.auto_loop_location();
770 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
771 // cancel looping directly, this is called from event handling context
772 set_play_loop (false);
774 else if (al && _transport_frame == al->start()) {
776 // this is only necessary for seamless looping
778 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
780 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
781 if ((*i)->record_enabled ()) {
782 // tell it we've looped, so it can deal with the record state
783 (*i)->transport_looped(_transport_frame);
788 TransportLooped(); // EMIT SIGNAL
792 loop_changing = false;
794 _send_smpte_update = true;
797 /** Set the transport speed.
798 * @param speed New speed
802 Session::set_transport_speed (double speed, bool abort)
804 if (_transport_speed == speed) {
809 speed = min (8.0, speed);
810 } else if (speed < 0) {
811 speed = max (-8.0, speed);
814 if (transport_rolling() && speed == 0.0) {
816 /* we are rolling and we want to stop */
818 if (Config->get_monitoring_model() == HardwareMonitoring)
820 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
822 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
823 if ((*i)->record_enabled ()) {
824 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
825 (*i)->monitor_input (true);
830 if (synced_to_jack ()) {
831 _engine.transport_stop ();
833 stop_transport (abort);
836 } else if (transport_stopped() && speed == 1.0) {
838 /* we are stopped and we want to start rolling at speed 1 */
840 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
844 if (Config->get_monitoring_model() == HardwareMonitoring) {
846 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
848 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
849 if (Config->get_auto_input() && (*i)->record_enabled ()) {
850 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
851 (*i)->monitor_input (false);
856 if (synced_to_jack()) {
857 _engine.transport_start ();
864 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
868 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
869 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
874 if (actively_recording()) {
878 if (speed > 0.0 && _transport_frame == current_end_frame()) {
882 if (speed < 0.0 && _transport_frame == 0) {
888 /* if we are reversing relative to the current speed, or relative to the speed
889 before the last stop, then we have to do extra work.
892 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
893 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
894 last_stop_frame = _transport_frame;
897 _last_transport_speed = _transport_speed;
898 _transport_speed = speed;
900 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
901 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
902 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
903 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
907 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
908 schedule_butler_transport_work ();
914 /** Stop the transport. */
916 Session::stop_transport (bool abort)
918 if (_transport_speed == 0.0f) {
922 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
923 _worst_output_latency > current_block_size)
926 /* we need to capture the audio that has still not yet been received by the system
927 at the time the stop is requested, so we have to roll past that time.
929 we want to declick before stopping, so schedule the autostop for one
930 block before the actual end. we'll declick in the subsequent block,
931 and then we'll really be stopped.
934 Event *ev = new Event (Event::StopOnce, Event::Replace,
935 _transport_frame + _worst_output_latency - current_block_size,
939 transport_sub_state |= StopPendingCapture;
940 pending_abort = abort;
945 if ((transport_sub_state & PendingDeclickOut) == 0) {
946 transport_sub_state |= PendingDeclickOut;
947 /* we'll be called again after the declick */
948 pending_abort = abort;
952 realtime_stop (abort);
953 schedule_butler_transport_work ();
957 Session::start_transport ()
959 _last_roll_location = _transport_frame;
962 /* if record status is Enabled, move it to Recording. if its
963 already Recording, move it to Disabled.
966 switch (record_status()) {
968 if (!Config->get_punch_in()) {
975 disable_record (false);
983 transport_sub_state |= PendingDeclickIn;
984 _transport_speed = 1.0;
986 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
987 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
988 (*i)->realtime_set_speed ((*i)->speed(), true);
991 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
993 TransportStateChange (); /* EMIT SIGNAL */
996 /** Do any transport work in the audio thread that needs to be done after the
997 * transport thread is finished. Audio thread, realtime safe.
1000 Session::post_transport ()
1002 if (post_transport_work & PostTransportAudition) {
1003 if (auditioner && auditioner->active()) {
1004 process_function = &Session::process_audition;
1006 process_function = &Session::process_with_events;
1010 if (post_transport_work & PostTransportStop) {
1012 transport_sub_state = 0;
1015 if (post_transport_work & PostTransportLocate) {
1017 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
1021 transport_sub_state = 0;
1027 post_transport_work = PostTransportWork (0);
1031 Session::reset_rf_scale (nframes_t motion)
1033 cumulative_rf_motion += motion;
1035 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1037 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1039 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1051 Session::set_slave_source (SlaveSource src)
1053 bool reverse = false;
1054 bool non_rt_required = false;
1056 if (_transport_speed) {
1057 error << _("please stop the transport before adjusting slave settings") << endmsg;
1061 // if (src == JACK && Config->get_jack_time_master()) {
1068 if (_transport_speed < 0.0) {
1080 _slave = new MTC_Slave (*this, *_mtc_port);
1083 catch (failed_constructor& err) {
1088 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1094 if (_midi_clock_port) {
1096 _slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24);
1099 catch (failed_constructor& err) {
1104 error << _("No MIDI Clock port defined: MIDI Clock slaving is impossible.") << endmsg;
1110 _slave = new JACK_Slave (_engine.jack());
1115 Config->set_slave_source (src);
1117 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1118 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1119 if (!(*i)->hidden()) {
1120 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1121 non_rt_required = true;
1123 (*i)->set_slaved (_slave);
1128 reverse_diskstream_buffers ();
1131 if (non_rt_required) {
1132 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1133 schedule_butler_transport_work ();
1140 Session::reverse_diskstream_buffers ()
1142 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1143 schedule_butler_transport_work ();
1147 Session::set_diskstream_speed (Diskstream* stream, double speed)
1149 if (stream->realtime_set_speed (speed, false)) {
1150 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1151 schedule_butler_transport_work ();
1157 Session::set_audio_range (list<AudioRange>& range)
1159 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1160 ev->audio_range = range;
1165 Session::request_play_range (bool yn)
1167 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1172 Session::set_play_range (bool yn)
1174 /* Called from event-processing context */
1176 if (_play_range != yn) {
1181 /* stop transport */
1182 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1189 Session::setup_auto_play ()
1191 /* Called from event-processing context */
1195 _clear_event_type (Event::RangeStop);
1196 _clear_event_type (Event::RangeLocate);
1202 list<AudioRange>::size_type sz = current_audio_range.size();
1206 list<AudioRange>::iterator i = current_audio_range.begin();
1207 list<AudioRange>::iterator next;
1209 while (i != current_audio_range.end()) {
1214 /* locating/stopping is subject to delays for declicking.
1217 nframes_t requested_frame = (*i).end;
1219 if (requested_frame > current_block_size) {
1220 requested_frame -= current_block_size;
1222 requested_frame = 0;
1225 if (next == current_audio_range.end()) {
1226 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1228 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1236 } else if (sz == 1) {
1238 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1243 /* now start rolling at the right place */
1245 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1250 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1252 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1253 ev->target2_frame = start;
1258 Session::request_bounded_roll (nframes_t start, nframes_t end)
1261 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1263 request_locate (start, true);
1267 Session::engine_halted ()
1271 /* there will be no more calls to process(), so
1272 we'd better clean up for ourselves, right now.
1274 but first, make sure the butler is out of
1278 g_atomic_int_set (&butler_should_do_transport_work, 0);
1279 post_transport_work = PostTransportWork (0);
1282 realtime_stop (false);
1283 non_realtime_stop (false, 0, ignored);
1284 transport_sub_state = 0;
1286 TransportStateChange (); /* EMIT SIGNAL */
1291 Session::xrun_recovery ()
1293 Xrun (transport_frame()); //EMIT SIGNAL
1295 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1297 /* it didn't actually halt, but we need
1298 to handle things in the same way.
1306 Session::update_latency_compensation (bool with_stop, bool abort)
1308 bool update_jack = false;
1310 if (_state_of_the_state & Deletion) {
1314 _worst_track_latency = 0;
1316 #undef DEBUG_LATENCY
1317 #ifdef DEBUG_LATENCY
1318 cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1321 boost::shared_ptr<RouteList> r = routes.reader ();
1323 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1326 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1327 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1330 nframes_t old_latency = (*i)->signal_latency ();
1331 nframes_t track_latency = (*i)->update_total_latency ();
1333 if (old_latency != track_latency) {
1334 (*i)->update_port_total_latencies ();
1338 if (!(*i)->is_hidden() && ((*i)->active())) {
1339 _worst_track_latency = max (_worst_track_latency, track_latency);
1344 _engine.update_total_latencies ();
1347 #ifdef DEBUG_LATENCY
1348 cerr << "\tworst was " << _worst_track_latency << endl;
1351 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1352 (*i)->set_latency_delay (_worst_track_latency);
1355 set_worst_io_latencies ();
1357 /* reflect any changes in latencies into capture offsets
1360 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1362 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1363 (*i)->set_capture_offset ();
1368 Session::allow_auto_play (bool yn)
1370 auto_play_legal = yn;
1374 Session::reset_jack_connection (jack_client_t* jack)
1378 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1379 js->reset_client (jack);