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/slave.h"
42 #include "ardour/ticker.h"
43 #include "ardour/types.h"
44 #include "ardour/vca.h"
45 #include "ardour/vca_manager.h"
47 #include "midi++/mmc.h"
51 using namespace ARDOUR;
55 /** Called by the audio engine when there is work to be done with JACK.
56 * @param nframes Number of frames to process.
60 Session::process (pframes_t nframes)
62 framepos_t transport_at_start = _transport_frame;
66 if (processing_blocked()) {
71 if (non_realtime_work_pending()) {
72 if (!_butler->transport_work_requested ()) {
77 _engine.main_thread()->get_buffers ();
79 (this->*process_function) (nframes);
81 /* realtime-safe meter-position and processor-order changes
83 * ideally this would be done in
84 * Route::process_output_buffers() but various functions
85 * callig it hold a _processor_lock reader-lock
87 boost::shared_ptr<RouteList> r = routes.reader ();
88 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
89 if ((*i)->apply_processor_changes_rt()) {
90 _rt_emit_pending = true;
93 if (_rt_emit_pending) {
94 if (!_rt_thread_active) {
95 emit_route_signals ();
97 if (pthread_mutex_trylock (&_rt_emit_mutex) == 0) {
98 pthread_cond_signal (&_rt_emit_cond);
99 pthread_mutex_unlock (&_rt_emit_mutex);
100 _rt_emit_pending = false;
104 _engine.main_thread()->drop_buffers ();
106 /* deliver MIDI clock. Note that we need to use the transport frame
107 * position at the start of process(), not the value at the end of
108 * it. We may already have ticked() because of a transport state
109 * change, for example.
113 if (!_silent && !_engine.freewheeling() && Config->get_send_midi_clock() && (transport_speed() == 1.0f || transport_speed() == 0.0f) && midi_clock->has_midi_port()) {
114 midi_clock->tick (transport_at_start, nframes);
117 _scene_changer->run (transport_at_start, transport_at_start + nframes);
120 /* don't bother with a message */
123 SendFeedback (); /* EMIT SIGNAL */
127 Session::fail_roll (pframes_t nframes)
129 return no_roll (nframes);
133 Session::no_roll (pframes_t nframes)
137 framepos_t end_frame = _transport_frame + nframes; // FIXME: varispeed + no_roll ??
139 int declick = (config.get_use_transport_fades() ? get_transport_declick_required() : false);
140 boost::shared_ptr<RouteList> r = routes.reader ();
143 _click_io->silence (nframes);
146 ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _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_frame, nframes);
153 if (_process_graph) {
154 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
155 _process_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), declick);
157 PT_TIMING_CHECK (10);
158 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
160 if ((*i)->is_auditioner()) {
164 (*i)->set_pending_declick (declick);
166 if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending())) {
167 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
172 PT_TIMING_CHECK (11);
179 /** @param need_butler to be set to true by this method if it needs the butler,
180 * otherwise it must be left alone.
183 Session::process_routes (pframes_t nframes, bool& need_butler)
185 int declick = (config.get_use_transport_fades() ? get_transport_declick_required() : false);
186 boost::shared_ptr<RouteList> r = routes.reader ();
188 const framepos_t start_frame = _transport_frame;
189 const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
191 VCAList v = _vca_manager->vcas ();
192 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
193 (*i)->automation_run (start_frame, nframes);
196 _global_locate_pending = locate_pending ();
198 if (_process_graph) {
199 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
200 if (_process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler) < 0) {
206 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
210 if ((*i)->is_auditioner()) {
214 (*i)->set_pending_declick (declick);
218 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, b)) < 0) {
224 DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 rolled and needs butler\n", (*i)->name()));
234 Session::get_track_statistics ()
239 boost::shared_ptr<RouteList> rl = routes.reader();
240 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
242 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
244 if (!tr || tr->is_private_route()) {
248 pworst = min (pworst, tr->playback_buffer_load());
249 cworst = min (cworst, tr->capture_buffer_load());
252 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
253 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
255 if (actively_recording()) {
260 /** Process callback used when the auditioner is not active */
262 Session::process_with_events (pframes_t nframes)
267 pframes_t this_nframes;
268 framepos_t end_frame;
269 bool session_needs_butler = false;
270 framecnt_t frames_moved;
272 /* make sure the auditioner is silent */
275 auditioner->silence (nframes);
278 /* handle any pending events */
280 while (pending_events.read (&ev, 1) == 1) {
284 /* if we are not in the middle of a state change,
285 and there are immediate events queued up,
289 while (!non_realtime_work_pending() && !immediate_events.empty()) {
290 SessionEvent *ev = immediate_events.front ();
291 immediate_events.pop_front ();
296 if (_transport_speed != 1.0 && _count_in_samples > 0) {
297 _count_in_samples = 0;
300 if (_count_in_samples > 0) {
301 framecnt_t ns = std::min ((framecnt_t)nframes, _count_in_samples);
304 run_click (_transport_frame - _count_in_samples, ns);
306 _count_in_samples -= ns;
309 /* process events.. */
310 if (!events.empty() && next_event != events.end()) {
311 SessionEvent* this_event = *next_event;
312 Events::iterator the_next_one = next_event;
315 while (this_event && this_event->action_frame == _transport_frame) {
316 process_event (this_event);
317 if (the_next_one == events.end()) {
320 this_event = *the_next_one;
327 check_declick_out ();
332 _engine.split_cycle (ns);
336 /* Decide on what to do with quarter-frame MTC during this cycle */
338 bool const was_sending_qf_mtc = _send_qf_mtc;
339 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
341 if (_transport_speed != 0) {
343 Config->get_send_mtc () &&
344 _transport_speed >= (1 - tolerance) &&
345 _transport_speed <= (1 + tolerance)
348 if (_send_qf_mtc && !was_sending_qf_mtc) {
349 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
350 _send_timecode_update = true;
353 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (frame_rate () / 4)) {
354 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
355 a quarter of a second since we sent anything at all, so send a full MTC update
358 _send_timecode_update = true;
361 _pframes_since_last_mtc += nframes;
364 /* Events caused a transport change (or we re-started sending
365 * MTC), so send an MTC Full Frame (Timecode) message. This
366 * is sent whether rolling or not, to give slaves an idea of
367 * ardour time on locates (and allow slow slaves to position
368 * and prepare for rolling)
370 if (_send_timecode_update) {
371 send_full_time_code (_transport_frame, nframes);
374 if (!process_can_proceed()) {
379 if (events.empty() || next_event == events.end()) {
380 try_run_lua (nframes); // also during export ?? ->move to process_without_events()
381 /* lua scripts may inject events */
382 while (_n_lua_scripts > 0 && pending_events.read (&ev, 1) == 1) {
385 if (events.empty() || next_event == events.end()) {
386 process_without_events (nframes);
391 if (_transport_speed == 1.0) {
392 frames_moved = (framecnt_t) nframes;
394 interpolation.set_target_speed (_target_transport_speed);
395 interpolation.set_speed (_transport_speed);
396 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
399 end_frame = _transport_frame + frames_moved;
402 SessionEvent* this_event;
403 Events::iterator the_next_one;
405 if (!process_can_proceed()) {
410 if (!_exporting && _slave) {
411 if (!follow_slave (nframes)) {
412 cerr << "P-w-E: FS fail\n";
417 if (_transport_speed == 0) {
418 cerr << "P-w-E: ts = 0\n";
423 if (!_exporting && !timecode_transmission_suspended()) {
424 send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
427 ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
429 framepos_t stop_limit = compute_stop_limit ();
431 if (maybe_stop (stop_limit)) {
432 cerr << "P-w-E: mebbe stop\n";
437 this_event = *next_event;
438 the_next_one = next_event;
441 /* yes folks, here it is, the actual loop where we really truly
447 this_nframes = nframes; /* real (jack) time relative */
448 frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
450 /* running an event, position transport precisely to its time */
451 if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
452 /* this isn't quite right for reverse play */
453 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
454 this_nframes = abs (floor(frames_moved / _transport_speed));
457 try_run_lua (this_nframes);
461 click (_transport_frame, this_nframes);
463 if (process_routes (this_nframes, session_needs_butler)) {
464 cerr << "P-w-E: PR fail\n";
469 get_track_statistics ();
471 nframes -= this_nframes;
473 if (frames_moved < 0) {
474 decrement_transport_position (-frames_moved);
475 } else if (frames_moved) {
476 increment_transport_position (frames_moved);
479 cerr << "P-w-E: ts now = " << _transport_frame << endl;
481 maybe_stop (stop_limit);
482 check_declick_out ();
486 _engine.split_cycle (this_nframes);
489 /* now handle this event and all others scheduled for the same time */
491 while (this_event && this_event->action_frame == _transport_frame) {
492 process_event (this_event);
494 if (the_next_one == events.end()) {
497 this_event = *the_next_one;
502 /* if an event left our state changing, do the right thing */
504 if (nframes && non_realtime_work_pending()) {
505 cerr << "P-w-E: nrtwp no roll\n";
510 /* this is necessary to handle the case of seamless looping */
511 end_frame = _transport_frame + floor (nframes * _transport_speed);
516 } /* implicit release of route lock */
518 cerr << "P-w-E: final ts = " << _transport_frame << endl;
520 if (session_needs_butler) {
521 DEBUG_TRACE (DEBUG::Butler, "p-with-events: session needs butler, call it\n");
527 Session::reset_slave_state ()
529 average_slave_delta = 1800;
530 delta_accumulator_cnt = 0;
531 have_first_delta_accumulator = false;
532 _slave_state = Stopped;
533 DiskReader::set_no_disk_output (false);
537 Session::transport_locked () const
541 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
549 Session::follow_slave (pframes_t nframes)
552 framepos_t slave_transport_frame;
553 framecnt_t this_delta;
558 config.set_external_sync (false);
562 _slave->speed_and_position (slave_speed, slave_transport_frame);
564 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
566 if (!_slave->locked()) {
567 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
571 if (slave_transport_frame > _transport_frame) {
572 this_delta = slave_transport_frame - _transport_frame;
575 this_delta = _transport_frame - slave_transport_frame;
579 if (_slave->starting()) {
583 if (_slave->is_always_synced() ||
584 (Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
587 /* if the TC source is synced, then we assume that its
588 speed is binary: 0.0 or 1.0
591 if (slave_speed != 0.0f) {
597 /* if we are chasing and the average delta between us and the
598 master gets too big, we want to switch to silent
599 motion. so keep track of that here.
602 if (_slave_state == Running) {
603 calculate_moving_average_of_slave_delta(dir, abs(this_delta));
607 track_slave_state (slave_speed, slave_transport_frame, this_delta);
609 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
610 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
613 if (_slave_state == Running && !_slave->is_always_synced() && !(Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)) {
615 /* may need to varispeed to sync with slave */
617 if (_transport_speed != 0.0f) {
620 note that average_dir is +1 or -1
625 if (average_slave_delta == 0) {
629 delta = average_slave_delta;
630 delta *= average_dir;
634 if (slave_speed != 0.0) {
635 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
636 (int) (dir * this_delta),
640 slave_transport_frame,
641 average_slave_delta));
645 if (_slave->give_slave_full_control_over_transport_speed()) {
646 set_transport_speed (slave_speed, 0, false, false);
647 //std::cout << "set speed = " << slave_speed << "\n";
649 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
650 request_transport_speed (adjusted_speed);
651 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
652 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
656 if (!actively_recording() && (framecnt_t) average_slave_delta > _slave->resolution()) {
657 DEBUG_TRACE (DEBUG::Slave, string_compose ("average slave delta %1 greater than slave resolution %2 => no disk output\n", average_slave_delta, _slave->resolution()));
658 /* run routes as normal, but no disk output */
659 DiskReader::set_no_disk_output (true);
663 if (!have_first_delta_accumulator) {
664 DEBUG_TRACE (DEBUG::Slave, "waiting for first slave delta accumulator to be ready, no disk output\n");
665 /* run routes as normal, but no disk output */
666 DiskReader::set_no_disk_output (true);
673 if (!have_first_delta_accumulator) {
674 DEBUG_TRACE (DEBUG::Slave, "still waiting to compute slave delta, no disk output\n");
675 DiskReader::set_no_disk_output (true);
677 DiskReader::set_no_disk_output (false);
680 if ((_slave_state == Running) && (0 == (post_transport_work () & ~PostTransportSpeed))) {
681 /* speed is set, we're locked, and good to go */
686 /* don't move at all */
687 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
693 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
695 if (delta_accumulator_cnt >= delta_accumulator_size) {
696 have_first_delta_accumulator = true;
697 delta_accumulator_cnt = 0;
700 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
701 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
704 if (have_first_delta_accumulator) {
705 average_slave_delta = 0L;
706 for (int i = 0; i < delta_accumulator_size; ++i) {
707 average_slave_delta += delta_accumulator[i];
709 average_slave_delta /= (int32_t) delta_accumulator_size;
710 if (average_slave_delta < 0L) {
712 average_slave_delta = average_slave_delta;
720 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t /*this_delta*/)
722 if (slave_speed != 0.0f) {
724 /* slave is running */
726 switch (_slave_state) {
728 if (_slave->requires_seekahead()) {
729 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
730 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
731 /* we can call locate() here because we are in process context */
732 locate (slave_wait_end, false, false);
733 _slave_state = Waiting;
737 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped -> running at %1\n", slave_transport_frame));
739 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
740 average_slave_delta = 0L;
742 Location* al = _locations->auto_loop_location();
744 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
746 request_play_loop(false);
749 if (slave_transport_frame != _transport_frame) {
750 DEBUG_TRACE (DEBUG::Slave, string_compose ("require locate to run. eng: %1 -> sl: %2\n", _transport_frame, slave_transport_frame));
751 locate (slave_transport_frame, false, false);
753 _slave_state = Running;
762 if (_slave_state == Waiting) {
764 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
766 if (slave_transport_frame >= slave_wait_end) {
768 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
770 _slave_state = Running;
772 /* now perform a "micro-seek" within the disk buffers to realign ourselves
773 precisely with the master.
778 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
780 boost::shared_ptr<RouteList> rl = routes.reader();
781 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
782 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
783 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
790 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
791 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
793 tr->internal_playback_seek (frame_delta);
796 _transport_frame += frame_delta;
799 cerr << "cannot micro-seek\n";
805 if (_slave_state == Running && _transport_speed == 0.0f) {
806 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
810 } else { // slave_speed is 0
812 /* slave has stopped */
814 if (_transport_speed != 0.0f) {
815 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
819 if (slave_transport_frame != _transport_frame) {
820 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
821 force_locate (slave_transport_frame, false);
829 Session::process_without_events (pframes_t nframes)
831 bool session_needs_butler = false;
832 framecnt_t frames_moved;
834 if (!process_can_proceed()) {
839 if (!_exporting && _slave) {
840 if (!follow_slave (nframes)) {
841 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame, 0, 0 , nframes);
842 cerr << "p-WO-E: FS fail\n";
847 if (_transport_speed == 0) {
848 cerr << "p-WO-E: ts = 0\n";
853 if (_transport_speed == 1.0) {
854 frames_moved = (framecnt_t) nframes;
856 interpolation.set_target_speed (_target_transport_speed);
857 interpolation.set_speed (_transport_speed);
858 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
859 cerr << "p-WO-E: current speed : " << _transport_speed << " interpolate says " << frames_moved << endl;
862 cerr << "p-WO-E: will move " << frames_moved << endl;
864 if (!_exporting && !timecode_transmission_suspended()) {
865 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
868 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, _target_transport_speed, _transport_speed, nframes);
870 framepos_t const stop_limit = compute_stop_limit ();
872 if (maybe_stop (stop_limit)) {
873 cerr << "p-WO-E: mebbe stop\n";
878 if (maybe_sync_start (nframes)) {
879 cerr << "p-WO-E: sync start said no\n";
883 click (_transport_frame, nframes);
885 if (process_routes (nframes, session_needs_butler)) {
886 cerr << "p-WO-E: pr failed\n";
891 get_track_statistics ();
893 if (frames_moved < 0) {
894 decrement_transport_position (-frames_moved);
895 } else if (frames_moved) {
896 increment_transport_position (frames_moved);
899 cerr << "p-WO-E: ts now " << _transport_frame << endl;
901 maybe_stop (stop_limit);
902 check_declick_out ();
904 if (session_needs_butler) {
905 DEBUG_TRACE (DEBUG::Butler, "p-without-events: session needs butler, call it\n");
910 /** Process callback used when the auditioner is active.
911 * @param nframes number of frames to process.
914 Session::process_audition (pframes_t nframes)
917 boost::shared_ptr<RouteList> r = routes.reader ();
919 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
920 if (!(*i)->is_auditioner()) {
921 (*i)->silence (nframes);
925 /* run the auditioner, and if it says we need butler service, ask for it */
927 if (auditioner->play_audition (nframes) > 0) {
928 DEBUG_TRACE (DEBUG::Butler, "auditioner needs butler, call it\n");
932 /* if using a monitor section, run it because otherwise we don't hear anything */
934 if (_monitor_out && auditioner->needs_monitor()) {
935 _monitor_out->monitor_run (_transport_frame, _transport_frame + nframes, nframes, false);
938 /* handle pending events */
940 while (pending_events.read (&ev, 1) == 1) {
944 /* if we are not in the middle of a state change,
945 and there are immediate events queued up,
949 while (!non_realtime_work_pending() && !immediate_events.empty()) {
950 SessionEvent *ev = immediate_events.front ();
951 immediate_events.pop_front ();
955 if (!auditioner->auditioning()) {
956 /* auditioner no longer active, so go back to the normal process callback */
957 process_function = &Session::process_with_events;
962 Session::maybe_sync_start (pframes_t & nframes)
964 pframes_t sync_offset;
966 if (!waiting_for_sync_offset) {
970 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
972 /* generate silence up to the sync point, then
973 adjust nframes + offset to reflect whatever
977 no_roll (sync_offset);
978 nframes -= sync_offset;
979 Port::increment_global_port_buffer_offset (sync_offset);
980 waiting_for_sync_offset = false;
983 return true; // done, nothing left to process
988 /* sync offset point is not within this process()
989 cycle, so just generate silence. and don't bother
990 with any fancy stuff here, just the minimal silence.
995 if (Config->get_locate_while_waiting_for_sync()) {
996 if (micro_locate (nframes)) {
997 /* XXX ERROR !!! XXX */
1001 return true; // done, nothing left to process
1008 Session::queue_event (SessionEvent* ev)
1010 if (_state_of_the_state & Deletion) {
1012 } else if (_state_of_the_state & Loading) {
1015 Glib::Threads::Mutex::Lock lm (rb_write_lock);
1016 pending_events.write (&ev, 1);
1021 Session::set_next_event ()
1023 if (events.empty()) {
1024 next_event = events.end();
1028 if (next_event == events.end()) {
1029 next_event = events.begin();
1032 if ((*next_event)->action_frame > _transport_frame) {
1033 next_event = events.begin();
1036 for (; next_event != events.end(); ++next_event) {
1037 if ((*next_event)->action_frame >= _transport_frame) {
1044 Session::process_event (SessionEvent* ev)
1049 /* if we're in the middle of a state change (i.e. waiting
1050 for the butler thread to complete the non-realtime
1051 part of the change), we'll just have to queue this
1052 event for a time when the change is complete.
1055 if (non_realtime_work_pending()) {
1057 /* except locates, which we have the capability to handle */
1059 if (ev->type != SessionEvent::Locate) {
1060 immediate_events.insert (immediate_events.end(), ev);
1066 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1069 case SessionEvent::SetLoop:
1070 set_play_loop (ev->yes_or_no, ev->speed);
1073 case SessionEvent::AutoLoop:
1075 /* roll after locate, do not flush, set "with loop"
1076 true only if we are seamless looping
1078 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1084 case SessionEvent::AutoLoopDeclick:
1086 /* Request a declick fade-out and a fade-in; the fade-out will happen
1087 at the end of the loop, and the fade-in at the start.
1089 transport_sub_state |= (PendingLoopDeclickOut | PendingLoopDeclickIn);
1095 case SessionEvent::Locate:
1096 if (ev->yes_or_no) {
1097 /* args: do not roll after locate, do flush, not with loop */
1098 locate (ev->target_frame, false, true, false);
1100 /* args: do not roll after locate, do flush, not with loop */
1101 start_locate (ev->target_frame, false, true, false);
1103 _send_timecode_update = true;
1106 case SessionEvent::LocateRoll:
1107 if (ev->yes_or_no) {
1108 /* args: roll after locate, do flush, not with loop */
1109 locate (ev->target_frame, true, true, false);
1111 /* args: roll after locate, do flush, not with loop */
1112 start_locate (ev->target_frame, true, true, false);
1114 _send_timecode_update = true;
1117 case SessionEvent::Skip:
1118 if (Config->get_skip_playback()) {
1119 start_locate (ev->target_frame, true, true, false);
1120 _send_timecode_update = true;
1126 case SessionEvent::LocateRollLocate:
1127 // locate is handled by ::request_roll_at_and_return()
1128 _requested_return_frame = ev->target_frame;
1129 request_locate (ev->target2_frame, true);
1133 case SessionEvent::SetTransportSpeed:
1134 set_transport_speed (ev->speed, ev->target_frame, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
1137 case SessionEvent::PunchIn:
1138 // cerr << "PunchIN at " << transport_frame() << endl;
1139 if (config.get_punch_in() && record_status() == Enabled && !preroll_record_punch_enabled()) {
1146 case SessionEvent::PunchOut:
1147 // cerr << "PunchOUT at " << transport_frame() << endl;
1148 if (config.get_punch_out() && !preroll_record_punch_enabled()) {
1149 step_back_from_record ();
1155 case SessionEvent::RecordStart:
1156 if (preroll_record_punch_enabled() && record_status() == Enabled) {
1163 case SessionEvent::StopOnce:
1164 if (!non_realtime_work_pending()) {
1165 _clear_event_type (SessionEvent::StopOnce);
1166 stop_transport (ev->yes_or_no);
1172 case SessionEvent::RangeStop:
1173 if (!non_realtime_work_pending()) {
1174 stop_transport (ev->yes_or_no);
1180 case SessionEvent::RangeLocate:
1181 /* args: roll after locate, do flush, not with loop */
1182 start_locate (ev->target_frame, true, true, false);
1187 case SessionEvent::Overwrite:
1188 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1191 case SessionEvent::SetSyncSource:
1192 DEBUG_TRACE (DEBUG::Slave, "seen request for new slave\n");
1193 use_sync_source (ev->slave);
1196 case SessionEvent::Audition:
1197 set_audition (ev->region);
1198 // drop reference to region
1199 ev->region.reset ();
1202 case SessionEvent::SetPlayAudioRange:
1203 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1206 case SessionEvent::CancelPlayAudioRange:
1210 case SessionEvent::RealTimeOperation:
1212 del = false; // other side of RT request needs to clean up
1215 case SessionEvent::AdjustPlaybackBuffering:
1216 schedule_playback_buffering_adjustment ();
1219 case SessionEvent::AdjustCaptureBuffering:
1220 schedule_capture_buffering_adjustment ();
1223 case SessionEvent::SetTimecodeTransmission:
1224 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1228 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1229 abort(); /*NOTREACHED*/
1234 del = del && !_remove_event (ev);
1243 Session::compute_stop_limit () const
1245 if (!Config->get_stop_at_session_end ()) {
1246 return max_framepos;
1250 return max_framepos;
1253 if (preroll_record_punch_enabled ()) {
1254 return max_framepos;
1257 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1258 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1260 if (actively_recording ()) {
1261 /* permanently recording */
1262 return max_framepos;
1263 } else if (punching_in && !punching_out) {
1264 /* punching in but never out */
1265 return max_framepos;
1266 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_frame()) {
1267 /* punching in and punching out after session end */
1268 return max_framepos;
1271 return current_end_frame ();
1276 /* dedicated thread for signal emission.
1278 * while sending cross-thread signals from the process thread
1279 * is fine in general, PBD::Signal's use of boost::function and
1280 * boost:bind can produce a vast overhead which is not
1281 * acceptable for low latency.
1283 * This works around the issue by moving the boost overhead
1284 * out of the RT thread. The overall load is probably higher but
1285 * the realtime thread remains unaffected.
1289 Session::emit_route_signals ()
1291 // TODO use RAII to allow using these signals in other places
1292 BatchUpdateStart(); /* EMIT SIGNAL */
1293 boost::shared_ptr<RouteList> r = routes.reader ();
1294 for (RouteList::const_iterator ci = r->begin(); ci != r->end(); ++ci) {
1295 (*ci)->emit_pending_signals ();
1297 BatchUpdateEnd(); /* EMIT SIGNAL */
1301 Session::emit_thread_start ()
1303 if (_rt_thread_active) {
1306 _rt_thread_active = true;
1308 if (pthread_create (&_rt_emit_thread, NULL, emit_thread, this)) {
1309 _rt_thread_active = false;
1314 Session::emit_thread_terminate ()
1316 if (!_rt_thread_active) {
1319 _rt_thread_active = false;
1321 if (pthread_mutex_lock (&_rt_emit_mutex) == 0) {
1322 pthread_cond_signal (&_rt_emit_cond);
1323 pthread_mutex_unlock (&_rt_emit_mutex);
1327 pthread_join (_rt_emit_thread, &status);
1331 Session::emit_thread (void *arg)
1333 Session *s = static_cast<Session *>(arg);
1334 s->emit_thread_run ();
1340 Session::emit_thread_run ()
1342 pthread_mutex_lock (&_rt_emit_mutex);
1343 while (_rt_thread_active) {
1344 emit_route_signals();
1345 pthread_cond_wait (&_rt_emit_cond, &_rt_emit_mutex);
1347 pthread_mutex_unlock (&_rt_emit_mutex);