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;
183 if (config.get_use_video_sync()) {
184 waiting_for_sync_offset = true;
187 transport_sub_state = ((Config->get_slave_source() == None && config.get_auto_return()) ? AutoReturning : 0);
191 Session::butler_transport_work ()
195 boost::shared_ptr<RouteList> r = routes.reader ();
196 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
198 int on_entry = g_atomic_int_get (&butler_should_do_transport_work);
201 if (post_transport_work & PostTransportCurveRealloc) {
202 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
203 (*i)->curve_reallocate();
207 if (post_transport_work & PostTransportInputChange) {
208 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
209 (*i)->non_realtime_input_change ();
213 if (post_transport_work & PostTransportSpeed) {
214 non_realtime_set_speed ();
217 if (post_transport_work & PostTransportReverse) {
220 cumulative_rf_motion = 0;
223 /* don't seek if locate will take care of that in non_realtime_stop() */
225 if (!(post_transport_work & PostTransportLocate)) {
227 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
228 if (!(*i)->hidden()) {
229 (*i)->non_realtime_locate (_transport_frame);
231 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
232 /* new request, stop seeking, and start again */
233 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
240 if (post_transport_work & PostTransportLocate) {
241 non_realtime_locate ();
244 if (post_transport_work & PostTransportStop) {
245 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
247 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
252 if (post_transport_work & PostTransportOverWrite) {
253 non_realtime_overwrite (on_entry, finished);
255 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
260 if (post_transport_work & PostTransportAudition) {
261 non_realtime_set_audition ();
264 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
268 Session::non_realtime_set_speed ()
270 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
272 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
273 (*i)->non_realtime_set_speed ();
278 Session::non_realtime_overwrite (int on_entry, bool& finished)
280 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
282 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
283 if ((*i)->pending_overwrite) {
284 (*i)->overwrite_existing_buffers ();
286 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
295 Session::non_realtime_locate ()
297 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
299 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
300 (*i)->non_realtime_locate (_transport_frame);
306 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
316 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
318 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
319 if ((*i)->get_captured_frames () != 0) {
325 /* stop and locate are merged here because they share a lot of common stuff */
328 now = localtime (&xnow);
331 auditioner->cancel_audition ();
335 cumulative_rf_motion = 0;
339 begin_reversible_command ("capture");
341 Location* loc = _locations.end_location();
342 bool change_end = false;
344 if (_transport_frame < loc->end()) {
346 /* stopped recording before current end */
348 if (config.get_end_marker_is_free()) {
350 /* first capture for this session, move end back to where we are */
355 } else if (_transport_frame > loc->end()) {
357 /* stopped recording after the current end, extend it */
363 XMLNode &before = loc->get_state();
364 loc->set_end(_transport_frame);
365 XMLNode &after = loc->get_state();
366 add_command (new MementoCommand<Location>(*loc, &before, &after));
369 config.set_end_marker_is_free (false);
370 _have_captured = true;
373 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
374 (*i)->transport_stopped (*now, xnow, abort);
377 boost::shared_ptr<RouteList> r = routes.reader ();
379 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
380 if (!(*i)->is_hidden()) {
381 (*i)->set_pending_declick (0);
386 commit_reversible_command ();
389 if (_engine.running()) {
390 update_latency_compensation (true, abort);
393 bool const auto_return_enabled =
394 (Config->get_slave_source() == None && config.get_auto_return());
396 if (auto_return_enabled ||
397 (post_transport_work & PostTransportLocate) ||
398 (_requested_return_frame >= 0) ||
401 if (pending_locate_flush) {
402 flush_all_inserts ();
405 if ((auto_return_enabled || synced_to_jack() || _requested_return_frame >= 0) &&
406 !(post_transport_work & PostTransportLocate)) {
408 bool do_locate = false;
410 if (_requested_return_frame >= 0) {
411 _transport_frame = _requested_return_frame;
412 _requested_return_frame = -1;
415 _transport_frame = _last_roll_location;
418 if (synced_to_jack() && !play_loop) {
423 // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl;
424 _engine.transport_locate (_transport_frame);
428 #ifndef LEAVE_TRANSPORT_UNADJUSTED
432 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
433 if (!(*i)->hidden()) {
434 (*i)->non_realtime_locate (_transport_frame);
436 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
438 /* we will be back */
443 #ifdef LEAVE_TRANSPORT_UNADJUSTED
449 send_full_time_code (0);
450 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
451 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
455 /* XXX its a little odd that we're doing this here
456 when realtime_stop(), which has already executed,
458 JLC - so let's not because it seems unnecessary and breaks loop record
461 if (!Config->get_latched_record_enable()) {
462 g_atomic_int_set (&_record_status, Disabled);
464 g_atomic_int_set (&_record_status, Enabled);
466 RecordStateChanged (); /* emit signal */
470 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
471 /* capture start has been changed, so save pending state */
472 save_state ("", true);
476 /* always try to get rid of this */
478 remove_pending_capture_state ();
480 /* save the current state of things if appropriate */
482 if (did_record && !saved) {
483 save_state (_current_snapshot_name);
486 if (post_transport_work & PostTransportDuration) {
487 DurationChanged (); /* EMIT SIGNAL */
490 if (post_transport_work & PostTransportStop) {
493 /* do not turn off autoloop on stop */
497 nframes_t tf = _transport_frame;
499 PositionChanged (tf); /* EMIT SIGNAL */
500 TransportStateChange (); /* EMIT SIGNAL */
502 /* and start it up again if relevant */
504 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
505 request_transport_speed (1.0);
506 pending_locate_roll = false;
511 Session::check_declick_out ()
513 bool locate_required = transport_sub_state & PendingLocate;
515 /* this is called after a process() iteration. if PendingDeclickOut was set,
516 it means that we were waiting to declick the output (which has just been
517 done) before doing something else. this is where we do that "something else".
519 note: called from the audio thread.
522 if (transport_sub_state & PendingDeclickOut) {
524 if (locate_required) {
525 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
526 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
528 stop_transport (pending_abort);
529 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
535 Session::set_play_loop (bool yn)
537 /* Called from event-handling context */
539 if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
545 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
546 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
547 "Recommend changing the configured options")
553 if ((play_loop = yn)) {
558 if ((loc = _locations.auto_loop_location()) != 0) {
560 if (Config->get_seamless_loop()) {
561 // set all diskstreams to use internal looping
562 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
563 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
564 if (!(*i)->hidden()) {
565 (*i)->set_loop (loc);
570 // set all diskstreams to NOT 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()) {
579 /* stick in the loop event */
581 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
584 /* locate to start of loop and roll if current pos is outside of the loop range */
585 if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
586 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
590 // locate to current position (+ 1 to force reload)
591 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
599 clear_events (Event::AutoLoop);
601 // set all diskstreams to NOT use internal looping
602 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
603 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
604 if (!(*i)->hidden()) {
613 Session::flush_all_inserts ()
615 boost::shared_ptr<RouteList> r = routes.reader ();
617 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
618 (*i)->flush_processors ();
623 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
625 if (synced_to_jack()) {
630 _slave->speed_and_position (sp, pos);
632 if (target_frame != pos) {
634 /* tell JACK to change transport position, and we will
635 follow along later in ::follow_slave()
638 _engine.transport_locate (target_frame);
640 if (sp != 1.0f && with_roll) {
641 _engine.transport_start ();
647 locate (target_frame, with_roll, with_flush, with_loop);
650 /* XXX: not sure if this should be emitted here in the synced_to_jack () case;
651 * perhaps it should happen when the slave is actually followed */
652 Located (); /* EMIT SIGNAL */
656 Session::micro_locate (nframes_t distance)
658 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
660 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
661 if (!(*i)->can_internal_playback_seek (distance)) {
666 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
667 (*i)->internal_playback_seek (distance);
670 _transport_frame += distance;
675 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
677 if (actively_recording() && !with_loop) {
681 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
683 set_transport_speed (1.0, false);
685 loop_changing = false;
690 // [DR] FIXME: find out exactly where this should go below
691 _transport_frame = target_frame;
692 smpte_time(_transport_frame, transmitting_smpte_time);
693 outbound_mtc_smpte_frame = _transport_frame;
694 next_quarter_frame_to_send = 0;
696 if (_transport_speed && (!with_loop || loop_changing)) {
697 /* schedule a declick. we'll be called again when its done */
699 if (!(transport_sub_state & PendingDeclickOut)) {
700 transport_sub_state |= (PendingDeclickOut|PendingLocate);
701 pending_locate_frame = target_frame;
702 pending_locate_roll = with_roll;
703 pending_locate_flush = with_flush;
708 if (transport_rolling() && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
709 realtime_stop (false);
712 if ( !with_loop || loop_changing) {
714 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
717 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
720 schedule_butler_transport_work ();
724 /* this is functionally what clear_clicks() does but with a tentative lock */
726 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
728 if (clickm.locked()) {
730 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
739 /* switch from input if we're going to roll */
740 if (Config->get_monitoring_model() == HardwareMonitoring) {
742 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
744 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
745 if ((*i)->record_enabled ()) {
746 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
747 (*i)->monitor_input (!config.get_auto_input());
752 /* otherwise we're going to stop, so do the opposite */
753 if (Config->get_monitoring_model() == HardwareMonitoring) {
754 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
756 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
757 if ((*i)->record_enabled ()) {
758 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
759 (*i)->monitor_input (true);
765 /* cancel looped playback if transport pos outside of loop range */
767 Location* al = _locations.auto_loop_location();
769 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
770 // cancel looping directly, this is called from event handling context
771 set_play_loop (false);
773 else if (al && _transport_frame == al->start()) {
775 // this is only necessary for seamless looping
777 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
779 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
780 if ((*i)->record_enabled ()) {
781 // tell it we've looped, so it can deal with the record state
782 (*i)->transport_looped(_transport_frame);
787 TransportLooped(); // EMIT SIGNAL
791 loop_changing = false;
793 _send_smpte_update = true;
796 /** Set the transport speed.
797 * @param speed New speed
801 Session::set_transport_speed (double speed, bool abort)
803 if (_transport_speed == speed) {
807 target_phi = (uint64_t) (0x1000000 * fabs(speed));
809 /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
810 and user needs. We really need CD-style "skip" playback for ffwd and rewind.
814 speed = min (8.0, speed);
815 } else if (speed < 0) {
816 speed = max (-8.0, 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.0 && _transport_frame == current_end_frame()) {
887 if (speed < 0.0 && _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.0) || (_last_transport_speed * speed < 0.0) || (_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;
966 /* if record status is Enabled, move it to Recording. if its
967 already Recording, move it to Disabled.
970 switch (record_status()) {
972 if (!config.get_punch_in()) {
979 disable_record (false);
987 transport_sub_state |= PendingDeclickIn;
989 _transport_speed = 1.0;
990 target_phi = 0x1000000; // speed = 1
994 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
995 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
996 (*i)->realtime_set_speed ((*i)->speed(), true);
999 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
1001 TransportStateChange (); /* EMIT SIGNAL */
1004 /** Do any transport work in the audio thread that needs to be done after the
1005 * transport thread is finished. Audio thread, realtime safe.
1008 Session::post_transport ()
1010 if (post_transport_work & PostTransportAudition) {
1011 if (auditioner && auditioner->active()) {
1012 process_function = &Session::process_audition;
1014 process_function = &Session::process_with_events;
1018 if (post_transport_work & PostTransportStop) {
1020 transport_sub_state = 0;
1023 if (post_transport_work & PostTransportLocate) {
1025 if (((Config->get_slave_source() == None && (auto_play_legal && config.get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
1029 transport_sub_state = 0;
1035 post_transport_work = PostTransportWork (0);
1039 Session::reset_rf_scale (nframes_t motion)
1041 cumulative_rf_motion += motion;
1043 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1045 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1047 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1059 Session::set_slave_source (SlaveSource src)
1061 bool reverse = false;
1062 bool non_rt_required = false;
1064 if (_transport_speed) {
1065 error << _("please stop the transport before adjusting slave settings") << endmsg;
1069 // if (src == JACK && Config->get_jack_time_master()) {
1076 if (_transport_speed < 0.0) {
1088 _slave = new MTC_Slave (*this, *_mtc_port);
1091 catch (failed_constructor& err) {
1096 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1102 if (_midi_clock_port) {
1104 _slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24);
1107 catch (failed_constructor& err) {
1112 error << _("No MIDI Clock port defined: MIDI Clock slaving is impossible.") << endmsg;
1118 _slave = new JACK_Slave (_engine.jack());
1123 Config->set_slave_source (src);
1125 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1126 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1127 if (!(*i)->hidden()) {
1128 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1129 non_rt_required = true;
1131 (*i)->set_slaved (_slave);
1136 reverse_diskstream_buffers ();
1139 if (non_rt_required) {
1140 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1141 schedule_butler_transport_work ();
1148 Session::reverse_diskstream_buffers ()
1150 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1151 schedule_butler_transport_work ();
1155 Session::set_diskstream_speed (Diskstream* stream, double speed)
1157 if (stream->realtime_set_speed (speed, false)) {
1158 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1159 schedule_butler_transport_work ();
1165 Session::set_audio_range (list<AudioRange>& range)
1167 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1168 ev->audio_range = range;
1173 Session::request_play_range (bool yn)
1175 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1180 Session::set_play_range (bool yn)
1182 /* Called from event-processing context */
1184 if (_play_range != yn) {
1189 /* stop transport */
1190 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1197 Session::setup_auto_play ()
1199 /* Called from event-processing context */
1203 _clear_event_type (Event::RangeStop);
1204 _clear_event_type (Event::RangeLocate);
1210 list<AudioRange>::size_type sz = current_audio_range.size();
1214 list<AudioRange>::iterator i = current_audio_range.begin();
1215 list<AudioRange>::iterator next;
1217 while (i != current_audio_range.end()) {
1222 /* locating/stopping is subject to delays for declicking.
1225 nframes_t requested_frame = (*i).end;
1227 if (requested_frame > current_block_size) {
1228 requested_frame -= current_block_size;
1230 requested_frame = 0;
1233 if (next == current_audio_range.end()) {
1234 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1236 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1244 } else if (sz == 1) {
1246 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1251 /* now start rolling at the right place */
1253 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1258 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1260 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1261 ev->target2_frame = start;
1266 Session::request_bounded_roll (nframes_t start, nframes_t end)
1269 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1271 request_locate (start, true);
1275 Session::engine_halted ()
1279 /* there will be no more calls to process(), so
1280 we'd better clean up for ourselves, right now.
1282 but first, make sure the butler is out of
1286 g_atomic_int_set (&butler_should_do_transport_work, 0);
1287 post_transport_work = PostTransportWork (0);
1290 realtime_stop (false);
1291 non_realtime_stop (false, 0, ignored);
1292 transport_sub_state = 0;
1294 TransportStateChange (); /* EMIT SIGNAL */
1299 Session::xrun_recovery ()
1301 Xrun (transport_frame()); //EMIT SIGNAL
1303 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1305 /* it didn't actually halt, but we need
1306 to handle things in the same way.
1314 Session::update_latency_compensation (bool with_stop, bool abort)
1316 bool update_jack = false;
1318 if (_state_of_the_state & Deletion) {
1322 _worst_track_latency = 0;
1324 #undef DEBUG_LATENCY
1325 #ifdef DEBUG_LATENCY
1326 cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1329 boost::shared_ptr<RouteList> r = routes.reader ();
1331 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1334 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1335 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1338 nframes_t old_latency = (*i)->output()->signal_latency ();
1339 nframes_t track_latency = (*i)->update_total_latency ();
1341 if (old_latency != track_latency) {
1342 (*i)->input()->update_port_total_latencies ();
1343 (*i)->output()->update_port_total_latencies ();
1347 if (!(*i)->is_hidden() && ((*i)->active())) {
1348 _worst_track_latency = max (_worst_track_latency, track_latency);
1353 _engine.update_total_latencies ();
1356 #ifdef DEBUG_LATENCY
1357 cerr << "\tworst was " << _worst_track_latency << endl;
1360 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1361 (*i)->set_latency_delay (_worst_track_latency);
1364 set_worst_io_latencies ();
1366 /* reflect any changes in latencies into capture offsets
1369 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1371 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1372 (*i)->set_capture_offset ();
1377 Session::allow_auto_play (bool yn)
1379 auto_play_legal = yn;
1383 Session::reset_jack_connection (jack_client_t* jack)
1387 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1388 js->reset_client (jack);