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);
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, bool leave_rolling)
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, (leave_rolling ? 1.0 : 0.0), yn);
127 if (!leave_rolling && !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 decrement_transport_position (_worst_output_latency);
159 /* the duration change is not guaranteed to have happened, but is likely */
161 post_transport_work = PostTransportWork (post_transport_work | PostTransportDuration);
165 post_transport_work = PostTransportWork (post_transport_work | PostTransportAbort);
168 _clear_event_type (Event::StopOnce);
169 _clear_event_type (Event::RangeStop);
170 _clear_event_type (Event::RangeLocate);
172 disable_record (true);
174 reset_slave_state ();
176 _transport_speed = 0;
177 _target_transport_speed = 0;
179 if (config.get_use_video_sync()) {
180 waiting_for_sync_offset = true;
183 transport_sub_state = ((Config->get_slave_source() == None && config.get_auto_return()) ? AutoReturning : 0);
187 Session::butler_transport_work ()
191 boost::shared_ptr<RouteList> r = routes.reader ();
192 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
194 int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
197 if (post_transport_work & PostTransportCurveRealloc) {
198 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
199 (*i)->curve_reallocate();
203 if (post_transport_work & PostTransportInputChange) {
204 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
205 (*i)->non_realtime_input_change ();
209 if (post_transport_work & PostTransportSpeed) {
210 non_realtime_set_speed ();
213 if (post_transport_work & PostTransportReverse) {
216 cumulative_rf_motion = 0;
219 /* don't seek if locate will take care of that in non_realtime_stop() */
221 if (!(post_transport_work & PostTransportLocate)) {
223 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
224 if (!(*i)->hidden()) {
225 (*i)->non_realtime_locate (_transport_frame);
227 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
228 /* new request, stop seeking, and start again */
229 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
236 if (post_transport_work & PostTransportLocate) {
237 non_realtime_locate ();
240 if (post_transport_work & PostTransportStop) {
241 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
243 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
248 if (post_transport_work & PostTransportOverWrite) {
249 non_realtime_overwrite (on_entry, finished);
251 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
256 if (post_transport_work & PostTransportAudition) {
257 non_realtime_set_audition ();
260 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
264 Session::non_realtime_set_speed ()
266 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
268 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
269 (*i)->non_realtime_set_speed ();
274 Session::non_realtime_overwrite (int on_entry, bool& finished)
276 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
278 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
279 if ((*i)->pending_overwrite) {
280 (*i)->overwrite_existing_buffers ();
282 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
291 Session::non_realtime_locate ()
293 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
295 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
296 (*i)->non_realtime_locate (_transport_frame);
302 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
312 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
314 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
315 if ((*i)->get_captured_frames () != 0) {
321 /* stop and locate are merged here because they share a lot of common stuff */
324 now = localtime (&xnow);
327 auditioner->cancel_audition ();
331 cumulative_rf_motion = 0;
335 begin_reversible_command ("capture");
337 Location* loc = _locations.end_location();
338 bool change_end = false;
340 if (_transport_frame < loc->end()) {
342 /* stopped recording before current end */
344 if (config.get_end_marker_is_free()) {
346 /* first capture for this session, move end back to where we are */
351 } else if (_transport_frame > loc->end()) {
353 /* stopped recording after the current end, extend it */
359 XMLNode &before = loc->get_state();
360 loc->set_end(_transport_frame);
361 XMLNode &after = loc->get_state();
362 add_command (new MementoCommand<Location>(*loc, &before, &after));
365 config.set_end_marker_is_free (false);
366 _have_captured = true;
369 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
370 (*i)->transport_stopped (*now, xnow, abort);
373 boost::shared_ptr<RouteList> r = routes.reader ();
375 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
376 if (!(*i)->is_hidden()) {
377 (*i)->set_pending_declick (0);
382 commit_reversible_command ();
385 if (_engine.running()) {
386 update_latency_compensation (true, abort);
389 bool const auto_return_enabled =
390 (Config->get_slave_source() == None && config.get_auto_return());
392 if (auto_return_enabled ||
393 (post_transport_work & PostTransportLocate) ||
394 (_requested_return_frame >= 0) ||
397 if (pending_locate_flush) {
398 flush_all_inserts ();
401 if ((auto_return_enabled || synced_to_jack() || _requested_return_frame >= 0) &&
402 !(post_transport_work & PostTransportLocate)) {
404 /* no explicit locate queued */
406 bool do_locate = false;
408 if (_requested_return_frame >= 0) {
410 /* explicit return request pre-queued in event list. overrides everything else */
412 cerr << "explicit auto-return to " << _requested_return_frame << endl;
414 _transport_frame = _requested_return_frame;
418 if (config.get_auto_return()) {
422 /* don't try to handle loop play when synced to JACK */
424 if (!synced_to_jack()) {
426 Location *location = _locations.auto_loop_location();
429 _transport_frame = location->start();
431 _transport_frame = _last_roll_location;
436 } else if (_play_range) {
438 /* return to start of range */
440 if (!current_audio_range.empty()) {
441 _transport_frame = current_audio_range.front().start;
447 /* regular auto-return */
449 _transport_frame = _last_roll_location;
455 _requested_return_frame = -1;
458 _engine.transport_locate (_transport_frame);
464 /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
467 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
468 if (!(*i)->hidden()) {
469 (*i)->non_realtime_locate (_transport_frame);
471 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
473 /* we will be back */
480 send_full_time_code (0);
481 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
482 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
486 /* XXX its a little odd that we're doing this here
487 when realtime_stop(), which has already executed,
489 JLC - so let's not because it seems unnecessary and breaks loop record
492 if (!Config->get_latched_record_enable()) {
493 g_atomic_int_set (&_record_status, Disabled);
495 g_atomic_int_set (&_record_status, Enabled);
497 RecordStateChanged (); /* emit signal */
501 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
502 /* capture start has been changed, so save pending state */
503 save_state ("", true);
507 /* always try to get rid of this */
509 remove_pending_capture_state ();
511 /* save the current state of things if appropriate */
513 if (did_record && !saved) {
514 save_state (_current_snapshot_name);
517 if (post_transport_work & PostTransportDuration) {
518 DurationChanged (); /* EMIT SIGNAL */
521 if (post_transport_work & PostTransportStop) {
526 nframes_t tf = _transport_frame;
528 PositionChanged (tf); /* EMIT SIGNAL */
529 TransportStateChange (); /* EMIT SIGNAL */
531 /* and start it up again if relevant */
533 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
534 request_transport_speed (1.0);
535 pending_locate_roll = false;
540 Session::check_declick_out ()
542 bool locate_required = transport_sub_state & PendingLocate;
544 /* this is called after a process() iteration. if PendingDeclickOut was set,
545 it means that we were waiting to declick the output (which has just been
546 done) before doing something else. this is where we do that "something else".
548 note: called from the audio thread.
551 if (transport_sub_state & PendingDeclickOut) {
553 if (locate_required) {
554 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
555 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
557 stop_transport (pending_abort);
558 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
564 Session::set_play_loop (bool yn, bool leave_rolling)
566 /* Called from event-handling context */
570 if (yn == play_loop) {
574 if ((actively_recording() && yn) || (loc = _locations.auto_loop_location()) == 0) {
580 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
581 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
582 "Recommend changing the configured options")
588 if ((play_loop = yn)) {
592 set_play_range (false, true);
594 if (Config->get_seamless_loop()) {
595 // set all diskstreams to 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()) {
599 (*i)->set_loop (loc);
604 // set all diskstreams to NOT use internal looping
605 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
606 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
607 if (!(*i)->hidden()) {
613 /* stick in the loop event */
615 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
619 // locate to start of loop and roll
620 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
626 clear_events (Event::AutoLoop);
628 // set all diskstreams to NOT use internal looping
629 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
630 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
631 if (!(*i)->hidden()) {
637 TransportStateChange (); /* EMIT SIGNAL */
641 Session::flush_all_inserts ()
643 boost::shared_ptr<RouteList> r = routes.reader ();
645 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
646 (*i)->flush_processors ();
651 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
653 if (synced_to_jack()) {
658 _slave->speed_and_position (sp, pos);
660 if (target_frame != pos) {
662 /* tell JACK to change transport position, and we will
663 follow along later in ::follow_slave()
666 _engine.transport_locate (target_frame);
668 if (sp != 1.0f && with_roll) {
669 _engine.transport_start ();
675 locate (target_frame, with_roll, with_flush, with_loop);
680 Session::micro_locate (nframes_t distance)
682 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
684 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
685 if (!(*i)->can_internal_playback_seek (distance)) {
690 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
691 (*i)->internal_playback_seek (distance);
694 _transport_frame += distance;
699 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
701 if (actively_recording() && !with_loop) {
705 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
707 set_transport_speed (1.0, false);
709 loop_changing = false;
713 // Update Timecode time
714 // [DR] FIXME: find out exactly where this should go below
715 _transport_frame = target_frame;
716 timecode_time(_transport_frame, transmitting_timecode_time);
717 outbound_mtc_timecode_frame = _transport_frame;
718 next_quarter_frame_to_send = 0;
720 if (_transport_speed && (!with_loop || loop_changing)) {
721 /* schedule a declick. we'll be called again when its done */
723 if (!(transport_sub_state & PendingDeclickOut)) {
724 transport_sub_state |= (PendingDeclickOut|PendingLocate);
725 pending_locate_frame = target_frame;
726 pending_locate_roll = with_roll;
727 pending_locate_flush = with_flush;
732 if (transport_rolling() && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
733 realtime_stop (false);
736 if ( !with_loop || loop_changing) {
738 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
741 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
744 _butler->schedule_transport_work ();
748 /* this is functionally what clear_clicks() does but with a tentative lock */
750 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
752 if (clickm.locked()) {
754 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
763 /* switch from input if we're going to roll */
764 if (Config->get_monitoring_model() == HardwareMonitoring) {
766 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
768 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
769 if ((*i)->record_enabled ()) {
770 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
771 (*i)->monitor_input (!config.get_auto_input());
776 /* otherwise we're going to stop, so do the opposite */
777 if (Config->get_monitoring_model() == HardwareMonitoring) {
778 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
780 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
781 if ((*i)->record_enabled ()) {
782 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
783 (*i)->monitor_input (true);
789 /* cancel looped playback if transport pos outside of loop range */
791 Location* al = _locations.auto_loop_location();
793 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
794 // cancel looping directly, this is called from event handling context
795 set_play_loop (false, false);
797 else if (al && _transport_frame == al->start()) {
799 // this is only necessary for seamless looping
801 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
803 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
804 if ((*i)->record_enabled ()) {
805 // tell it we've looped, so it can deal with the record state
806 (*i)->transport_looped(_transport_frame);
811 TransportLooped(); // EMIT SIGNAL
815 loop_changing = false;
817 _send_timecode_update = true;
819 Located (); /* EMIT SIGNAL */
822 /** Set the transport speed.
823 * @param speed New speed
827 Session::set_transport_speed (double speed, bool abort)
829 if (_transport_speed == speed) {
833 _target_transport_speed = fabs(speed);
835 /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
836 and user needs. We really need CD-style "skip" playback for ffwd and rewind.
840 speed = min (8.0, speed);
841 } else if (speed < 0) {
842 speed = max (-8.0, speed);
845 if (transport_rolling() && speed == 0.0) {
847 /* we are rolling and we want to stop */
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 ((*i)->record_enabled ()) {
855 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
856 (*i)->monitor_input (true);
861 if (synced_to_jack ()) {
862 _engine.transport_stop ();
864 stop_transport (abort);
867 } else if (transport_stopped() && speed == 1.0) {
869 /* we are stopped and we want to start rolling at speed 1 */
871 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
875 if (Config->get_monitoring_model() == HardwareMonitoring) {
877 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
879 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
880 if (config.get_auto_input() && (*i)->record_enabled ()) {
881 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
882 (*i)->monitor_input (false);
887 if (synced_to_jack()) {
888 _engine.transport_start ();
895 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
899 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
900 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
905 if (actively_recording()) {
909 if (speed > 0.0 && _transport_frame == current_end_frame()) {
913 if (speed < 0.0 && _transport_frame == 0) {
919 /* if we are reversing relative to the current speed, or relative to the speed
920 before the last stop, then we have to do extra work.
923 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
924 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
927 _last_transport_speed = _transport_speed;
928 _transport_speed = speed;
930 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
931 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
932 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
933 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
937 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
938 _butler->schedule_transport_work ();
944 /** Stop the transport. */
946 Session::stop_transport (bool abort)
948 if (_transport_speed == 0.0f) {
952 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
953 _worst_output_latency > current_block_size)
956 /* we need to capture the audio that has still not yet been received by the system
957 at the time the stop is requested, so we have to roll past that time.
959 we want to declick before stopping, so schedule the autostop for one
960 block before the actual end. we'll declick in the subsequent block,
961 and then we'll really be stopped.
964 Event *ev = new Event (Event::StopOnce, Event::Replace,
965 _transport_frame + _worst_output_latency - current_block_size,
969 transport_sub_state |= StopPendingCapture;
970 pending_abort = abort;
975 if ((transport_sub_state & PendingDeclickOut) == 0) {
976 transport_sub_state |= PendingDeclickOut;
977 /* we'll be called again after the declick */
978 pending_abort = abort;
982 realtime_stop (abort);
983 _butler->schedule_transport_work ();
987 Session::start_transport ()
989 _last_roll_location = _transport_frame;
992 /* if record status is Enabled, move it to Recording. if its
993 already Recording, move it to Disabled.
996 switch (record_status()) {
998 if (!config.get_punch_in()) {
1005 disable_record (false);
1013 transport_sub_state |= PendingDeclickIn;
1015 _transport_speed = 1.0;
1016 _target_transport_speed = 1.0;
1018 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1019 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1020 (*i)->realtime_set_speed ((*i)->speed(), true);
1023 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
1025 TransportStateChange (); /* EMIT SIGNAL */
1028 /** Do any transport work in the audio thread that needs to be done after the
1029 * transport thread is finished. Audio thread, realtime safe.
1032 Session::post_transport ()
1034 if (post_transport_work & PostTransportAudition) {
1035 if (auditioner && auditioner->active()) {
1036 process_function = &Session::process_audition;
1038 process_function = &Session::process_with_events;
1042 if (post_transport_work & PostTransportStop) {
1044 transport_sub_state = 0;
1047 if (post_transport_work & PostTransportLocate) {
1049 if (((Config->get_slave_source() == None && (auto_play_legal && config.get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
1053 transport_sub_state = 0;
1059 post_transport_work = PostTransportWork (0);
1063 Session::reset_rf_scale (nframes_t motion)
1065 cumulative_rf_motion += motion;
1067 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1069 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1071 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1083 Session::set_slave_source (SlaveSource src)
1085 bool reverse = false;
1086 bool non_rt_required = false;
1088 if (_transport_speed) {
1089 error << _("please stop the transport before adjusting slave settings") << endmsg;
1093 // if (src == JACK && Config->get_jack_time_master()) {
1100 if (_transport_speed < 0.0) {
1112 _slave = new MTC_Slave (*this, *_mtc_port);
1115 catch (failed_constructor& err) {
1120 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1126 if (_midi_clock_port) {
1128 _slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24);
1131 catch (failed_constructor& err) {
1136 error << _("No MIDI Clock port defined: MIDI Clock slaving is impossible.") << endmsg;
1142 _slave = new JACK_Slave (_engine.jack());
1147 Config->set_slave_source (src);
1149 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1150 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1151 if (!(*i)->hidden()) {
1152 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1153 non_rt_required = true;
1155 (*i)->set_slaved (_slave);
1160 reverse_diskstream_buffers ();
1163 if (non_rt_required) {
1164 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1165 _butler->schedule_transport_work ();
1172 Session::reverse_diskstream_buffers ()
1174 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1175 _butler->schedule_transport_work ();
1179 Session::set_diskstream_speed (Diskstream* stream, double speed)
1181 if (stream->realtime_set_speed (speed, false)) {
1182 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1183 _butler->schedule_transport_work ();
1189 Session::set_audio_range (list<AudioRange>& range)
1191 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1192 ev->audio_range = range;
1197 Session::request_play_range (bool yn, bool leave_rolling)
1199 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, (leave_rolling ? 1.0f : 0.0f), yn);
1204 Session::set_play_range (bool yn, bool leave_rolling)
1206 /* Called from event-processing context */
1209 /* cancel loop play */
1210 set_play_range (false, true);
1217 if (!_play_range && !leave_rolling) {
1218 /* stop transport */
1219 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1222 TransportStateChange (); /* EMIT SIGNAL */
1226 Session::setup_auto_play ()
1228 /* Called from event-processing context */
1232 _clear_event_type (Event::RangeStop);
1233 _clear_event_type (Event::RangeLocate);
1239 list<AudioRange>::size_type sz = current_audio_range.size();
1243 list<AudioRange>::iterator i = current_audio_range.begin();
1244 list<AudioRange>::iterator next;
1246 while (i != current_audio_range.end()) {
1251 /* locating/stopping is subject to delays for declicking.
1254 nframes_t requested_frame = (*i).end;
1256 if (requested_frame > current_block_size) {
1257 requested_frame -= current_block_size;
1259 requested_frame = 0;
1262 if (next == current_audio_range.end()) {
1263 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1265 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1273 } else if (sz == 1) {
1275 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1280 /* now start rolling at the right place */
1282 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1287 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1289 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1290 ev->target2_frame = start;
1295 Session::request_bounded_roll (nframes_t start, nframes_t end)
1297 Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1299 request_locate (start, true);
1303 Session::engine_halted ()
1307 /* there will be no more calls to process(), so
1308 we'd better clean up for ourselves, right now.
1310 but first, make sure the butler is out of
1314 g_atomic_int_set (&_butler->should_do_transport_work, 0);
1315 post_transport_work = PostTransportWork (0);
1318 realtime_stop (false);
1319 non_realtime_stop (false, 0, ignored);
1320 transport_sub_state = 0;
1322 TransportStateChange (); /* EMIT SIGNAL */
1327 Session::xrun_recovery ()
1329 Xrun (transport_frame()); //EMIT SIGNAL
1331 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1333 /* it didn't actually halt, but we need
1334 to handle things in the same way.
1342 Session::update_latency_compensation (bool with_stop, bool abort)
1344 bool update_jack = false;
1346 if (_state_of_the_state & Deletion) {
1350 _worst_track_latency = 0;
1352 #undef DEBUG_LATENCY
1353 #ifdef DEBUG_LATENCY
1354 cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1357 boost::shared_ptr<RouteList> r = routes.reader ();
1359 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1362 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1363 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1366 nframes_t old_latency = (*i)->output()->signal_latency ();
1367 nframes_t track_latency = (*i)->update_total_latency ();
1369 if (old_latency != track_latency) {
1370 (*i)->input()->update_port_total_latencies ();
1371 (*i)->output()->update_port_total_latencies ();
1375 if (!(*i)->is_hidden() && ((*i)->active())) {
1376 _worst_track_latency = max (_worst_track_latency, track_latency);
1381 _engine.update_total_latencies ();
1384 #ifdef DEBUG_LATENCY
1385 cerr << "\tworst was " << _worst_track_latency << endl;
1388 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1389 (*i)->set_latency_delay (_worst_track_latency);
1392 set_worst_io_latencies ();
1394 /* reflect any changes in latencies into capture offsets
1397 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1399 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1400 (*i)->set_capture_offset ();
1405 Session::allow_auto_play (bool yn)
1407 auto_play_legal = yn;
1411 Session::reset_jack_connection (jack_client_t* jack)
1415 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1416 js->reset_client (jack);
1421 Session::maybe_stop (nframes_t limit)
1423 if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
1424 if (synced_to_jack () && config.get_jack_time_master ()) {
1425 _engine.transport_stop ();
1426 } else if (!synced_to_jack ()) {