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 samples to process.
60 Session::process (pframes_t nframes)
62 samplepos_t transport_at_start = _transport_sample;
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 sample
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 samplepos_t end_sample = _transport_sample + nframes; // FIXME: varispeed + no_roll ??
139 boost::shared_ptr<RouteList> r = routes.reader ();
142 _click_io->silence (nframes);
145 ltc_tx_send_time_code_for_cycle (_transport_sample, end_sample, _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_sample, nframes);
152 if (_process_graph) {
153 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
154 _process_graph->routes_no_roll( nframes, _transport_sample, end_sample, non_realtime_work_pending());
156 PT_TIMING_CHECK (10);
157 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
159 if ((*i)->is_auditioner()) {
163 if ((*i)->no_roll (nframes, _transport_sample, end_sample, non_realtime_work_pending())) {
164 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
169 PT_TIMING_CHECK (11);
176 /** @param need_butler to be set to true by this method if it needs the butler,
177 * otherwise it must be left alone.
180 Session::process_routes (pframes_t nframes, bool& need_butler)
182 boost::shared_ptr<RouteList> r = routes.reader ();
184 const samplepos_t start_sample = _transport_sample;
185 const samplepos_t end_sample = _transport_sample + floor (nframes * _transport_speed);
187 VCAList v = _vca_manager->vcas ();
188 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
189 (*i)->automation_run (start_sample, nframes);
192 _global_locate_pending = locate_pending ();
194 if (_process_graph) {
195 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
196 if (_process_graph->process_routes (nframes, start_sample, end_sample, need_butler) < 0) {
202 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
206 if ((*i)->is_auditioner()) {
212 if ((ret = (*i)->roll (nframes, start_sample, end_sample, b)) < 0) {
218 DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 rolled and needs butler\n", (*i)->name()));
228 Session::get_track_statistics ()
233 boost::shared_ptr<RouteList> rl = routes.reader();
234 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
236 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
238 if (!tr || tr->is_private_route()) {
242 pworst = min (pworst, tr->playback_buffer_load());
243 cworst = min (cworst, tr->capture_buffer_load());
246 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
247 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
249 if (actively_recording()) {
254 /** Process callback used when the auditioner is not active */
256 Session::process_with_events (pframes_t nframes)
261 pframes_t this_nframes;
262 samplepos_t end_sample;
263 bool session_needs_butler = false;
264 samplecnt_t samples_moved;
266 /* make sure the auditioner is silent */
269 auditioner->silence (nframes);
272 /* handle any pending events */
274 while (pending_events.read (&ev, 1) == 1) {
278 /* if we are not in the middle of a state change,
279 and there are immediate events queued up,
283 while (!non_realtime_work_pending() && !immediate_events.empty()) {
284 SessionEvent *ev = immediate_events.front ();
285 immediate_events.pop_front ();
289 /* only count-in when going to roll at speed 1.0 */
290 if (_transport_speed != 1.0 && _count_in_samples > 0) {
291 _count_in_samples = 0;
293 if (_transport_speed == 0.0) {
294 _remaining_latency_preroll = 0;
297 assert (_count_in_samples == 0 || _remaining_latency_preroll == 0 || _count_in_samples == _remaining_latency_preroll);
299 while (_count_in_samples > 0 || _remaining_latency_preroll > 0) {
302 if (_remaining_latency_preroll > 0) {
303 ns = std::min ((samplecnt_t)nframes, _remaining_latency_preroll);
305 ns = std::min ((samplecnt_t)nframes, _count_in_samples);
308 boost::shared_ptr<RouteList> r = routes.reader ();
309 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
310 samplecnt_t route_offset = (*i)->playback_latency ();
311 if (_remaining_latency_preroll > route_offset + ns) {
312 /* route will no-roll for complete pre-roll cycle */
315 if (_remaining_latency_preroll > route_offset) {
316 /* route may need partial no-roll and partial roll from
317 * (_transport_sample - _remaining_latency_preroll) .. +ns.
318 * shorten and split the cycle.
320 ns = std::min (ns, (_remaining_latency_preroll - route_offset));
324 if (_count_in_samples > 0) {
325 run_click (_transport_sample - _count_in_samples, ns);
326 assert (_count_in_samples >= ns);
327 _count_in_samples -= ns;
330 if (_remaining_latency_preroll > 0) {
331 if (_count_in_samples == 0) {
332 click (_transport_sample - _remaining_latency_preroll, ns);
334 if (process_routes (ns, session_needs_butler)) {
341 if (_remaining_latency_preroll > 0) {
342 assert (_remaining_latency_preroll >= ns);
343 _remaining_latency_preroll -= ns;
348 /* process events.. */
349 if (!events.empty() && next_event != events.end()) {
350 SessionEvent* this_event = *next_event;
351 Events::iterator the_next_one = next_event;
354 while (this_event && this_event->action_sample == _transport_sample) {
355 process_event (this_event);
356 if (the_next_one == events.end()) {
359 this_event = *the_next_one;
369 _engine.split_cycle (ns);
373 /* Decide on what to do with quarter-frame MTC during this cycle */
375 bool const was_sending_qf_mtc = _send_qf_mtc;
376 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
378 if (_transport_speed != 0) {
380 Config->get_send_mtc () &&
381 _transport_speed >= (1 - tolerance) &&
382 _transport_speed <= (1 + tolerance)
385 if (_send_qf_mtc && !was_sending_qf_mtc) {
386 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
387 _send_timecode_update = true;
390 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (sample_rate () / 4)) {
391 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
392 a quarter of a second since we sent anything at all, so send a full MTC update
395 _send_timecode_update = true;
398 _pframes_since_last_mtc += nframes;
401 /* Events caused a transport change (or we re-started sending
402 * MTC), so send an MTC Full Frame (Timecode) message. This
403 * is sent whether rolling or not, to give slaves an idea of
404 * ardour time on locates (and allow slow slaves to position
405 * and prepare for rolling)
407 if (_send_timecode_update) {
408 send_full_time_code (_transport_sample, nframes);
411 if (!process_can_proceed()) {
416 if (events.empty() || next_event == events.end()) {
417 try_run_lua (nframes); // also during export ?? ->move to process_without_events()
418 /* lua scripts may inject events */
419 while (_n_lua_scripts > 0 && pending_events.read (&ev, 1) == 1) {
422 if (events.empty() || next_event == events.end()) {
423 process_without_events (nframes);
428 assert (_transport_speed == 0 || _transport_speed == 1.0 || _transport_speed == -1.0);
430 samples_moved = (samplecnt_t) nframes * _transport_speed;
432 end_sample = _transport_sample + samples_moved;
435 SessionEvent* this_event;
436 Events::iterator the_next_one;
438 if (!process_can_proceed()) {
443 if (!_exporting && _slave) {
444 if (!follow_slave (nframes)) {
449 if (_transport_speed == 0) {
454 if (!_exporting && !timecode_transmission_suspended()) {
455 send_midi_time_code_for_cycle (_transport_sample, end_sample, nframes);
458 ltc_tx_send_time_code_for_cycle (_transport_sample, end_sample, _target_transport_speed, _transport_speed, nframes);
460 samplepos_t stop_limit = compute_stop_limit ();
462 if (maybe_stop (stop_limit)) {
467 this_event = *next_event;
468 the_next_one = next_event;
471 /* yes folks, here it is, the actual loop where we really truly
477 this_nframes = nframes; /* real (jack) time relative */
478 samples_moved = (samplecnt_t) floor (_transport_speed * nframes); /* transport relative */
480 /* running an event, position transport precisely to its time */
481 if (this_event && this_event->action_sample <= end_sample && this_event->action_sample >= _transport_sample) {
482 /* this isn't quite right for reverse play */
483 samples_moved = (samplecnt_t) (this_event->action_sample - _transport_sample);
484 this_nframes = abs (floor(samples_moved / _transport_speed));
487 try_run_lua (this_nframes);
491 click (_transport_sample, this_nframes);
493 if (process_routes (this_nframes, session_needs_butler)) {
498 get_track_statistics ();
500 nframes -= this_nframes;
502 if (samples_moved < 0) {
503 decrement_transport_position (-samples_moved);
504 } else if (samples_moved) {
505 increment_transport_position (samples_moved);
508 maybe_stop (stop_limit);
512 _engine.split_cycle (this_nframes);
515 /* now handle this event and all others scheduled for the same time */
517 while (this_event && this_event->action_sample == _transport_sample) {
518 process_event (this_event);
520 if (the_next_one == events.end()) {
523 this_event = *the_next_one;
528 /* if an event left our state changing, do the right thing */
530 if (nframes && non_realtime_work_pending()) {
535 /* this is necessary to handle the case of seamless looping */
536 end_sample = _transport_sample + floor (nframes * _transport_speed);
541 } /* implicit release of route lock */
543 if (session_needs_butler) {
544 DEBUG_TRACE (DEBUG::Butler, "p-with-events: session needs butler, call it\n");
550 Session::reset_slave_state ()
552 average_slave_delta = 1800;
553 delta_accumulator_cnt = 0;
554 have_first_delta_accumulator = false;
555 _slave_state = Stopped;
556 DiskReader::set_no_disk_output (false);
560 Session::transport_locked () const
564 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
572 Session::follow_slave (pframes_t nframes)
575 samplepos_t slave_transport_sample;
576 samplecnt_t this_delta;
581 config.set_external_sync (false);
585 _slave->speed_and_position (slave_speed, slave_transport_sample);
587 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_sample, slave_speed));
589 if (!_slave->locked()) {
590 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
594 if (slave_transport_sample > _transport_sample) {
595 this_delta = slave_transport_sample - _transport_sample;
598 this_delta = _transport_sample - slave_transport_sample;
602 if (_slave->starting()) {
606 if (_slave->is_always_synced() ||
607 (Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
610 /* if the TC source is synced, then we assume that its
611 speed is binary: 0.0 or 1.0
614 if (slave_speed != 0.0f) {
620 /* if we are chasing and the average delta between us and the
621 master gets too big, we want to switch to silent
622 motion. so keep track of that here.
625 if (_slave_state == Running) {
626 calculate_moving_average_of_slave_delta(dir, abs(this_delta));
630 track_slave_state (slave_speed, slave_transport_sample, this_delta);
632 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
633 _slave_state, slave_transport_sample, slave_speed, this_delta, average_slave_delta));
636 if (_slave_state == Running && !_slave->is_always_synced() && !(Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)) {
638 /* may need to varispeed to sync with slave */
640 if (_transport_speed != 0.0f) {
643 note that average_dir is +1 or -1
648 if (average_slave_delta == 0) {
652 delta = average_slave_delta;
653 delta *= average_dir;
657 if (slave_speed != 0.0) {
658 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
659 (int) (dir * this_delta),
663 slave_transport_sample,
664 average_slave_delta));
668 if (_slave->give_slave_full_control_over_transport_speed()) {
669 set_transport_speed (slave_speed, 0, false, false);
670 //std::cout << "set speed = " << slave_speed << "\n";
672 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_sample_rate)));
673 request_transport_speed (adjusted_speed);
674 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
675 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
679 if (!actively_recording() && (samplecnt_t) average_slave_delta > _slave->resolution()) {
680 DEBUG_TRACE (DEBUG::Slave, string_compose ("average slave delta %1 greater than slave resolution %2 => no disk output\n", average_slave_delta, _slave->resolution()));
681 /* run routes as normal, but no disk output */
682 DiskReader::set_no_disk_output (true);
686 if (!have_first_delta_accumulator) {
687 DEBUG_TRACE (DEBUG::Slave, "waiting for first slave delta accumulator to be ready, no disk output\n");
688 /* run routes as normal, but no disk output */
689 DiskReader::set_no_disk_output (true);
696 if (!have_first_delta_accumulator) {
697 DEBUG_TRACE (DEBUG::Slave, "still waiting to compute slave delta, no disk output\n");
698 DiskReader::set_no_disk_output (true);
700 DiskReader::set_no_disk_output (false);
703 if ((_slave_state == Running) && (0 == (post_transport_work () & ~PostTransportSpeed))) {
704 /* speed is set, we're locked, and good to go */
709 /* don't move at all */
710 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
716 Session::calculate_moving_average_of_slave_delta (int dir, samplecnt_t this_delta)
718 if (delta_accumulator_cnt >= delta_accumulator_size) {
719 have_first_delta_accumulator = true;
720 delta_accumulator_cnt = 0;
723 if (delta_accumulator_cnt != 0 || this_delta < _current_sample_rate) {
724 delta_accumulator[delta_accumulator_cnt++] = (samplecnt_t) dir * (samplecnt_t) this_delta;
727 if (have_first_delta_accumulator) {
728 average_slave_delta = 0L;
729 for (int i = 0; i < delta_accumulator_size; ++i) {
730 average_slave_delta += delta_accumulator[i];
732 average_slave_delta /= (int32_t) delta_accumulator_size;
733 if (average_slave_delta < 0L) {
735 average_slave_delta = average_slave_delta;
743 Session::track_slave_state (float slave_speed, samplepos_t slave_transport_sample, samplecnt_t /*this_delta*/)
745 if (slave_speed != 0.0f) {
747 /* slave is running */
749 switch (_slave_state) {
751 if (_slave->requires_seekahead()) {
752 slave_wait_end = slave_transport_sample + _slave->seekahead_distance ();
753 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
754 /* we can call locate() here because we are in process context */
755 locate (slave_wait_end, false, false);
756 _slave_state = Waiting;
760 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped -> running at %1\n", slave_transport_sample));
762 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
763 average_slave_delta = 0L;
765 Location* al = _locations->auto_loop_location();
767 if (al && play_loop && (slave_transport_sample < al->start() || slave_transport_sample > al->end())) {
769 request_play_loop(false);
772 if (slave_transport_sample != _transport_sample) {
773 DEBUG_TRACE (DEBUG::Slave, string_compose ("require locate to run. eng: %1 -> sl: %2\n", _transport_sample, slave_transport_sample));
774 locate (slave_transport_sample, false, false);
776 _slave_state = Running;
785 if (_slave_state == Waiting) {
787 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_sample));
789 if (slave_transport_sample >= slave_wait_end) {
791 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_sample, _transport_sample));
793 _slave_state = Running;
795 /* now perform a "micro-seek" within the disk buffers to realign ourselves
796 precisely with the master.
801 samplecnt_t sample_delta = slave_transport_sample - _transport_sample;
803 boost::shared_ptr<RouteList> rl = routes.reader();
804 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
805 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
806 if (tr && !tr->can_internal_playback_seek (sample_delta)) {
813 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
814 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
816 tr->internal_playback_seek (sample_delta);
819 _transport_sample += sample_delta;
822 cerr << "cannot micro-seek\n";
828 if (_slave_state == Running && _transport_speed == 0.0f) {
829 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
833 } else { // slave_speed is 0
835 /* slave has stopped */
837 if (_transport_speed != 0.0f) {
838 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 sample %2 tf %3\n", slave_speed, slave_transport_sample, _transport_sample));
842 if (slave_transport_sample != _transport_sample) {
843 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_sample));
844 force_locate (slave_transport_sample, false);
852 Session::process_without_events (pframes_t nframes)
854 bool session_needs_butler = false;
855 samplecnt_t samples_moved;
857 if (!process_can_proceed()) {
862 if (!_exporting && _slave) {
863 if (!follow_slave (nframes)) {
864 ltc_tx_send_time_code_for_cycle (_transport_sample, _transport_sample, 0, 0 , nframes);
869 if (_transport_speed == 0) {
874 assert (_transport_speed == 1.f || _transport_speed == -1.f);
875 samples_moved = (samplecnt_t) nframes * _transport_speed;
877 if (!_exporting && !timecode_transmission_suspended()) {
878 send_midi_time_code_for_cycle (_transport_sample, _transport_sample + samples_moved, nframes);
881 ltc_tx_send_time_code_for_cycle (_transport_sample, _transport_sample + samples_moved, _target_transport_speed, _transport_speed, nframes);
883 samplepos_t const stop_limit = compute_stop_limit ();
885 if (maybe_stop (stop_limit)) {
890 if (maybe_sync_start (nframes)) {
894 click (_transport_sample, nframes);
896 if (process_routes (nframes, session_needs_butler)) {
901 get_track_statistics ();
903 if (samples_moved < 0) {
904 decrement_transport_position (-samples_moved);
905 } else if (samples_moved) {
906 increment_transport_position (samples_moved);
909 maybe_stop (stop_limit);
911 if (session_needs_butler) {
912 DEBUG_TRACE (DEBUG::Butler, "p-without-events: session needs butler, call it\n");
917 /** Process callback used when the auditioner is active.
918 * @param nframes number of samples to process.
921 Session::process_audition (pframes_t nframes)
924 boost::shared_ptr<RouteList> r = routes.reader ();
926 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
927 if (!(*i)->is_auditioner()) {
928 (*i)->silence (nframes);
932 /* run the auditioner, and if it says we need butler service, ask for it */
934 if (auditioner->play_audition (nframes) > 0) {
935 DEBUG_TRACE (DEBUG::Butler, "auditioner needs butler, call it\n");
939 /* if using a monitor section, run it because otherwise we don't hear anything */
941 if (_monitor_out && auditioner->needs_monitor()) {
942 _monitor_out->monitor_run (_transport_sample, _transport_sample + nframes, nframes);
945 /* handle pending events */
947 while (pending_events.read (&ev, 1) == 1) {
951 /* if we are not in the middle of a state change,
952 and there are immediate events queued up,
956 while (!non_realtime_work_pending() && !immediate_events.empty()) {
957 SessionEvent *ev = immediate_events.front ();
958 immediate_events.pop_front ();
962 if (!auditioner->auditioning()) {
963 /* auditioner no longer active, so go back to the normal process callback */
964 process_function = &Session::process_with_events;
969 Session::maybe_sync_start (pframes_t & nframes)
971 pframes_t sync_offset;
973 if (!waiting_for_sync_offset) {
977 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
979 /* generate silence up to the sync point, then
980 adjust nframes + offset to reflect whatever
984 no_roll (sync_offset);
985 nframes -= sync_offset;
986 Port::increment_global_port_buffer_offset (sync_offset);
987 waiting_for_sync_offset = false;
990 return true; // done, nothing left to process
995 /* sync offset point is not within this process()
996 cycle, so just generate silence. and don't bother
997 with any fancy stuff here, just the minimal silence.
1002 if (Config->get_locate_while_waiting_for_sync()) {
1003 if (micro_locate (nframes)) {
1004 /* XXX ERROR !!! XXX */
1008 return true; // done, nothing left to process
1015 Session::queue_event (SessionEvent* ev)
1017 if (_state_of_the_state & Deletion) {
1019 } else if (_state_of_the_state & Loading) {
1022 Glib::Threads::Mutex::Lock lm (rb_write_lock);
1023 pending_events.write (&ev, 1);
1028 Session::set_next_event ()
1030 if (events.empty()) {
1031 next_event = events.end();
1035 if (next_event == events.end()) {
1036 next_event = events.begin();
1039 if ((*next_event)->action_sample > _transport_sample) {
1040 next_event = events.begin();
1043 for (; next_event != events.end(); ++next_event) {
1044 if ((*next_event)->action_sample >= _transport_sample) {
1051 Session::process_event (SessionEvent* ev)
1056 /* if we're in the middle of a state change (i.e. waiting
1057 for the butler thread to complete the non-realtime
1058 part of the change), we'll just have to queue this
1059 event for a time when the change is complete.
1062 if (non_realtime_work_pending()) {
1064 /* except locates, which we have the capability to handle */
1066 if (ev->type != SessionEvent::Locate) {
1067 immediate_events.insert (immediate_events.end(), ev);
1073 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_sample));
1076 case SessionEvent::SetLoop:
1077 set_play_loop (ev->yes_or_no, ev->speed);
1080 case SessionEvent::AutoLoop:
1082 /* roll after locate, do not flush, set "with loop"
1083 true only if we are seamless looping
1085 start_locate (ev->target_sample, true, false, Config->get_seamless_loop());
1091 case SessionEvent::Locate:
1092 if (ev->yes_or_no) { /* force locate */
1093 /* args: do not roll after locate, do flush, not with loop */
1094 locate (ev->target_sample, false, true, false);
1096 /* args: do not roll after locate, do flush, not with loop */
1097 start_locate (ev->target_sample, false, true, false);
1099 _send_timecode_update = true;
1102 case SessionEvent::LocateRoll:
1103 if (ev->yes_or_no) {
1104 /* args: roll after locate, do flush, not with loop */
1105 locate (ev->target_sample, true, true, false);
1107 /* args: roll after locate, do flush, not with loop */
1108 start_locate (ev->target_sample, true, true, false);
1110 _send_timecode_update = true;
1113 case SessionEvent::Skip:
1114 if (Config->get_skip_playback()) {
1115 start_locate (ev->target_sample, true, true, false);
1116 _send_timecode_update = true;
1122 case SessionEvent::LocateRollLocate:
1123 // locate is handled by ::request_roll_at_and_return()
1124 _requested_return_sample = ev->target_sample;
1125 request_locate (ev->target2_sample, true);
1129 case SessionEvent::SetTransportSpeed:
1130 set_transport_speed (ev->speed, ev->target_sample, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
1133 case SessionEvent::PunchIn:
1134 // cerr << "PunchIN at " << transport_sample() << endl;
1135 if (config.get_punch_in() && record_status() == Enabled) {
1142 case SessionEvent::PunchOut:
1143 // cerr << "PunchOUT at " << transport_sample() << endl;
1144 if (config.get_punch_out()) {
1145 step_back_from_record ();
1151 case SessionEvent::StopOnce:
1152 if (!non_realtime_work_pending()) {
1153 _clear_event_type (SessionEvent::StopOnce);
1154 stop_transport (ev->yes_or_no);
1160 case SessionEvent::RangeStop:
1161 if (!non_realtime_work_pending()) {
1162 stop_transport (ev->yes_or_no);
1168 case SessionEvent::RangeLocate:
1169 /* args: roll after locate, do flush, not with loop */
1170 start_locate (ev->target_sample, true, true, false);
1175 case SessionEvent::Overwrite:
1176 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1179 case SessionEvent::SetSyncSource:
1180 DEBUG_TRACE (DEBUG::Slave, "seen request for new slave\n");
1181 use_sync_source (ev->slave);
1184 case SessionEvent::Audition:
1185 set_audition (ev->region);
1186 // drop reference to region
1187 ev->region.reset ();
1190 case SessionEvent::SetPlayAudioRange:
1191 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1194 case SessionEvent::CancelPlayAudioRange:
1198 case SessionEvent::RealTimeOperation:
1200 del = false; // other side of RT request needs to clean up
1203 case SessionEvent::AdjustPlaybackBuffering:
1204 schedule_playback_buffering_adjustment ();
1207 case SessionEvent::AdjustCaptureBuffering:
1208 schedule_capture_buffering_adjustment ();
1211 case SessionEvent::SetTimecodeTransmission:
1212 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1216 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1217 abort(); /*NOTREACHED*/
1222 del = del && !_remove_event (ev);
1231 Session::compute_stop_limit () const
1233 if (!Config->get_stop_at_session_end ()) {
1234 return max_samplepos;
1238 return max_samplepos;
1241 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1242 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1244 if (actively_recording ()) {
1245 /* permanently recording */
1246 return max_samplepos;
1247 } else if (punching_in && !punching_out) {
1248 /* punching in but never out */
1249 return max_samplepos;
1250 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_sample()) {
1251 /* punching in and punching out after session end */
1252 return max_samplepos;
1255 return current_end_sample ();
1260 /* dedicated thread for signal emission.
1262 * while sending cross-thread signals from the process thread
1263 * is fine in general, PBD::Signal's use of boost::function and
1264 * boost:bind can produce a vast overhead which is not
1265 * acceptable for low latency.
1267 * This works around the issue by moving the boost overhead
1268 * out of the RT thread. The overall load is probably higher but
1269 * the realtime thread remains unaffected.
1273 Session::emit_route_signals ()
1275 // TODO use RAII to allow using these signals in other places
1276 BatchUpdateStart(); /* EMIT SIGNAL */
1277 boost::shared_ptr<RouteList> r = routes.reader ();
1278 for (RouteList::const_iterator ci = r->begin(); ci != r->end(); ++ci) {
1279 (*ci)->emit_pending_signals ();
1281 BatchUpdateEnd(); /* EMIT SIGNAL */
1285 Session::emit_thread_start ()
1287 if (_rt_thread_active) {
1290 _rt_thread_active = true;
1292 if (pthread_create (&_rt_emit_thread, NULL, emit_thread, this)) {
1293 _rt_thread_active = false;
1298 Session::emit_thread_terminate ()
1300 if (!_rt_thread_active) {
1303 _rt_thread_active = false;
1305 if (pthread_mutex_lock (&_rt_emit_mutex) == 0) {
1306 pthread_cond_signal (&_rt_emit_cond);
1307 pthread_mutex_unlock (&_rt_emit_mutex);
1311 pthread_join (_rt_emit_thread, &status);
1315 Session::emit_thread (void *arg)
1317 Session *s = static_cast<Session *>(arg);
1318 s->emit_thread_run ();
1324 Session::emit_thread_run ()
1326 pthread_mutex_lock (&_rt_emit_mutex);
1327 while (_rt_thread_active) {
1328 emit_route_signals();
1329 pthread_cond_wait (&_rt_emit_cond, &_rt_emit_mutex);
1331 pthread_mutex_unlock (&_rt_emit_mutex);