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 decrement_transport_position (_worst_output_latency);
160 /* the duration change is not guaranteed to have happened, but is likely */
162 post_transport_work = PostTransportWork (post_transport_work | PostTransportDuration);
166 post_transport_work = PostTransportWork (post_transport_work | PostTransportAbort);
169 _clear_event_type (Event::StopOnce);
170 _clear_event_type (Event::RangeStop);
171 _clear_event_type (Event::RangeLocate);
173 disable_record (true);
175 reset_slave_state ();
177 _transport_speed = 0;
178 _target_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) {
217 cumulative_rf_motion = 0;
220 /* don't seek if locate will take care of that in non_realtime_stop() */
222 if (!(post_transport_work & PostTransportLocate)) {
224 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
225 if (!(*i)->hidden()) {
226 (*i)->non_realtime_locate (_transport_frame);
228 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
229 /* new request, stop seeking, and start again */
230 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
237 if (post_transport_work & PostTransportLocate) {
238 non_realtime_locate ();
241 if (post_transport_work & PostTransportStop) {
242 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
244 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
249 if (post_transport_work & PostTransportOverWrite) {
250 non_realtime_overwrite (on_entry, finished);
252 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
257 if (post_transport_work & PostTransportAudition) {
258 non_realtime_set_audition ();
261 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
265 Session::non_realtime_set_speed ()
267 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
269 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
270 (*i)->non_realtime_set_speed ();
275 Session::non_realtime_overwrite (int on_entry, bool& finished)
277 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
279 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
280 if ((*i)->pending_overwrite) {
281 (*i)->overwrite_existing_buffers ();
283 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
292 Session::non_realtime_locate ()
294 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
296 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
297 (*i)->non_realtime_locate (_transport_frame);
303 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
313 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
315 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
316 if ((*i)->get_captured_frames () != 0) {
322 /* stop and locate are merged here because they share a lot of common stuff */
325 now = localtime (&xnow);
328 auditioner->cancel_audition ();
332 cumulative_rf_motion = 0;
336 begin_reversible_command ("capture");
338 Location* loc = _locations.end_location();
339 bool change_end = false;
341 if (_transport_frame < loc->end()) {
343 /* stopped recording before current end */
345 if (config.get_end_marker_is_free()) {
347 /* first capture for this session, move end back to where we are */
352 } else if (_transport_frame > loc->end()) {
354 /* stopped recording after the current end, extend it */
360 XMLNode &before = loc->get_state();
361 loc->set_end(_transport_frame);
362 XMLNode &after = loc->get_state();
363 add_command (new MementoCommand<Location>(*loc, &before, &after));
366 config.set_end_marker_is_free (false);
367 _have_captured = true;
370 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
371 (*i)->transport_stopped (*now, xnow, abort);
374 boost::shared_ptr<RouteList> r = routes.reader ();
376 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
377 if (!(*i)->is_hidden()) {
378 (*i)->set_pending_declick (0);
383 commit_reversible_command ();
386 if (_engine.running()) {
387 update_latency_compensation (true, abort);
390 bool const auto_return_enabled =
391 (Config->get_slave_source() == None && config.get_auto_return());
393 if (auto_return_enabled ||
394 (post_transport_work & PostTransportLocate) ||
395 (_requested_return_frame >= 0) ||
398 if (pending_locate_flush) {
399 flush_all_inserts ();
402 if ((auto_return_enabled || synced_to_jack() || _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_roll_location;
415 if (synced_to_jack() && !play_loop) {
420 // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl;
421 _engine.transport_locate (_transport_frame);
427 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
428 if (!(*i)->hidden()) {
429 (*i)->non_realtime_locate (_transport_frame);
431 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
433 /* we will be back */
440 send_full_time_code (0);
441 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
442 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
446 /* XXX its a little odd that we're doing this here
447 when realtime_stop(), which has already executed,
449 JLC - so let's not because it seems unnecessary and breaks loop record
452 if (!Config->get_latched_record_enable()) {
453 g_atomic_int_set (&_record_status, Disabled);
455 g_atomic_int_set (&_record_status, Enabled);
457 RecordStateChanged (); /* emit signal */
461 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
462 /* capture start has been changed, so save pending state */
463 save_state ("", true);
467 /* always try to get rid of this */
469 remove_pending_capture_state ();
471 /* save the current state of things if appropriate */
473 if (did_record && !saved) {
474 save_state (_current_snapshot_name);
477 if (post_transport_work & PostTransportDuration) {
478 DurationChanged (); /* EMIT SIGNAL */
481 if (post_transport_work & PostTransportStop) {
484 /* do not turn off autoloop on stop */
488 nframes_t tf = _transport_frame;
490 PositionChanged (tf); /* EMIT SIGNAL */
491 TransportStateChange (); /* EMIT SIGNAL */
493 /* and start it up again if relevant */
495 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
496 request_transport_speed (1.0);
497 pending_locate_roll = false;
502 Session::check_declick_out ()
504 bool locate_required = transport_sub_state & PendingLocate;
506 /* this is called after a process() iteration. if PendingDeclickOut was set,
507 it means that we were waiting to declick the output (which has just been
508 done) before doing something else. this is where we do that "something else".
510 note: called from the audio thread.
513 if (transport_sub_state & PendingDeclickOut) {
515 if (locate_required) {
516 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
517 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
519 stop_transport (pending_abort);
520 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
526 Session::set_play_loop (bool yn)
528 /* Called from event-handling context */
530 if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
536 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
537 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
538 "Recommend changing the configured options")
544 if ((play_loop = yn)) {
549 if ((loc = _locations.auto_loop_location()) != 0) {
551 if (Config->get_seamless_loop()) {
552 // set all diskstreams to use internal looping
553 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
554 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
555 if (!(*i)->hidden()) {
556 (*i)->set_loop (loc);
561 // set all diskstreams to NOT 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()) {
570 /* stick in the loop event */
572 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
575 /* locate to start of loop and roll if current pos is outside of the loop range */
576 if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
577 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
581 // locate to current position (+ 1 to force reload)
582 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
590 clear_events (Event::AutoLoop);
592 // set all diskstreams to NOT use internal looping
593 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
594 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
595 if (!(*i)->hidden()) {
604 Session::flush_all_inserts ()
606 boost::shared_ptr<RouteList> r = routes.reader ();
608 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
609 (*i)->flush_processors ();
614 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
616 if (synced_to_jack()) {
621 _slave->speed_and_position (sp, pos);
623 if (target_frame != pos) {
625 /* tell JACK to change transport position, and we will
626 follow along later in ::follow_slave()
629 _engine.transport_locate (target_frame);
631 if (sp != 1.0f && with_roll) {
632 _engine.transport_start ();
638 locate (target_frame, with_roll, with_flush, with_loop);
643 Session::micro_locate (nframes_t distance)
645 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
647 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
648 if (!(*i)->can_internal_playback_seek (distance)) {
653 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
654 (*i)->internal_playback_seek (distance);
657 _transport_frame += distance;
662 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
664 if (actively_recording() && !with_loop) {
668 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
670 set_transport_speed (1.0, false);
672 loop_changing = false;
676 // Update Timecode time
677 // [DR] FIXME: find out exactly where this should go below
678 _transport_frame = target_frame;
679 timecode_time(_transport_frame, transmitting_timecode_time);
680 outbound_mtc_timecode_frame = _transport_frame;
681 next_quarter_frame_to_send = 0;
683 if (_transport_speed && (!with_loop || loop_changing)) {
684 /* schedule a declick. we'll be called again when its done */
686 if (!(transport_sub_state & PendingDeclickOut)) {
687 transport_sub_state |= (PendingDeclickOut|PendingLocate);
688 pending_locate_frame = target_frame;
689 pending_locate_roll = with_roll;
690 pending_locate_flush = with_flush;
695 if (transport_rolling() && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
696 realtime_stop (false);
699 if ( !with_loop || loop_changing) {
701 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
704 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
707 _butler->schedule_transport_work ();
711 /* this is functionally what clear_clicks() does but with a tentative lock */
713 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
715 if (clickm.locked()) {
717 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
726 /* switch from input if we're going to roll */
727 if (Config->get_monitoring_model() == HardwareMonitoring) {
729 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
731 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
732 if ((*i)->record_enabled ()) {
733 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
734 (*i)->monitor_input (!config.get_auto_input());
739 /* otherwise we're going to stop, so do the opposite */
740 if (Config->get_monitoring_model() == HardwareMonitoring) {
741 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
743 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
744 if ((*i)->record_enabled ()) {
745 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
746 (*i)->monitor_input (true);
752 /* cancel looped playback if transport pos outside of loop range */
754 Location* al = _locations.auto_loop_location();
756 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
757 // cancel looping directly, this is called from event handling context
758 set_play_loop (false);
760 else if (al && _transport_frame == al->start()) {
762 // this is only necessary for seamless looping
764 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
766 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
767 if ((*i)->record_enabled ()) {
768 // tell it we've looped, so it can deal with the record state
769 (*i)->transport_looped(_transport_frame);
774 TransportLooped(); // EMIT SIGNAL
778 loop_changing = false;
780 _send_timecode_update = true;
782 Located (); /* EMIT SIGNAL */
785 /** Set the transport speed.
786 * @param speed New speed
790 Session::set_transport_speed (double speed, bool abort)
792 if (_transport_speed == speed) {
796 _target_transport_speed = fabs(speed);
798 /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
799 and user needs. We really need CD-style "skip" playback for ffwd and rewind.
803 speed = min (8.0, speed);
804 } else if (speed < 0) {
805 speed = max (-8.0, speed);
808 if (transport_rolling() && speed == 0.0) {
810 /* we are rolling and we want to stop */
812 if (Config->get_monitoring_model() == HardwareMonitoring)
814 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
816 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
817 if ((*i)->record_enabled ()) {
818 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
819 (*i)->monitor_input (true);
824 if (synced_to_jack ()) {
825 _engine.transport_stop ();
827 stop_transport (abort);
830 } else if (transport_stopped() && speed == 1.0) {
832 /* we are stopped and we want to start rolling at speed 1 */
834 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
838 if (Config->get_monitoring_model() == HardwareMonitoring) {
840 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
842 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
843 if (config.get_auto_input() && (*i)->record_enabled ()) {
844 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
845 (*i)->monitor_input (false);
850 if (synced_to_jack()) {
851 _engine.transport_start ();
858 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
862 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
863 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
868 if (actively_recording()) {
872 if (speed > 0.0 && _transport_frame == current_end_frame()) {
876 if (speed < 0.0 && _transport_frame == 0) {
882 /* if we are reversing relative to the current speed, or relative to the speed
883 before the last stop, then we have to do extra work.
886 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
887 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
890 _last_transport_speed = _transport_speed;
891 _transport_speed = speed;
893 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
894 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
895 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
896 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
900 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
901 _butler->schedule_transport_work ();
907 /** Stop the transport. */
909 Session::stop_transport (bool abort)
911 if (_transport_speed == 0.0f) {
915 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
916 _worst_output_latency > current_block_size)
919 /* we need to capture the audio that has still not yet been received by the system
920 at the time the stop is requested, so we have to roll past that time.
922 we want to declick before stopping, so schedule the autostop for one
923 block before the actual end. we'll declick in the subsequent block,
924 and then we'll really be stopped.
927 Event *ev = new Event (Event::StopOnce, Event::Replace,
928 _transport_frame + _worst_output_latency - current_block_size,
932 transport_sub_state |= StopPendingCapture;
933 pending_abort = abort;
938 if ((transport_sub_state & PendingDeclickOut) == 0) {
939 transport_sub_state |= PendingDeclickOut;
940 /* we'll be called again after the declick */
941 pending_abort = abort;
945 realtime_stop (abort);
946 _butler->schedule_transport_work ();
950 Session::start_transport ()
952 _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;
978 _transport_speed = 1.0;
979 _target_transport_speed = 1.0;
981 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
982 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
983 (*i)->realtime_set_speed ((*i)->speed(), true);
986 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
988 TransportStateChange (); /* EMIT SIGNAL */
991 /** Do any transport work in the audio thread that needs to be done after the
992 * transport thread is finished. Audio thread, realtime safe.
995 Session::post_transport ()
997 if (post_transport_work & PostTransportAudition) {
998 if (auditioner && auditioner->active()) {
999 process_function = &Session::process_audition;
1001 process_function = &Session::process_with_events;
1005 if (post_transport_work & PostTransportStop) {
1007 transport_sub_state = 0;
1010 if (post_transport_work & PostTransportLocate) {
1012 if (((Config->get_slave_source() == None && (auto_play_legal && config.get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
1016 transport_sub_state = 0;
1022 post_transport_work = PostTransportWork (0);
1026 Session::reset_rf_scale (nframes_t motion)
1028 cumulative_rf_motion += motion;
1030 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1032 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1034 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1046 Session::set_slave_source (SlaveSource src)
1048 bool reverse = false;
1049 bool non_rt_required = false;
1051 if (_transport_speed) {
1052 error << _("please stop the transport before adjusting slave settings") << endmsg;
1056 // 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;
1089 if (_midi_clock_port) {
1091 _slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24);
1094 catch (failed_constructor& err) {
1099 error << _("No MIDI Clock port defined: MIDI Clock slaving is impossible.") << endmsg;
1105 _slave = new JACK_Slave (_engine.jack());
1110 Config->set_slave_source (src);
1112 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1113 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1114 if (!(*i)->hidden()) {
1115 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1116 non_rt_required = true;
1118 (*i)->set_slaved (_slave);
1123 reverse_diskstream_buffers ();
1126 if (non_rt_required) {
1127 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1128 _butler->schedule_transport_work ();
1135 Session::reverse_diskstream_buffers ()
1137 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1138 _butler->schedule_transport_work ();
1142 Session::set_diskstream_speed (Diskstream* stream, double speed)
1144 if (stream->realtime_set_speed (speed, false)) {
1145 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1146 _butler->schedule_transport_work ();
1152 Session::set_audio_range (list<AudioRange>& range)
1154 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1155 ev->audio_range = range;
1160 Session::request_play_range (bool yn)
1162 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1167 Session::set_play_range (bool yn)
1169 /* Called from event-processing context */
1171 if (_play_range != yn) {
1176 /* stop transport */
1177 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1184 Session::setup_auto_play ()
1186 /* Called from event-processing context */
1190 _clear_event_type (Event::RangeStop);
1191 _clear_event_type (Event::RangeLocate);
1197 list<AudioRange>::size_type sz = current_audio_range.size();
1201 list<AudioRange>::iterator i = current_audio_range.begin();
1202 list<AudioRange>::iterator next;
1204 while (i != current_audio_range.end()) {
1209 /* locating/stopping is subject to delays for declicking.
1212 nframes_t requested_frame = (*i).end;
1214 if (requested_frame > current_block_size) {
1215 requested_frame -= current_block_size;
1217 requested_frame = 0;
1220 if (next == current_audio_range.end()) {
1221 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1223 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1231 } else if (sz == 1) {
1233 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1238 /* now start rolling at the right place */
1240 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1245 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1247 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1248 ev->target2_frame = start;
1253 Session::request_bounded_roll (nframes_t start, nframes_t end)
1256 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1258 request_locate (start, true);
1262 Session::engine_halted ()
1266 /* there will be no more calls to process(), so
1267 we'd better clean up for ourselves, right now.
1269 but first, make sure the butler is out of
1273 g_atomic_int_set (&_butler->should_do_transport_work, 0);
1274 post_transport_work = PostTransportWork (0);
1277 realtime_stop (false);
1278 non_realtime_stop (false, 0, ignored);
1279 transport_sub_state = 0;
1281 TransportStateChange (); /* EMIT SIGNAL */
1286 Session::xrun_recovery ()
1288 Xrun (transport_frame()); //EMIT SIGNAL
1290 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1292 /* it didn't actually halt, but we need
1293 to handle things in the same way.
1301 Session::update_latency_compensation (bool with_stop, bool abort)
1303 bool update_jack = false;
1305 if (_state_of_the_state & Deletion) {
1309 _worst_track_latency = 0;
1311 #undef DEBUG_LATENCY
1312 #ifdef DEBUG_LATENCY
1313 cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1316 boost::shared_ptr<RouteList> r = routes.reader ();
1318 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1321 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1322 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1325 nframes_t old_latency = (*i)->output()->signal_latency ();
1326 nframes_t track_latency = (*i)->update_total_latency ();
1328 if (old_latency != track_latency) {
1329 (*i)->input()->update_port_total_latencies ();
1330 (*i)->output()->update_port_total_latencies ();
1334 if (!(*i)->is_hidden() && ((*i)->active())) {
1335 _worst_track_latency = max (_worst_track_latency, track_latency);
1340 _engine.update_total_latencies ();
1343 #ifdef DEBUG_LATENCY
1344 cerr << "\tworst was " << _worst_track_latency << endl;
1347 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1348 (*i)->set_latency_delay (_worst_track_latency);
1351 set_worst_io_latencies ();
1353 /* reflect any changes in latencies into capture offsets
1356 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1358 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1359 (*i)->set_capture_offset ();
1364 Session::allow_auto_play (bool yn)
1366 auto_play_legal = yn;
1370 Session::reset_jack_connection (jack_client_t* jack)
1374 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1375 js->reset_client (jack);