2 Copyright (C) 1999-2009 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 if (_transport_speed < 0.0f) {
140 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop | PostTransportReverse);
142 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop);
145 if (actively_recording()) {
147 /* move the transport position back to where the
148 request for a stop was noticed. we rolled
149 past that point to pick up delayed input.
152 #ifndef LEAVE_TRANSPORT_UNADJUSTED
153 decrement_transport_position (_worst_output_latency);
156 /* the duration change is not guaranteed to have happened, but is likely */
158 post_transport_work = PostTransportWork (post_transport_work | PostTransportDuration);
162 post_transport_work = PostTransportWork (post_transport_work | PostTransportAbort);
165 _clear_event_type (Event::StopOnce);
166 _clear_event_type (Event::RangeStop);
167 _clear_event_type (Event::RangeLocate);
169 disable_record (true);
171 reset_slave_state ();
173 _transport_speed = 0;
175 if (Config->get_use_video_sync()) {
176 waiting_for_sync_offset = true;
179 transport_sub_state = ((Config->get_slave_source() == None && Config->get_auto_return()) ? AutoReturning : 0);
183 Session::butler_transport_work ()
187 boost::shared_ptr<RouteList> r = routes.reader ();
188 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
190 int on_entry = g_atomic_int_get (&butler_should_do_transport_work);
193 if (post_transport_work & PostTransportCurveRealloc) {
194 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
195 (*i)->curve_reallocate();
199 if (post_transport_work & PostTransportInputChange) {
200 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
201 (*i)->non_realtime_input_change ();
205 if (post_transport_work & PostTransportSpeed) {
206 non_realtime_set_speed ();
209 if (post_transport_work & PostTransportReverse) {
212 cumulative_rf_motion = 0;
215 /* don't seek if locate will take care of that in non_realtime_stop() */
217 if (!(post_transport_work & PostTransportLocate)) {
219 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
220 if (!(*i)->hidden()) {
221 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
222 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
225 (*i)->seek (_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 & (PostTransportStop|PostTransportLocate)) {
238 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
240 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
245 if (post_transport_work & PostTransportOverWrite) {
246 non_realtime_overwrite (on_entry, finished);
248 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
253 if (post_transport_work & PostTransportAudition) {
254 non_realtime_set_audition ();
257 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
261 Session::non_realtime_set_speed ()
263 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
265 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
266 (*i)->non_realtime_set_speed ();
271 Session::non_realtime_overwrite (int on_entry, bool& finished)
273 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
275 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
276 if ((*i)->pending_overwrite) {
277 (*i)->overwrite_existing_buffers ();
279 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
287 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
297 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
299 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
300 if ((*i)->get_captured_frames () != 0) {
306 /* stop and locate are merged here because they share a lot of common stuff */
309 now = localtime (&xnow);
312 auditioner->cancel_audition ();
316 cumulative_rf_motion = 0;
320 begin_reversible_command ("capture");
322 Location* loc = _locations.end_location();
323 bool change_end = false;
325 if (_transport_frame < loc->end()) {
327 /* stopped recording before current end */
329 if (_end_location_is_free) {
331 /* first capture for this session, move end back to where we are */
336 } else if (_transport_frame > loc->end()) {
338 /* stopped recording after the current end, extend it */
344 XMLNode &before = loc->get_state();
345 loc->set_end(_transport_frame);
346 XMLNode &after = loc->get_state();
347 add_command (new MementoCommand<Location>(*loc, &before, &after));
350 _end_location_is_free = false;
351 _have_captured = true;
354 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
355 (*i)->transport_stopped (*now, xnow, abort);
358 boost::shared_ptr<RouteList> r = routes.reader ();
360 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
361 if (!(*i)->hidden()) {
362 (*i)->set_pending_declick (0);
367 commit_reversible_command ();
370 if (_engine.running()) {
371 update_latency_compensation (true, abort);
374 if ((Config->get_slave_source() == None && Config->get_auto_return()) ||
375 (post_transport_work & PostTransportLocate) ||
376 (_requested_return_frame >= 0) ||
379 if (pending_locate_flush) {
380 flush_all_redirects ();
383 if (((Config->get_slave_source() == None && Config->get_auto_return()) ||
385 _requested_return_frame >= 0) &&
386 !(post_transport_work & PostTransportLocate)) {
388 /* no explicit locate queued */
390 bool do_locate = false;
392 if (_requested_return_frame >= 0) {
393 _transport_frame = _requested_return_frame;
394 _requested_return_frame = -1;
397 if (play_loop && !synced_to_jack()) {
398 Location *location = _locations.auto_loop_location();
401 _transport_frame = location->start();
404 _transport_frame = last_stop_frame;
407 _transport_frame = last_stop_frame;
409 _requested_return_frame = -1;
412 if (synced_to_jack() && !play_loop) {
417 // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl;
418 _engine.transport_locate (_transport_frame);
422 #ifndef LEAVE_TRANSPORT_UNADJUSTED
426 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
427 if (!(*i)->hidden()) {
428 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
429 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
432 (*i)->seek (_transport_frame);
435 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
437 /* 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 send_full_time_code ();
455 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
456 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
460 /* XXX its a little odd that we're doing this here
461 when realtime_stop(), which has already executed,
463 JLC - so let's not because it seems unnecessary and breaks loop record
466 if (!Config->get_latched_record_enable()) {
467 g_atomic_int_set (&_record_status, Disabled);
469 g_atomic_int_set (&_record_status, Enabled);
471 RecordStateChanged (); /* emit signal */
475 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
476 /* capture start has been changed, so save pending state */
477 save_state ("", true);
481 /* always try to get rid of this */
483 remove_pending_capture_state ();
485 /* save the current state of things if appropriate */
487 if (did_record && !saved) {
488 save_state (_current_snapshot_name);
491 if (post_transport_work & PostTransportDuration) {
492 DurationChanged (); /* EMIT SIGNAL */
495 if (post_transport_work & PostTransportStop) {
500 nframes_t tf = _transport_frame;
502 PositionChanged (tf); /* EMIT SIGNAL */
503 TransportStateChange (); /* EMIT SIGNAL */
505 /* and start it up again if relevant */
507 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
508 request_transport_speed (1.0);
509 pending_locate_roll = false;
514 Session::check_declick_out ()
516 bool locate_required = transport_sub_state & PendingLocate;
518 /* this is called after a process() iteration. if PendingDeclickOut was set,
519 it means that we were waiting to declick the output (which has just been
520 done) before doing something else. this is where we do that "something else".
522 note: called from the audio thread.
525 if (transport_sub_state & PendingDeclickOut) {
527 if (locate_required) {
528 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
529 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
531 stop_transport (pending_abort);
532 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
538 Session::set_play_loop (bool yn)
540 /* Called from event-handling context */
544 if ((actively_recording() && yn) || (loc = _locations.auto_loop_location()) == 0) {
550 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
551 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
552 "Recommend changing the configured options")
558 if ((play_loop = yn)) {
563 if (Config->get_seamless_loop()) {
564 // set all diskstreams to 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()) {
568 (*i)->set_loop (loc);
573 // set all diskstreams to NOT use internal looping
574 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
575 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
576 if (!(*i)->hidden()) {
582 /* put the loop event into the event list */
584 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
587 /* locate to start of loop and roll */
588 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
594 clear_events (Event::AutoLoop);
596 // set all diskstreams to NOT use internal looping
597 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
598 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
599 if (!(*i)->hidden()) {
608 Session::flush_all_redirects ()
610 boost::shared_ptr<RouteList> r = routes.reader ();
612 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
613 (*i)->flush_redirects ();
618 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
620 if (synced_to_jack()) {
625 _slave->speed_and_position (sp, pos);
627 if (target_frame != pos) {
629 /* tell JACK to change transport position, and we will
630 follow along later in ::follow_slave()
633 _engine.transport_locate (target_frame);
635 if (sp != 1.0f && with_roll) {
636 _engine.transport_start ();
643 locate (target_frame, with_roll, with_flush, with_loop);
648 Session::micro_locate (nframes_t distance)
650 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
652 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
653 if (!(*i)->can_internal_playback_seek (distance)) {
658 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
659 (*i)->internal_playback_seek (distance);
662 _transport_frame += distance;
667 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
669 if (actively_recording() && !with_loop) {
673 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
675 set_transport_speed (1.0, false);
677 loop_changing = false;
681 _transport_frame = target_frame;
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 schedule_butler_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_smpte_update = true;
784 Session::set_transport_speed (float speed, bool abort)
786 if (_transport_speed == speed) {
791 speed = min (8.0f, speed);
792 } else if (speed < 0) {
793 speed = max (-8.0f, speed);
796 if (transport_rolling() && speed == 0.0) {
798 if (Config->get_monitoring_model() == HardwareMonitoring)
800 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
802 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
803 if ((*i)->record_enabled ()) {
804 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
805 (*i)->monitor_input (true);
810 if (synced_to_jack ()) {
811 _engine.transport_stop ();
813 stop_transport (abort);
816 } else if (transport_stopped() && speed == 1.0) {
818 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
822 if (Config->get_monitoring_model() == HardwareMonitoring) {
824 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
826 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
827 if (Config->get_auto_input() && (*i)->record_enabled ()) {
828 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
829 (*i)->monitor_input (false);
834 if (synced_to_jack()) {
835 _engine.transport_start ();
842 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
846 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
847 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
852 if (actively_recording()) {
856 if (speed > 0.0f && _transport_frame == current_end_frame()) {
860 if (speed < 0.0f && _transport_frame == 0) {
866 /* if we are reversing relative to the current speed, or relative to the speed
867 before the last stop, then we have to do extra work.
870 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
871 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
872 last_stop_frame = _transport_frame;
875 _last_transport_speed = _transport_speed;
876 _transport_speed = speed;
878 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
879 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
880 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
881 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
885 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
886 schedule_butler_transport_work ();
892 Session::stop_transport (bool abort)
894 if (_transport_speed == 0.0f) {
898 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
899 _worst_output_latency > current_block_size)
902 /* we need to capture the audio that has still not yet been received by the system
903 at the time the stop is requested, so we have to roll past that time.
905 we want to declick before stopping, so schedule the autostop for one
906 block before the actual end. we'll declick in the subsequent block,
907 and then we'll really be stopped.
910 Event *ev = new Event (Event::StopOnce, Event::Replace,
911 _transport_frame + _worst_output_latency - current_block_size,
915 transport_sub_state |= StopPendingCapture;
916 pending_abort = abort;
921 if ((transport_sub_state & PendingDeclickOut) == 0) {
922 transport_sub_state |= PendingDeclickOut;
923 /* we'll be called again after the declick */
924 pending_abort = abort;
928 realtime_stop (abort);
929 schedule_butler_transport_work ();
933 Session::start_transport ()
935 _last_roll_location = _transport_frame;
938 /* if record status is Enabled, move it to Recording. if its
939 already Recording, move it to Disabled.
942 switch (record_status()) {
944 if (!Config->get_punch_in()) {
951 disable_record (false);
959 transport_sub_state |= PendingDeclickIn;
960 _transport_speed = 1.0;
962 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
963 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
964 (*i)->realtime_set_speed ((*i)->speed(), true);
967 send_mmc_in_another_thread (MIDI::MachineControl::cmdDeferredPlay, 0);
969 TransportStateChange (); /* EMIT SIGNAL */
973 Session::post_transport ()
975 if (post_transport_work & PostTransportAudition) {
976 if (auditioner && auditioner->active()) {
977 process_function = &Session::process_audition;
979 process_function = &Session::process_with_events;
983 if (post_transport_work & PostTransportStop) {
985 transport_sub_state = 0;
988 if (post_transport_work & PostTransportLocate) {
990 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
994 transport_sub_state = 0;
1000 post_transport_work = PostTransportWork (0);
1004 Session::reset_rf_scale (nframes_t motion)
1006 cumulative_rf_motion += motion;
1008 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1010 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1012 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1024 Session::set_slave_source (SlaveSource src, bool stop_the_transport)
1026 bool reverse = false;
1027 bool non_rt_required = false;
1029 if (_transport_speed) {
1030 error << _("please stop the transport before adjusting slave settings") << endmsg;
1034 // if (src == JACK && Config->get_jack_time_master()) {
1043 if (_transport_speed < 0.0) {
1049 if (stop_the_transport) {
1057 _slave = new MTC_Slave (*this, *_mtc_port);
1060 catch (failed_constructor& err) {
1065 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1068 _desired_transport_speed = _transport_speed;
1072 _slave = new JACK_Slave (_engine.jack());
1073 _desired_transport_speed = _transport_speed;
1077 Config->set_slave_source (src);
1079 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1080 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1081 if (!(*i)->hidden()) {
1082 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1083 non_rt_required = true;
1085 (*i)->set_slaved (_slave);
1090 reverse_diskstream_buffers ();
1093 if (non_rt_required) {
1094 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1095 schedule_butler_transport_work ();
1102 Session::reverse_diskstream_buffers ()
1104 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1105 schedule_butler_transport_work ();
1109 Session::set_diskstream_speed (Diskstream* stream, float speed)
1111 if (stream->realtime_set_speed (speed, false)) {
1112 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1113 schedule_butler_transport_work ();
1119 Session::set_audio_range (list<AudioRange>& range)
1121 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1122 ev->audio_range = range;
1127 Session::request_play_range (bool yn)
1129 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1134 Session::set_play_range (bool yn)
1136 /* Called from event-processing context */
1138 if (_play_range != yn) {
1143 /* stop transport */
1144 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1151 Session::setup_auto_play ()
1153 /* Called from event-processing context */
1157 _clear_event_type (Event::RangeStop);
1158 _clear_event_type (Event::RangeLocate);
1164 list<AudioRange>::size_type sz = current_audio_range.size();
1168 list<AudioRange>::iterator i = current_audio_range.begin();
1169 list<AudioRange>::iterator next;
1171 while (i != current_audio_range.end()) {
1176 /* locating/stopping is subject to delays for declicking.
1179 nframes_t requested_frame = (*i).end;
1181 if (requested_frame > current_block_size) {
1182 requested_frame -= current_block_size;
1184 requested_frame = 0;
1187 if (next == current_audio_range.end()) {
1188 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1190 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1198 } else if (sz == 1) {
1200 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1205 /* now start rolling at the right place */
1207 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1212 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1214 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1215 ev->target2_frame = start;
1220 Session::request_bounded_roll (nframes_t start, nframes_t end)
1223 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1225 request_locate (start, true);
1229 Session::engine_halted ()
1233 /* there will be no more calls to process(), so
1234 we'd better clean up for ourselves, right now.
1236 but first, make sure the butler is out of
1240 g_atomic_int_set (&butler_should_do_transport_work, 0);
1241 post_transport_work = PostTransportWork (0);
1244 realtime_stop (false);
1245 non_realtime_stop (false, 0, ignored);
1246 transport_sub_state = 0;
1248 if (synced_to_jack()) {
1249 /* transport is already stopped, hence the second argument */
1250 set_slave_source (None, false);
1253 TransportStateChange (); /* EMIT SIGNAL */
1258 Session::xrun_recovery ()
1260 Xrun (transport_frame()); //EMIT SIGNAL
1262 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1264 /* it didn't actually halt, but we need
1265 to handle things in the same way.
1273 Session::update_latency_compensation (bool with_stop, bool abort)
1275 bool update_jack = false;
1277 if (_state_of_the_state & Deletion) {
1281 _worst_track_latency = 0;
1283 #undef DEBUG_LATENCY
1284 #ifdef DEBUG_LATENCY
1285 cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1288 boost::shared_ptr<RouteList> r = routes.reader ();
1290 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1292 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1293 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1296 nframes_t old_latency = (*i)->signal_latency ();
1297 nframes_t track_latency = (*i)->update_total_latency ();
1299 if (old_latency != track_latency) {
1303 if (!(*i)->hidden() && ((*i)->active())) {
1304 _worst_track_latency = max (_worst_track_latency, track_latency);
1308 #ifdef DEBUG_LATENCY
1309 cerr << "\tworst was " << _worst_track_latency << endl;
1312 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1313 (*i)->set_latency_delay (_worst_track_latency);
1316 /* tell JACK to play catch up */
1319 _engine.update_total_latencies ();
1322 set_worst_io_latencies ();
1324 /* reflect any changes in latencies into capture offsets
1327 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1329 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1330 (*i)->set_capture_offset ();
1335 Session::update_latency_compensation_proxy (void* ignored)
1337 update_latency_compensation (false, false);
1341 Session::allow_auto_play (bool yn)
1343 auto_play_legal = yn;
1347 Session::reset_jack_connection (jack_client_t* jack)
1351 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1352 js->reset_client (jack);