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/graph.h"
36 #include "ardour/port.h"
37 #include "ardour/process_thread.h"
38 #include "ardour/scene_changer.h"
39 #include "ardour/session.h"
40 #include "ardour/slave.h"
41 #include "ardour/ticker.h"
42 #include "ardour/types.h"
44 #include "midi++/mmc.h"
48 using namespace ARDOUR;
52 /** Called by the audio engine when there is work to be done with JACK.
53 * @param nframes Number of frames to process.
57 Session::process (pframes_t nframes)
59 framepos_t transport_at_start = _transport_frame;
63 if (processing_blocked()) {
68 if (non_realtime_work_pending()) {
69 if (!_butler->transport_work_requested ()) {
74 _engine.main_thread()->get_buffers ();
76 (this->*process_function) (nframes);
78 /* realtime-safe meter-position and processor-order changes
80 * ideally this would be done in
81 * Route::process_output_buffers() but various functions
82 * callig it hold a _processor_lock reader-lock
84 boost::shared_ptr<RouteList> r = routes.reader ();
85 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
86 if ((*i)->apply_processor_changes_rt()) {
87 _rt_emit_pending = true;
90 if (_rt_emit_pending) {
91 if (!_rt_thread_active) {
92 emit_route_signals ();
94 if (pthread_mutex_trylock (&_rt_emit_mutex) == 0) {
95 pthread_cond_signal (&_rt_emit_cond);
96 pthread_mutex_unlock (&_rt_emit_mutex);
97 _rt_emit_pending = false;
101 _engine.main_thread()->drop_buffers ();
103 /* deliver MIDI clock. Note that we need to use the transport frame
104 * position at the start of process(), not the value at the end of
105 * it. We may already have ticked() because of a transport state
106 * change, for example.
110 if (!_silent && !_engine.freewheeling() && Config->get_send_midi_clock() && (transport_speed() == 1.0f || transport_speed() == 0.0f) && midi_clock->has_midi_port()) {
111 midi_clock->tick (transport_at_start, nframes);
114 _scene_changer->run (transport_at_start, transport_at_start + nframes);
117 /* don't bother with a message */
120 SendFeedback (); /* EMIT SIGNAL */
124 Session::fail_roll (pframes_t nframes)
126 return no_roll (nframes);
130 Session::no_roll (pframes_t nframes)
134 framepos_t end_frame = _transport_frame + nframes; // FIXME: varispeed + no_roll ??
136 int declick = (config.get_use_transport_fades() ? get_transport_declick_required() : false);
137 boost::shared_ptr<RouteList> r = routes.reader ();
140 _click_io->silence (nframes);
143 ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
145 if (_process_graph) {
146 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
147 _process_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), declick);
149 PT_TIMING_CHECK (10);
150 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
152 if ((*i)->is_auditioner()) {
156 (*i)->set_pending_declick (declick);
158 if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending())) {
159 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
164 PT_TIMING_CHECK (11);
171 /** @param need_butler to be set to true by this method if it needs the butler,
172 * otherwise it must be left alone.
175 Session::process_routes (pframes_t nframes, bool& need_butler)
177 int declick = (config.get_use_transport_fades() ? get_transport_declick_required() : false);
178 boost::shared_ptr<RouteList> r = routes.reader ();
180 const framepos_t start_frame = _transport_frame;
181 const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
183 if (_process_graph) {
184 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
185 if (_process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler) < 0) {
191 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
195 if ((*i)->is_auditioner()) {
199 (*i)->set_pending_declick (declick);
203 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, b)) < 0) {
217 /** @param need_butler to be set to true by this method if it needs the butler,
218 * otherwise it must be left alone.
221 Session::silent_process_routes (pframes_t nframes, bool& need_butler)
223 boost::shared_ptr<RouteList> r = routes.reader ();
225 const framepos_t start_frame = _transport_frame;
226 const framepos_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
228 if (_process_graph) {
229 _process_graph->silent_process_routes (nframes, start_frame, end_frame, need_butler);
231 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
235 if ((*i)->is_auditioner()) {
241 if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, b)) < 0) {
256 Session::get_track_statistics ()
261 boost::shared_ptr<RouteList> rl = routes.reader();
262 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
264 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
266 if (!tr || tr->hidden()) {
270 pworst = min (pworst, tr->playback_buffer_load());
271 cworst = min (cworst, tr->capture_buffer_load());
274 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
275 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
277 if (actively_recording()) {
282 /** Process callback used when the auditioner is not active */
284 Session::process_with_events (pframes_t nframes)
289 pframes_t this_nframes;
290 framepos_t end_frame;
291 bool session_needs_butler = false;
292 framecnt_t frames_moved;
294 /* make sure the auditioner is silent */
297 auditioner->silence (nframes);
300 /* handle any pending events */
302 while (pending_events.read (&ev, 1) == 1) {
306 /* if we are not in the middle of a state change,
307 and there are immediate events queued up,
311 while (!non_realtime_work_pending() && !immediate_events.empty()) {
312 SessionEvent *ev = immediate_events.front ();
313 immediate_events.pop_front ();
317 /* Decide on what to do with quarter-frame MTC during this cycle */
319 bool const was_sending_qf_mtc = _send_qf_mtc;
320 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
322 if (_transport_speed != 0) {
324 Config->get_send_mtc () &&
325 _transport_speed >= (1 - tolerance) &&
326 _transport_speed <= (1 + tolerance)
329 if (_send_qf_mtc && !was_sending_qf_mtc) {
330 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
331 _send_timecode_update = true;
334 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (frame_rate () / 4)) {
335 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
336 a quarter of a second since we sent anything at all, so send a full MTC update
339 _send_timecode_update = true;
342 _pframes_since_last_mtc += nframes;
345 /* Events caused a transport change (or we re-started sending
346 * MTC), so send an MTC Full Frame (Timecode) message. This
347 * is sent whether rolling or not, to give slaves an idea of
348 * ardour time on locates (and allow slow slaves to position
349 * and prepare for rolling)
351 if (_send_timecode_update) {
352 send_full_time_code (_transport_frame, nframes);
355 if (!process_can_proceed()) {
360 if (events.empty() || next_event == events.end()) {
361 process_without_events (nframes);
365 if (_transport_speed == 1.0) {
366 frames_moved = (framecnt_t) nframes;
368 interpolation.set_target_speed (_target_transport_speed);
369 interpolation.set_speed (_transport_speed);
370 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
373 end_frame = _transport_frame + frames_moved;
376 SessionEvent* this_event;
377 Events::iterator the_next_one;
379 if (!process_can_proceed()) {
384 if (!_exporting && _slave) {
385 if (!follow_slave (nframes)) {
390 if (_transport_speed == 0) {
395 if (!_exporting && !timecode_transmission_suspended()) {
396 send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
399 ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
401 framepos_t stop_limit = compute_stop_limit ();
403 if (maybe_stop (stop_limit)) {
408 this_event = *next_event;
409 the_next_one = next_event;
412 /* yes folks, here it is, the actual loop where we really truly
418 this_nframes = nframes; /* real (jack) time relative */
419 frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
421 /* running an event, position transport precisely to its time */
422 if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
423 /* this isn't quite right for reverse play */
424 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
425 this_nframes = abs (floor(frames_moved / _transport_speed));
430 click (_transport_frame, this_nframes);
432 if (process_routes (this_nframes, session_needs_butler)) {
437 get_track_statistics ();
439 nframes -= this_nframes;
441 if (frames_moved < 0) {
442 decrement_transport_position (-frames_moved);
444 increment_transport_position (frames_moved);
447 maybe_stop (stop_limit);
448 check_declick_out ();
452 _engine.split_cycle (this_nframes);
455 /* now handle this event and all others scheduled for the same time */
457 while (this_event && this_event->action_frame == _transport_frame) {
458 process_event (this_event);
460 if (the_next_one == events.end()) {
463 this_event = *the_next_one;
468 /* if an event left our state changing, do the right thing */
470 if (nframes && non_realtime_work_pending()) {
475 /* this is necessary to handle the case of seamless looping */
476 end_frame = _transport_frame + floor (nframes * _transport_speed);
481 } /* implicit release of route lock */
483 if (session_needs_butler) {
489 Session::reset_slave_state ()
491 average_slave_delta = 1800;
492 delta_accumulator_cnt = 0;
493 have_first_delta_accumulator = false;
494 _slave_state = Stopped;
498 Session::transport_locked () const
502 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
510 Session::follow_slave (pframes_t nframes)
513 framepos_t slave_transport_frame;
514 framecnt_t this_delta;
519 config.set_external_sync (false);
523 _slave->speed_and_position (slave_speed, slave_transport_frame);
525 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
527 if (!_slave->locked()) {
528 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
532 if (slave_transport_frame > _transport_frame) {
533 this_delta = slave_transport_frame - _transport_frame;
536 this_delta = _transport_frame - slave_transport_frame;
540 if (_slave->starting()) {
544 if (_slave->is_always_synced() ||
545 (Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
548 /* if the TC source is synced, then we assume that its
549 speed is binary: 0.0 or 1.0
552 if (slave_speed != 0.0f) {
558 /* if we are chasing and the average delta between us and the
559 master gets too big, we want to switch to silent
560 motion. so keep track of that here.
563 if (_slave_state == Running) {
564 calculate_moving_average_of_slave_delta(dir, this_delta);
568 track_slave_state (slave_speed, slave_transport_frame, this_delta);
570 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
571 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
574 if (_slave_state == Running && !_slave->is_always_synced() &&
575 !(Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
578 if (_transport_speed != 0.0f) {
581 note that average_dir is +1 or -1
586 if (average_slave_delta == 0) {
590 delta = average_slave_delta;
591 delta *= average_dir;
595 if (slave_speed != 0.0) {
596 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
597 (int) (dir * this_delta),
601 slave_transport_frame,
602 average_slave_delta));
606 if (_slave->give_slave_full_control_over_transport_speed()) {
607 set_transport_speed (slave_speed, 0, false, false);
608 //std::cout << "set speed = " << slave_speed << "\n";
610 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
611 request_transport_speed (adjusted_speed);
612 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
613 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
618 if (!actively_recording() && (framecnt_t) abs(average_slave_delta) > _slave->resolution()) {
619 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
627 if (_slave_state == Running && !non_realtime_work_pending()) {
628 /* speed is set, we're locked, and good to go */
633 DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
634 follow_slave_silently (nframes, slave_speed);
637 /* don't move at all */
638 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
644 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
646 if (delta_accumulator_cnt >= delta_accumulator_size) {
647 have_first_delta_accumulator = true;
648 delta_accumulator_cnt = 0;
651 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
652 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
655 if (have_first_delta_accumulator) {
656 average_slave_delta = 0L;
657 for (int i = 0; i < delta_accumulator_size; ++i) {
658 average_slave_delta += delta_accumulator[i];
660 average_slave_delta /= (int32_t) delta_accumulator_size;
661 if (average_slave_delta < 0L) {
663 average_slave_delta = abs(average_slave_delta);
671 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t /*this_delta*/)
673 if (slave_speed != 0.0f) {
675 /* slave is running */
677 switch (_slave_state) {
679 if (_slave->requires_seekahead()) {
680 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
681 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
682 /* we can call locate() here because we are in process context */
683 locate (slave_wait_end, false, false);
684 _slave_state = Waiting;
688 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped -> running at %1\n", slave_transport_frame));
690 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
691 average_slave_delta = 0L;
693 Location* al = _locations->auto_loop_location();
695 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
697 request_play_loop(false);
700 if (slave_transport_frame != _transport_frame) {
701 DEBUG_TRACE (DEBUG::Slave, string_compose ("require locate to run. eng: %1 -> sl: %2\n", _transport_frame, slave_transport_frame));
702 locate (slave_transport_frame, false, false);
704 _slave_state = Running;
713 if (_slave_state == Waiting) {
715 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
717 if (slave_transport_frame >= slave_wait_end) {
719 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
721 _slave_state = Running;
723 /* now perform a "micro-seek" within the disk buffers to realign ourselves
724 precisely with the master.
729 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
731 boost::shared_ptr<RouteList> rl = routes.reader();
732 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
733 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
734 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
741 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
742 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
744 tr->internal_playback_seek (frame_delta);
747 _transport_frame += frame_delta;
750 cerr << "cannot micro-seek\n";
756 if (_slave_state == Running && _transport_speed == 0.0f) {
757 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
761 } else { // slave_speed is 0
763 /* slave has stopped */
765 if (_transport_speed != 0.0f) {
766 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
770 if (slave_transport_frame != _transport_frame) {
771 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
772 force_locate (slave_transport_frame, false);
780 Session::follow_slave_silently (pframes_t nframes, float slave_speed)
782 if (slave_speed && _transport_speed) {
784 /* something isn't right, but we should move with the master
788 bool need_butler = false;
790 silent_process_routes (nframes, need_butler);
792 get_track_statistics ();
798 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
800 if (frames_moved < 0) {
801 decrement_transport_position (-frames_moved);
803 increment_transport_position (frames_moved);
806 framepos_t const stop_limit = compute_stop_limit ();
807 maybe_stop (stop_limit);
812 Session::process_without_events (pframes_t nframes)
814 bool session_needs_butler = false;
815 framecnt_t frames_moved;
817 if (!process_can_proceed()) {
822 if (!_exporting && _slave) {
823 if (!follow_slave (nframes)) {
824 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame, 0, 0 , nframes);
829 if (_transport_speed == 0) {
834 if (_transport_speed == 1.0) {
835 frames_moved = (framecnt_t) nframes;
837 interpolation.set_target_speed (_target_transport_speed);
838 interpolation.set_speed (_transport_speed);
839 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
842 if (!_exporting && !timecode_transmission_suspended()) {
843 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
846 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, _target_transport_speed, _transport_speed, nframes);
848 framepos_t const stop_limit = compute_stop_limit ();
850 if (maybe_stop (stop_limit)) {
855 if (maybe_sync_start (nframes)) {
859 click (_transport_frame, nframes);
861 if (process_routes (nframes, session_needs_butler)) {
866 get_track_statistics ();
868 if (frames_moved < 0) {
869 decrement_transport_position (-frames_moved);
871 increment_transport_position (frames_moved);
874 maybe_stop (stop_limit);
875 check_declick_out ();
877 if (session_needs_butler) {
882 /** Process callback used when the auditioner is active.
883 * @param nframes number of frames to process.
886 Session::process_audition (pframes_t nframes)
889 boost::shared_ptr<RouteList> r = routes.reader ();
891 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
892 if (!(*i)->is_auditioner()) {
893 (*i)->silence (nframes);
897 /* run the auditioner, and if it says we need butler service, ask for it */
899 if (auditioner->play_audition (nframes) > 0) {
903 /* if using a monitor section, run it because otherwise we don't hear anything */
905 if (_monitor_out && auditioner->needs_monitor()) {
906 _monitor_out->monitor_run (_transport_frame, _transport_frame + nframes, nframes, false);
909 /* handle pending events */
911 while (pending_events.read (&ev, 1) == 1) {
915 /* if we are not in the middle of a state change,
916 and there are immediate events queued up,
920 while (!non_realtime_work_pending() && !immediate_events.empty()) {
921 SessionEvent *ev = immediate_events.front ();
922 immediate_events.pop_front ();
926 if (!auditioner->auditioning()) {
927 /* auditioner no longer active, so go back to the normal process callback */
928 process_function = &Session::process_with_events;
933 Session::maybe_sync_start (pframes_t & nframes)
935 pframes_t sync_offset;
937 if (!waiting_for_sync_offset) {
941 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
943 /* generate silence up to the sync point, then
944 adjust nframes + offset to reflect whatever
948 no_roll (sync_offset);
949 nframes -= sync_offset;
950 Port::increment_global_port_buffer_offset (sync_offset);
951 waiting_for_sync_offset = false;
954 return true; // done, nothing left to process
959 /* sync offset point is not within this process()
960 cycle, so just generate silence. and don't bother
961 with any fancy stuff here, just the minimal silence.
966 if (Config->get_locate_while_waiting_for_sync()) {
967 if (micro_locate (nframes)) {
968 /* XXX ERROR !!! XXX */
972 return true; // done, nothing left to process
979 Session::queue_event (SessionEvent* ev)
981 if (_state_of_the_state & Deletion) {
983 } else if (_state_of_the_state & Loading) {
986 pending_events.write (&ev, 1);
991 Session::set_next_event ()
993 if (events.empty()) {
994 next_event = events.end();
998 if (next_event == events.end()) {
999 next_event = events.begin();
1002 if ((*next_event)->action_frame > _transport_frame) {
1003 next_event = events.begin();
1006 for (; next_event != events.end(); ++next_event) {
1007 if ((*next_event)->action_frame >= _transport_frame) {
1014 Session::process_event (SessionEvent* ev)
1019 /* if we're in the middle of a state change (i.e. waiting
1020 for the butler thread to complete the non-realtime
1021 part of the change), we'll just have to queue this
1022 event for a time when the change is complete.
1025 if (non_realtime_work_pending()) {
1027 /* except locates, which we have the capability to handle */
1029 if (ev->type != SessionEvent::Locate) {
1030 immediate_events.insert (immediate_events.end(), ev);
1036 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1039 case SessionEvent::SetLoop:
1040 set_play_loop (ev->yes_or_no, ev->speed);
1043 case SessionEvent::AutoLoop:
1045 /* roll after locate, do not flush, set "with loop"
1046 true only if we are seamless looping
1048 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1054 case SessionEvent::AutoLoopDeclick:
1056 /* Request a declick fade-out and a fade-in; the fade-out will happen
1057 at the end of the loop, and the fade-in at the start.
1059 transport_sub_state |= (PendingLoopDeclickOut | PendingLoopDeclickIn);
1065 case SessionEvent::Locate:
1066 if (ev->yes_or_no) {
1067 /* args: do not roll after locate, do flush, not with loop */
1068 locate (ev->target_frame, false, true, false);
1070 /* args: do not roll after locate, do flush, not with loop */
1071 start_locate (ev->target_frame, false, true, false);
1073 _send_timecode_update = true;
1076 case SessionEvent::LocateRoll:
1077 if (ev->yes_or_no) {
1078 /* args: roll after locate, do flush, not with loop */
1079 locate (ev->target_frame, true, true, false);
1081 /* args: roll after locate, do flush, not with loop */
1082 start_locate (ev->target_frame, true, true, false);
1084 _send_timecode_update = true;
1087 case SessionEvent::Skip:
1088 if (Config->get_skip_playback()) {
1089 start_locate (ev->target_frame, true, true, false);
1090 _send_timecode_update = true;
1096 case SessionEvent::LocateRollLocate:
1097 // locate is handled by ::request_roll_at_and_return()
1098 _requested_return_frame = ev->target_frame;
1099 request_locate (ev->target2_frame, true);
1103 case SessionEvent::SetTransportSpeed:
1104 set_transport_speed (ev->speed, ev->target_frame, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
1107 case SessionEvent::PunchIn:
1108 // cerr << "PunchIN at " << transport_frame() << endl;
1109 if (config.get_punch_in() && record_status() == Enabled) {
1116 case SessionEvent::PunchOut:
1117 // cerr << "PunchOUT at " << transport_frame() << endl;
1118 if (config.get_punch_out()) {
1119 step_back_from_record ();
1125 case SessionEvent::StopOnce:
1126 if (!non_realtime_work_pending()) {
1127 _clear_event_type (SessionEvent::StopOnce);
1128 stop_transport (ev->yes_or_no);
1134 case SessionEvent::RangeStop:
1135 if (!non_realtime_work_pending()) {
1136 stop_transport (ev->yes_or_no);
1142 case SessionEvent::RangeLocate:
1143 /* args: roll after locate, do flush, not with loop */
1144 start_locate (ev->target_frame, true, true, false);
1149 case SessionEvent::Overwrite:
1150 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1153 case SessionEvent::SetTrackSpeed:
1154 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1157 case SessionEvent::SetSyncSource:
1158 DEBUG_TRACE (DEBUG::Slave, "seen request for new slave\n");
1159 use_sync_source (ev->slave);
1162 case SessionEvent::Audition:
1163 set_audition (ev->region);
1164 // drop reference to region
1165 ev->region.reset ();
1168 case SessionEvent::InputConfigurationChange:
1169 add_post_transport_work (PostTransportInputChange);
1170 _butler->schedule_transport_work ();
1173 case SessionEvent::SetPlayAudioRange:
1174 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1177 case SessionEvent::CancelPlayAudioRange:
1181 case SessionEvent::RealTimeOperation:
1183 del = false; // other side of RT request needs to clean up
1186 case SessionEvent::AdjustPlaybackBuffering:
1187 schedule_playback_buffering_adjustment ();
1190 case SessionEvent::AdjustCaptureBuffering:
1191 schedule_capture_buffering_adjustment ();
1194 case SessionEvent::SetTimecodeTransmission:
1195 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1199 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1200 abort(); /*NOTREACHED*/
1205 del = del && !_remove_event (ev);
1214 Session::compute_stop_limit () const
1216 if (!Config->get_stop_at_session_end ()) {
1217 return max_framepos;
1221 return max_framepos;
1225 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1226 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1228 if (actively_recording ()) {
1229 /* permanently recording */
1230 return max_framepos;
1231 } else if (punching_in && !punching_out) {
1232 /* punching in but never out */
1233 return max_framepos;
1234 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_frame()) {
1235 /* punching in and punching out after session end */
1236 return max_framepos;
1239 return current_end_frame ();
1244 /* dedicated thread for signal emission.
1246 * while sending cross-thread signals from the process thread
1247 * is fine in general, PBD::Signal's use of boost::function and
1248 * boost:bind can produce a vast overhead which is not
1249 * acceptable for low latency.
1251 * This works around the issue by moving the boost overhead
1252 * out of the RT thread. The overall load is probably higher but
1253 * the realtime thread remains unaffected.
1257 Session::emit_route_signals ()
1259 // TODO use RAII to allow using these signals in other places
1260 BatchUpdateStart(); /* EMIT SIGNAL */
1261 boost::shared_ptr<RouteList> r = routes.reader ();
1262 for (RouteList::const_iterator ci = r->begin(); ci != r->end(); ++ci) {
1263 (*ci)->emit_pending_signals ();
1265 BatchUpdateEnd(); /* EMIT SIGNAL */
1269 Session::emit_thread_start ()
1271 if (_rt_thread_active) {
1274 _rt_thread_active = true;
1276 if (pthread_create (&_rt_emit_thread, NULL, emit_thread, this)) {
1277 _rt_thread_active = false;
1282 Session::emit_thread_terminate ()
1284 if (!_rt_thread_active) {
1287 _rt_thread_active = false;
1289 if (pthread_mutex_lock (&_rt_emit_mutex) == 0) {
1290 pthread_cond_signal (&_rt_emit_cond);
1291 pthread_mutex_unlock (&_rt_emit_mutex);
1295 pthread_join (_rt_emit_thread, &status);
1299 Session::emit_thread (void *arg)
1301 Session *s = static_cast<Session *>(arg);
1302 s->emit_thread_run ();
1308 Session::emit_thread_run ()
1310 pthread_mutex_lock (&_rt_emit_mutex);
1311 while (_rt_thread_active) {
1312 emit_route_signals();
1313 pthread_cond_wait (&_rt_emit_cond, &_rt_emit_mutex);
1315 pthread_mutex_unlock (&_rt_emit_mutex);