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 (_end_location_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 _end_location_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));
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_phi = 0x1000000; // speed = 1
990 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
991 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
992 (*i)->realtime_set_speed ((*i)->speed(), true);
995 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
997 TransportStateChange (); /* EMIT SIGNAL */
1000 /** Do any transport work in the audio thread that needs to be done after the
1001 * transport thread is finished. Audio thread, realtime safe.
1004 Session::post_transport ()
1006 if (post_transport_work & PostTransportAudition) {
1007 if (auditioner && auditioner->active()) {
1008 process_function = &Session::process_audition;
1010 process_function = &Session::process_with_events;
1014 if (post_transport_work & PostTransportStop) {
1016 transport_sub_state = 0;
1019 if (post_transport_work & PostTransportLocate) {
1021 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
1025 transport_sub_state = 0;
1031 post_transport_work = PostTransportWork (0);
1035 Session::reset_rf_scale (nframes_t motion)
1037 cumulative_rf_motion += motion;
1039 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1041 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1043 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1055 Session::set_slave_source (SlaveSource src)
1057 bool reverse = false;
1058 bool non_rt_required = false;
1060 if (_transport_speed) {
1061 error << _("please stop the transport before adjusting slave settings") << endmsg;
1065 // if (src == JACK && Config->get_jack_time_master()) {
1072 if (_transport_speed < 0.0) {
1084 _slave = new MTC_Slave (*this, *_mtc_port);
1087 catch (failed_constructor& err) {
1092 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1098 if (_midi_clock_port) {
1100 _slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24);
1103 catch (failed_constructor& err) {
1108 error << _("No MIDI Clock port defined: MIDI Clock slaving is impossible.") << endmsg;
1114 _slave = new JACK_Slave (_engine.jack());
1119 Config->set_slave_source (src);
1121 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1122 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1123 if (!(*i)->hidden()) {
1124 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1125 non_rt_required = true;
1127 (*i)->set_slaved (_slave);
1132 reverse_diskstream_buffers ();
1135 if (non_rt_required) {
1136 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1137 schedule_butler_transport_work ();
1144 Session::reverse_diskstream_buffers ()
1146 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1147 schedule_butler_transport_work ();
1151 Session::set_diskstream_speed (Diskstream* stream, double speed)
1153 if (stream->realtime_set_speed (speed, false)) {
1154 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1155 schedule_butler_transport_work ();
1161 Session::set_audio_range (list<AudioRange>& range)
1163 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1164 ev->audio_range = range;
1169 Session::request_play_range (bool yn)
1171 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1176 Session::set_play_range (bool yn)
1178 /* Called from event-processing context */
1180 if (_play_range != yn) {
1185 /* stop transport */
1186 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1193 Session::setup_auto_play ()
1195 /* Called from event-processing context */
1199 _clear_event_type (Event::RangeStop);
1200 _clear_event_type (Event::RangeLocate);
1206 list<AudioRange>::size_type sz = current_audio_range.size();
1210 list<AudioRange>::iterator i = current_audio_range.begin();
1211 list<AudioRange>::iterator next;
1213 while (i != current_audio_range.end()) {
1218 /* locating/stopping is subject to delays for declicking.
1221 nframes_t requested_frame = (*i).end;
1223 if (requested_frame > current_block_size) {
1224 requested_frame -= current_block_size;
1226 requested_frame = 0;
1229 if (next == current_audio_range.end()) {
1230 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1232 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1240 } else if (sz == 1) {
1242 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1247 /* now start rolling at the right place */
1249 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1254 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1256 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1257 ev->target2_frame = start;
1262 Session::request_bounded_roll (nframes_t start, nframes_t end)
1265 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1267 request_locate (start, true);
1271 Session::engine_halted ()
1275 /* there will be no more calls to process(), so
1276 we'd better clean up for ourselves, right now.
1278 but first, make sure the butler is out of
1282 g_atomic_int_set (&butler_should_do_transport_work, 0);
1283 post_transport_work = PostTransportWork (0);
1286 realtime_stop (false);
1287 non_realtime_stop (false, 0, ignored);
1288 transport_sub_state = 0;
1290 TransportStateChange (); /* EMIT SIGNAL */
1295 Session::xrun_recovery ()
1297 Xrun (transport_frame()); //EMIT SIGNAL
1299 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1301 /* it didn't actually halt, but we need
1302 to handle things in the same way.
1310 Session::update_latency_compensation (bool with_stop, bool abort)
1312 bool update_jack = false;
1314 if (_state_of_the_state & Deletion) {
1318 _worst_track_latency = 0;
1320 #undef DEBUG_LATENCY
1321 #ifdef DEBUG_LATENCY
1322 cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1325 boost::shared_ptr<RouteList> r = routes.reader ();
1327 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1330 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1331 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1334 nframes_t old_latency = (*i)->signal_latency ();
1335 nframes_t track_latency = (*i)->update_total_latency ();
1337 if (old_latency != track_latency) {
1338 (*i)->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);