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 if ((Config->get_slave_source() == None && Config->get_auto_return()) ||
394 (post_transport_work & PostTransportLocate) ||
395 (_requested_return_frame >= 0) ||
398 if (pending_locate_flush) {
399 flush_all_inserts ();
402 if (((Config->get_slave_source() == None && Config->get_auto_return()) ||
404 _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_stop_frame;
415 _requested_return_frame = -1;
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
447 if (_requested_return_frame < 0) {
448 last_stop_frame = _transport_frame;
450 last_stop_frame = _requested_return_frame;
451 _requested_return_frame = -1;
456 send_full_time_code (0);
457 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
458 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
462 /* XXX its a little odd that we're doing this here
463 when realtime_stop(), which has already executed,
465 JLC - so let's not because it seems unnecessary and breaks loop record
468 if (!Config->get_latched_record_enable()) {
469 g_atomic_int_set (&_record_status, Disabled);
471 g_atomic_int_set (&_record_status, Enabled);
473 RecordStateChanged (); /* emit signal */
477 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
478 /* capture start has been changed, so save pending state */
479 save_state ("", true);
483 /* always try to get rid of this */
485 remove_pending_capture_state ();
487 /* save the current state of things if appropriate */
489 if (did_record && !saved) {
490 save_state (_current_snapshot_name);
493 if (post_transport_work & PostTransportDuration) {
494 DurationChanged (); /* EMIT SIGNAL */
497 if (post_transport_work & PostTransportStop) {
500 /* do not turn off autoloop on stop */
504 nframes_t tf = _transport_frame;
506 PositionChanged (tf); /* EMIT SIGNAL */
507 TransportStateChange (); /* EMIT SIGNAL */
509 /* and start it up again if relevant */
511 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
512 request_transport_speed (1.0);
513 pending_locate_roll = false;
518 Session::check_declick_out ()
520 bool locate_required = transport_sub_state & PendingLocate;
522 /* this is called after a process() iteration. if PendingDeclickOut was set,
523 it means that we were waiting to declick the output (which has just been
524 done) before doing something else. this is where we do that "something else".
526 note: called from the audio thread.
529 if (transport_sub_state & PendingDeclickOut) {
531 if (locate_required) {
532 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
533 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
535 stop_transport (pending_abort);
536 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
542 Session::set_play_loop (bool yn)
544 /* Called from event-handling context */
546 if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
552 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
553 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
554 "Recommend changing the configured options")
560 if ((play_loop = yn)) {
565 if ((loc = _locations.auto_loop_location()) != 0) {
567 if (Config->get_seamless_loop()) {
568 // set all diskstreams to use internal looping
569 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
570 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
571 if (!(*i)->hidden()) {
572 (*i)->set_loop (loc);
577 // set all diskstreams to NOT use internal looping
578 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
579 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
580 if (!(*i)->hidden()) {
586 /* stick in the loop event */
588 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
591 /* locate to start of loop and roll if current pos is outside of the loop range */
592 if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
593 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
597 // locate to current position (+ 1 to force reload)
598 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
606 clear_events (Event::AutoLoop);
608 // set all diskstreams to NOT use internal looping
609 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
610 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
611 if (!(*i)->hidden()) {
620 Session::flush_all_inserts ()
622 boost::shared_ptr<RouteList> r = routes.reader ();
624 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
625 (*i)->flush_processors ();
630 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
632 if (synced_to_jack()) {
637 _slave->speed_and_position (sp, pos);
639 if (target_frame != pos) {
641 /* tell JACK to change transport position, and we will
642 follow along later in ::follow_slave()
645 _engine.transport_locate (target_frame);
647 if (sp != 1.0f && with_roll) {
648 _engine.transport_start ();
655 locate (target_frame, with_roll, with_flush, with_loop);
660 Session::micro_locate (nframes_t distance)
662 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
664 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
665 if (!(*i)->can_internal_playback_seek (distance)) {
670 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
671 (*i)->internal_playback_seek (distance);
674 _transport_frame += distance;
679 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
681 if (actively_recording() && !with_loop) {
685 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
687 set_transport_speed (1.0, false);
689 loop_changing = false;
694 // [DR] FIXME: find out exactly where this should go below
695 _transport_frame = target_frame;
696 smpte_time(_transport_frame, transmitting_smpte_time);
697 outbound_mtc_smpte_frame = _transport_frame;
698 next_quarter_frame_to_send = 0;
700 if (_transport_speed && (!with_loop || loop_changing)) {
701 /* schedule a declick. we'll be called again when its done */
703 if (!(transport_sub_state & PendingDeclickOut)) {
704 transport_sub_state |= (PendingDeclickOut|PendingLocate);
705 pending_locate_frame = target_frame;
706 pending_locate_roll = with_roll;
707 pending_locate_flush = with_flush;
712 if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
713 realtime_stop (false);
716 if ( !with_loop || loop_changing) {
718 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
721 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
724 schedule_butler_transport_work ();
728 /* this is functionally what clear_clicks() does but with a tentative lock */
730 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
732 if (clickm.locked()) {
734 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
743 /* switch from input if we're going to roll */
744 if (Config->get_monitoring_model() == HardwareMonitoring) {
746 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
748 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
749 if ((*i)->record_enabled ()) {
750 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
751 (*i)->monitor_input (!Config->get_auto_input());
756 /* otherwise we're going to stop, so do the opposite */
757 if (Config->get_monitoring_model() == HardwareMonitoring) {
758 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
760 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
761 if ((*i)->record_enabled ()) {
762 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
763 (*i)->monitor_input (true);
769 /* cancel looped playback if transport pos outside of loop range */
771 Location* al = _locations.auto_loop_location();
773 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
774 // cancel looping directly, this is called from event handling context
775 set_play_loop (false);
777 else if (al && _transport_frame == al->start()) {
779 // this is only necessary for seamless looping
781 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
783 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
784 if ((*i)->record_enabled ()) {
785 // tell it we've looped, so it can deal with the record state
786 (*i)->transport_looped(_transport_frame);
791 TransportLooped(); // EMIT SIGNAL
795 loop_changing = false;
797 _send_smpte_update = true;
800 /** Set the transport speed.
801 * @param speed New speed
805 Session::set_transport_speed (double speed, bool abort)
807 if (_transport_speed == speed) {
811 target_phi = (uint64_t) (0x1000000 * fabs(speed));
814 speed = min (8.0, speed);
815 } else if (speed < 0) {
816 speed = max (-8.0, speed);
819 if (transport_rolling() && speed == 0.0) {
821 /* we are rolling and we want to stop */
823 if (Config->get_monitoring_model() == HardwareMonitoring)
825 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
827 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
828 if ((*i)->record_enabled ()) {
829 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
830 (*i)->monitor_input (true);
835 if (synced_to_jack ()) {
836 _engine.transport_stop ();
838 stop_transport (abort);
841 } else if (transport_stopped() && speed == 1.0) {
843 /* we are stopped and we want to start rolling at speed 1 */
845 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
849 if (Config->get_monitoring_model() == HardwareMonitoring) {
851 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
853 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
854 if (Config->get_auto_input() && (*i)->record_enabled ()) {
855 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
856 (*i)->monitor_input (false);
861 if (synced_to_jack()) {
862 _engine.transport_start ();
869 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
873 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
874 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
879 if (actively_recording()) {
883 if (speed > 0.0 && _transport_frame == current_end_frame()) {
887 if (speed < 0.0 && _transport_frame == 0) {
893 /* if we are reversing relative to the current speed, or relative to the speed
894 before the last stop, then we have to do extra work.
897 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
898 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
899 last_stop_frame = _transport_frame;
902 _last_transport_speed = _transport_speed;
903 _transport_speed = speed;
905 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
906 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
907 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
908 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
912 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
913 schedule_butler_transport_work ();
919 /** Stop the transport. */
921 Session::stop_transport (bool abort)
923 if (_transport_speed == 0.0f) {
927 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
928 _worst_output_latency > current_block_size)
931 /* we need to capture the audio that has still not yet been received by the system
932 at the time the stop is requested, so we have to roll past that time.
934 we want to declick before stopping, so schedule the autostop for one
935 block before the actual end. we'll declick in the subsequent block,
936 and then we'll really be stopped.
939 Event *ev = new Event (Event::StopOnce, Event::Replace,
940 _transport_frame + _worst_output_latency - current_block_size,
944 transport_sub_state |= StopPendingCapture;
945 pending_abort = abort;
950 if ((transport_sub_state & PendingDeclickOut) == 0) {
951 transport_sub_state |= PendingDeclickOut;
952 /* we'll be called again after the declick */
953 pending_abort = abort;
957 realtime_stop (abort);
958 schedule_butler_transport_work ();
962 Session::start_transport ()
964 _last_roll_location = _transport_frame;
967 /* if record status is Enabled, move it to Recording. if its
968 already Recording, move it to Disabled.
971 switch (record_status()) {
973 if (!Config->get_punch_in()) {
980 disable_record (false);
988 transport_sub_state |= PendingDeclickIn;
990 _transport_speed = 1.0;
991 target_phi = 0x1000000; // speed = 1
995 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
996 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
997 (*i)->realtime_set_speed ((*i)->speed(), true);
1000 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
1002 TransportStateChange (); /* EMIT SIGNAL */
1005 /** Do any transport work in the audio thread that needs to be done after the
1006 * transport thread is finished. Audio thread, realtime safe.
1009 Session::post_transport ()
1011 if (post_transport_work & PostTransportAudition) {
1012 if (auditioner && auditioner->active()) {
1013 process_function = &Session::process_audition;
1015 process_function = &Session::process_with_events;
1019 if (post_transport_work & PostTransportStop) {
1021 transport_sub_state = 0;
1024 if (post_transport_work & PostTransportLocate) {
1026 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
1030 transport_sub_state = 0;
1036 post_transport_work = PostTransportWork (0);
1040 Session::reset_rf_scale (nframes_t motion)
1042 cumulative_rf_motion += motion;
1044 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1046 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1048 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1060 Session::set_slave_source (SlaveSource src)
1062 bool reverse = false;
1063 bool non_rt_required = false;
1065 if (_transport_speed) {
1066 error << _("please stop the transport before adjusting slave settings") << endmsg;
1070 // if (src == JACK && Config->get_jack_time_master()) {
1077 if (_transport_speed < 0.0) {
1089 _slave = new MTC_Slave (*this, *_mtc_port);
1092 catch (failed_constructor& err) {
1097 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1103 if (_midi_clock_port) {
1105 _slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24);
1108 catch (failed_constructor& err) {
1113 error << _("No MIDI Clock port defined: MIDI Clock slaving is impossible.") << endmsg;
1119 _slave = new JACK_Slave (_engine.jack());
1124 Config->set_slave_source (src);
1126 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1127 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1128 if (!(*i)->hidden()) {
1129 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1130 non_rt_required = true;
1132 (*i)->set_slaved (_slave);
1137 reverse_diskstream_buffers ();
1140 if (non_rt_required) {
1141 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1142 schedule_butler_transport_work ();
1149 Session::reverse_diskstream_buffers ()
1151 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1152 schedule_butler_transport_work ();
1156 Session::set_diskstream_speed (Diskstream* stream, double speed)
1158 if (stream->realtime_set_speed (speed, false)) {
1159 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1160 schedule_butler_transport_work ();
1166 Session::set_audio_range (list<AudioRange>& range)
1168 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1169 ev->audio_range = range;
1174 Session::request_play_range (bool yn)
1176 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1181 Session::set_play_range (bool yn)
1183 /* Called from event-processing context */
1185 if (_play_range != yn) {
1190 /* stop transport */
1191 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1198 Session::setup_auto_play ()
1200 /* Called from event-processing context */
1204 _clear_event_type (Event::RangeStop);
1205 _clear_event_type (Event::RangeLocate);
1211 list<AudioRange>::size_type sz = current_audio_range.size();
1215 list<AudioRange>::iterator i = current_audio_range.begin();
1216 list<AudioRange>::iterator next;
1218 while (i != current_audio_range.end()) {
1223 /* locating/stopping is subject to delays for declicking.
1226 nframes_t requested_frame = (*i).end;
1228 if (requested_frame > current_block_size) {
1229 requested_frame -= current_block_size;
1231 requested_frame = 0;
1234 if (next == current_audio_range.end()) {
1235 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1237 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1245 } else if (sz == 1) {
1247 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1252 /* now start rolling at the right place */
1254 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1259 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1261 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1262 ev->target2_frame = start;
1267 Session::request_bounded_roll (nframes_t start, nframes_t end)
1270 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1272 request_locate (start, true);
1276 Session::engine_halted ()
1280 /* there will be no more calls to process(), so
1281 we'd better clean up for ourselves, right now.
1283 but first, make sure the butler is out of
1287 g_atomic_int_set (&butler_should_do_transport_work, 0);
1288 post_transport_work = PostTransportWork (0);
1291 realtime_stop (false);
1292 non_realtime_stop (false, 0, ignored);
1293 transport_sub_state = 0;
1295 TransportStateChange (); /* EMIT SIGNAL */
1300 Session::xrun_recovery ()
1302 Xrun (transport_frame()); //EMIT SIGNAL
1304 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1306 /* it didn't actually halt, but we need
1307 to handle things in the same way.
1315 Session::update_latency_compensation (bool with_stop, bool abort)
1317 bool update_jack = false;
1319 if (_state_of_the_state & Deletion) {
1323 _worst_track_latency = 0;
1325 #undef DEBUG_LATENCY
1326 #ifdef DEBUG_LATENCY
1327 cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1330 boost::shared_ptr<RouteList> r = routes.reader ();
1332 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1335 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1336 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1339 nframes_t old_latency = (*i)->signal_latency ();
1340 nframes_t track_latency = (*i)->update_total_latency ();
1342 if (old_latency != track_latency) {
1343 (*i)->update_port_total_latencies ();
1347 if (!(*i)->is_hidden() && ((*i)->active())) {
1348 _worst_track_latency = max (_worst_track_latency, track_latency);
1353 _engine.update_total_latencies ();
1356 #ifdef DEBUG_LATENCY
1357 cerr << "\tworst was " << _worst_track_latency << endl;
1360 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1361 (*i)->set_latency_delay (_worst_track_latency);
1364 set_worst_io_latencies ();
1366 /* reflect any changes in latencies into capture offsets
1369 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1371 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1372 (*i)->set_capture_offset ();
1377 Session::allow_auto_play (bool yn)
1379 auto_play_legal = yn;
1383 Session::reset_jack_connection (jack_client_t* jack)
1387 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1388 js->reset_client (jack);