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 // 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 (float speed, bool abort)
804 if (_transport_speed == speed) {
809 speed = min (8.0f, speed);
810 } else if (speed < 0) {
811 speed = max (-8.0f, 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.0f && _transport_frame == current_end_frame()) {
882 if (speed < 0.0f && _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.0f) || (_last_transport_speed * speed < 0.0f) || (_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;
1091 _desired_transport_speed = _transport_speed;
1095 if (_midi_clock_port) {
1097 _slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24);
1100 catch (failed_constructor& err) {
1105 error << _("No MIDI Clock port defined: MIDI Clock slaving is impossible.") << endmsg;
1108 _desired_transport_speed = _transport_speed;
1112 _slave = new JACK_Slave (_engine.jack());
1113 _desired_transport_speed = _transport_speed;
1118 Config->set_slave_source (src);
1120 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1121 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1122 if (!(*i)->hidden()) {
1123 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1124 non_rt_required = true;
1126 (*i)->set_slaved (_slave);
1131 reverse_diskstream_buffers ();
1134 if (non_rt_required) {
1135 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1136 schedule_butler_transport_work ();
1143 Session::reverse_diskstream_buffers ()
1145 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1146 schedule_butler_transport_work ();
1150 Session::set_diskstream_speed (Diskstream* stream, float speed)
1152 if (stream->realtime_set_speed (speed, false)) {
1153 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1154 schedule_butler_transport_work ();
1160 Session::set_audio_range (list<AudioRange>& range)
1162 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1163 ev->audio_range = range;
1168 Session::request_play_range (bool yn)
1170 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1175 Session::set_play_range (bool yn)
1177 /* Called from event-processing context */
1179 if (_play_range != yn) {
1184 /* stop transport */
1185 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1192 Session::setup_auto_play ()
1194 /* Called from event-processing context */
1198 _clear_event_type (Event::RangeStop);
1199 _clear_event_type (Event::RangeLocate);
1205 list<AudioRange>::size_type sz = current_audio_range.size();
1209 list<AudioRange>::iterator i = current_audio_range.begin();
1210 list<AudioRange>::iterator next;
1212 while (i != current_audio_range.end()) {
1217 /* locating/stopping is subject to delays for declicking.
1220 nframes_t requested_frame = (*i).end;
1222 if (requested_frame > current_block_size) {
1223 requested_frame -= current_block_size;
1225 requested_frame = 0;
1228 if (next == current_audio_range.end()) {
1229 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1231 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1239 } else if (sz == 1) {
1241 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1246 /* now start rolling at the right place */
1248 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1253 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1255 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1256 ev->target2_frame = start;
1261 Session::request_bounded_roll (nframes_t start, nframes_t end)
1264 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1266 request_locate (start, true);
1270 Session::engine_halted ()
1274 /* there will be no more calls to process(), so
1275 we'd better clean up for ourselves, right now.
1277 but first, make sure the butler is out of
1281 g_atomic_int_set (&butler_should_do_transport_work, 0);
1282 post_transport_work = PostTransportWork (0);
1285 realtime_stop (false);
1286 non_realtime_stop (false, 0, ignored);
1287 transport_sub_state = 0;
1289 TransportStateChange (); /* EMIT SIGNAL */
1294 Session::xrun_recovery ()
1296 Xrun (transport_frame()); //EMIT SIGNAL
1298 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1300 /* it didn't actually halt, but we need
1301 to handle things in the same way.
1309 Session::update_latency_compensation (bool with_stop, bool abort)
1311 bool update_jack = false;
1313 if (_state_of_the_state & Deletion) {
1317 _worst_track_latency = 0;
1319 #undef DEBUG_LATENCY
1320 #ifdef DEBUG_LATENCY
1321 cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1324 boost::shared_ptr<RouteList> r = routes.reader ();
1326 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1329 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1330 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1333 nframes_t old_latency = (*i)->signal_latency ();
1334 nframes_t track_latency = (*i)->update_total_latency ();
1336 if (old_latency != track_latency) {
1337 (*i)->update_port_total_latencies ();
1341 if (!(*i)->is_hidden() && ((*i)->active())) {
1342 _worst_track_latency = max (_worst_track_latency, track_latency);
1347 _engine.update_total_latencies ();
1350 #ifdef DEBUG_LATENCY
1351 cerr << "\tworst was " << _worst_track_latency << endl;
1354 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1355 (*i)->set_latency_delay (_worst_track_latency);
1358 set_worst_io_latencies ();
1360 /* reflect any changes in latencies into capture offsets
1363 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1365 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1366 (*i)->set_capture_offset ();
1371 Session::allow_auto_play (bool yn)
1373 auto_play_legal = yn;
1377 Session::reset_jack_connection (jack_client_t* jack)
1381 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1382 js->reset_client (jack);