2 Copyright (C) 1999-2003 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include <sigc++/bind.h>
25 #include <sigc++/retype.h>
28 #include "pbd/error.h"
29 #include <glibmm/thread.h>
30 #include "pbd/pthread_utils.h"
31 #include "pbd/memento_command.h"
32 #include "pbd/stacktrace.h"
34 #include "midi++/mmc.h"
35 #include "midi++/port.h"
37 #include "ardour/ardour.h"
38 #include "ardour/audio_diskstream.h"
39 #include "ardour/audioengine.h"
40 #include "ardour/auditioner.h"
41 #include "ardour/butler.h"
42 #include "ardour/location.h"
43 #include "ardour/session.h"
44 #include "ardour/slave.h"
49 using namespace ARDOUR;
54 Session::request_input_change_handling ()
56 if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
57 Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0);
63 Session::request_slave_source (SlaveSource src)
65 Event* ev = new Event (Event::SetSlaveSource, Event::Add, Event::Immediate, 0, 0.0);
68 /* could set_seamless_loop() be disposed of entirely?*/
69 Config->set_seamless_loop (false);
71 Config->set_seamless_loop (true);
78 Session::request_transport_speed (double speed)
80 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, speed);
85 Session::request_diskstream_speed (Diskstream& ds, double speed)
87 Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed);
93 Session::request_stop (bool abort)
95 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0, abort);
100 Session::request_locate (nframes_t target_frame, bool with_roll)
102 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, false);
107 Session::force_locate (nframes_t target_frame, bool with_roll)
109 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, true);
114 Session::request_play_loop (bool yn)
117 Location *location = _locations.auto_loop_location();
119 if (location == 0 && yn) {
120 error << _("Cannot loop - no loop range defined")
125 ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, 0.0, yn);
128 if (!yn && Config->get_seamless_loop() && transport_rolling()) {
129 // request an immediate locate to refresh the diskstreams
130 // after disabling looping
131 request_locate (_transport_frame-1, false);
136 Session::realtime_stop (bool abort)
138 /* assume that when we start, we'll be moving forwards */
140 // FIXME: where should this really be? [DR]
141 //send_full_time_code();
142 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
143 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
145 if (_transport_speed < 0.0f) {
146 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop | PostTransportReverse);
148 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop);
151 if (actively_recording()) {
153 /* move the transport position back to where the
154 request for a stop was noticed. we rolled
155 past that point to pick up delayed input.
158 #ifndef LEAVE_TRANSPORT_UNADJUSTED
159 decrement_transport_position (_worst_output_latency);
162 /* the duration change is not guaranteed to have happened, but is likely */
164 post_transport_work = PostTransportWork (post_transport_work | PostTransportDuration);
168 post_transport_work = PostTransportWork (post_transport_work | PostTransportAbort);
171 _clear_event_type (Event::StopOnce);
172 _clear_event_type (Event::RangeStop);
173 _clear_event_type (Event::RangeLocate);
175 disable_record (true);
177 reset_slave_state ();
179 _transport_speed = 0;
180 _target_transport_speed = 0;
182 if (config.get_use_video_sync()) {
183 waiting_for_sync_offset = true;
186 transport_sub_state = ((Config->get_slave_source() == None && config.get_auto_return()) ? AutoReturning : 0);
190 Session::butler_transport_work ()
194 boost::shared_ptr<RouteList> r = routes.reader ();
195 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
197 int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
200 if (post_transport_work & PostTransportCurveRealloc) {
201 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
202 (*i)->curve_reallocate();
206 if (post_transport_work & PostTransportInputChange) {
207 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
208 (*i)->non_realtime_input_change ();
212 if (post_transport_work & PostTransportSpeed) {
213 non_realtime_set_speed ();
216 if (post_transport_work & PostTransportReverse) {
219 cumulative_rf_motion = 0;
222 /* don't seek if locate will take care of that in non_realtime_stop() */
224 if (!(post_transport_work & PostTransportLocate)) {
226 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
227 if (!(*i)->hidden()) {
228 (*i)->non_realtime_locate (_transport_frame);
230 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
231 /* new request, stop seeking, and start again */
232 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
239 if (post_transport_work & PostTransportLocate) {
240 non_realtime_locate ();
243 if (post_transport_work & PostTransportStop) {
244 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
246 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
251 if (post_transport_work & PostTransportOverWrite) {
252 non_realtime_overwrite (on_entry, finished);
254 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
259 if (post_transport_work & PostTransportAudition) {
260 non_realtime_set_audition ();
263 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
267 Session::non_realtime_set_speed ()
269 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
271 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
272 (*i)->non_realtime_set_speed ();
277 Session::non_realtime_overwrite (int on_entry, bool& finished)
279 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
281 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
282 if ((*i)->pending_overwrite) {
283 (*i)->overwrite_existing_buffers ();
285 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
294 Session::non_realtime_locate ()
296 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
298 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
299 (*i)->non_realtime_locate (_transport_frame);
305 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
315 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
317 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
318 if ((*i)->get_captured_frames () != 0) {
324 /* stop and locate are merged here because they share a lot of common stuff */
327 now = localtime (&xnow);
330 auditioner->cancel_audition ();
334 cumulative_rf_motion = 0;
338 begin_reversible_command ("capture");
340 Location* loc = _locations.end_location();
341 bool change_end = false;
343 if (_transport_frame < loc->end()) {
345 /* stopped recording before current end */
347 if (config.get_end_marker_is_free()) {
349 /* first capture for this session, move end back to where we are */
354 } else if (_transport_frame > loc->end()) {
356 /* stopped recording after the current end, extend it */
362 XMLNode &before = loc->get_state();
363 loc->set_end(_transport_frame);
364 XMLNode &after = loc->get_state();
365 add_command (new MementoCommand<Location>(*loc, &before, &after));
368 config.set_end_marker_is_free (false);
369 _have_captured = true;
372 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
373 (*i)->transport_stopped (*now, xnow, abort);
376 boost::shared_ptr<RouteList> r = routes.reader ();
378 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
379 if (!(*i)->is_hidden()) {
380 (*i)->set_pending_declick (0);
385 commit_reversible_command ();
388 if (_engine.running()) {
389 update_latency_compensation (true, abort);
392 bool const auto_return_enabled =
393 (Config->get_slave_source() == None && config.get_auto_return());
395 if (auto_return_enabled ||
396 (post_transport_work & PostTransportLocate) ||
397 (_requested_return_frame >= 0) ||
400 if (pending_locate_flush) {
401 flush_all_inserts ();
404 if ((auto_return_enabled || synced_to_jack() || _requested_return_frame >= 0) &&
405 !(post_transport_work & PostTransportLocate)) {
407 bool do_locate = false;
409 if (_requested_return_frame >= 0) {
410 _transport_frame = _requested_return_frame;
411 _requested_return_frame = -1;
414 _transport_frame = _last_roll_location;
417 if (synced_to_jack() && !play_loop) {
422 // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl;
423 _engine.transport_locate (_transport_frame);
427 #ifdef LEAVE_TRANSPORT_UNADJUSTED
428 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
429 if (!(*i)->hidden()) {
430 (*i)->non_realtime_locate (_transport_frame);
432 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
434 /* we will be back */
443 send_full_time_code (0);
444 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
445 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
449 /* XXX its a little odd that we're doing this here
450 when realtime_stop(), which has already executed,
452 JLC - so let's not because it seems unnecessary and breaks loop record
455 if (!Config->get_latched_record_enable()) {
456 g_atomic_int_set (&_record_status, Disabled);
458 g_atomic_int_set (&_record_status, Enabled);
460 RecordStateChanged (); /* emit signal */
464 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
465 /* capture start has been changed, so save pending state */
466 save_state ("", true);
470 /* always try to get rid of this */
472 remove_pending_capture_state ();
474 /* save the current state of things if appropriate */
476 if (did_record && !saved) {
477 save_state (_current_snapshot_name);
480 if (post_transport_work & PostTransportDuration) {
481 DurationChanged (); /* EMIT SIGNAL */
484 if (post_transport_work & PostTransportStop) {
487 /* do not turn off autoloop on stop */
491 nframes_t tf = _transport_frame;
493 PositionChanged (tf); /* EMIT SIGNAL */
494 TransportStateChange (); /* EMIT SIGNAL */
496 /* and start it up again if relevant */
498 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
499 request_transport_speed (1.0);
500 pending_locate_roll = false;
505 Session::check_declick_out ()
507 bool locate_required = transport_sub_state & PendingLocate;
509 /* this is called after a process() iteration. if PendingDeclickOut was set,
510 it means that we were waiting to declick the output (which has just been
511 done) before doing something else. this is where we do that "something else".
513 note: called from the audio thread.
516 if (transport_sub_state & PendingDeclickOut) {
518 if (locate_required) {
519 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
520 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
522 stop_transport (pending_abort);
523 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
529 Session::set_play_loop (bool yn)
531 /* Called from event-handling context */
533 if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
539 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
540 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
541 "Recommend changing the configured options")
547 if ((play_loop = yn)) {
552 if ((loc = _locations.auto_loop_location()) != 0) {
554 if (Config->get_seamless_loop()) {
555 // set all diskstreams to use internal looping
556 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
557 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
558 if (!(*i)->hidden()) {
559 (*i)->set_loop (loc);
564 // set all diskstreams to NOT use internal looping
565 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
566 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
567 if (!(*i)->hidden()) {
573 /* stick in the loop event */
575 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
578 /* locate to start of loop and roll if current pos is outside of the loop range */
579 if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
580 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
584 // locate to current position (+ 1 to force reload)
585 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
593 clear_events (Event::AutoLoop);
595 // set all diskstreams to NOT use internal looping
596 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
597 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
598 if (!(*i)->hidden()) {
607 Session::flush_all_inserts ()
609 boost::shared_ptr<RouteList> r = routes.reader ();
611 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
612 (*i)->flush_processors ();
617 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
619 if (synced_to_jack()) {
624 _slave->speed_and_position (sp, pos);
626 if (target_frame != pos) {
628 /* tell JACK to change transport position, and we will
629 follow along later in ::follow_slave()
632 _engine.transport_locate (target_frame);
634 if (sp != 1.0f && with_roll) {
635 _engine.transport_start ();
641 locate (target_frame, with_roll, with_flush, with_loop);
646 Session::micro_locate (nframes_t distance)
648 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
650 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
651 if (!(*i)->can_internal_playback_seek (distance)) {
656 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
657 (*i)->internal_playback_seek (distance);
660 _transport_frame += distance;
665 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
667 if (actively_recording() && !with_loop) {
671 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
673 set_transport_speed (1.0, false);
675 loop_changing = false;
679 // Update Timecode time
680 // [DR] FIXME: find out exactly where this should go below
681 _transport_frame = target_frame;
682 timecode_time(_transport_frame, transmitting_timecode_time);
683 outbound_mtc_timecode_frame = _transport_frame;
684 next_quarter_frame_to_send = 0;
686 if (_transport_speed && (!with_loop || loop_changing)) {
687 /* schedule a declick. we'll be called again when its done */
689 if (!(transport_sub_state & PendingDeclickOut)) {
690 transport_sub_state |= (PendingDeclickOut|PendingLocate);
691 pending_locate_frame = target_frame;
692 pending_locate_roll = with_roll;
693 pending_locate_flush = with_flush;
698 if (transport_rolling() && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
699 realtime_stop (false);
702 if ( !with_loop || loop_changing) {
704 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
707 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
710 _butler->schedule_transport_work ();
714 /* this is functionally what clear_clicks() does but with a tentative lock */
716 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
718 if (clickm.locked()) {
720 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
729 /* switch from input if we're going to roll */
730 if (Config->get_monitoring_model() == HardwareMonitoring) {
732 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
734 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
735 if ((*i)->record_enabled ()) {
736 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
737 (*i)->monitor_input (!config.get_auto_input());
742 /* otherwise we're going to stop, so do the opposite */
743 if (Config->get_monitoring_model() == HardwareMonitoring) {
744 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
746 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
747 if ((*i)->record_enabled ()) {
748 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
749 (*i)->monitor_input (true);
755 /* cancel looped playback if transport pos outside of loop range */
757 Location* al = _locations.auto_loop_location();
759 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
760 // cancel looping directly, this is called from event handling context
761 set_play_loop (false);
763 else if (al && _transport_frame == al->start()) {
765 // this is only necessary for seamless looping
767 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
769 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
770 if ((*i)->record_enabled ()) {
771 // tell it we've looped, so it can deal with the record state
772 (*i)->transport_looped(_transport_frame);
777 TransportLooped(); // EMIT SIGNAL
781 loop_changing = false;
783 _send_timecode_update = true;
785 Located (); /* EMIT SIGNAL */
788 /** Set the transport speed.
789 * @param speed New speed
793 Session::set_transport_speed (double speed, bool abort)
795 if (_transport_speed == speed) {
799 _target_transport_speed = fabs(speed);
801 /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
802 and user needs. We really need CD-style "skip" playback for ffwd and rewind.
806 speed = min (8.0, speed);
807 } else if (speed < 0) {
808 speed = max (-8.0, speed);
811 if (transport_rolling() && speed == 0.0) {
813 /* we are rolling and we want to stop */
815 if (Config->get_monitoring_model() == HardwareMonitoring)
817 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
819 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
820 if ((*i)->record_enabled ()) {
821 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
822 (*i)->monitor_input (true);
827 if (synced_to_jack ()) {
828 _engine.transport_stop ();
830 stop_transport (abort);
833 } else if (transport_stopped() && speed == 1.0) {
835 /* we are stopped and we want to start rolling at speed 1 */
837 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
841 if (Config->get_monitoring_model() == HardwareMonitoring) {
843 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
845 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
846 if (config.get_auto_input() && (*i)->record_enabled ()) {
847 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
848 (*i)->monitor_input (false);
853 if (synced_to_jack()) {
854 _engine.transport_start ();
861 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
865 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
866 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
871 if (actively_recording()) {
875 if (speed > 0.0 && _transport_frame == current_end_frame()) {
879 if (speed < 0.0 && _transport_frame == 0) {
885 /* if we are reversing relative to the current speed, or relative to the speed
886 before the last stop, then we have to do extra work.
889 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
890 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
893 _last_transport_speed = _transport_speed;
894 _transport_speed = speed;
896 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
897 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
898 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
899 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
903 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
904 _butler->schedule_transport_work ();
910 /** Stop the transport. */
912 Session::stop_transport (bool abort)
914 if (_transport_speed == 0.0f) {
918 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
919 _worst_output_latency > current_block_size)
922 /* we need to capture the audio that has still not yet been received by the system
923 at the time the stop is requested, so we have to roll past that time.
925 we want to declick before stopping, so schedule the autostop for one
926 block before the actual end. we'll declick in the subsequent block,
927 and then we'll really be stopped.
930 Event *ev = new Event (Event::StopOnce, Event::Replace,
931 _transport_frame + _worst_output_latency - current_block_size,
935 transport_sub_state |= StopPendingCapture;
936 pending_abort = abort;
941 if ((transport_sub_state & PendingDeclickOut) == 0) {
942 transport_sub_state |= PendingDeclickOut;
943 /* we'll be called again after the declick */
944 pending_abort = abort;
948 realtime_stop (abort);
949 _butler->schedule_transport_work ();
953 Session::start_transport ()
955 _last_roll_location = _transport_frame;
958 /* if record status is Enabled, move it to Recording. if its
959 already Recording, move it to Disabled.
962 switch (record_status()) {
964 if (!config.get_punch_in()) {
971 disable_record (false);
979 transport_sub_state |= PendingDeclickIn;
981 _transport_speed = 1.0;
982 _target_transport_speed = 1.0;
984 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
985 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
986 (*i)->realtime_set_speed ((*i)->speed(), true);
989 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
991 TransportStateChange (); /* EMIT SIGNAL */
994 /** Do any transport work in the audio thread that needs to be done after the
995 * transport thread is finished. Audio thread, realtime safe.
998 Session::post_transport ()
1000 if (post_transport_work & PostTransportAudition) {
1001 if (auditioner && auditioner->active()) {
1002 process_function = &Session::process_audition;
1004 process_function = &Session::process_with_events;
1008 if (post_transport_work & PostTransportStop) {
1010 transport_sub_state = 0;
1013 if (post_transport_work & PostTransportLocate) {
1015 if (((Config->get_slave_source() == None && (auto_play_legal && config.get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
1019 transport_sub_state = 0;
1025 post_transport_work = PostTransportWork (0);
1029 Session::reset_rf_scale (nframes_t motion)
1031 cumulative_rf_motion += motion;
1033 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1035 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1037 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1049 Session::set_slave_source (SlaveSource src)
1051 bool reverse = false;
1052 bool non_rt_required = false;
1054 if (_transport_speed) {
1055 error << _("please stop the transport before adjusting slave settings") << endmsg;
1059 // if (src == JACK && Config->get_jack_time_master()) {
1066 if (_transport_speed < 0.0) {
1078 _slave = new MTC_Slave (*this, *_mtc_port);
1081 catch (failed_constructor& err) {
1086 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1092 if (_midi_clock_port) {
1094 _slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24);
1097 catch (failed_constructor& err) {
1102 error << _("No MIDI Clock port defined: MIDI Clock slaving is impossible.") << endmsg;
1108 _slave = new JACK_Slave (_engine.jack());
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 _butler->schedule_transport_work ();
1138 Session::reverse_diskstream_buffers ()
1140 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1141 _butler->schedule_transport_work ();
1145 Session::set_diskstream_speed (Diskstream* stream, double speed)
1147 if (stream->realtime_set_speed (speed, false)) {
1148 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1149 _butler->schedule_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)->output()->signal_latency ();
1329 nframes_t track_latency = (*i)->update_total_latency ();
1331 if (old_latency != track_latency) {
1332 (*i)->input()->update_port_total_latencies ();
1333 (*i)->output()->update_port_total_latencies ();
1337 if (!(*i)->is_hidden() && ((*i)->active())) {
1338 _worst_track_latency = max (_worst_track_latency, track_latency);
1343 _engine.update_total_latencies ();
1346 #ifdef DEBUG_LATENCY
1347 cerr << "\tworst was " << _worst_track_latency << endl;
1350 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1351 (*i)->set_latency_delay (_worst_track_latency);
1354 set_worst_io_latencies ();
1356 /* reflect any changes in latencies into capture offsets
1359 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1361 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1362 (*i)->set_capture_offset ();
1367 Session::allow_auto_play (bool yn)
1369 auto_play_legal = yn;
1373 Session::reset_jack_connection (jack_client_t* jack)
1377 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1378 js->reset_client (jack);