2 Copyright (C) 1999-2003 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include <sigc++/bind.h>
25 #include <sigc++/retype.h>
28 #include <pbd/error.h>
29 #include <glibmm/thread.h>
30 #include <pbd/pthread_utils.h>
31 #include <pbd/memento_command.h>
32 #include <pbd/stacktrace.h>
34 #include <midi++/mmc.h>
35 #include <midi++/port.h>
37 #include <ardour/ardour.h>
38 #include <ardour/audioengine.h>
39 #include <ardour/session.h>
40 #include <ardour/audio_diskstream.h>
41 #include <ardour/auditioner.h>
42 #include <ardour/slave.h>
43 #include <ardour/location.h>
48 using namespace ARDOUR;
53 Session::request_input_change_handling ()
55 if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
56 Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0);
62 Session::request_slave_source (SlaveSource src)
64 Event* ev = new Event (Event::SetSlaveSource, Event::Add, Event::Immediate, 0, 0.0);
67 /* could set_seamless_loop() be disposed of entirely?*/
68 Config->set_seamless_loop (false);
70 Config->set_seamless_loop (true);
77 Session::request_transport_speed (float speed)
79 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, speed);
84 Session::request_diskstream_speed (Diskstream& ds, float speed)
86 Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed);
92 Session::request_stop (bool abort)
94 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0, abort);
99 Session::request_locate (nframes_t target_frame, bool with_roll)
101 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, false);
106 Session::force_locate (nframes_t target_frame, bool with_roll)
108 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, true);
113 Session::request_play_loop (bool yn)
116 Location *location = _locations.auto_loop_location();
118 if (location == 0 && yn) {
119 error << _("Cannot loop - no loop range defined")
124 ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, 0.0, yn);
127 if (!yn && Config->get_seamless_loop() && transport_rolling()) {
128 // request an immediate locate to refresh the diskstreams
129 // after disabling looping
130 request_locate (_transport_frame-1, false);
135 Session::realtime_stop (bool abort)
137 /* assume that when we start, we'll be moving forwards */
139 // FIXME: where should this really be? [DR]
140 //send_full_time_code();
141 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
142 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
144 if (_transport_speed < 0.0f) {
145 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop | PostTransportReverse);
147 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop);
150 if (actively_recording()) {
152 /* move the transport position back to where the
153 request for a stop was noticed. we rolled
154 past that point to pick up delayed input.
157 #ifndef LEAVE_TRANSPORT_UNADJUSTED
158 decrement_transport_position (_worst_output_latency);
161 /* the duration change is not guaranteed to have happened, but is likely */
163 post_transport_work = PostTransportWork (post_transport_work | PostTransportDuration);
167 post_transport_work = PostTransportWork (post_transport_work | PostTransportAbort);
170 _clear_event_type (Event::StopOnce);
171 _clear_event_type (Event::RangeStop);
172 _clear_event_type (Event::RangeLocate);
174 disable_record (true);
176 reset_slave_state ();
178 _transport_speed = 0;
180 if (Config->get_use_video_sync()) {
181 waiting_for_sync_offset = true;
184 transport_sub_state = ((Config->get_slave_source() == None && Config->get_auto_return()) ? AutoReturning : 0);
188 Session::butler_transport_work ()
192 boost::shared_ptr<RouteList> r = routes.reader ();
193 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
195 int on_entry = g_atomic_int_get (&butler_should_do_transport_work);
198 if (post_transport_work & PostTransportCurveRealloc) {
199 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
200 (*i)->curve_reallocate();
204 if (post_transport_work & PostTransportInputChange) {
205 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
206 (*i)->non_realtime_input_change ();
210 if (post_transport_work & PostTransportSpeed) {
211 non_realtime_set_speed ();
214 if (post_transport_work & PostTransportReverse) {
218 cumulative_rf_motion = 0;
221 /* don't seek if locate will take care of that in non_realtime_stop() */
223 if (!(post_transport_work & PostTransportLocate)) {
225 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
226 if (!(*i)->hidden()) {
227 (*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 (_end_location_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 _end_location_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 if ((Config->get_slave_source() == None && Config->get_auto_return()) ||
392 (post_transport_work & PostTransportLocate) ||
393 (_requested_return_frame >= 0) ||
396 if (pending_locate_flush) {
397 flush_all_inserts ();
400 if (((Config->get_slave_source() == None && Config->get_auto_return()) ||
402 _requested_return_frame >= 0) &&
403 !(post_transport_work & PostTransportLocate)) {
405 bool do_locate = false;
407 if (_requested_return_frame >= 0) {
408 _transport_frame = _requested_return_frame;
409 _requested_return_frame = -1;
412 _transport_frame = last_stop_frame;
413 _requested_return_frame = -1;
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
445 if (_requested_return_frame < 0) {
446 last_stop_frame = _transport_frame;
448 last_stop_frame = _requested_return_frame;
449 _requested_return_frame = -1;
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 ();
647 locate (target_frame, with_roll, with_flush, with_loop);
652 Session::micro_locate (nframes_t distance)
654 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
656 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
657 if (!(*i)->can_internal_playback_seek (distance)) {
662 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
663 (*i)->internal_playback_seek (distance);
666 _transport_frame += distance;
671 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
673 if (actively_recording() && !with_loop) {
677 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
679 set_transport_speed (1.0, false);
681 loop_changing = false;
686 // [DR] FIXME: find out exactly where this should go below
687 _transport_frame = target_frame;
688 smpte_time(_transport_frame, transmitting_smpte_time);
689 outbound_mtc_smpte_frame = _transport_frame;
690 next_quarter_frame_to_send = 0;
692 if (_transport_speed && (!with_loop || loop_changing)) {
693 /* schedule a declick. we'll be called again when its done */
695 if (!(transport_sub_state & PendingDeclickOut)) {
696 transport_sub_state |= (PendingDeclickOut|PendingLocate);
697 pending_locate_frame = target_frame;
698 pending_locate_roll = with_roll;
699 pending_locate_flush = with_flush;
704 if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
705 realtime_stop (false);
708 if ( !with_loop || loop_changing) {
710 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
713 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
716 schedule_butler_transport_work ();
720 /* this is functionally what clear_clicks() does but with a tentative lock */
722 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
724 if (clickm.locked()) {
726 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
735 /* switch from input if we're going to roll */
736 if (Config->get_monitoring_model() == HardwareMonitoring) {
738 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
740 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
741 if ((*i)->record_enabled ()) {
742 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
743 (*i)->monitor_input (!Config->get_auto_input());
748 /* otherwise we're going to stop, so do the opposite */
749 if (Config->get_monitoring_model() == HardwareMonitoring) {
750 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
752 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
753 if ((*i)->record_enabled ()) {
754 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
755 (*i)->monitor_input (true);
761 /* cancel looped playback if transport pos outside of loop range */
763 Location* al = _locations.auto_loop_location();
765 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
766 // cancel looping directly, this is called from event handling context
767 set_play_loop (false);
769 else if (al && _transport_frame == al->start()) {
771 // this is only necessary for seamless looping
773 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
775 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
776 if ((*i)->record_enabled ()) {
777 // tell it we've looped, so it can deal with the record state
778 (*i)->transport_looped(_transport_frame);
783 TransportLooped(); // EMIT SIGNAL
787 loop_changing = false;
789 _send_smpte_update = true;
792 /** Set the transport speed.
793 * @param speed New speed
797 Session::set_transport_speed (float speed, bool abort)
799 if (_transport_speed == speed) {
804 speed = min (8.0f, speed);
805 } else if (speed < 0) {
806 speed = max (-8.0f, speed);
809 if (transport_rolling() && speed == 0.0) {
811 /* we are rolling and we want to stop */
813 if (Config->get_monitoring_model() == HardwareMonitoring)
815 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
817 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
818 if ((*i)->record_enabled ()) {
819 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
820 (*i)->monitor_input (true);
825 if (synced_to_jack ()) {
826 _engine.transport_stop ();
828 stop_transport (abort);
831 } else if (transport_stopped() && speed == 1.0) {
833 /* we are stopped and we want to start rolling at speed 1 */
835 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
839 if (Config->get_monitoring_model() == HardwareMonitoring) {
841 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
843 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
844 if (Config->get_auto_input() && (*i)->record_enabled ()) {
845 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
846 (*i)->monitor_input (false);
851 if (synced_to_jack()) {
852 _engine.transport_start ();
859 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
863 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
864 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
869 if (actively_recording()) {
873 if (speed > 0.0f && _transport_frame == current_end_frame()) {
877 if (speed < 0.0f && _transport_frame == 0) {
883 /* if we are reversing relative to the current speed, or relative to the speed
884 before the last stop, then we have to do extra work.
887 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
888 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
891 _last_transport_speed = _transport_speed;
892 _transport_speed = speed;
894 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
895 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
896 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
897 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
901 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
902 schedule_butler_transport_work ();
908 /** Stop the transport. */
910 Session::stop_transport (bool abort)
912 if (_transport_speed == 0.0f) {
916 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
917 _worst_output_latency > current_block_size)
920 /* we need to capture the audio that has still not yet been received by the system
921 at the time the stop is requested, so we have to roll past that time.
923 we want to declick before stopping, so schedule the autostop for one
924 block before the actual end. we'll declick in the subsequent block,
925 and then we'll really be stopped.
928 Event *ev = new Event (Event::StopOnce, Event::Replace,
929 _transport_frame + _worst_output_latency - current_block_size,
933 transport_sub_state |= StopPendingCapture;
934 pending_abort = abort;
939 if ((transport_sub_state & PendingDeclickOut) == 0) {
940 transport_sub_state |= PendingDeclickOut;
941 /* we'll be called again after the declick */
942 pending_abort = abort;
946 realtime_stop (abort);
947 schedule_butler_transport_work ();
951 Session::start_transport ()
953 _last_roll_location = _transport_frame;
955 /* if record status is Enabled, move it to Recording. if its
956 already Recording, move it to Disabled.
959 switch (record_status()) {
961 if (!Config->get_punch_in()) {
968 disable_record (false);
976 transport_sub_state |= PendingDeclickIn;
977 _transport_speed = 1.0;
979 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
980 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
981 (*i)->realtime_set_speed ((*i)->speed(), true);
984 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
986 TransportStateChange (); /* EMIT SIGNAL */
989 /** Do any transport work in the audio thread that needs to be done after the
990 * transport thread is finished. Audio thread, realtime safe.
993 Session::post_transport ()
995 if (post_transport_work & PostTransportAudition) {
996 if (auditioner && auditioner->active()) {
997 process_function = &Session::process_audition;
999 process_function = &Session::process_with_events;
1003 if (post_transport_work & PostTransportStop) {
1005 transport_sub_state = 0;
1008 if (post_transport_work & PostTransportLocate) {
1010 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
1014 transport_sub_state = 0;
1020 post_transport_work = PostTransportWork (0);
1024 Session::reset_rf_scale (nframes_t motion)
1026 cumulative_rf_motion += motion;
1028 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1030 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1032 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1044 Session::set_slave_source (SlaveSource src)
1046 bool reverse = false;
1047 bool non_rt_required = false;
1049 if (_transport_speed) {
1050 error << _("please stop the transport before adjusting slave settings") << endmsg;
1054 // if (src == JACK && Config->get_jack_time_master()) {
1063 if (_transport_speed < 0.0) {
1075 _slave = new MTC_Slave (*this, *_mtc_port);
1078 catch (failed_constructor& err) {
1083 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1086 _desired_transport_speed = _transport_speed;
1090 if (_midi_clock_port) {
1092 _slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24);
1095 catch (failed_constructor& err) {
1100 error << _("No MIDI Clock port defined: MIDI Clock slaving is impossible.") << endmsg;
1103 _desired_transport_speed = _transport_speed;
1107 _slave = new JACK_Slave (_engine.jack());
1108 _desired_transport_speed = _transport_speed;
1113 Config->set_slave_source (src);
1115 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1116 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1117 if (!(*i)->hidden()) {
1118 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1119 non_rt_required = true;
1121 (*i)->set_slaved (_slave);
1126 reverse_diskstream_buffers ();
1129 if (non_rt_required) {
1130 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1131 schedule_butler_transport_work ();
1138 Session::reverse_diskstream_buffers ()
1140 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1141 schedule_butler_transport_work ();
1145 Session::set_diskstream_speed (Diskstream* stream, float speed)
1147 if (stream->realtime_set_speed (speed, false)) {
1148 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1149 schedule_butler_transport_work ();
1155 Session::set_audio_range (list<AudioRange>& range)
1157 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1158 ev->audio_range = range;
1163 Session::request_play_range (bool yn)
1165 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1170 Session::set_play_range (bool yn)
1172 /* Called from event-processing context */
1174 if (_play_range != yn) {
1179 /* stop transport */
1180 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1187 Session::setup_auto_play ()
1189 /* Called from event-processing context */
1193 _clear_event_type (Event::RangeStop);
1194 _clear_event_type (Event::RangeLocate);
1200 list<AudioRange>::size_type sz = current_audio_range.size();
1204 list<AudioRange>::iterator i = current_audio_range.begin();
1205 list<AudioRange>::iterator next;
1207 while (i != current_audio_range.end()) {
1212 /* locating/stopping is subject to delays for declicking.
1215 nframes_t requested_frame = (*i).end;
1217 if (requested_frame > current_block_size) {
1218 requested_frame -= current_block_size;
1220 requested_frame = 0;
1223 if (next == current_audio_range.end()) {
1224 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1226 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1234 } else if (sz == 1) {
1236 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1241 /* now start rolling at the right place */
1243 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1248 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1250 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1251 ev->target2_frame = start;
1256 Session::request_bounded_roll (nframes_t start, nframes_t end)
1259 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1261 request_locate (start, true);
1265 Session::engine_halted ()
1269 /* there will be no more calls to process(), so
1270 we'd better clean up for ourselves, right now.
1272 but first, make sure the butler is out of
1276 g_atomic_int_set (&butler_should_do_transport_work, 0);
1277 post_transport_work = PostTransportWork (0);
1280 realtime_stop (false);
1281 non_realtime_stop (false, 0, ignored);
1282 transport_sub_state = 0;
1284 TransportStateChange (); /* EMIT SIGNAL */
1289 Session::xrun_recovery ()
1291 Xrun (transport_frame()); //EMIT SIGNAL
1293 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1295 /* it didn't actually halt, but we need
1296 to handle things in the same way.
1304 Session::update_latency_compensation (bool with_stop, bool abort)
1306 bool update_jack = false;
1308 if (_state_of_the_state & Deletion) {
1312 _worst_track_latency = 0;
1314 #undef DEBUG_LATENCY
1315 #ifdef DEBUG_LATENCY
1316 cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1319 boost::shared_ptr<RouteList> r = routes.reader ();
1321 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1324 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1325 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1328 nframes_t old_latency = (*i)->signal_latency ();
1329 nframes_t track_latency = (*i)->update_total_latency ();
1331 if (old_latency != track_latency) {
1332 (*i)->update_port_total_latencies ();
1336 if (!(*i)->is_hidden() && ((*i)->active())) {
1337 _worst_track_latency = max (_worst_track_latency, track_latency);
1342 _engine.update_total_latencies ();
1345 #ifdef DEBUG_LATENCY
1346 cerr << "\tworst was " << _worst_track_latency << endl;
1349 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1350 (*i)->set_latency_delay (_worst_track_latency);
1353 set_worst_io_latencies ();
1355 /* reflect any changes in latencies into capture offsets
1358 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1360 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1361 (*i)->set_capture_offset ();
1366 Session::allow_auto_play (bool yn)
1368 auto_play_legal = yn;
1372 Session::reset_jack_connection (jack_client_t* jack)
1376 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1377 js->reset_client (jack);