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()) {
69 cerr << "%%%%%%%%%%%%%% session process blocked\n";
73 if (non_realtime_work_pending()) {
74 if (!_butler->transport_work_requested ()) {
79 _engine.main_thread()->get_buffers ();
81 (this->*process_function) (nframes);
83 /* realtime-safe meter-position and processor-order changes
85 * ideally this would be done in
86 * Route::process_output_buffers() but various functions
87 * callig it hold a _processor_lock reader-lock
89 boost::shared_ptr<RouteList> r = routes.reader ();
90 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
91 if ((*i)->apply_processor_changes_rt()) {
92 _rt_emit_pending = true;
95 if (_rt_emit_pending) {
96 if (!_rt_thread_active) {
97 emit_route_signals ();
99 if (pthread_mutex_trylock (&_rt_emit_mutex) == 0) {
100 pthread_cond_signal (&_rt_emit_cond);
101 pthread_mutex_unlock (&_rt_emit_mutex);
102 _rt_emit_pending = false;
106 _engine.main_thread()->drop_buffers ();
108 /* deliver MIDI clock. Note that we need to use the transport sample
109 * position at the start of process(), not the value at the end of
110 * it. We may already have ticked() because of a transport state
111 * change, for example.
115 if (!_silent && !_engine.freewheeling() && Config->get_send_midi_clock() && (transport_speed() == 1.0f || transport_speed() == 0.0f) && midi_clock->has_midi_port()) {
116 midi_clock->tick (transport_at_start, nframes);
119 _scene_changer->run (transport_at_start, transport_at_start + nframes);
122 /* don't bother with a message */
125 SendFeedback (); /* EMIT SIGNAL */
129 Session::fail_roll (pframes_t nframes)
131 return no_roll (nframes);
135 Session::no_roll (pframes_t nframes)
139 samplepos_t end_sample = _transport_sample + nframes; // FIXME: varispeed + no_roll ??
141 boost::shared_ptr<RouteList> r = routes.reader ();
144 _click_io->silence (nframes);
147 ltc_tx_send_time_code_for_cycle (_transport_sample, end_sample, _target_transport_speed, _transport_speed, nframes);
149 VCAList v = _vca_manager->vcas ();
150 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
151 (*i)->automation_run (_transport_sample, nframes);
154 if (_process_graph) {
155 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
156 _process_graph->routes_no_roll( nframes, _transport_sample, end_sample, non_realtime_work_pending());
158 PT_TIMING_CHECK (10);
159 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
161 if ((*i)->is_auditioner()) {
165 if ((*i)->no_roll (nframes, _transport_sample, end_sample, non_realtime_work_pending())) {
166 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
171 PT_TIMING_CHECK (11);
178 /** @param need_butler to be set to true by this method if it needs the butler,
179 * otherwise it must be left alone.
182 Session::process_routes (pframes_t nframes, bool& need_butler)
184 boost::shared_ptr<RouteList> r = routes.reader ();
186 const samplepos_t start_sample = _transport_sample;
187 const samplepos_t end_sample = _transport_sample + floor (nframes * _transport_speed);
189 VCAList v = _vca_manager->vcas ();
190 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
191 (*i)->automation_run (start_sample, nframes);
194 _global_locate_pending = locate_pending ();
196 if (_process_graph) {
197 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
198 if (_process_graph->process_routes (nframes, start_sample, end_sample, need_butler) < 0) {
204 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
208 if ((*i)->is_auditioner()) {
214 if ((ret = (*i)->roll (nframes, start_sample, end_sample, b)) < 0) {
220 DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 rolled and needs butler\n", (*i)->name()));
230 Session::get_track_statistics ()
235 boost::shared_ptr<RouteList> rl = routes.reader();
236 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
238 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
240 if (!tr || tr->is_private_route()) {
244 pworst = min (pworst, tr->playback_buffer_load());
245 cworst = min (cworst, tr->capture_buffer_load());
248 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
249 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
251 if (actively_recording()) {
257 Session::compute_audible_delta (samplepos_t& pos_and_delta) const
259 if (_transport_speed == 0.0 || _count_in_samples > 0 || _remaining_latency_preroll > 0) {
260 /* cannot compute audible delta, because the session is
261 generating silence that does not correspond to the timeline,
262 but is instead filling playback buffers to manage latency
265 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));
269 pos_and_delta -= _transport_sample;
273 /** Process callback used when the auditioner is not active */
275 Session::process_with_events (pframes_t nframes)
280 pframes_t this_nframes;
281 samplepos_t end_sample;
282 bool session_needs_butler = false;
283 samplecnt_t samples_moved;
285 /* make sure the auditioner is silent */
288 auditioner->silence (nframes);
291 /* handle any pending events */
293 while (pending_events.read (&ev, 1) == 1) {
297 /* if we are not in the middle of a state change,
298 and there are immediate events queued up,
302 while (!non_realtime_work_pending() && !immediate_events.empty()) {
303 SessionEvent *ev = immediate_events.front ();
304 immediate_events.pop_front ();
307 /* only count-in when going to roll at speed 1.0 */
308 if (_transport_speed != 1.0 && _count_in_samples > 0) {
309 _count_in_samples = 0;
311 if (_transport_speed == 0.0) {
312 _remaining_latency_preroll = 0;
315 assert (_count_in_samples == 0 || _remaining_latency_preroll == 0 || _count_in_samples == _remaining_latency_preroll);
317 DEBUG_TRACE (DEBUG::Transport, string_compose ("Running count in/latency preroll of %1 & %2\n", _count_in_samples, _remaining_latency_preroll));
319 while (_count_in_samples > 0 || _remaining_latency_preroll > 0) {
322 if (_remaining_latency_preroll > 0) {
323 ns = std::min ((samplecnt_t)nframes, _remaining_latency_preroll);
325 ns = std::min ((samplecnt_t)nframes, _count_in_samples);
328 boost::shared_ptr<RouteList> r = routes.reader ();
329 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
330 samplecnt_t route_offset = (*i)->playback_latency ();
331 if (_remaining_latency_preroll > route_offset + ns) {
332 /* route will no-roll for complete pre-roll cycle */
335 if (_remaining_latency_preroll > route_offset) {
336 /* route may need partial no-roll and partial roll from
337 * (_transport_sample - _remaining_latency_preroll) .. +ns.
338 * shorten and split the cycle.
340 ns = std::min (ns, (_remaining_latency_preroll - route_offset));
344 if (_count_in_samples > 0) {
345 run_click (_transport_sample - _count_in_samples, ns);
346 assert (_count_in_samples >= ns);
347 _count_in_samples -= ns;
350 if (_remaining_latency_preroll > 0) {
351 if (_count_in_samples == 0) {
352 click (_transport_sample - _remaining_latency_preroll, ns);
354 if (process_routes (ns, session_needs_butler)) {
361 if (_remaining_latency_preroll > 0) {
362 assert (_remaining_latency_preroll >= ns);
363 _remaining_latency_preroll -= ns;
368 /* process events.. */
369 if (!events.empty() && next_event != events.end()) {
370 SessionEvent* this_event = *next_event;
371 Events::iterator the_next_one = next_event;
374 while (this_event && this_event->action_sample == _transport_sample) {
375 process_event (this_event);
376 if (the_next_one == events.end()) {
379 this_event = *the_next_one;
389 _engine.split_cycle (ns);
393 /* Decide on what to do with quarter-frame MTC during this cycle */
395 bool const was_sending_qf_mtc = _send_qf_mtc;
396 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
398 if (_transport_speed != 0) {
400 Config->get_send_mtc () &&
401 _transport_speed >= (1 - tolerance) &&
402 _transport_speed <= (1 + tolerance)
405 if (_send_qf_mtc && !was_sending_qf_mtc) {
406 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
407 _send_timecode_update = true;
410 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (sample_rate () / 4)) {
411 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
412 a quarter of a second since we sent anything at all, so send a full MTC update
415 _send_timecode_update = true;
418 _pframes_since_last_mtc += nframes;
421 /* Events caused a transport change (or we re-started sending
422 * MTC), so send an MTC Full Frame (Timecode) message. This
423 * is sent whether rolling or not, to give slaves an idea of
424 * ardour time on locates (and allow slow slaves to position
425 * and prepare for rolling)
427 if (_send_timecode_update) {
428 send_full_time_code (_transport_sample, nframes);
431 if (!process_can_proceed()) {
436 if (events.empty() || next_event == events.end()) {
437 try_run_lua (nframes); // also during export ?? ->move to process_without_events()
438 /* lua scripts may inject events */
439 while (_n_lua_scripts > 0 && pending_events.read (&ev, 1) == 1) {
442 if (events.empty() || next_event == events.end()) {
443 process_without_events (nframes);
448 assert (_transport_speed == 0 || _transport_speed == 1.0 || _transport_speed == -1.0);
450 samples_moved = (samplecnt_t) 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 */
501 /* running an event, position transport precisely to its time */
502 if (this_event && this_event->action_sample <= end_sample && this_event->action_sample >= _transport_sample) {
503 /* this isn't quite right for reverse play */
504 samples_moved = (samplecnt_t) (this_event->action_sample - _transport_sample);
505 this_nframes = abs (floor(samples_moved / _transport_speed));
508 try_run_lua (this_nframes);
512 click (_transport_sample, this_nframes);
514 if (process_routes (this_nframes, session_needs_butler)) {
519 get_track_statistics ();
521 nframes -= this_nframes;
523 if (samples_moved < 0) {
524 decrement_transport_position (-samples_moved);
525 } else if (samples_moved) {
526 increment_transport_position (samples_moved);
529 maybe_stop (stop_limit);
533 _engine.split_cycle (this_nframes);
536 /* now handle this event and all others scheduled for the same time */
538 while (this_event && this_event->action_sample == _transport_sample) {
539 process_event (this_event);
541 if (the_next_one == events.end()) {
544 this_event = *the_next_one;
549 /* if an event left our state changing, do the right thing */
551 if (nframes && non_realtime_work_pending()) {
556 /* this is necessary to handle the case of seamless looping */
557 end_sample = _transport_sample + floor (nframes * _transport_speed);
562 } /* implicit release of route lock */
564 if (session_needs_butler) {
565 DEBUG_TRACE (DEBUG::Butler, "p-with-events: session needs butler, call it\n");
571 Session::transport_locked () const
573 if (!locate_pending() && (!config.get_external_sync() || (transport_master()->ok() && transport_master()->locked()))) {
581 Session::process_without_events (pframes_t nframes)
583 bool session_needs_butler = false;
584 samplecnt_t samples_moved;
586 if (!process_can_proceed()) {
591 if (!_exporting && config.get_external_sync()) {
592 if (!follow_transport_master (nframes)) {
593 ltc_tx_send_time_code_for_cycle (_transport_sample, _transport_sample, 0, 0 , nframes);
598 assert (_transport_speed == 0 || _transport_speed == 1.0 || _transport_speed == -1.0);
600 if (_transport_speed == 0) {
604 samples_moved = (samplecnt_t) nframes;
607 if (!_exporting && !timecode_transmission_suspended()) {
608 send_midi_time_code_for_cycle (_transport_sample, _transport_sample + samples_moved, nframes);
611 ltc_tx_send_time_code_for_cycle (_transport_sample, _transport_sample + samples_moved, _target_transport_speed, _transport_speed, nframes);
613 samplepos_t const stop_limit = compute_stop_limit ();
615 if (maybe_stop (stop_limit)) {
620 if (maybe_sync_start (nframes)) {
624 click (_transport_sample, nframes);
626 if (process_routes (nframes, session_needs_butler)) {
631 get_track_statistics ();
633 if (samples_moved < 0) {
634 decrement_transport_position (-samples_moved);
635 } else if (samples_moved) {
636 increment_transport_position (samples_moved);
639 maybe_stop (stop_limit);
641 if (session_needs_butler) {
642 DEBUG_TRACE (DEBUG::Butler, "p-without-events: session needs butler, call it\n");
647 /** Process callback used when the auditioner is active.
648 * @param nframes number of samples to process.
651 Session::process_audition (pframes_t nframes)
654 boost::shared_ptr<RouteList> r = routes.reader ();
656 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
657 if (!(*i)->is_auditioner()) {
658 (*i)->silence (nframes);
662 /* run the auditioner, and if it says we need butler service, ask for it */
664 if (auditioner->play_audition (nframes) > 0) {
665 DEBUG_TRACE (DEBUG::Butler, "auditioner needs butler, call it\n");
669 /* if using a monitor section, run it because otherwise we don't hear anything */
671 if (_monitor_out && auditioner->needs_monitor()) {
672 _monitor_out->monitor_run (_transport_sample, _transport_sample + nframes, nframes);
675 /* handle pending events */
677 while (pending_events.read (&ev, 1) == 1) {
681 /* if we are not in the middle of a state change,
682 and there are immediate events queued up,
686 while (!non_realtime_work_pending() && !immediate_events.empty()) {
687 SessionEvent *ev = immediate_events.front ();
688 immediate_events.pop_front ();
692 if (!auditioner->auditioning()) {
693 /* auditioner no longer active, so go back to the normal process callback */
694 process_function = &Session::process_with_events;
699 Session::maybe_sync_start (pframes_t & nframes)
701 pframes_t sync_offset;
703 if (!waiting_for_sync_offset) {
707 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
709 /* generate silence up to the sync point, then
710 adjust nframes + offset to reflect whatever
714 no_roll (sync_offset);
715 nframes -= sync_offset;
716 Port::increment_global_port_buffer_offset (sync_offset);
717 waiting_for_sync_offset = false;
720 return true; // done, nothing left to process
725 /* sync offset point is not within this process()
726 cycle, so just generate silence. and don't bother
727 with any fancy stuff here, just the minimal silence.
732 if (Config->get_locate_while_waiting_for_sync()) {
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 ();
1079 delta = _transport_sample - slave_transport_sample;
1081 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()));
1083 track_transport_master (slave_speed, slave_transport_sample);
1085 if (transport_master_tracking_state == Running) {
1087 if (!actively_recording() && abs (delta) > tmm.current()->resolution()) {
1088 DEBUG_TRACE (DEBUG::Slave, string_compose ("average slave delta %1 greater than slave resolution %2\n", delta, tmm.current()->resolution()));
1089 if (micro_locate (-delta) != 0) {
1090 DEBUG_TRACE (DEBUG::Slave, "micro-locate didn't work, set no disk output true\n");
1092 /* run routes as normal, but no disk output */
1093 DiskReader::set_no_disk_output (true);
1098 if (transport_master_tracking_state == Running) {
1099 /* speed is set, we're locked, and good to go */
1100 DiskReader::set_no_disk_output (false);
1106 /* don't move at all */
1107 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
1113 Session::track_transport_master (float slave_speed, samplepos_t slave_transport_sample)
1115 boost::shared_ptr<TransportMaster> master (TransportMasterManager::instance().current());
1119 DEBUG_TRACE (DEBUG::Slave, string_compose ("session has master tracking state as %1\n", transport_master_tracking_state));
1121 if (slave_speed != 0.0f) {
1123 /* slave is running */
1125 switch (transport_master_tracking_state) {
1127 if (master->requires_seekahead()) {
1128 master_wait_end = slave_transport_sample + master->seekahead_distance ();
1129 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", master_wait_end));
1130 /* we can call locate() here because we are in process context */
1131 if (micro_locate (master_wait_end - _transport_sample) != 0) {
1132 locate (master_wait_end, false, false);
1134 transport_master_tracking_state = Waiting;
1138 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped -> running at %1\n", slave_transport_sample));
1140 if (slave_transport_sample != _transport_sample) {
1141 DEBUG_TRACE (DEBUG::Slave, string_compose ("require locate to run. eng: %1 -> sl: %2\n", _transport_sample, slave_transport_sample));
1142 if (micro_locate (slave_transport_sample - _transport_sample) != 0) {
1143 locate (slave_transport_sample, false, false);
1146 transport_master_tracking_state = Running;
1155 if (transport_master_tracking_state == Waiting) {
1157 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_sample));
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);