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/audio_diskstream.h"
39 #include "ardour/audioengine.h"
40 #include "ardour/auditioner.h"
41 #include "ardour/butler.h"
42 #include "ardour/location.h"
43 #include "ardour/session.h"
44 #include "ardour/slave.h"
49 using namespace ARDOUR;
54 Session::request_input_change_handling ()
56 if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
57 Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0);
63 Session::request_slave_source (SlaveSource src)
65 Event* ev = new Event (Event::SetSlaveSource, Event::Add, Event::Immediate, 0, 0.0);
68 /* could set_seamless_loop() be disposed of entirely?*/
69 Config->set_seamless_loop (false);
71 Config->set_seamless_loop (true);
78 Session::request_transport_speed (double speed)
80 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, speed);
85 Session::request_diskstream_speed (Diskstream& ds, double speed)
87 Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed);
93 Session::request_stop (bool abort)
95 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0, abort);
100 Session::request_locate (nframes_t target_frame, bool with_roll)
102 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, false);
107 Session::force_locate (nframes_t target_frame, bool with_roll)
109 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, true);
114 Session::request_play_loop (bool yn)
117 Location *location = _locations.auto_loop_location();
119 if (location == 0 && yn) {
120 error << _("Cannot loop - no loop range defined")
125 ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, 0.0, yn);
128 if (!yn && Config->get_seamless_loop() && transport_rolling()) {
129 // request an immediate locate to refresh the diskstreams
130 // after disabling looping
131 request_locate (_transport_frame-1, false);
136 Session::realtime_stop (bool abort)
138 /* assume that when we start, we'll be moving forwards */
140 // FIXME: where should this really be? [DR]
141 //send_full_time_code();
142 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
143 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
145 if (_transport_speed < 0.0f) {
146 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop | PostTransportReverse);
148 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop);
151 if (actively_recording()) {
153 /* move the transport position back to where the
154 request for a stop was noticed. we rolled
155 past that point to pick up delayed input.
158 #ifndef LEAVE_TRANSPORT_UNADJUSTED
159 decrement_transport_position (_worst_output_latency);
162 /* the duration change is not guaranteed to have happened, but is likely */
164 post_transport_work = PostTransportWork (post_transport_work | PostTransportDuration);
168 post_transport_work = PostTransportWork (post_transport_work | PostTransportAbort);
171 _clear_event_type (Event::StopOnce);
172 _clear_event_type (Event::RangeStop);
173 _clear_event_type (Event::RangeLocate);
175 disable_record (true);
177 reset_slave_state ();
179 _transport_speed = 0;
180 _target_transport_speed = 0;
182 if (config.get_use_video_sync()) {
183 waiting_for_sync_offset = true;
186 transport_sub_state = ((Config->get_slave_source() == None && config.get_auto_return()) ? AutoReturning : 0);
190 Session::butler_transport_work ()
194 boost::shared_ptr<RouteList> r = routes.reader ();
195 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
197 int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
200 if (post_transport_work & PostTransportCurveRealloc) {
201 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
202 (*i)->curve_reallocate();
206 if (post_transport_work & PostTransportInputChange) {
207 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
208 (*i)->non_realtime_input_change ();
212 if (post_transport_work & PostTransportSpeed) {
213 non_realtime_set_speed ();
216 if (post_transport_work & PostTransportReverse) {
219 cumulative_rf_motion = 0;
222 /* don't seek if locate will take care of that in non_realtime_stop() */
224 if (!(post_transport_work & PostTransportLocate)) {
226 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
227 if (!(*i)->hidden()) {
228 (*i)->non_realtime_locate (_transport_frame);
230 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
231 /* new request, stop seeking, and start again */
232 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
239 if (post_transport_work & PostTransportLocate) {
240 non_realtime_locate ();
243 if (post_transport_work & PostTransportStop) {
244 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
246 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
251 if (post_transport_work & PostTransportOverWrite) {
252 non_realtime_overwrite (on_entry, finished);
254 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
259 if (post_transport_work & PostTransportAudition) {
260 non_realtime_set_audition ();
263 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
267 Session::non_realtime_set_speed ()
269 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
271 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
272 (*i)->non_realtime_set_speed ();
277 Session::non_realtime_overwrite (int on_entry, bool& finished)
279 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
281 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
282 if ((*i)->pending_overwrite) {
283 (*i)->overwrite_existing_buffers ();
285 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
294 Session::non_realtime_locate ()
296 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
298 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
299 (*i)->non_realtime_locate (_transport_frame);
305 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
315 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
317 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
318 if ((*i)->get_captured_frames () != 0) {
324 /* stop and locate are merged here because they share a lot of common stuff */
327 now = localtime (&xnow);
330 auditioner->cancel_audition ();
334 cumulative_rf_motion = 0;
338 begin_reversible_command ("capture");
340 Location* loc = _locations.end_location();
341 bool change_end = false;
343 if (_transport_frame < loc->end()) {
345 /* stopped recording before current end */
347 if (config.get_end_marker_is_free()) {
349 /* first capture for this session, move end back to where we are */
354 } else if (_transport_frame > loc->end()) {
356 /* stopped recording after the current end, extend it */
362 XMLNode &before = loc->get_state();
363 loc->set_end(_transport_frame);
364 XMLNode &after = loc->get_state();
365 add_command (new MementoCommand<Location>(*loc, &before, &after));
368 config.set_end_marker_is_free (false);
369 _have_captured = true;
372 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
373 (*i)->transport_stopped (*now, xnow, abort);
376 boost::shared_ptr<RouteList> r = routes.reader ();
378 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
379 if (!(*i)->is_hidden()) {
380 (*i)->set_pending_declick (0);
385 commit_reversible_command ();
388 if (_engine.running()) {
389 update_latency_compensation (true, abort);
392 bool const auto_return_enabled =
393 (Config->get_slave_source() == None && config.get_auto_return());
395 if (auto_return_enabled ||
396 (post_transport_work & PostTransportLocate) ||
397 (_requested_return_frame >= 0) ||
400 if (pending_locate_flush) {
401 flush_all_inserts ();
404 if ((auto_return_enabled || synced_to_jack() || _requested_return_frame >= 0) &&
405 !(post_transport_work & PostTransportLocate)) {
407 bool do_locate = false;
409 if (_requested_return_frame >= 0) {
410 _transport_frame = _requested_return_frame;
411 _requested_return_frame = -1;
414 _transport_frame = _last_roll_location;
417 if (synced_to_jack() && !play_loop) {
422 // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl;
423 _engine.transport_locate (_transport_frame);
427 #ifndef LEAVE_TRANSPORT_UNADJUSTED
431 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
432 if (!(*i)->hidden()) {
433 (*i)->non_realtime_locate (_transport_frame);
435 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
437 /* we will be back */
442 #ifdef LEAVE_TRANSPORT_UNADJUSTED
448 send_full_time_code (0);
449 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
450 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
454 /* XXX its a little odd that we're doing this here
455 when realtime_stop(), which has already executed,
457 JLC - so let's not because it seems unnecessary and breaks loop record
460 if (!Config->get_latched_record_enable()) {
461 g_atomic_int_set (&_record_status, Disabled);
463 g_atomic_int_set (&_record_status, Enabled);
465 RecordStateChanged (); /* emit signal */
469 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
470 /* capture start has been changed, so save pending state */
471 save_state ("", true);
475 /* always try to get rid of this */
477 remove_pending_capture_state ();
479 /* save the current state of things if appropriate */
481 if (did_record && !saved) {
482 save_state (_current_snapshot_name);
485 if (post_transport_work & PostTransportDuration) {
486 DurationChanged (); /* EMIT SIGNAL */
489 if (post_transport_work & PostTransportStop) {
492 /* do not turn off autoloop on stop */
496 nframes_t tf = _transport_frame;
498 PositionChanged (tf); /* EMIT SIGNAL */
499 TransportStateChange (); /* EMIT SIGNAL */
501 /* and start it up again if relevant */
503 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
504 request_transport_speed (1.0);
505 pending_locate_roll = false;
510 Session::check_declick_out ()
512 bool locate_required = transport_sub_state & PendingLocate;
514 /* this is called after a process() iteration. if PendingDeclickOut was set,
515 it means that we were waiting to declick the output (which has just been
516 done) before doing something else. this is where we do that "something else".
518 note: called from the audio thread.
521 if (transport_sub_state & PendingDeclickOut) {
523 if (locate_required) {
524 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
525 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
527 stop_transport (pending_abort);
528 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
534 Session::set_play_loop (bool yn)
536 /* Called from event-handling context */
538 if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
544 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
545 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
546 "Recommend changing the configured options")
552 if ((play_loop = yn)) {
557 if ((loc = _locations.auto_loop_location()) != 0) {
559 if (Config->get_seamless_loop()) {
560 // set all diskstreams to use internal looping
561 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
562 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
563 if (!(*i)->hidden()) {
564 (*i)->set_loop (loc);
569 // set all diskstreams to NOT use internal looping
570 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
571 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
572 if (!(*i)->hidden()) {
578 /* stick in the loop event */
580 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
583 /* locate to start of loop and roll if current pos is outside of the loop range */
584 if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
585 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
589 // locate to current position (+ 1 to force reload)
590 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
598 clear_events (Event::AutoLoop);
600 // set all diskstreams to NOT use internal looping
601 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
602 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
603 if (!(*i)->hidden()) {
612 Session::flush_all_inserts ()
614 boost::shared_ptr<RouteList> r = routes.reader ();
616 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
617 (*i)->flush_processors ();
622 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
624 if (synced_to_jack()) {
629 _slave->speed_and_position (sp, pos);
631 if (target_frame != pos) {
633 /* tell JACK to change transport position, and we will
634 follow along later in ::follow_slave()
637 _engine.transport_locate (target_frame);
639 if (sp != 1.0f && with_roll) {
640 _engine.transport_start ();
646 locate (target_frame, with_roll, with_flush, with_loop);
651 Session::micro_locate (nframes_t distance)
653 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
655 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
656 if (!(*i)->can_internal_playback_seek (distance)) {
661 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
662 (*i)->internal_playback_seek (distance);
665 _transport_frame += distance;
670 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
672 if (actively_recording() && !with_loop) {
676 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
678 set_transport_speed (1.0, false);
680 loop_changing = false;
684 // Update Timecode time
685 // [DR] FIXME: find out exactly where this should go below
686 _transport_frame = target_frame;
687 timecode_time(_transport_frame, transmitting_timecode_time);
688 outbound_mtc_timecode_frame = _transport_frame;
689 next_quarter_frame_to_send = 0;
691 if (_transport_speed && (!with_loop || loop_changing)) {
692 /* schedule a declick. we'll be called again when its done */
694 if (!(transport_sub_state & PendingDeclickOut)) {
695 transport_sub_state |= (PendingDeclickOut|PendingLocate);
696 pending_locate_frame = target_frame;
697 pending_locate_roll = with_roll;
698 pending_locate_flush = with_flush;
703 if (transport_rolling() && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
704 realtime_stop (false);
707 if ( !with_loop || loop_changing) {
709 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
712 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
715 _butler->schedule_transport_work ();
719 /* this is functionally what clear_clicks() does but with a tentative lock */
721 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
723 if (clickm.locked()) {
725 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
734 /* switch from input if we're going to roll */
735 if (Config->get_monitoring_model() == HardwareMonitoring) {
737 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
739 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
740 if ((*i)->record_enabled ()) {
741 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
742 (*i)->monitor_input (!config.get_auto_input());
747 /* otherwise we're going to stop, so do the opposite */
748 if (Config->get_monitoring_model() == HardwareMonitoring) {
749 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
751 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
752 if ((*i)->record_enabled ()) {
753 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
754 (*i)->monitor_input (true);
760 /* cancel looped playback if transport pos outside of loop range */
762 Location* al = _locations.auto_loop_location();
764 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
765 // cancel looping directly, this is called from event handling context
766 set_play_loop (false);
768 else if (al && _transport_frame == al->start()) {
770 // this is only necessary for seamless looping
772 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
774 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
775 if ((*i)->record_enabled ()) {
776 // tell it we've looped, so it can deal with the record state
777 (*i)->transport_looped(_transport_frame);
782 TransportLooped(); // EMIT SIGNAL
786 loop_changing = false;
788 _send_timecode_update = true;
790 Located (); /* EMIT SIGNAL */
793 /** Set the transport speed.
794 * @param speed New speed
798 Session::set_transport_speed (double speed, bool abort)
800 if (_transport_speed == speed) {
804 _target_transport_speed = fabs(speed);
806 /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
807 and user needs. We really need CD-style "skip" playback for ffwd and rewind.
811 speed = min (8.0, speed);
812 } else if (speed < 0) {
813 speed = max (-8.0, speed);
816 if (transport_rolling() && speed == 0.0) {
818 /* we are rolling and we want to stop */
820 if (Config->get_monitoring_model() == HardwareMonitoring)
822 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
824 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
825 if ((*i)->record_enabled ()) {
826 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
827 (*i)->monitor_input (true);
832 if (synced_to_jack ()) {
833 _engine.transport_stop ();
835 stop_transport (abort);
838 } else if (transport_stopped() && speed == 1.0) {
840 /* we are stopped and we want to start rolling at speed 1 */
842 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
846 if (Config->get_monitoring_model() == HardwareMonitoring) {
848 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
850 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
851 if (config.get_auto_input() && (*i)->record_enabled ()) {
852 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
853 (*i)->monitor_input (false);
858 if (synced_to_jack()) {
859 _engine.transport_start ();
866 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
870 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
871 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
876 if (actively_recording()) {
880 if (speed > 0.0 && _transport_frame == current_end_frame()) {
884 if (speed < 0.0 && _transport_frame == 0) {
890 /* if we are reversing relative to the current speed, or relative to the speed
891 before the last stop, then we have to do extra work.
894 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
895 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
898 _last_transport_speed = _transport_speed;
899 _transport_speed = speed;
901 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
902 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
903 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
904 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
908 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
909 _butler->schedule_transport_work ();
915 /** Stop the transport. */
917 Session::stop_transport (bool abort)
919 if (_transport_speed == 0.0f) {
923 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
924 _worst_output_latency > current_block_size)
927 /* we need to capture the audio that has still not yet been received by the system
928 at the time the stop is requested, so we have to roll past that time.
930 we want to declick before stopping, so schedule the autostop for one
931 block before the actual end. we'll declick in the subsequent block,
932 and then we'll really be stopped.
935 Event *ev = new Event (Event::StopOnce, Event::Replace,
936 _transport_frame + _worst_output_latency - current_block_size,
940 transport_sub_state |= StopPendingCapture;
941 pending_abort = abort;
946 if ((transport_sub_state & PendingDeclickOut) == 0) {
947 transport_sub_state |= PendingDeclickOut;
948 /* we'll be called again after the declick */
949 pending_abort = abort;
953 realtime_stop (abort);
954 _butler->schedule_transport_work ();
958 Session::start_transport ()
960 _last_roll_location = _transport_frame;
963 /* if record status is Enabled, move it to Recording. if its
964 already Recording, move it to Disabled.
967 switch (record_status()) {
969 if (!config.get_punch_in()) {
976 disable_record (false);
984 transport_sub_state |= PendingDeclickIn;
986 _transport_speed = 1.0;
987 _target_transport_speed = 1.0;
989 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
990 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
991 (*i)->realtime_set_speed ((*i)->speed(), true);
994 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
996 TransportStateChange (); /* EMIT SIGNAL */
999 /** Do any transport work in the audio thread that needs to be done after the
1000 * transport thread is finished. Audio thread, realtime safe.
1003 Session::post_transport ()
1005 if (post_transport_work & PostTransportAudition) {
1006 if (auditioner && auditioner->active()) {
1007 process_function = &Session::process_audition;
1009 process_function = &Session::process_with_events;
1013 if (post_transport_work & PostTransportStop) {
1015 transport_sub_state = 0;
1018 if (post_transport_work & PostTransportLocate) {
1020 if (((Config->get_slave_source() == None && (auto_play_legal && config.get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
1024 transport_sub_state = 0;
1030 post_transport_work = PostTransportWork (0);
1034 Session::reset_rf_scale (nframes_t motion)
1036 cumulative_rf_motion += motion;
1038 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1040 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1042 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1054 Session::set_slave_source (SlaveSource src)
1056 bool reverse = false;
1057 bool non_rt_required = false;
1059 if (_transport_speed) {
1060 error << _("please stop the transport before adjusting slave settings") << endmsg;
1064 // if (src == JACK && Config->get_jack_time_master()) {
1071 if (_transport_speed < 0.0) {
1083 _slave = new MTC_Slave (*this, *_mtc_port);
1086 catch (failed_constructor& err) {
1091 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1097 if (_midi_clock_port) {
1099 _slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24);
1102 catch (failed_constructor& err) {
1107 error << _("No MIDI Clock port defined: MIDI Clock slaving is impossible.") << endmsg;
1113 _slave = new JACK_Slave (_engine.jack());
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 _butler->schedule_transport_work ();
1143 Session::reverse_diskstream_buffers ()
1145 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1146 _butler->schedule_transport_work ();
1150 Session::set_diskstream_speed (Diskstream* stream, double speed)
1152 if (stream->realtime_set_speed (speed, false)) {
1153 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1154 _butler->schedule_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)->output()->signal_latency ();
1334 nframes_t track_latency = (*i)->update_total_latency ();
1336 if (old_latency != track_latency) {
1337 (*i)->input()->update_port_total_latencies ();
1338 (*i)->output()->update_port_total_latencies ();
1342 if (!(*i)->is_hidden() && ((*i)->active())) {
1343 _worst_track_latency = max (_worst_track_latency, track_latency);
1348 _engine.update_total_latencies ();
1351 #ifdef DEBUG_LATENCY
1352 cerr << "\tworst was " << _worst_track_latency << endl;
1355 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1356 (*i)->set_latency_delay (_worst_track_latency);
1359 set_worst_io_latencies ();
1361 /* reflect any changes in latencies into capture offsets
1364 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1366 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1367 (*i)->set_capture_offset ();
1372 Session::allow_auto_play (bool yn)
1374 auto_play_legal = yn;
1378 Session::reset_jack_connection (jack_client_t* jack)
1382 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1383 js->reset_client (jack);