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;
451 end_sample = _transport_sample + samples_moved;
454 SessionEvent* this_event;
455 Events::iterator the_next_one;
457 if (!process_can_proceed()) {
462 if (!_exporting && config.get_external_sync()) {
463 if (!follow_transport_master (nframes)) {
464 ltc_tx_send_time_code_for_cycle (_transport_sample, end_sample, _target_transport_speed, _transport_speed, nframes);
469 if (_transport_speed == 0) {
474 if (!_exporting && !timecode_transmission_suspended()) {
475 send_midi_time_code_for_cycle (_transport_sample, end_sample, nframes);
478 ltc_tx_send_time_code_for_cycle (_transport_sample, end_sample, _target_transport_speed, _transport_speed, nframes);
480 samplepos_t stop_limit = compute_stop_limit ();
482 if (maybe_stop (stop_limit)) {
487 this_event = *next_event;
488 the_next_one = next_event;
491 /* yes folks, here it is, the actual loop where we really truly
497 this_nframes = nframes; /* real (jack) time relative */
498 samples_moved = (samplecnt_t) floor (_transport_speed * nframes); /* transport relative */
500 /* running an event, position transport precisely to its time */
501 if (this_event && this_event->action_sample <= end_sample && this_event->action_sample >= _transport_sample) {
502 /* this isn't quite right for reverse play */
503 samples_moved = (samplecnt_t) (this_event->action_sample - _transport_sample);
504 this_nframes = abs (floor(samples_moved / _transport_speed));
507 try_run_lua (this_nframes);
511 click (_transport_sample, this_nframes);
513 if (process_routes (this_nframes, session_needs_butler)) {
518 get_track_statistics ();
520 nframes -= this_nframes;
522 if (samples_moved < 0) {
523 decrement_transport_position (-samples_moved);
524 } else if (samples_moved) {
525 increment_transport_position (samples_moved);
528 maybe_stop (stop_limit);
532 _engine.split_cycle (this_nframes);
535 /* now handle this event and all others scheduled for the same time */
537 while (this_event && this_event->action_sample == _transport_sample) {
538 process_event (this_event);
540 if (the_next_one == events.end()) {
543 this_event = *the_next_one;
548 /* if an event left our state changing, do the right thing */
550 if (nframes && non_realtime_work_pending()) {
555 /* this is necessary to handle the case of seamless looping */
556 end_sample = _transport_sample + floor (nframes * _transport_speed);
561 } /* implicit release of route lock */
563 if (session_needs_butler) {
564 DEBUG_TRACE (DEBUG::Butler, "p-with-events: session needs butler, call it\n");
570 Session::transport_locked () const
572 if (!locate_pending() && (!config.get_external_sync() || (transport_master()->ok() && transport_master()->locked()))) {
580 Session::process_without_events (pframes_t nframes)
582 bool session_needs_butler = false;
583 samplecnt_t samples_moved;
585 if (!process_can_proceed()) {
590 if (!_exporting && config.get_external_sync()) {
591 if (!follow_transport_master (nframes)) {
592 ltc_tx_send_time_code_for_cycle (_transport_sample, _transport_sample, 0, 0 , nframes);
597 assert (_transport_speed == 0 || _transport_speed == 1.0 || _transport_speed == -1.0);
599 if (_transport_speed == 0) {
603 samples_moved = (samplecnt_t) nframes * _transport_speed;
606 if (!_exporting && !timecode_transmission_suspended()) {
607 send_midi_time_code_for_cycle (_transport_sample, _transport_sample + samples_moved, nframes);
610 ltc_tx_send_time_code_for_cycle (_transport_sample, _transport_sample + samples_moved, _target_transport_speed, _transport_speed, nframes);
612 samplepos_t const stop_limit = compute_stop_limit ();
614 if (maybe_stop (stop_limit)) {
619 if (maybe_sync_start (nframes)) {
623 click (_transport_sample, nframes);
625 if (process_routes (nframes, session_needs_butler)) {
630 get_track_statistics ();
632 if (samples_moved < 0) {
633 decrement_transport_position (-samples_moved);
634 } else if (samples_moved) {
635 increment_transport_position (samples_moved);
638 maybe_stop (stop_limit);
640 if (session_needs_butler) {
641 DEBUG_TRACE (DEBUG::Butler, "p-without-events: session needs butler, call it\n");
646 /** Process callback used when the auditioner is active.
647 * @param nframes number of samples to process.
650 Session::process_audition (pframes_t nframes)
653 boost::shared_ptr<RouteList> r = routes.reader ();
655 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
656 if (!(*i)->is_auditioner()) {
657 (*i)->silence (nframes);
661 /* run the auditioner, and if it says we need butler service, ask for it */
663 if (auditioner->play_audition (nframes) > 0) {
664 DEBUG_TRACE (DEBUG::Butler, "auditioner needs butler, call it\n");
668 /* if using a monitor section, run it because otherwise we don't hear anything */
670 if (_monitor_out && auditioner->needs_monitor()) {
671 _monitor_out->monitor_run (_transport_sample, _transport_sample + nframes, nframes);
674 /* handle pending events */
676 while (pending_events.read (&ev, 1) == 1) {
680 /* if we are not in the middle of a state change,
681 and there are immediate events queued up,
685 while (!non_realtime_work_pending() && !immediate_events.empty()) {
686 SessionEvent *ev = immediate_events.front ();
687 immediate_events.pop_front ();
691 if (!auditioner->auditioning()) {
692 /* auditioner no longer active, so go back to the normal process callback */
693 process_function = &Session::process_with_events;
698 Session::maybe_sync_start (pframes_t & nframes)
700 pframes_t sync_offset;
702 if (!waiting_for_sync_offset) {
706 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
708 /* generate silence up to the sync point, then
709 adjust nframes + offset to reflect whatever
713 no_roll (sync_offset);
714 nframes -= sync_offset;
715 Port::increment_global_port_buffer_offset (sync_offset);
716 waiting_for_sync_offset = false;
719 return true; // done, nothing left to process
724 /* sync offset point is not within this process()
725 cycle, so just generate silence. and don't bother
726 with any fancy stuff here, just the minimal silence.
731 if (Config->get_locate_while_waiting_for_sync()) {
732 DEBUG_TRACE (DEBUG::Transport, "micro-locate while waiting for sync\n");
733 if (micro_locate (nframes)) {
734 /* XXX ERROR !!! XXX */
738 return true; // done, nothing left to process
745 Session::queue_event (SessionEvent* ev)
747 if (_state_of_the_state & Deletion) {
749 } else if (_state_of_the_state & Loading) {
752 Glib::Threads::Mutex::Lock lm (rb_write_lock);
753 pending_events.write (&ev, 1);
758 Session::set_next_event ()
760 if (events.empty()) {
761 next_event = events.end();
765 if (next_event == events.end()) {
766 next_event = events.begin();
769 if ((*next_event)->action_sample > _transport_sample) {
770 next_event = events.begin();
773 for (; next_event != events.end(); ++next_event) {
774 if ((*next_event)->action_sample >= _transport_sample) {
781 Session::process_event (SessionEvent* ev)
786 /* if we're in the middle of a state change (i.e. waiting
787 for the butler thread to complete the non-realtime
788 part of the change), we'll just have to queue this
789 event for a time when the change is complete.
792 if (non_realtime_work_pending()) {
794 /* except locates, which we have the capability to handle */
796 if (ev->type != SessionEvent::Locate) {
797 immediate_events.insert (immediate_events.end(), ev);
803 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_sample));
806 case SessionEvent::SetLoop:
807 set_play_loop (ev->yes_or_no, ev->speed);
810 case SessionEvent::AutoLoop:
812 /* roll after locate, do not flush, set "with loop"
813 true only if we are seamless looping
815 start_locate (ev->target_sample, true, false, Config->get_seamless_loop());
821 case SessionEvent::Locate:
822 if (ev->yes_or_no) { /* force locate */
823 /* args: do not roll after locate, do flush, not with loop */
824 locate (ev->target_sample, false, true, false);
826 /* args: do not roll after locate, do flush, not with loop */
827 start_locate (ev->target_sample, false, true, false);
829 _send_timecode_update = true;
832 case SessionEvent::LocateRoll:
834 /* args: roll after locate, do flush, not with loop */
835 locate (ev->target_sample, true, true, false);
837 /* args: roll after locate, do flush, not with loop */
838 start_locate (ev->target_sample, true, true, false);
840 _send_timecode_update = true;
843 case SessionEvent::Skip:
844 if (Config->get_skip_playback()) {
845 start_locate (ev->target_sample, true, true, false);
846 _send_timecode_update = true;
852 case SessionEvent::LocateRollLocate:
853 // locate is handled by ::request_roll_at_and_return()
854 _requested_return_sample = ev->target_sample;
855 request_locate (ev->target2_sample, true);
859 case SessionEvent::SetTransportSpeed:
860 set_transport_speed (ev->speed, ev->target_sample, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
863 case SessionEvent::SetTransportMaster:
864 TransportMasterManager::instance().set_current (ev->transport_master);
867 case SessionEvent::PunchIn:
868 // cerr << "PunchIN at " << transport_sample() << endl;
869 if (config.get_punch_in() && record_status() == Enabled) {
876 case SessionEvent::PunchOut:
877 // cerr << "PunchOUT at " << transport_sample() << endl;
878 if (config.get_punch_out()) {
879 step_back_from_record ();
885 case SessionEvent::StopOnce:
886 if (!non_realtime_work_pending()) {
887 _clear_event_type (SessionEvent::StopOnce);
888 stop_transport (ev->yes_or_no);
894 case SessionEvent::RangeStop:
895 if (!non_realtime_work_pending()) {
896 stop_transport (ev->yes_or_no);
902 case SessionEvent::RangeLocate:
903 /* args: roll after locate, do flush, not with loop */
904 start_locate (ev->target_sample, true, true, false);
909 case SessionEvent::Overwrite:
910 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
913 case SessionEvent::Audition:
914 set_audition (ev->region);
915 // drop reference to region
919 case SessionEvent::SetPlayAudioRange:
920 set_play_range (ev->audio_range, (ev->speed == 1.0f));
923 case SessionEvent::CancelPlayAudioRange:
927 case SessionEvent::RealTimeOperation:
929 del = false; // other side of RT request needs to clean up
932 case SessionEvent::AdjustPlaybackBuffering:
933 schedule_playback_buffering_adjustment ();
936 case SessionEvent::AdjustCaptureBuffering:
937 schedule_capture_buffering_adjustment ();
940 case SessionEvent::SetTimecodeTransmission:
941 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
945 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
946 abort(); /*NOTREACHED*/
951 del = del && !_remove_event (ev);
960 Session::compute_stop_limit () const
962 if (!Config->get_stop_at_session_end ()) {
963 return max_samplepos;
966 if (config.get_external_sync()) {
967 return max_samplepos;
970 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
971 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
973 if (actively_recording ()) {
974 /* permanently recording */
975 return max_samplepos;
976 } else if (punching_in && !punching_out) {
977 /* punching in but never out */
978 return max_samplepos;
979 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_sample()) {
980 /* punching in and punching out after session end */
981 return max_samplepos;
984 return current_end_sample ();
989 /* dedicated thread for signal emission.
991 * while sending cross-thread signals from the process thread
992 * is fine in general, PBD::Signal's use of boost::function and
993 * boost:bind can produce a vast overhead which is not
994 * acceptable for low latency.
996 * This works around the issue by moving the boost overhead
997 * out of the RT thread. The overall load is probably higher but
998 * the realtime thread remains unaffected.
1002 Session::emit_route_signals ()
1004 // TODO use RAII to allow using these signals in other places
1005 BatchUpdateStart(); /* EMIT SIGNAL */
1006 boost::shared_ptr<RouteList> r = routes.reader ();
1007 for (RouteList::const_iterator ci = r->begin(); ci != r->end(); ++ci) {
1008 (*ci)->emit_pending_signals ();
1010 BatchUpdateEnd(); /* EMIT SIGNAL */
1014 Session::emit_thread_start ()
1016 if (_rt_thread_active) {
1019 _rt_thread_active = true;
1021 if (pthread_create (&_rt_emit_thread, NULL, emit_thread, this)) {
1022 _rt_thread_active = false;
1027 Session::emit_thread_terminate ()
1029 if (!_rt_thread_active) {
1032 _rt_thread_active = false;
1034 if (pthread_mutex_lock (&_rt_emit_mutex) == 0) {
1035 pthread_cond_signal (&_rt_emit_cond);
1036 pthread_mutex_unlock (&_rt_emit_mutex);
1040 pthread_join (_rt_emit_thread, &status);
1044 Session::emit_thread (void *arg)
1046 Session *s = static_cast<Session *>(arg);
1047 s->emit_thread_run ();
1053 Session::emit_thread_run ()
1055 pthread_mutex_lock (&_rt_emit_mutex);
1056 while (_rt_thread_active) {
1057 emit_route_signals();
1058 pthread_cond_wait (&_rt_emit_cond, &_rt_emit_mutex);
1060 pthread_mutex_unlock (&_rt_emit_mutex);
1064 Session::follow_transport_master (pframes_t nframes)
1066 TransportMasterManager& tmm (TransportMasterManager::instance());
1069 samplepos_t slave_transport_sample;
1070 sampleoffset_t delta;
1072 if (tmm.master_invalid_this_cycle()) {
1073 DEBUG_TRACE (DEBUG::Slave, "session told not to use the transport master this cycle\n");
1077 slave_speed = tmm.get_current_speed_in_process_context();
1078 slave_transport_sample = tmm.get_current_position_in_process_context ();
1080 track_transport_master (slave_speed, slave_transport_sample);
1082 /* transport sample may have been moved during ::track_transport_master() */
1084 delta = _transport_sample - slave_transport_sample;
1086 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()));
1088 if (transport_master_tracking_state == Running) {
1090 if (!actively_recording() && abs (delta) > tmm.current()->resolution()) {
1091 DEBUG_TRACE (DEBUG::Slave, string_compose ("current slave delta %1 greater than slave resolution %2\n", delta, tmm.current()->resolution()));
1092 if (micro_locate (-delta) != 0) {
1093 DEBUG_TRACE (DEBUG::Slave, "micro-locate didn't work, set no disk output true\n");
1095 /* run routes as normal, but no disk output */
1096 DiskReader::set_no_disk_output (true);
1101 if (transport_master_tracking_state == Running) {
1102 /* speed is set, we're locked, and good to go */
1103 DiskReader::set_no_disk_output (false);
1109 /* don't move at all */
1110 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
1116 Session::track_transport_master (float slave_speed, samplepos_t slave_transport_sample)
1118 boost::shared_ptr<TransportMaster> master (TransportMasterManager::instance().current());
1122 DEBUG_TRACE (DEBUG::Slave, string_compose ("session has master tracking state as %1\n", transport_master_tracking_state));
1124 if (slave_speed != 0.0f) {
1126 /* slave is running */
1128 switch (transport_master_tracking_state) {
1130 master_wait_end = slave_transport_sample + worst_latency_preroll() + master->seekahead_distance ();
1131 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1, now WAITING\n", master_wait_end));
1132 /* we can call locate() here because we are in process context */
1133 if (micro_locate (master_wait_end - _transport_sample) != 0) {
1134 locate (master_wait_end, false, false);
1136 transport_master_tracking_state = Waiting;
1143 if (transport_master_tracking_state == Waiting) {
1145 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_sample));
1147 if (slave_transport_sample >= master_wait_end) {
1149 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_sample, _transport_sample));
1151 transport_master_tracking_state = Running;
1153 /* now perform a "micro-seek" within the disk buffers to realign ourselves
1154 precisely with the master.
1157 if (micro_locate (slave_transport_sample - _transport_sample) != 0) {
1158 cerr << "cannot micro-seek\n";
1164 if (transport_master_tracking_state == Running && _transport_speed == 0.0f) {
1165 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
1169 } else { // slave_speed is 0
1171 /* slave has stopped */
1173 if (_transport_speed != 0.0f) {
1174 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 sample %2 tf %3\n", slave_speed, slave_transport_sample, _transport_sample));
1178 if (slave_transport_sample != _transport_sample) {
1179 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_sample));
1180 force_locate (slave_transport_sample, false);
1183 reset_slave_state();
1188 Session::reset_slave_state ()
1190 transport_master_tracking_state = Stopped;
1191 DiskReader::set_no_disk_output (false);