2 Copyright (C) 1999-2002 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.
25 #include "pbd/error.h"
26 #include "pbd/enumwriter.h"
28 #include <glibmm/threads.h>
30 #include "ardour/audioengine.h"
31 #include "ardour/auditioner.h"
32 #include "ardour/butler.h"
33 #include "ardour/cycle_timer.h"
34 #include "ardour/debug.h"
35 #include "ardour/disk_reader.h"
36 #include "ardour/graph.h"
37 #include "ardour/port.h"
38 #include "ardour/process_thread.h"
39 #include "ardour/scene_changer.h"
40 #include "ardour/session.h"
41 #include "ardour/transport_master.h"
42 #include "ardour/transport_master_manager.h"
43 #include "ardour/ticker.h"
44 #include "ardour/types.h"
45 #include "ardour/vca.h"
46 #include "ardour/vca_manager.h"
48 #include "midi++/mmc.h"
52 using namespace ARDOUR;
56 /** Called by the audio engine when there is work to be done with JACK.
57 * @param nframes Number of samples to process.
61 Session::process (pframes_t nframes)
63 samplepos_t transport_at_start = _transport_sample;
67 if (processing_blocked()) {
72 if (non_realtime_work_pending()) {
73 if (!_butler->transport_work_requested ()) {
78 _engine.main_thread()->get_buffers ();
80 (this->*process_function) (nframes);
82 /* realtime-safe meter-position and processor-order changes
84 * ideally this would be done in
85 * Route::process_output_buffers() but various functions
86 * callig it hold a _processor_lock reader-lock
88 boost::shared_ptr<RouteList> r = routes.reader ();
89 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
90 if ((*i)->apply_processor_changes_rt()) {
91 _rt_emit_pending = true;
94 if (_rt_emit_pending) {
95 if (!_rt_thread_active) {
96 emit_route_signals ();
98 if (pthread_mutex_trylock (&_rt_emit_mutex) == 0) {
99 pthread_cond_signal (&_rt_emit_cond);
100 pthread_mutex_unlock (&_rt_emit_mutex);
101 _rt_emit_pending = false;
105 _engine.main_thread()->drop_buffers ();
107 /* deliver MIDI clock. Note that we need to use the transport sample
108 * position at the start of process(), not the value at the end of
109 * it. We may already have ticked() because of a transport state
110 * change, for example.
114 if (!_silent && !_engine.freewheeling() && Config->get_send_midi_clock() && (transport_speed() == 1.0f || transport_speed() == 0.0f) && midi_clock->has_midi_port()) {
115 midi_clock->tick (transport_at_start, nframes);
118 _scene_changer->run (transport_at_start, transport_at_start + nframes);
121 /* don't bother with a message */
124 SendFeedback (); /* EMIT SIGNAL */
128 Session::fail_roll (pframes_t nframes)
130 return no_roll (nframes);
134 Session::no_roll (pframes_t nframes)
138 samplepos_t end_sample = _transport_sample + nframes; // FIXME: varispeed + no_roll ??
140 boost::shared_ptr<RouteList> r = routes.reader ();
143 _click_io->silence (nframes);
146 ltc_tx_send_time_code_for_cycle (_transport_sample, end_sample, _target_transport_speed, _transport_speed, nframes);
148 VCAList v = _vca_manager->vcas ();
149 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
150 (*i)->automation_run (_transport_sample, nframes);
153 if (_process_graph) {
154 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
155 _process_graph->routes_no_roll( nframes, _transport_sample, end_sample, non_realtime_work_pending());
157 PT_TIMING_CHECK (10);
158 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
160 if ((*i)->is_auditioner()) {
164 if ((*i)->no_roll (nframes, _transport_sample, end_sample, non_realtime_work_pending())) {
165 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
170 PT_TIMING_CHECK (11);
177 /** @param need_butler to be set to true by this method if it needs the butler,
178 * otherwise it must be left alone.
181 Session::process_routes (pframes_t nframes, bool& need_butler)
183 boost::shared_ptr<RouteList> r = routes.reader ();
185 const samplepos_t start_sample = _transport_sample;
186 const samplepos_t end_sample = _transport_sample + floor (nframes * _transport_speed);
188 VCAList v = _vca_manager->vcas ();
189 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
190 (*i)->automation_run (start_sample, nframes);
193 _global_locate_pending = locate_pending ();
195 if (_process_graph) {
196 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
197 if (_process_graph->process_routes (nframes, start_sample, end_sample, need_butler) < 0) {
203 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
207 if ((*i)->is_auditioner()) {
213 if ((ret = (*i)->roll (nframes, start_sample, end_sample, b)) < 0) {
219 DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 rolled and needs butler\n", (*i)->name()));
229 Session::get_track_statistics ()
234 boost::shared_ptr<RouteList> rl = routes.reader();
235 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
237 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
239 if (!tr || tr->is_private_route()) {
243 pworst = min (pworst, tr->playback_buffer_load());
244 cworst = min (cworst, tr->capture_buffer_load());
247 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
248 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
250 if (actively_recording()) {
256 Session::compute_audible_delta (samplepos_t& pos_and_delta) const
258 if (_transport_speed == 0.0 || _count_in_samples > 0 || _remaining_latency_preroll > 0) {
259 /* cannot compute audible delta, because the session is
260 generating silence that does not correspond to the timeline,
261 but is instead filling playback buffers to manage latency
264 DEBUG_TRACE (DEBUG::Slave, string_compose ("still adjusting for latency (%1) and/or count-in (%2) or stopped %1\n", _remaining_latency_preroll, _count_in_samples, _transport_speed));
268 pos_and_delta -= _transport_sample;
272 /** Process callback used when the auditioner is not active */
274 Session::process_with_events (pframes_t nframes)
279 pframes_t this_nframes;
280 samplepos_t end_sample;
281 bool session_needs_butler = false;
282 samplecnt_t samples_moved;
284 /* make sure the auditioner is silent */
287 auditioner->silence (nframes);
290 /* handle any pending events */
292 while (pending_events.read (&ev, 1) == 1) {
296 /* if we are not in the middle of a state change,
297 and there are immediate events queued up,
301 while (!non_realtime_work_pending() && !immediate_events.empty()) {
302 SessionEvent *ev = immediate_events.front ();
303 immediate_events.pop_front ();
306 /* only count-in when going to roll at speed 1.0 */
307 if (_transport_speed != 1.0 && _count_in_samples > 0) {
308 _count_in_samples = 0;
310 if (_transport_speed == 0.0) {
311 _remaining_latency_preroll = 0;
314 assert (_count_in_samples == 0 || _remaining_latency_preroll == 0 || _count_in_samples == _remaining_latency_preroll);
316 DEBUG_TRACE (DEBUG::Transport, string_compose ("Running count in/latency preroll of %1 & %2\n", _count_in_samples, _remaining_latency_preroll));
318 while (_count_in_samples > 0 || _remaining_latency_preroll > 0) {
321 if (_remaining_latency_preroll > 0) {
322 ns = std::min ((samplecnt_t)nframes, _remaining_latency_preroll);
324 ns = std::min ((samplecnt_t)nframes, _count_in_samples);
327 boost::shared_ptr<RouteList> r = routes.reader ();
328 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
329 samplecnt_t route_offset = (*i)->playback_latency ();
330 if (_remaining_latency_preroll > route_offset + ns) {
331 /* route will no-roll for complete pre-roll cycle */
334 if (_remaining_latency_preroll > route_offset) {
335 /* route may need partial no-roll and partial roll from
336 * (_transport_sample - _remaining_latency_preroll) .. +ns.
337 * shorten and split the cycle.
339 ns = std::min (ns, (_remaining_latency_preroll - route_offset));
343 if (_count_in_samples > 0) {
344 run_click (_transport_sample - _count_in_samples, ns);
345 assert (_count_in_samples >= ns);
346 _count_in_samples -= ns;
349 if (_remaining_latency_preroll > 0) {
350 if (_count_in_samples == 0) {
351 click (_transport_sample - _remaining_latency_preroll, ns);
353 if (process_routes (ns, session_needs_butler)) {
360 if (_remaining_latency_preroll > 0) {
361 assert (_remaining_latency_preroll >= ns);
362 _remaining_latency_preroll -= ns;
367 /* process events.. */
368 if (!events.empty() && next_event != events.end()) {
369 SessionEvent* this_event = *next_event;
370 Events::iterator the_next_one = next_event;
373 while (this_event && this_event->action_sample == _transport_sample) {
374 process_event (this_event);
375 if (the_next_one == events.end()) {
378 this_event = *the_next_one;
388 _engine.split_cycle (ns);
392 /* Decide on what to do with quarter-frame MTC during this cycle */
394 bool const was_sending_qf_mtc = _send_qf_mtc;
395 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
397 if (_transport_speed != 0) {
399 Config->get_send_mtc () &&
400 _transport_speed >= (1 - tolerance) &&
401 _transport_speed <= (1 + tolerance)
404 if (_send_qf_mtc && !was_sending_qf_mtc) {
405 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
406 _send_timecode_update = true;
409 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (sample_rate () / 4)) {
410 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
411 a quarter of a second since we sent anything at all, so send a full MTC update
414 _send_timecode_update = true;
417 _pframes_since_last_mtc += nframes;
420 /* Events caused a transport change (or we re-started sending
421 * MTC), so send an MTC Full Frame (Timecode) message. This
422 * is sent whether rolling or not, to give slaves an idea of
423 * ardour time on locates (and allow slow slaves to position
424 * and prepare for rolling)
426 if (_send_timecode_update) {
427 send_full_time_code (_transport_sample, nframes);
430 if (!process_can_proceed()) {
435 if (events.empty() || next_event == events.end()) {
436 try_run_lua (nframes); // also during export ?? ->move to process_without_events()
437 /* lua scripts may inject events */
438 while (_n_lua_scripts > 0 && pending_events.read (&ev, 1) == 1) {
441 if (events.empty() || next_event == events.end()) {
442 process_without_events (nframes);
447 assert (_transport_speed == 0 || _transport_speed == 1.0 || _transport_speed == -1.0);
449 samples_moved = (samplecnt_t) nframes * _transport_speed;
450 DEBUG_TRACE (DEBUG::Transport, string_compose ("plan to move transport by %1 (%2 @ %3)\n", samples_moved, nframes, _transport_speed));
452 end_sample = _transport_sample + samples_moved;
455 SessionEvent* this_event;
456 Events::iterator the_next_one;
458 if (!process_can_proceed()) {
463 if (!_exporting && config.get_external_sync()) {
464 if (!follow_transport_master (nframes)) {
465 ltc_tx_send_time_code_for_cycle (_transport_sample, end_sample, _target_transport_speed, _transport_speed, nframes);
470 if (_transport_speed == 0) {
475 if (!_exporting && !timecode_transmission_suspended()) {
476 send_midi_time_code_for_cycle (_transport_sample, end_sample, nframes);
479 ltc_tx_send_time_code_for_cycle (_transport_sample, end_sample, _target_transport_speed, _transport_speed, nframes);
481 samplepos_t stop_limit = compute_stop_limit ();
483 if (maybe_stop (stop_limit)) {
488 this_event = *next_event;
489 the_next_one = next_event;
492 /* yes folks, here it is, the actual loop where we really truly
498 this_nframes = nframes; /* real (jack) time relative */
499 samples_moved = (samplecnt_t) floor (_transport_speed * nframes); /* transport relative */
500 DEBUG_TRACE (DEBUG::Transport, string_compose ("sub-loop plan to move transport by %1 (%2 @ %3)\n", samples_moved, nframes, _transport_speed));
502 /* running an event, position transport precisely to its time */
503 if (this_event && this_event->action_sample <= end_sample && this_event->action_sample >= _transport_sample) {
504 /* this isn't quite right for reverse play */
505 samples_moved = (samplecnt_t) (this_event->action_sample - _transport_sample);
506 DEBUG_TRACE (DEBUG::Transport, string_compose ("sub-loop2 plan to move transport by %1 (%2 @ %3)\n", samples_moved, nframes, _transport_speed));
507 this_nframes = abs (floor(samples_moved / _transport_speed));
510 try_run_lua (this_nframes);
514 click (_transport_sample, this_nframes);
516 if (process_routes (this_nframes, session_needs_butler)) {
521 get_track_statistics ();
523 nframes -= this_nframes;
525 if (samples_moved < 0) {
526 decrement_transport_position (-samples_moved);
527 DEBUG_TRACE (DEBUG::Transport, string_compose ("DEcrement transport by %1 to %2\n", samples_moved, _transport_sample));
528 } else if (samples_moved) {
529 increment_transport_position (samples_moved);
530 DEBUG_TRACE (DEBUG::Transport, string_compose ("INcrement transport by %1 to %2\n", samples_moved, _transport_sample));
532 DEBUG_TRACE (DEBUG::Transport, "no transport motion\n");
535 maybe_stop (stop_limit);
539 _engine.split_cycle (this_nframes);
542 /* now handle this event and all others scheduled for the same time */
544 while (this_event && this_event->action_sample == _transport_sample) {
545 process_event (this_event);
547 if (the_next_one == events.end()) {
550 this_event = *the_next_one;
555 /* if an event left our state changing, do the right thing */
557 if (nframes && non_realtime_work_pending()) {
562 /* this is necessary to handle the case of seamless looping */
563 end_sample = _transport_sample + floor (nframes * _transport_speed);
568 } /* implicit release of route lock */
570 if (session_needs_butler) {
571 DEBUG_TRACE (DEBUG::Butler, "p-with-events: session needs butler, call it\n");
577 Session::transport_locked () const
579 if (!locate_pending() && (!config.get_external_sync() || (transport_master()->ok() && transport_master()->locked()))) {
587 Session::process_without_events (pframes_t nframes)
589 bool session_needs_butler = false;
590 samplecnt_t samples_moved;
592 if (!process_can_proceed()) {
597 if (!_exporting && config.get_external_sync()) {
598 if (!follow_transport_master (nframes)) {
599 ltc_tx_send_time_code_for_cycle (_transport_sample, _transport_sample, 0, 0 , nframes);
604 assert (_transport_speed == 0 || _transport_speed == 1.0 || _transport_speed == -1.0);
606 if (_transport_speed == 0) {
610 samples_moved = (samplecnt_t) nframes * _transport_speed;
611 DEBUG_TRACE (DEBUG::Transport, string_compose ("no-events, plan to move transport by %1 (%2 @ %3)\n", samples_moved, nframes, _transport_speed));
614 if (!_exporting && !timecode_transmission_suspended()) {
615 send_midi_time_code_for_cycle (_transport_sample, _transport_sample + samples_moved, nframes);
618 ltc_tx_send_time_code_for_cycle (_transport_sample, _transport_sample + samples_moved, _target_transport_speed, _transport_speed, nframes);
620 samplepos_t const stop_limit = compute_stop_limit ();
622 if (maybe_stop (stop_limit)) {
627 if (maybe_sync_start (nframes)) {
631 click (_transport_sample, nframes);
633 if (process_routes (nframes, session_needs_butler)) {
638 get_track_statistics ();
640 if (samples_moved < 0) {
641 decrement_transport_position (-samples_moved);
642 DEBUG_TRACE (DEBUG::Transport, string_compose ("DEcrement transport by %1 to %2\n", samples_moved, _transport_sample));
643 } else if (samples_moved) {
644 increment_transport_position (samples_moved);
645 DEBUG_TRACE (DEBUG::Transport, string_compose ("INcrement transport by %1 to %2\n", samples_moved, _transport_sample));
647 DEBUG_TRACE (DEBUG::Transport, "no transport motion\n");
650 maybe_stop (stop_limit);
652 if (session_needs_butler) {
653 DEBUG_TRACE (DEBUG::Butler, "p-without-events: session needs butler, call it\n");
658 /** Process callback used when the auditioner is active.
659 * @param nframes number of samples to process.
662 Session::process_audition (pframes_t nframes)
665 boost::shared_ptr<RouteList> r = routes.reader ();
667 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
668 if (!(*i)->is_auditioner()) {
669 (*i)->silence (nframes);
673 /* run the auditioner, and if it says we need butler service, ask for it */
675 if (auditioner->play_audition (nframes) > 0) {
676 DEBUG_TRACE (DEBUG::Butler, "auditioner needs butler, call it\n");
680 /* if using a monitor section, run it because otherwise we don't hear anything */
682 if (_monitor_out && auditioner->needs_monitor()) {
683 _monitor_out->monitor_run (_transport_sample, _transport_sample + nframes, nframes);
686 /* handle pending events */
688 while (pending_events.read (&ev, 1) == 1) {
692 /* if we are not in the middle of a state change,
693 and there are immediate events queued up,
697 while (!non_realtime_work_pending() && !immediate_events.empty()) {
698 SessionEvent *ev = immediate_events.front ();
699 immediate_events.pop_front ();
703 if (!auditioner->auditioning()) {
704 /* auditioner no longer active, so go back to the normal process callback */
705 process_function = &Session::process_with_events;
710 Session::maybe_sync_start (pframes_t & nframes)
712 pframes_t sync_offset;
714 if (!waiting_for_sync_offset) {
718 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
720 /* generate silence up to the sync point, then
721 adjust nframes + offset to reflect whatever
725 no_roll (sync_offset);
726 nframes -= sync_offset;
727 Port::increment_global_port_buffer_offset (sync_offset);
728 waiting_for_sync_offset = false;
731 return true; // done, nothing left to process
736 /* sync offset point is not within this process()
737 cycle, so just generate silence. and don't bother
738 with any fancy stuff here, just the minimal silence.
743 if (Config->get_locate_while_waiting_for_sync()) {
744 DEBUG_TRACE (DEBUG::Transport, "micro-locate while waiting for sync\n");
745 if (micro_locate (nframes)) {
746 /* XXX ERROR !!! XXX */
750 return true; // done, nothing left to process
757 Session::queue_event (SessionEvent* ev)
759 if (_state_of_the_state & Deletion) {
761 } else if (_state_of_the_state & Loading) {
764 Glib::Threads::Mutex::Lock lm (rb_write_lock);
765 pending_events.write (&ev, 1);
770 Session::set_next_event ()
772 if (events.empty()) {
773 next_event = events.end();
777 if (next_event == events.end()) {
778 next_event = events.begin();
781 if ((*next_event)->action_sample > _transport_sample) {
782 next_event = events.begin();
785 for (; next_event != events.end(); ++next_event) {
786 if ((*next_event)->action_sample >= _transport_sample) {
793 Session::process_event (SessionEvent* ev)
798 /* if we're in the middle of a state change (i.e. waiting
799 for the butler thread to complete the non-realtime
800 part of the change), we'll just have to queue this
801 event for a time when the change is complete.
804 if (non_realtime_work_pending()) {
806 /* except locates, which we have the capability to handle */
808 if (ev->type != SessionEvent::Locate) {
809 immediate_events.insert (immediate_events.end(), ev);
815 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_sample));
818 case SessionEvent::SetLoop:
819 set_play_loop (ev->yes_or_no, ev->speed);
822 case SessionEvent::AutoLoop:
824 /* roll after locate, do not flush, set "with loop"
825 true only if we are seamless looping
827 start_locate (ev->target_sample, true, false, Config->get_seamless_loop());
833 case SessionEvent::Locate:
834 if (ev->yes_or_no) { /* force locate */
835 /* args: do not roll after locate, do flush, not with loop */
836 locate (ev->target_sample, false, true, false);
838 /* args: do not roll after locate, do flush, not with loop */
839 start_locate (ev->target_sample, false, true, false);
841 _send_timecode_update = true;
844 case SessionEvent::LocateRoll:
846 /* args: roll after locate, do flush, not with loop */
847 locate (ev->target_sample, true, true, false);
849 /* args: roll after locate, do flush, not with loop */
850 start_locate (ev->target_sample, true, true, false);
852 _send_timecode_update = true;
855 case SessionEvent::Skip:
856 if (Config->get_skip_playback()) {
857 start_locate (ev->target_sample, true, true, false);
858 _send_timecode_update = true;
864 case SessionEvent::LocateRollLocate:
865 // locate is handled by ::request_roll_at_and_return()
866 _requested_return_sample = ev->target_sample;
867 request_locate (ev->target2_sample, true);
871 case SessionEvent::SetTransportSpeed:
872 set_transport_speed (ev->speed, ev->target_sample, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
875 case SessionEvent::SetTransportMaster:
876 TransportMasterManager::instance().set_current (ev->transport_master);
879 case SessionEvent::PunchIn:
880 // cerr << "PunchIN at " << transport_sample() << endl;
881 if (config.get_punch_in() && record_status() == Enabled) {
888 case SessionEvent::PunchOut:
889 // cerr << "PunchOUT at " << transport_sample() << endl;
890 if (config.get_punch_out()) {
891 step_back_from_record ();
897 case SessionEvent::StopOnce:
898 if (!non_realtime_work_pending()) {
899 _clear_event_type (SessionEvent::StopOnce);
900 stop_transport (ev->yes_or_no);
906 case SessionEvent::RangeStop:
907 if (!non_realtime_work_pending()) {
908 stop_transport (ev->yes_or_no);
914 case SessionEvent::RangeLocate:
915 /* args: roll after locate, do flush, not with loop */
916 start_locate (ev->target_sample, true, true, false);
921 case SessionEvent::Overwrite:
922 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
925 case SessionEvent::Audition:
926 set_audition (ev->region);
927 // drop reference to region
931 case SessionEvent::SetPlayAudioRange:
932 set_play_range (ev->audio_range, (ev->speed == 1.0f));
935 case SessionEvent::CancelPlayAudioRange:
939 case SessionEvent::RealTimeOperation:
941 del = false; // other side of RT request needs to clean up
944 case SessionEvent::AdjustPlaybackBuffering:
945 schedule_playback_buffering_adjustment ();
948 case SessionEvent::AdjustCaptureBuffering:
949 schedule_capture_buffering_adjustment ();
952 case SessionEvent::SetTimecodeTransmission:
953 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
957 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
958 abort(); /*NOTREACHED*/
963 del = del && !_remove_event (ev);
972 Session::compute_stop_limit () const
974 if (!Config->get_stop_at_session_end ()) {
975 return max_samplepos;
978 if (config.get_external_sync()) {
979 return max_samplepos;
982 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
983 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
985 if (actively_recording ()) {
986 /* permanently recording */
987 return max_samplepos;
988 } else if (punching_in && !punching_out) {
989 /* punching in but never out */
990 return max_samplepos;
991 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_sample()) {
992 /* punching in and punching out after session end */
993 return max_samplepos;
996 return current_end_sample ();
1001 /* dedicated thread for signal emission.
1003 * while sending cross-thread signals from the process thread
1004 * is fine in general, PBD::Signal's use of boost::function and
1005 * boost:bind can produce a vast overhead which is not
1006 * acceptable for low latency.
1008 * This works around the issue by moving the boost overhead
1009 * out of the RT thread. The overall load is probably higher but
1010 * the realtime thread remains unaffected.
1014 Session::emit_route_signals ()
1016 // TODO use RAII to allow using these signals in other places
1017 BatchUpdateStart(); /* EMIT SIGNAL */
1018 boost::shared_ptr<RouteList> r = routes.reader ();
1019 for (RouteList::const_iterator ci = r->begin(); ci != r->end(); ++ci) {
1020 (*ci)->emit_pending_signals ();
1022 BatchUpdateEnd(); /* EMIT SIGNAL */
1026 Session::emit_thread_start ()
1028 if (_rt_thread_active) {
1031 _rt_thread_active = true;
1033 if (pthread_create (&_rt_emit_thread, NULL, emit_thread, this)) {
1034 _rt_thread_active = false;
1039 Session::emit_thread_terminate ()
1041 if (!_rt_thread_active) {
1044 _rt_thread_active = false;
1046 if (pthread_mutex_lock (&_rt_emit_mutex) == 0) {
1047 pthread_cond_signal (&_rt_emit_cond);
1048 pthread_mutex_unlock (&_rt_emit_mutex);
1052 pthread_join (_rt_emit_thread, &status);
1056 Session::emit_thread (void *arg)
1058 Session *s = static_cast<Session *>(arg);
1059 s->emit_thread_run ();
1065 Session::emit_thread_run ()
1067 pthread_mutex_lock (&_rt_emit_mutex);
1068 while (_rt_thread_active) {
1069 emit_route_signals();
1070 pthread_cond_wait (&_rt_emit_cond, &_rt_emit_mutex);
1072 pthread_mutex_unlock (&_rt_emit_mutex);
1076 Session::follow_transport_master (pframes_t nframes)
1078 TransportMasterManager& tmm (TransportMasterManager::instance());
1081 samplepos_t slave_transport_sample;
1082 sampleoffset_t delta;
1084 if (tmm.master_invalid_this_cycle()) {
1085 DEBUG_TRACE (DEBUG::Slave, "session told not to use the transport master this cycle\n");
1089 slave_speed = tmm.get_current_speed_in_process_context();
1090 slave_transport_sample = tmm.get_current_position_in_process_context ();
1092 track_transport_master (slave_speed, slave_transport_sample);
1094 /* transport sample may have been moved during ::track_transport_master() */
1096 delta = _transport_sample - slave_transport_sample;
1098 DEBUG_TRACE (DEBUG::Slave, string_compose ("session at %1, master at %2, delta: %3 res: %4\n", _transport_sample, slave_transport_sample, delta, tmm.current()->resolution()));
1100 if (transport_master_tracking_state == Running) {
1102 if (!actively_recording() && abs (delta) > tmm.current()->resolution()) {
1103 DEBUG_TRACE (DEBUG::Slave, string_compose ("current slave delta %1 greater than slave resolution %2\n", delta, tmm.current()->resolution()));
1104 if (micro_locate (-delta) != 0) {
1105 DEBUG_TRACE (DEBUG::Slave, "micro-locate didn't work, set no disk output true\n");
1107 /* run routes as normal, but no disk output */
1108 DiskReader::set_no_disk_output (true);
1113 if (transport_master_tracking_state == Running) {
1114 /* speed is set, we're locked, and good to go */
1115 DiskReader::set_no_disk_output (false);
1121 /* don't move at all */
1122 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
1128 Session::track_transport_master (float slave_speed, samplepos_t slave_transport_sample)
1130 boost::shared_ptr<TransportMaster> master (TransportMasterManager::instance().current());
1134 DEBUG_TRACE (DEBUG::Slave, string_compose ("session has master tracking state as %1\n", transport_master_tracking_state));
1136 if (slave_speed != 0.0f) {
1138 /* slave is running */
1140 switch (transport_master_tracking_state) {
1142 master_wait_end = slave_transport_sample + worst_latency_preroll() + master->seekahead_distance ();
1143 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1, now WAITING\n", master_wait_end));
1144 /* we can call locate() here because we are in process context */
1145 if (micro_locate (master_wait_end - _transport_sample) != 0) {
1146 locate (master_wait_end, false, false);
1148 transport_master_tracking_state = Waiting;
1155 if (transport_master_tracking_state == Waiting) {
1157 DEBUG_TRACE (DEBUG::Slave, string_compose ("master currently at %1, waiting to pass %2\n", slave_transport_sample, master_wait_end));
1159 if (slave_transport_sample >= master_wait_end) {
1161 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_sample, _transport_sample));
1163 transport_master_tracking_state = Running;
1165 /* now perform a "micro-seek" within the disk buffers to realign ourselves
1166 precisely with the master.
1169 if (micro_locate (slave_transport_sample - _transport_sample) != 0) {
1170 cerr << "cannot micro-seek\n";
1176 if (transport_master_tracking_state == Running && _transport_speed == 0.0f) {
1177 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
1181 } else { // slave_speed is 0
1183 /* slave has stopped */
1185 if (_transport_speed != 0.0f) {
1186 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 sample %2 tf %3\n", slave_speed, slave_transport_sample, _transport_sample));
1190 if (slave_transport_sample != _transport_sample) {
1191 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_sample));
1192 force_locate (slave_transport_sample, false);
1195 reset_slave_state();
1200 Session::reset_slave_state ()
1202 transport_master_tracking_state = Stopped;
1203 DiskReader::set_no_disk_output (false);