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"
43 #include "ardour/vca.h"
44 #include "ardour/vca_manager.h"
46 #include "midi++/mmc.h"
50 using namespace ARDOUR;
54 /** Called by the audio engine when there is work to be done with JACK.
55 * @param nframes Number of frames to process.
59 Session::process (pframes_t nframes)
61 framepos_t transport_at_start = _transport_frame;
65 if (processing_blocked()) {
70 if (non_realtime_work_pending()) {
71 if (!_butler->transport_work_requested ()) {
76 _engine.main_thread()->get_buffers ();
78 (this->*process_function) (nframes);
80 /* realtime-safe meter-position and processor-order changes
82 * ideally this would be done in
83 * Route::process_output_buffers() but various functions
84 * callig it hold a _processor_lock reader-lock
86 boost::shared_ptr<RouteList> r = routes.reader ();
87 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
88 if ((*i)->apply_processor_changes_rt()) {
89 _rt_emit_pending = true;
92 if (_rt_emit_pending) {
93 if (!_rt_thread_active) {
94 emit_route_signals ();
96 if (pthread_mutex_trylock (&_rt_emit_mutex) == 0) {
97 pthread_cond_signal (&_rt_emit_cond);
98 pthread_mutex_unlock (&_rt_emit_mutex);
99 _rt_emit_pending = false;
103 _engine.main_thread()->drop_buffers ();
105 /* deliver MIDI clock. Note that we need to use the transport frame
106 * position at the start of process(), not the value at the end of
107 * it. We may already have ticked() because of a transport state
108 * change, for example.
112 if (!_silent && !_engine.freewheeling() && Config->get_send_midi_clock() && (transport_speed() == 1.0f || transport_speed() == 0.0f) && midi_clock->has_midi_port()) {
113 midi_clock->tick (transport_at_start, nframes);
116 _scene_changer->run (transport_at_start, transport_at_start + nframes);
119 /* don't bother with a message */
122 SendFeedback (); /* EMIT SIGNAL */
126 Session::fail_roll (pframes_t nframes)
128 return no_roll (nframes);
132 Session::no_roll (pframes_t nframes)
136 framepos_t end_frame = _transport_frame + nframes; // FIXME: varispeed + no_roll ??
138 int declick = (config.get_use_transport_fades() ? get_transport_declick_required() : false);
139 boost::shared_ptr<RouteList> r = routes.reader ();
142 _click_io->silence (nframes);
145 ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
147 VCAList v = _vca_manager->vcas ();
148 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
149 (*i)->automation_run (_transport_frame, nframes);
152 if (_process_graph) {
153 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
154 _process_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), declick);
156 PT_TIMING_CHECK (10);
157 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
159 if ((*i)->is_auditioner()) {
163 (*i)->set_pending_declick (declick);
165 if ((*i)->no_roll (nframes, _transport_frame, end_frame, 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 int declick = (config.get_use_transport_fades() ? get_transport_declick_required() : false);
185 boost::shared_ptr<RouteList> r = routes.reader ();
187 const framepos_t start_frame = _transport_frame;
188 const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
190 VCAList v = _vca_manager->vcas ();
191 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
192 (*i)->automation_run (start_frame, nframes);
195 if (_process_graph) {
196 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
197 if (_process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler) < 0) {
203 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
207 if ((*i)->is_auditioner()) {
211 (*i)->set_pending_declick (declick);
215 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, b)) < 0) {
221 DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 rolled and needs butler\n", (*i)->name()));
230 /** @param need_butler to be set to true by this method if it needs the butler,
231 * otherwise it must be left alone.
234 Session::silent_process_routes (pframes_t nframes, bool& need_butler)
236 boost::shared_ptr<RouteList> r = routes.reader ();
238 const framepos_t start_frame = _transport_frame;
239 const framepos_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
241 VCAList v = _vca_manager->vcas ();
242 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
243 (*i)->automation_run (start_frame, nframes);
246 if (_process_graph) {
247 _process_graph->silent_process_routes (nframes, start_frame, end_frame, need_butler);
249 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
253 if ((*i)->is_auditioner()) {
259 if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, b)) < 0) {
274 Session::get_track_statistics ()
279 boost::shared_ptr<RouteList> rl = routes.reader();
280 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
282 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
284 if (!tr || tr->hidden()) {
288 pworst = min (pworst, tr->playback_buffer_load());
289 cworst = min (cworst, tr->capture_buffer_load());
292 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
293 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
295 if (actively_recording()) {
300 /** Process callback used when the auditioner is not active */
302 Session::process_with_events (pframes_t nframes)
307 pframes_t this_nframes;
308 framepos_t end_frame;
309 bool session_needs_butler = false;
310 framecnt_t frames_moved;
312 /* make sure the auditioner is silent */
315 auditioner->silence (nframes);
318 /* handle any pending events */
320 while (pending_events.read (&ev, 1) == 1) {
324 /* if we are not in the middle of a state change,
325 and there are immediate events queued up,
329 while (!non_realtime_work_pending() && !immediate_events.empty()) {
330 SessionEvent *ev = immediate_events.front ();
331 immediate_events.pop_front ();
336 if (_transport_speed != 1.0 && _count_in_samples > 0) {
337 _count_in_samples = 0;
340 if (_count_in_samples > 0) {
341 framecnt_t ns = std::min ((framecnt_t)nframes, _count_in_samples);
344 run_click (_transport_frame - _count_in_samples, ns);
346 _count_in_samples -= ns;
349 /* process events.. */
350 if (!events.empty() && next_event != events.end()) {
351 SessionEvent* this_event = *next_event;
352 Events::iterator the_next_one = next_event;
355 while (this_event && this_event->action_frame == _transport_frame) {
356 process_event (this_event);
357 if (the_next_one == events.end()) {
360 this_event = *the_next_one;
367 check_declick_out ();
372 _engine.split_cycle (ns);
376 /* Decide on what to do with quarter-frame MTC during this cycle */
378 bool const was_sending_qf_mtc = _send_qf_mtc;
379 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
381 if (_transport_speed != 0) {
383 Config->get_send_mtc () &&
384 _transport_speed >= (1 - tolerance) &&
385 _transport_speed <= (1 + tolerance)
388 if (_send_qf_mtc && !was_sending_qf_mtc) {
389 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
390 _send_timecode_update = true;
393 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (frame_rate () / 4)) {
394 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
395 a quarter of a second since we sent anything at all, so send a full MTC update
398 _send_timecode_update = true;
401 _pframes_since_last_mtc += nframes;
404 /* Events caused a transport change (or we re-started sending
405 * MTC), so send an MTC Full Frame (Timecode) message. This
406 * is sent whether rolling or not, to give slaves an idea of
407 * ardour time on locates (and allow slow slaves to position
408 * and prepare for rolling)
410 if (_send_timecode_update) {
411 send_full_time_code (_transport_frame, nframes);
414 if (!process_can_proceed()) {
419 if (events.empty() || next_event == events.end()) {
420 try_run_lua (nframes); // also during export ?? ->move to process_without_events()
421 /* lua scripts may inject events */
422 while (_n_lua_scripts > 0 && pending_events.read (&ev, 1) == 1) {
425 if (events.empty() || next_event == events.end()) {
426 process_without_events (nframes);
431 if (locate_pending()) {
434 if (_transport_speed == 1.0) {
435 frames_moved = (framecnt_t) nframes;
437 interpolation.set_target_speed (_target_transport_speed);
438 interpolation.set_speed (_transport_speed);
439 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
443 end_frame = _transport_frame + frames_moved;
446 SessionEvent* this_event;
447 Events::iterator the_next_one;
449 if (!process_can_proceed()) {
454 if (!_exporting && _slave) {
455 if (!follow_slave (nframes)) {
460 if (_transport_speed == 0) {
465 if (!_exporting && !timecode_transmission_suspended()) {
466 send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
469 ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
471 framepos_t stop_limit = compute_stop_limit ();
473 if (maybe_stop (stop_limit)) {
478 this_event = *next_event;
479 the_next_one = next_event;
482 /* yes folks, here it is, the actual loop where we really truly
488 this_nframes = nframes; /* real (jack) time relative */
489 if (locate_pending()) {
492 frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
495 /* running an event, position transport precisely to its time */
496 if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
497 /* this isn't quite right for reverse play */
498 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
499 this_nframes = abs (floor(frames_moved / _transport_speed));
502 try_run_lua (this_nframes);
506 click (_transport_frame, this_nframes);
508 if (process_routes (this_nframes, session_needs_butler)) {
513 get_track_statistics ();
515 nframes -= this_nframes;
517 if (frames_moved < 0) {
518 decrement_transport_position (-frames_moved);
519 } else if (frames_moved) {
520 increment_transport_position (frames_moved);
523 maybe_stop (stop_limit);
524 check_declick_out ();
528 _engine.split_cycle (this_nframes);
531 /* now handle this event and all others scheduled for the same time */
533 while (this_event && this_event->action_frame == _transport_frame) {
534 process_event (this_event);
536 if (the_next_one == events.end()) {
539 this_event = *the_next_one;
544 /* if an event left our state changing, do the right thing */
546 if (nframes && non_realtime_work_pending()) {
551 /* this is necessary to handle the case of seamless looping */
552 end_frame = _transport_frame + floor (nframes * _transport_speed);
557 } /* implicit release of route lock */
559 if (session_needs_butler) {
560 DEBUG_TRACE (DEBUG::Butler, "p-with-events: session needs butler, call it\n");
566 Session::reset_slave_state ()
568 average_slave_delta = 1800;
569 delta_accumulator_cnt = 0;
570 have_first_delta_accumulator = false;
571 _slave_state = Stopped;
575 Session::transport_locked () const
579 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
587 Session::follow_slave (pframes_t nframes)
590 framepos_t slave_transport_frame;
591 framecnt_t this_delta;
596 config.set_external_sync (false);
600 _slave->speed_and_position (slave_speed, slave_transport_frame);
602 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
604 if (!_slave->locked()) {
605 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
609 if (slave_transport_frame > _transport_frame) {
610 this_delta = slave_transport_frame - _transport_frame;
613 this_delta = _transport_frame - slave_transport_frame;
617 if (_slave->starting()) {
621 if (_slave->is_always_synced() ||
622 (Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
625 /* if the TC source is synced, then we assume that its
626 speed is binary: 0.0 or 1.0
629 if (slave_speed != 0.0f) {
635 /* if we are chasing and the average delta between us and the
636 master gets too big, we want to switch to silent
637 motion. so keep track of that here.
640 if (_slave_state == Running) {
641 calculate_moving_average_of_slave_delta(dir, this_delta);
645 track_slave_state (slave_speed, slave_transport_frame, this_delta);
647 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
648 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
651 if (_slave_state == Running && !_slave->is_always_synced() &&
652 !(Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
655 if (_transport_speed != 0.0f) {
658 note that average_dir is +1 or -1
663 if (average_slave_delta == 0) {
667 delta = average_slave_delta;
668 delta *= average_dir;
672 if (slave_speed != 0.0) {
673 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
674 (int) (dir * this_delta),
678 slave_transport_frame,
679 average_slave_delta));
683 if (_slave->give_slave_full_control_over_transport_speed()) {
684 set_transport_speed (slave_speed, 0, false, false);
685 //std::cout << "set speed = " << slave_speed << "\n";
687 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
688 request_transport_speed (adjusted_speed);
689 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
690 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
695 if (!actively_recording() && (framecnt_t) abs(average_slave_delta) > _slave->resolution()) {
696 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
704 if (_slave_state == Running && 0 == (post_transport_work () & ~PostTransportSpeed)) {
705 /* speed is set, we're locked, and good to go */
710 DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
711 follow_slave_silently (nframes, slave_speed);
714 /* don't move at all */
715 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
721 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
723 if (delta_accumulator_cnt >= delta_accumulator_size) {
724 have_first_delta_accumulator = true;
725 delta_accumulator_cnt = 0;
728 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
729 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
732 if (have_first_delta_accumulator) {
733 average_slave_delta = 0L;
734 for (int i = 0; i < delta_accumulator_size; ++i) {
735 average_slave_delta += delta_accumulator[i];
737 average_slave_delta /= (int32_t) delta_accumulator_size;
738 if (average_slave_delta < 0L) {
740 average_slave_delta = abs(average_slave_delta);
748 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t /*this_delta*/)
750 if (slave_speed != 0.0f) {
752 /* slave is running */
754 switch (_slave_state) {
756 if (_slave->requires_seekahead()) {
757 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
758 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
759 /* we can call locate() here because we are in process context */
760 locate (slave_wait_end, false, false);
761 _slave_state = Waiting;
765 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped -> running at %1\n", slave_transport_frame));
767 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
768 average_slave_delta = 0L;
770 Location* al = _locations->auto_loop_location();
772 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
774 request_play_loop(false);
777 if (slave_transport_frame != _transport_frame) {
778 DEBUG_TRACE (DEBUG::Slave, string_compose ("require locate to run. eng: %1 -> sl: %2\n", _transport_frame, slave_transport_frame));
779 locate (slave_transport_frame, false, false);
781 _slave_state = Running;
790 if (_slave_state == Waiting) {
792 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
794 if (slave_transport_frame >= slave_wait_end) {
796 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
798 _slave_state = Running;
800 /* now perform a "micro-seek" within the disk buffers to realign ourselves
801 precisely with the master.
806 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
808 boost::shared_ptr<RouteList> rl = routes.reader();
809 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
810 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
811 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
818 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
819 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
821 tr->internal_playback_seek (frame_delta);
824 _transport_frame += frame_delta;
827 cerr << "cannot micro-seek\n";
833 if (_slave_state == Running && _transport_speed == 0.0f) {
834 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
838 } else { // slave_speed is 0
840 /* slave has stopped */
842 if (_transport_speed != 0.0f) {
843 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
847 if (slave_transport_frame != _transport_frame) {
848 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
849 force_locate (slave_transport_frame, false);
857 Session::follow_slave_silently (pframes_t nframes, float slave_speed)
859 if (slave_speed && _transport_speed) {
861 /* something isn't right, but we should move with the master
865 bool need_butler = false;
867 silent_process_routes (nframes, need_butler);
869 get_track_statistics ();
872 DEBUG_TRACE (DEBUG::Butler, "f-slave-silently: session needs butler, call it\n");
876 int32_t frames_moved;
878 if (locate_pending()) {
881 frames_moved = (int32_t) floor (_transport_speed * nframes);
884 if (frames_moved < 0) {
885 decrement_transport_position (-frames_moved);
886 } else if (frames_moved) {
887 increment_transport_position (frames_moved);
890 framepos_t const stop_limit = compute_stop_limit ();
891 maybe_stop (stop_limit);
896 Session::process_without_events (pframes_t nframes)
898 bool session_needs_butler = false;
899 framecnt_t frames_moved;
901 if (!process_can_proceed()) {
906 if (!_exporting && _slave) {
907 if (!follow_slave (nframes)) {
908 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame, 0, 0 , nframes);
913 if (_transport_speed == 0) {
918 if (locate_pending()) {
921 if (_transport_speed == 1.0) {
922 frames_moved = (framecnt_t) nframes;
924 interpolation.set_target_speed (_target_transport_speed);
925 interpolation.set_speed (_transport_speed);
926 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
930 if (!_exporting && !timecode_transmission_suspended()) {
931 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
934 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, _target_transport_speed, _transport_speed, nframes);
936 framepos_t const stop_limit = compute_stop_limit ();
938 if (maybe_stop (stop_limit)) {
943 if (maybe_sync_start (nframes)) {
947 click (_transport_frame, nframes);
949 if (process_routes (nframes, session_needs_butler)) {
954 get_track_statistics ();
956 if (frames_moved < 0) {
957 decrement_transport_position (-frames_moved);
958 } else if (frames_moved) {
959 increment_transport_position (frames_moved);
962 maybe_stop (stop_limit);
963 check_declick_out ();
965 if (session_needs_butler) {
966 DEBUG_TRACE (DEBUG::Butler, "p-without-events: session needs butler, call it\n");
971 /** Process callback used when the auditioner is active.
972 * @param nframes number of frames to process.
975 Session::process_audition (pframes_t nframes)
978 boost::shared_ptr<RouteList> r = routes.reader ();
980 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
981 if (!(*i)->is_auditioner()) {
982 (*i)->silence (nframes);
986 /* run the auditioner, and if it says we need butler service, ask for it */
988 if (auditioner->play_audition (nframes) > 0) {
989 DEBUG_TRACE (DEBUG::Butler, "auditioner needs butler, call it\n");
993 /* if using a monitor section, run it because otherwise we don't hear anything */
995 if (_monitor_out && auditioner->needs_monitor()) {
996 _monitor_out->monitor_run (_transport_frame, _transport_frame + nframes, nframes, false);
999 /* handle pending events */
1001 while (pending_events.read (&ev, 1) == 1) {
1005 /* if we are not in the middle of a state change,
1006 and there are immediate events queued up,
1010 while (!non_realtime_work_pending() && !immediate_events.empty()) {
1011 SessionEvent *ev = immediate_events.front ();
1012 immediate_events.pop_front ();
1016 if (!auditioner->auditioning()) {
1017 /* auditioner no longer active, so go back to the normal process callback */
1018 process_function = &Session::process_with_events;
1023 Session::maybe_sync_start (pframes_t & nframes)
1025 pframes_t sync_offset;
1027 if (!waiting_for_sync_offset) {
1031 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
1033 /* generate silence up to the sync point, then
1034 adjust nframes + offset to reflect whatever
1038 no_roll (sync_offset);
1039 nframes -= sync_offset;
1040 Port::increment_global_port_buffer_offset (sync_offset);
1041 waiting_for_sync_offset = false;
1044 return true; // done, nothing left to process
1049 /* sync offset point is not within this process()
1050 cycle, so just generate silence. and don't bother
1051 with any fancy stuff here, just the minimal silence.
1056 if (Config->get_locate_while_waiting_for_sync()) {
1057 if (micro_locate (nframes)) {
1058 /* XXX ERROR !!! XXX */
1062 return true; // done, nothing left to process
1069 Session::queue_event (SessionEvent* ev)
1071 if (_state_of_the_state & Deletion) {
1073 } else if (_state_of_the_state & Loading) {
1076 Glib::Threads::Mutex::Lock lm (rb_write_lock);
1077 pending_events.write (&ev, 1);
1082 Session::set_next_event ()
1084 if (events.empty()) {
1085 next_event = events.end();
1089 if (next_event == events.end()) {
1090 next_event = events.begin();
1093 if ((*next_event)->action_frame > _transport_frame) {
1094 next_event = events.begin();
1097 for (; next_event != events.end(); ++next_event) {
1098 if ((*next_event)->action_frame >= _transport_frame) {
1105 Session::process_event (SessionEvent* ev)
1110 /* if we're in the middle of a state change (i.e. waiting
1111 for the butler thread to complete the non-realtime
1112 part of the change), we'll just have to queue this
1113 event for a time when the change is complete.
1116 if (non_realtime_work_pending()) {
1118 /* except locates, which we have the capability to handle */
1120 if (ev->type != SessionEvent::Locate) {
1121 immediate_events.insert (immediate_events.end(), ev);
1127 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1130 case SessionEvent::SetLoop:
1131 set_play_loop (ev->yes_or_no, ev->speed);
1134 case SessionEvent::AutoLoop:
1136 /* roll after locate, do not flush, set "with loop"
1137 true only if we are seamless looping
1139 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1145 case SessionEvent::AutoLoopDeclick:
1147 /* Request a declick fade-out and a fade-in; the fade-out will happen
1148 at the end of the loop, and the fade-in at the start.
1150 transport_sub_state |= (PendingLoopDeclickOut | PendingLoopDeclickIn);
1156 case SessionEvent::Locate:
1157 if (ev->yes_or_no) {
1158 /* args: do not roll after locate, do flush, not with loop */
1159 locate (ev->target_frame, false, true, false);
1161 /* args: do not roll after locate, do flush, not with loop */
1162 start_locate (ev->target_frame, false, true, false);
1164 _send_timecode_update = true;
1167 case SessionEvent::LocateRoll:
1168 if (ev->yes_or_no) {
1169 /* args: roll after locate, do flush, not with loop */
1170 locate (ev->target_frame, true, true, false);
1172 /* args: roll after locate, do flush, not with loop */
1173 start_locate (ev->target_frame, true, true, false);
1175 _send_timecode_update = true;
1178 case SessionEvent::Skip:
1179 if (Config->get_skip_playback()) {
1180 start_locate (ev->target_frame, true, true, false);
1181 _send_timecode_update = true;
1187 case SessionEvent::LocateRollLocate:
1188 // locate is handled by ::request_roll_at_and_return()
1189 _requested_return_frame = ev->target_frame;
1190 request_locate (ev->target2_frame, true);
1194 case SessionEvent::SetTransportSpeed:
1195 set_transport_speed (ev->speed, ev->target_frame, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
1198 case SessionEvent::PunchIn:
1199 // cerr << "PunchIN at " << transport_frame() << endl;
1200 if (config.get_punch_in() && record_status() == Enabled && !preroll_record_punch_enabled()) {
1207 case SessionEvent::PunchOut:
1208 // cerr << "PunchOUT at " << transport_frame() << endl;
1209 if (config.get_punch_out() && !preroll_record_punch_enabled()) {
1210 step_back_from_record ();
1216 case SessionEvent::RecordStart:
1217 if (preroll_record_punch_enabled() && record_status() == Enabled) {
1224 case SessionEvent::StopOnce:
1225 if (!non_realtime_work_pending()) {
1226 _clear_event_type (SessionEvent::StopOnce);
1227 stop_transport (ev->yes_or_no);
1233 case SessionEvent::RangeStop:
1234 if (!non_realtime_work_pending()) {
1235 stop_transport (ev->yes_or_no);
1241 case SessionEvent::RangeLocate:
1242 /* args: roll after locate, do flush, not with loop */
1243 start_locate (ev->target_frame, true, true, false);
1248 case SessionEvent::Overwrite:
1249 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1252 case SessionEvent::SetSyncSource:
1253 DEBUG_TRACE (DEBUG::Slave, "seen request for new slave\n");
1254 use_sync_source (ev->slave);
1257 case SessionEvent::Audition:
1258 set_audition (ev->region);
1259 // drop reference to region
1260 ev->region.reset ();
1263 case SessionEvent::SetPlayAudioRange:
1264 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1267 case SessionEvent::CancelPlayAudioRange:
1271 case SessionEvent::RealTimeOperation:
1273 del = false; // other side of RT request needs to clean up
1276 case SessionEvent::AdjustPlaybackBuffering:
1277 schedule_playback_buffering_adjustment ();
1280 case SessionEvent::AdjustCaptureBuffering:
1281 schedule_capture_buffering_adjustment ();
1284 case SessionEvent::SetTimecodeTransmission:
1285 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1289 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1290 abort(); /*NOTREACHED*/
1295 del = del && !_remove_event (ev);
1304 Session::compute_stop_limit () const
1306 if (!Config->get_stop_at_session_end ()) {
1307 return max_framepos;
1311 return max_framepos;
1314 if (preroll_record_punch_enabled ()) {
1315 return max_framepos;
1318 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1319 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1321 if (actively_recording ()) {
1322 /* permanently recording */
1323 return max_framepos;
1324 } else if (punching_in && !punching_out) {
1325 /* punching in but never out */
1326 return max_framepos;
1327 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_frame()) {
1328 /* punching in and punching out after session end */
1329 return max_framepos;
1332 return current_end_frame ();
1337 /* dedicated thread for signal emission.
1339 * while sending cross-thread signals from the process thread
1340 * is fine in general, PBD::Signal's use of boost::function and
1341 * boost:bind can produce a vast overhead which is not
1342 * acceptable for low latency.
1344 * This works around the issue by moving the boost overhead
1345 * out of the RT thread. The overall load is probably higher but
1346 * the realtime thread remains unaffected.
1350 Session::emit_route_signals ()
1352 // TODO use RAII to allow using these signals in other places
1353 BatchUpdateStart(); /* EMIT SIGNAL */
1354 boost::shared_ptr<RouteList> r = routes.reader ();
1355 for (RouteList::const_iterator ci = r->begin(); ci != r->end(); ++ci) {
1356 (*ci)->emit_pending_signals ();
1358 BatchUpdateEnd(); /* EMIT SIGNAL */
1362 Session::emit_thread_start ()
1364 if (_rt_thread_active) {
1367 _rt_thread_active = true;
1369 if (pthread_create (&_rt_emit_thread, NULL, emit_thread, this)) {
1370 _rt_thread_active = false;
1375 Session::emit_thread_terminate ()
1377 if (!_rt_thread_active) {
1380 _rt_thread_active = false;
1382 if (pthread_mutex_lock (&_rt_emit_mutex) == 0) {
1383 pthread_cond_signal (&_rt_emit_cond);
1384 pthread_mutex_unlock (&_rt_emit_mutex);
1388 pthread_join (_rt_emit_thread, &status);
1392 Session::emit_thread (void *arg)
1394 Session *s = static_cast<Session *>(arg);
1395 s->emit_thread_run ();
1401 Session::emit_thread_run ()
1403 pthread_mutex_lock (&_rt_emit_mutex);
1404 while (_rt_thread_active) {
1405 emit_route_signals();
1406 pthread_cond_wait (&_rt_emit_cond, &_rt_emit_mutex);
1408 pthread_mutex_unlock (&_rt_emit_mutex);