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) {
218 cumulative_rf_motion = 0;
221 /* don't seek if locate will take care of that in non_realtime_stop() */
223 if (!(post_transport_work & PostTransportLocate)) {
225 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
226 if (!(*i)->hidden()) {
227 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
228 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
231 (*i)->seek (_transport_frame);
234 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
235 /* new request, stop seeking, and start again */
236 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
243 if (post_transport_work & PostTransportLocate) {
244 non_realtime_locate ();
247 if (post_transport_work & PostTransportStop) {
248 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
250 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
255 if (post_transport_work & PostTransportOverWrite) {
256 non_realtime_overwrite (on_entry, finished);
258 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
263 if (post_transport_work & PostTransportAudition) {
264 non_realtime_set_audition ();
267 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
271 Session::non_realtime_set_speed ()
273 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
275 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
276 (*i)->non_realtime_set_speed ();
281 Session::non_realtime_overwrite (int on_entry, bool& finished)
283 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
285 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
286 if ((*i)->pending_overwrite) {
287 (*i)->overwrite_existing_buffers ();
289 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
298 Session::non_realtime_locate ()
300 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
302 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
303 (*i)->non_realtime_locate (_transport_frame);
309 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
319 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
321 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
322 if ((*i)->get_captured_frames () != 0) {
328 /* stop and locate are merged here because they share a lot of common stuff */
331 now = localtime (&xnow);
334 auditioner->cancel_audition ();
338 cumulative_rf_motion = 0;
342 begin_reversible_command ("capture");
344 Location* loc = _locations.end_location();
345 bool change_end = false;
347 if (_transport_frame < loc->end()) {
349 /* stopped recording before current end */
351 if (_end_location_is_free) {
353 /* first capture for this session, move end back to where we are */
358 } else if (_transport_frame > loc->end()) {
360 /* stopped recording after the current end, extend it */
366 XMLNode &before = loc->get_state();
367 loc->set_end(_transport_frame);
368 XMLNode &after = loc->get_state();
369 add_command (new MementoCommand<Location>(*loc, &before, &after));
372 _end_location_is_free = false;
373 _have_captured = true;
376 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
377 (*i)->transport_stopped (*now, xnow, abort);
380 boost::shared_ptr<RouteList> r = routes.reader ();
382 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
383 if (!(*i)->is_hidden()) {
384 (*i)->set_pending_declick (0);
389 commit_reversible_command ();
392 if (_engine.running()) {
393 update_latency_compensation (true, abort);
396 if ((Config->get_slave_source() == None && Config->get_auto_return()) ||
397 (post_transport_work & PostTransportLocate) ||
398 (_requested_return_frame >= 0) ||
401 if (pending_locate_flush) {
402 flush_all_inserts ();
405 if (((Config->get_slave_source() == None && Config->get_auto_return()) ||
407 _requested_return_frame >= 0) &&
408 !(post_transport_work & PostTransportLocate)) {
410 bool do_locate = false;
412 if (_requested_return_frame >= 0) {
413 _transport_frame = _requested_return_frame;
414 _requested_return_frame = -1;
417 _transport_frame = last_stop_frame;
418 _requested_return_frame = -1;
421 if (synced_to_jack() && !play_loop) {
426 // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl;
427 _engine.transport_locate (_transport_frame);
431 #ifndef LEAVE_TRANSPORT_UNADJUSTED
435 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
436 if (!(*i)->hidden()) {
437 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
438 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
441 (*i)->seek (_transport_frame);
444 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
446 /* we will be back */
451 #ifdef LEAVE_TRANSPORT_UNADJUSTED
455 if (_requested_return_frame < 0) {
456 last_stop_frame = _transport_frame;
458 last_stop_frame = _requested_return_frame;
459 _requested_return_frame = -1;
464 /* XXX its a little odd that we're doing this here
465 when realtime_stop(), which has already executed,
467 JLC - so let's not because it seems unnecessary and breaks loop record
470 if (!Config->get_latched_record_enable()) {
471 g_atomic_int_set (&_record_status, Disabled);
473 g_atomic_int_set (&_record_status, Enabled);
475 RecordStateChanged (); /* emit signal */
479 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
480 /* capture start has been changed, so save pending state */
481 save_state ("", true);
485 /* always try to get rid of this */
487 remove_pending_capture_state ();
489 /* save the current state of things if appropriate */
491 if (did_record && !saved) {
492 save_state (_current_snapshot_name);
495 if (post_transport_work & PostTransportDuration) {
496 DurationChanged (); /* EMIT SIGNAL */
499 if (post_transport_work & PostTransportStop) {
502 /* do not turn off autoloop on stop */
506 nframes_t tf = _transport_frame;
508 PositionChanged (tf); /* EMIT SIGNAL */
509 TransportStateChange (); /* EMIT SIGNAL */
511 /* and start it up again if relevant */
513 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
514 request_transport_speed (1.0);
515 pending_locate_roll = false;
520 Session::check_declick_out ()
522 bool locate_required = transport_sub_state & PendingLocate;
524 /* this is called after a process() iteration. if PendingDeclickOut was set,
525 it means that we were waiting to declick the output (which has just been
526 done) before doing something else. this is where we do that "something else".
528 note: called from the audio thread.
531 if (transport_sub_state & PendingDeclickOut) {
533 if (locate_required) {
534 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
535 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
537 stop_transport (pending_abort);
538 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
544 Session::set_play_loop (bool yn)
546 /* Called from event-handling context */
548 if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
554 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
555 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
556 "Recommend changing the configured options")
562 if ((play_loop = yn)) {
567 if ((loc = _locations.auto_loop_location()) != 0) {
569 if (Config->get_seamless_loop()) {
570 // set all diskstreams to use internal looping
571 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
572 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
573 if (!(*i)->hidden()) {
574 (*i)->set_loop (loc);
579 // set all diskstreams to NOT use internal looping
580 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
581 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
582 if (!(*i)->hidden()) {
588 /* stick in the loop event */
590 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
593 /* locate to start of loop and roll if current pos is outside of the loop range */
594 if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
595 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
599 // locate to current position (+ 1 to force reload)
600 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
608 clear_events (Event::AutoLoop);
610 // set all diskstreams to NOT use internal looping
611 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
612 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
613 if (!(*i)->hidden()) {
622 Session::flush_all_inserts ()
624 boost::shared_ptr<RouteList> r = routes.reader ();
626 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
627 (*i)->flush_processors ();
632 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
634 if (synced_to_jack()) {
639 _slave->speed_and_position (sp, pos);
641 if (target_frame != pos) {
643 /* tell JACK to change transport position, and we will
644 follow along later in ::follow_slave()
647 _engine.transport_locate (target_frame);
649 if (sp != 1.0f && with_roll) {
650 _engine.transport_start ();
657 locate (target_frame, with_roll, with_flush, with_loop);
662 Session::micro_locate (nframes_t distance)
664 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
666 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
667 if (!(*i)->can_internal_playback_seek (distance)) {
672 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
673 (*i)->internal_playback_seek (distance);
676 _transport_frame += distance;
681 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
683 if (actively_recording() && !with_loop) {
687 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
689 set_transport_speed (1.0, false);
691 loop_changing = false;
696 // [DR] FIXME: find out exactly where this should go below
697 _transport_frame = target_frame;
698 smpte_time(_transport_frame, transmitting_smpte_time);
699 outbound_mtc_smpte_frame = _transport_frame;
700 next_quarter_frame_to_send = 0;
702 if (_transport_speed && (!with_loop || loop_changing)) {
703 /* schedule a declick. we'll be called again when its done */
705 if (!(transport_sub_state & PendingDeclickOut)) {
706 transport_sub_state |= (PendingDeclickOut|PendingLocate);
707 pending_locate_frame = target_frame;
708 pending_locate_roll = with_roll;
709 pending_locate_flush = with_flush;
714 if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
715 realtime_stop (false);
718 if ( !with_loop || loop_changing) {
720 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
723 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
726 schedule_butler_transport_work ();
730 /* this is functionally what clear_clicks() does but with a tentative lock */
732 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
734 if (clickm.locked()) {
736 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
745 /* switch from input if we're going to roll */
746 if (Config->get_monitoring_model() == HardwareMonitoring) {
748 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
750 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
751 if ((*i)->record_enabled ()) {
752 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
753 (*i)->monitor_input (!Config->get_auto_input());
758 /* otherwise we're going to stop, so do the opposite */
759 if (Config->get_monitoring_model() == HardwareMonitoring) {
760 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
762 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
763 if ((*i)->record_enabled ()) {
764 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
765 (*i)->monitor_input (true);
771 /* cancel looped playback if transport pos outside of loop range */
773 Location* al = _locations.auto_loop_location();
775 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
776 // cancel looping directly, this is called from event handling context
777 set_play_loop (false);
779 else if (al && _transport_frame == al->start()) {
781 // this is only necessary for seamless looping
783 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
785 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
786 if ((*i)->record_enabled ()) {
787 // tell it we've looped, so it can deal with the record state
788 (*i)->transport_looped(_transport_frame);
793 TransportLooped(); // EMIT SIGNAL
797 loop_changing = false;
799 _send_smpte_update = true;
802 /** Set the transport speed.
803 * @param speed New speed
807 Session::set_transport_speed (float speed, bool abort)
809 if (_transport_speed == speed) {
814 speed = min (8.0f, speed);
815 } else if (speed < 0) {
816 speed = max (-8.0f, speed);
819 if (transport_rolling() && speed == 0.0) {
821 /* we are rolling and we want to stop */
823 if (Config->get_monitoring_model() == HardwareMonitoring)
825 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
827 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
828 if ((*i)->record_enabled ()) {
829 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
830 (*i)->monitor_input (true);
835 if (synced_to_jack ()) {
836 _engine.transport_stop ();
838 stop_transport (abort);
841 } else if (transport_stopped() && speed == 1.0) {
843 /* we are stopped and we want to start rolling at speed 1 */
845 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
849 if (Config->get_monitoring_model() == HardwareMonitoring) {
851 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
853 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
854 if (Config->get_auto_input() && (*i)->record_enabled ()) {
855 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
856 (*i)->monitor_input (false);
861 if (synced_to_jack()) {
862 _engine.transport_start ();
869 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
873 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
874 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
879 if (actively_recording()) {
883 if (speed > 0.0f && _transport_frame == current_end_frame()) {
887 if (speed < 0.0f && _transport_frame == 0) {
893 /* if we are reversing relative to the current speed, or relative to the speed
894 before the last stop, then we have to do extra work.
897 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
898 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
901 _last_transport_speed = _transport_speed;
902 _transport_speed = speed;
904 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
905 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
906 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
907 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
911 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
912 schedule_butler_transport_work ();
918 /** Stop the transport. */
920 Session::stop_transport (bool abort)
922 if (_transport_speed == 0.0f) {
926 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
927 _worst_output_latency > current_block_size)
930 /* we need to capture the audio that has still not yet been received by the system
931 at the time the stop is requested, so we have to roll past that time.
933 we want to declick before stopping, so schedule the autostop for one
934 block before the actual end. we'll declick in the subsequent block,
935 and then we'll really be stopped.
938 Event *ev = new Event (Event::StopOnce, Event::Replace,
939 _transport_frame + _worst_output_latency - current_block_size,
943 transport_sub_state |= StopPendingCapture;
944 pending_abort = abort;
949 if ((transport_sub_state & PendingDeclickOut) == 0) {
950 transport_sub_state |= PendingDeclickOut;
951 /* we'll be called again after the declick */
952 pending_abort = abort;
956 realtime_stop (abort);
957 schedule_butler_transport_work ();
961 Session::start_transport ()
963 _last_roll_location = _transport_frame;
965 /* if record status is Enabled, move it to Recording. if its
966 already Recording, move it to Disabled.
969 switch (record_status()) {
971 if (!Config->get_punch_in()) {
978 disable_record (false);
986 if (!synced_to_jack() || _exporting) {
987 actually_start_transport ();
989 waiting_to_start = true;
994 Session::actually_start_transport ()
996 waiting_to_start = false;
998 transport_sub_state |= PendingDeclickIn;
999 _transport_speed = 1.0;
1001 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1002 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1003 (*i)->realtime_set_speed ((*i)->speed(), true);
1006 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
1008 TransportStateChange (); /* EMIT SIGNAL */
1011 /** Do any transport work in the audio thread that needs to be done after the
1012 * transport thread is finished. Audio thread, realtime safe.
1015 Session::post_transport ()
1017 if (post_transport_work & PostTransportAudition) {
1018 if (auditioner && auditioner->active()) {
1019 process_function = &Session::process_audition;
1021 process_function = &Session::process_with_events;
1025 if (post_transport_work & PostTransportStop) {
1027 transport_sub_state = 0;
1030 if (post_transport_work & PostTransportLocate) {
1032 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
1036 transport_sub_state = 0;
1042 post_transport_work = PostTransportWork (0);
1046 Session::reset_rf_scale (nframes_t motion)
1048 cumulative_rf_motion += motion;
1050 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1052 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1054 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1066 Session::set_slave_source (SlaveSource src)
1068 bool reverse = false;
1069 bool non_rt_required = false;
1071 if (_transport_speed) {
1072 error << _("please stop the transport before adjusting slave settings") << endmsg;
1076 // if (src == JACK && Config->get_jack_time_master()) {
1085 if (_transport_speed < 0.0) {
1097 _slave = new MTC_Slave (*this, *_mtc_port);
1100 catch (failed_constructor& err) {
1105 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1108 _desired_transport_speed = _transport_speed;
1112 if (_midi_clock_port) {
1114 _slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24);
1117 catch (failed_constructor& err) {
1122 error << _("No MIDI Clock port defined: MIDI Clock slaving is impossible.") << endmsg;
1125 _desired_transport_speed = _transport_speed;
1129 _slave = new JACK_Slave (_engine.jack());
1130 _desired_transport_speed = _transport_speed;
1135 Config->set_slave_source (src);
1137 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1138 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1139 if (!(*i)->hidden()) {
1140 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1141 non_rt_required = true;
1143 (*i)->set_slaved (_slave);
1148 reverse_diskstream_buffers ();
1151 if (non_rt_required) {
1152 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1153 schedule_butler_transport_work ();
1160 Session::reverse_diskstream_buffers ()
1162 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1163 schedule_butler_transport_work ();
1167 Session::set_diskstream_speed (Diskstream* stream, float speed)
1169 if (stream->realtime_set_speed (speed, false)) {
1170 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1171 schedule_butler_transport_work ();
1177 Session::set_audio_range (list<AudioRange>& range)
1179 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1180 ev->audio_range = range;
1185 Session::request_play_range (bool yn)
1187 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1192 Session::set_play_range (bool yn)
1194 /* Called from event-processing context */
1196 if (_play_range != yn) {
1201 /* stop transport */
1202 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1209 Session::setup_auto_play ()
1211 /* Called from event-processing context */
1215 _clear_event_type (Event::RangeStop);
1216 _clear_event_type (Event::RangeLocate);
1222 list<AudioRange>::size_type sz = current_audio_range.size();
1226 list<AudioRange>::iterator i = current_audio_range.begin();
1227 list<AudioRange>::iterator next;
1229 while (i != current_audio_range.end()) {
1234 /* locating/stopping is subject to delays for declicking.
1237 nframes_t requested_frame = (*i).end;
1239 if (requested_frame > current_block_size) {
1240 requested_frame -= current_block_size;
1242 requested_frame = 0;
1245 if (next == current_audio_range.end()) {
1246 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1248 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1256 } else if (sz == 1) {
1258 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1263 /* now start rolling at the right place */
1265 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1270 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1272 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1273 ev->target2_frame = start;
1278 Session::request_bounded_roll (nframes_t start, nframes_t end)
1281 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1283 request_locate (start, true);
1287 Session::engine_halted ()
1291 /* there will be no more calls to process(), so
1292 we'd better clean up for ourselves, right now.
1294 but first, make sure the butler is out of
1298 g_atomic_int_set (&butler_should_do_transport_work, 0);
1299 post_transport_work = PostTransportWork (0);
1302 realtime_stop (false);
1303 non_realtime_stop (false, 0, ignored);
1304 transport_sub_state = 0;
1306 TransportStateChange (); /* EMIT SIGNAL */
1311 Session::xrun_recovery ()
1313 Xrun (transport_frame()); //EMIT SIGNAL
1315 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1317 /* it didn't actually halt, but we need
1318 to handle things in the same way.
1326 Session::update_latency_compensation (bool with_stop, bool abort)
1328 bool update_jack = false;
1330 if (_state_of_the_state & Deletion) {
1334 _worst_track_latency = 0;
1336 #undef DEBUG_LATENCY
1337 #ifdef DEBUG_LATENCY
1338 cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1341 boost::shared_ptr<RouteList> r = routes.reader ();
1343 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1346 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1347 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1350 nframes_t old_latency = (*i)->signal_latency ();
1351 nframes_t track_latency = (*i)->update_total_latency ();
1353 if (old_latency != track_latency) {
1354 (*i)->update_port_total_latencies ();
1358 if (!(*i)->is_hidden() && ((*i)->active())) {
1359 _worst_track_latency = max (_worst_track_latency, track_latency);
1364 _engine.update_total_latencies ();
1367 #ifdef DEBUG_LATENCY
1368 cerr << "\tworst was " << _worst_track_latency << endl;
1371 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1372 (*i)->set_latency_delay (_worst_track_latency);
1375 set_worst_io_latencies ();
1377 /* reflect any changes in latencies into capture offsets
1380 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1382 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1383 (*i)->set_capture_offset ();
1388 Session::allow_auto_play (bool yn)
1390 auto_play_legal = yn;
1394 Session::reset_jack_connection (jack_client_t* jack)
1398 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1399 js->reset_client (jack);