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;
179 _target_transport_speed = 0;
181 if (config.get_use_video_sync()) {
182 waiting_for_sync_offset = true;
185 transport_sub_state = ((Config->get_slave_source() == None && config.get_auto_return()) ? AutoReturning : 0);
189 Session::butler_transport_work ()
193 boost::shared_ptr<RouteList> r = routes.reader ();
194 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
196 int on_entry = g_atomic_int_get (&butler_should_do_transport_work);
199 if (post_transport_work & PostTransportCurveRealloc) {
200 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
201 (*i)->curve_reallocate();
205 if (post_transport_work & PostTransportInputChange) {
206 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
207 (*i)->non_realtime_input_change ();
211 if (post_transport_work & PostTransportSpeed) {
212 non_realtime_set_speed ();
215 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 (*i)->non_realtime_locate (_transport_frame);
229 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
230 /* new request, stop seeking, and start again */
231 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
238 if (post_transport_work & PostTransportLocate) {
239 non_realtime_locate ();
242 if (post_transport_work & PostTransportStop) {
243 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
245 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
250 if (post_transport_work & PostTransportOverWrite) {
251 non_realtime_overwrite (on_entry, finished);
253 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
258 if (post_transport_work & PostTransportAudition) {
259 non_realtime_set_audition ();
262 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
266 Session::non_realtime_set_speed ()
268 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
270 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
271 (*i)->non_realtime_set_speed ();
276 Session::non_realtime_overwrite (int on_entry, bool& finished)
278 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
280 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
281 if ((*i)->pending_overwrite) {
282 (*i)->overwrite_existing_buffers ();
284 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
293 Session::non_realtime_locate ()
295 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
297 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
298 (*i)->non_realtime_locate (_transport_frame);
304 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
314 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
316 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
317 if ((*i)->get_captured_frames () != 0) {
323 /* stop and locate are merged here because they share a lot of common stuff */
326 now = localtime (&xnow);
329 auditioner->cancel_audition ();
333 cumulative_rf_motion = 0;
337 begin_reversible_command ("capture");
339 Location* loc = _locations.end_location();
340 bool change_end = false;
342 if (_transport_frame < loc->end()) {
344 /* stopped recording before current end */
346 if (config.get_end_marker_is_free()) {
348 /* first capture for this session, move end back to where we are */
353 } else if (_transport_frame > loc->end()) {
355 /* stopped recording after the current end, extend it */
361 XMLNode &before = loc->get_state();
362 loc->set_end(_transport_frame);
363 XMLNode &after = loc->get_state();
364 add_command (new MementoCommand<Location>(*loc, &before, &after));
367 config.set_end_marker_is_free (false);
368 _have_captured = true;
371 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
372 (*i)->transport_stopped (*now, xnow, abort);
375 boost::shared_ptr<RouteList> r = routes.reader ();
377 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
378 if (!(*i)->is_hidden()) {
379 (*i)->set_pending_declick (0);
384 commit_reversible_command ();
387 if (_engine.running()) {
388 update_latency_compensation (true, abort);
391 bool const auto_return_enabled =
392 (Config->get_slave_source() == None && config.get_auto_return());
394 if (auto_return_enabled ||
395 (post_transport_work & PostTransportLocate) ||
396 (_requested_return_frame >= 0) ||
399 if (pending_locate_flush) {
400 flush_all_inserts ();
403 if ((auto_return_enabled || synced_to_jack() || _requested_return_frame >= 0) &&
404 !(post_transport_work & PostTransportLocate)) {
406 bool do_locate = false;
408 if (_requested_return_frame >= 0) {
409 _transport_frame = _requested_return_frame;
410 _requested_return_frame = -1;
413 _transport_frame = _last_roll_location;
416 if (synced_to_jack() && !play_loop) {
421 // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl;
422 _engine.transport_locate (_transport_frame);
426 #ifndef LEAVE_TRANSPORT_UNADJUSTED
430 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
431 if (!(*i)->hidden()) {
432 (*i)->non_realtime_locate (_transport_frame);
434 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
436 /* we will be back */
441 #ifdef LEAVE_TRANSPORT_UNADJUSTED
447 send_full_time_code (0);
448 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
449 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
453 /* XXX its a little odd that we're doing this here
454 when realtime_stop(), which has already executed,
456 JLC - so let's not because it seems unnecessary and breaks loop record
459 if (!Config->get_latched_record_enable()) {
460 g_atomic_int_set (&_record_status, Disabled);
462 g_atomic_int_set (&_record_status, Enabled);
464 RecordStateChanged (); /* emit signal */
468 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
469 /* capture start has been changed, so save pending state */
470 save_state ("", true);
474 /* always try to get rid of this */
476 remove_pending_capture_state ();
478 /* save the current state of things if appropriate */
480 if (did_record && !saved) {
481 save_state (_current_snapshot_name);
484 if (post_transport_work & PostTransportDuration) {
485 DurationChanged (); /* EMIT SIGNAL */
488 if (post_transport_work & PostTransportStop) {
491 /* do not turn off autoloop on stop */
495 nframes_t tf = _transport_frame;
497 PositionChanged (tf); /* EMIT SIGNAL */
498 TransportStateChange (); /* EMIT SIGNAL */
500 /* and start it up again if relevant */
502 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
503 request_transport_speed (1.0);
504 pending_locate_roll = false;
509 Session::check_declick_out ()
511 bool locate_required = transport_sub_state & PendingLocate;
513 /* this is called after a process() iteration. if PendingDeclickOut was set,
514 it means that we were waiting to declick the output (which has just been
515 done) before doing something else. this is where we do that "something else".
517 note: called from the audio thread.
520 if (transport_sub_state & PendingDeclickOut) {
522 if (locate_required) {
523 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
524 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
526 stop_transport (pending_abort);
527 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
533 Session::set_play_loop (bool yn)
535 /* Called from event-handling context */
537 if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
543 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
544 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
545 "Recommend changing the configured options")
551 if ((play_loop = yn)) {
556 if ((loc = _locations.auto_loop_location()) != 0) {
558 if (Config->get_seamless_loop()) {
559 // set all diskstreams to use internal looping
560 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
561 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
562 if (!(*i)->hidden()) {
563 (*i)->set_loop (loc);
568 // set all diskstreams to NOT use internal looping
569 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
570 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
571 if (!(*i)->hidden()) {
577 /* stick in the loop event */
579 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
582 /* locate to start of loop and roll if current pos is outside of the loop range */
583 if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
584 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
588 // locate to current position (+ 1 to force reload)
589 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
597 clear_events (Event::AutoLoop);
599 // set all diskstreams to NOT use internal looping
600 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
601 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
602 if (!(*i)->hidden()) {
611 Session::flush_all_inserts ()
613 boost::shared_ptr<RouteList> r = routes.reader ();
615 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
616 (*i)->flush_processors ();
621 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
623 if (synced_to_jack()) {
628 _slave->speed_and_position (sp, pos);
630 if (target_frame != pos) {
632 /* tell JACK to change transport position, and we will
633 follow along later in ::follow_slave()
636 _engine.transport_locate (target_frame);
638 if (sp != 1.0f && with_roll) {
639 _engine.transport_start ();
645 locate (target_frame, with_roll, with_flush, with_loop);
650 Session::micro_locate (nframes_t distance)
652 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
654 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
655 if (!(*i)->can_internal_playback_seek (distance)) {
660 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
661 (*i)->internal_playback_seek (distance);
664 _transport_frame += distance;
669 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
671 if (actively_recording() && !with_loop) {
675 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
677 set_transport_speed (1.0, false);
679 loop_changing = false;
684 // [DR] FIXME: find out exactly where this should go below
685 _transport_frame = target_frame;
686 smpte_time(_transport_frame, transmitting_smpte_time);
687 outbound_mtc_smpte_frame = _transport_frame;
688 next_quarter_frame_to_send = 0;
690 if (_transport_speed && (!with_loop || loop_changing)) {
691 /* schedule a declick. we'll be called again when its done */
693 if (!(transport_sub_state & PendingDeclickOut)) {
694 transport_sub_state |= (PendingDeclickOut|PendingLocate);
695 pending_locate_frame = target_frame;
696 pending_locate_roll = with_roll;
697 pending_locate_flush = with_flush;
702 if (transport_rolling() && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
703 realtime_stop (false);
706 if ( !with_loop || loop_changing) {
708 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
711 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
714 schedule_butler_transport_work ();
718 /* this is functionally what clear_clicks() does but with a tentative lock */
720 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
722 if (clickm.locked()) {
724 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
733 /* switch from input if we're going to roll */
734 if (Config->get_monitoring_model() == HardwareMonitoring) {
736 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
738 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
739 if ((*i)->record_enabled ()) {
740 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
741 (*i)->monitor_input (!config.get_auto_input());
746 /* otherwise we're going to stop, so do the opposite */
747 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 to input" << __FILE__ << __LINE__ << endl << endl;
753 (*i)->monitor_input (true);
759 /* cancel looped playback if transport pos outside of loop range */
761 Location* al = _locations.auto_loop_location();
763 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
764 // cancel looping directly, this is called from event handling context
765 set_play_loop (false);
767 else if (al && _transport_frame == al->start()) {
769 // this is only necessary for seamless looping
771 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
773 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
774 if ((*i)->record_enabled ()) {
775 // tell it we've looped, so it can deal with the record state
776 (*i)->transport_looped(_transport_frame);
781 TransportLooped(); // EMIT SIGNAL
785 loop_changing = false;
787 _send_smpte_update = true;
789 Located (); /* EMIT SIGNAL */
792 /** Set the transport speed.
793 * @param speed New speed
797 Session::set_transport_speed (double speed, bool abort)
799 if (_transport_speed == speed) {
803 _target_transport_speed = fabs(speed);
805 /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
806 and user needs. We really need CD-style "skip" playback for ffwd and rewind.
810 speed = min (8.0, speed);
811 } else if (speed < 0) {
812 speed = max (-8.0, speed);
815 if (transport_rolling() && speed == 0.0) {
817 /* we are rolling and we want to stop */
819 if (Config->get_monitoring_model() == HardwareMonitoring)
821 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
823 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
824 if ((*i)->record_enabled ()) {
825 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
826 (*i)->monitor_input (true);
831 if (synced_to_jack ()) {
832 _engine.transport_stop ();
834 stop_transport (abort);
837 } else if (transport_stopped() && speed == 1.0) {
839 /* we are stopped and we want to start rolling at speed 1 */
841 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
845 if (Config->get_monitoring_model() == HardwareMonitoring) {
847 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
849 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
850 if (config.get_auto_input() && (*i)->record_enabled ()) {
851 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
852 (*i)->monitor_input (false);
857 if (synced_to_jack()) {
858 _engine.transport_start ();
865 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
869 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
870 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
875 if (actively_recording()) {
879 if (speed > 0.0 && _transport_frame == current_end_frame()) {
883 if (speed < 0.0 && _transport_frame == 0) {
889 /* if we are reversing relative to the current speed, or relative to the speed
890 before the last stop, then we have to do extra work.
893 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
894 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
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;
985 _transport_speed = 1.0;
986 _target_transport_speed = 1.0;
988 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
989 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
990 (*i)->realtime_set_speed ((*i)->speed(), true);
993 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
995 TransportStateChange (); /* EMIT SIGNAL */
998 /** Do any transport work in the audio thread that needs to be done after the
999 * transport thread is finished. Audio thread, realtime safe.
1002 Session::post_transport ()
1004 if (post_transport_work & PostTransportAudition) {
1005 if (auditioner && auditioner->active()) {
1006 process_function = &Session::process_audition;
1008 process_function = &Session::process_with_events;
1012 if (post_transport_work & PostTransportStop) {
1014 transport_sub_state = 0;
1017 if (post_transport_work & PostTransportLocate) {
1019 if (((Config->get_slave_source() == None && (auto_play_legal && config.get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
1023 transport_sub_state = 0;
1029 post_transport_work = PostTransportWork (0);
1033 Session::reset_rf_scale (nframes_t motion)
1035 cumulative_rf_motion += motion;
1037 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1039 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1041 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1053 Session::set_slave_source (SlaveSource src)
1055 bool reverse = false;
1056 bool non_rt_required = false;
1058 if (_transport_speed) {
1059 error << _("please stop the transport before adjusting slave settings") << endmsg;
1063 // if (src == JACK && Config->get_jack_time_master()) {
1070 if (_transport_speed < 0.0) {
1082 _slave = new MTC_Slave (*this, *_mtc_port);
1085 catch (failed_constructor& err) {
1090 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1096 if (_midi_clock_port) {
1098 _slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24);
1101 catch (failed_constructor& err) {
1106 error << _("No MIDI Clock port defined: MIDI Clock slaving is impossible.") << endmsg;
1112 _slave = new JACK_Slave (_engine.jack());
1117 Config->set_slave_source (src);
1119 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1120 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1121 if (!(*i)->hidden()) {
1122 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1123 non_rt_required = true;
1125 (*i)->set_slaved (_slave);
1130 reverse_diskstream_buffers ();
1133 if (non_rt_required) {
1134 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1135 schedule_butler_transport_work ();
1142 Session::reverse_diskstream_buffers ()
1144 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1145 schedule_butler_transport_work ();
1149 Session::set_diskstream_speed (Diskstream* stream, double speed)
1151 if (stream->realtime_set_speed (speed, false)) {
1152 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1153 schedule_butler_transport_work ();
1159 Session::set_audio_range (list<AudioRange>& range)
1161 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1162 ev->audio_range = range;
1167 Session::request_play_range (bool yn)
1169 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1174 Session::set_play_range (bool yn)
1176 /* Called from event-processing context */
1178 if (_play_range != yn) {
1183 /* stop transport */
1184 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1191 Session::setup_auto_play ()
1193 /* Called from event-processing context */
1197 _clear_event_type (Event::RangeStop);
1198 _clear_event_type (Event::RangeLocate);
1204 list<AudioRange>::size_type sz = current_audio_range.size();
1208 list<AudioRange>::iterator i = current_audio_range.begin();
1209 list<AudioRange>::iterator next;
1211 while (i != current_audio_range.end()) {
1216 /* locating/stopping is subject to delays for declicking.
1219 nframes_t requested_frame = (*i).end;
1221 if (requested_frame > current_block_size) {
1222 requested_frame -= current_block_size;
1224 requested_frame = 0;
1227 if (next == current_audio_range.end()) {
1228 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1230 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1238 } else if (sz == 1) {
1240 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1245 /* now start rolling at the right place */
1247 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1252 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1254 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1255 ev->target2_frame = start;
1260 Session::request_bounded_roll (nframes_t start, nframes_t end)
1263 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1265 request_locate (start, true);
1269 Session::engine_halted ()
1273 /* there will be no more calls to process(), so
1274 we'd better clean up for ourselves, right now.
1276 but first, make sure the butler is out of
1280 g_atomic_int_set (&butler_should_do_transport_work, 0);
1281 post_transport_work = PostTransportWork (0);
1284 realtime_stop (false);
1285 non_realtime_stop (false, 0, ignored);
1286 transport_sub_state = 0;
1288 TransportStateChange (); /* EMIT SIGNAL */
1293 Session::xrun_recovery ()
1295 Xrun (transport_frame()); //EMIT SIGNAL
1297 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1299 /* it didn't actually halt, but we need
1300 to handle things in the same way.
1308 Session::update_latency_compensation (bool with_stop, bool abort)
1310 bool update_jack = false;
1312 if (_state_of_the_state & Deletion) {
1316 _worst_track_latency = 0;
1318 #undef DEBUG_LATENCY
1319 #ifdef DEBUG_LATENCY
1320 cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1323 boost::shared_ptr<RouteList> r = routes.reader ();
1325 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1328 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1329 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1332 nframes_t old_latency = (*i)->output()->signal_latency ();
1333 nframes_t track_latency = (*i)->update_total_latency ();
1335 if (old_latency != track_latency) {
1336 (*i)->input()->update_port_total_latencies ();
1337 (*i)->output()->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);