21 #include "libardour-config.h"
35 #include "midi++/mmc.h"
36 #include "midi++/port.h"
42 #include "ardour/debug.h"
66 if (g_atomic_int_compare_and_exchange (&_post_transport_work, oldval, newval)) {
72 error <<
"Could not set post transport work! Crazy thread madness, call the programmers" <<
endmsg;
76 Session::request_input_change_handling ()
78 if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
79 SessionEvent* ev =
new SessionEvent (SessionEvent::InputConfigurationChange, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
85 Session::request_sync_source (
Slave* new_slave)
87 SessionEvent* ev =
new SessionEvent (SessionEvent::SetSyncSource, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
90 seamless =
Config->get_seamless_loop ();
92 if (dynamic_cast<Engine_Slave*>(new_slave)) {
94 Config->set_seamless_loop (
false);
97 Config->set_seamless_loop (_was_seamless);
101 _was_seamless = seamless;
103 ev->
slave = new_slave;
109 Session::request_transport_speed (
double speed,
bool as_default)
111 SessionEvent* ev =
new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
122 Session::request_transport_speed_nonzero (
double speed,
bool as_default)
128 request_transport_speed (speed, as_default);
132 Session::request_track_speed (
Track* tr,
double speed)
134 SessionEvent* ev =
new SessionEvent (SessionEvent::SetTrackSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
140 Session::request_stop (
bool abort,
bool clear_state)
142 SessionEvent* ev =
new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, audible_frame(), 0.0, abort, clear_state);
148 Session::request_locate (
framepos_t target_frame,
bool with_roll)
150 SessionEvent *ev =
new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0,
false);
156 Session::force_locate (
framepos_t target_frame,
bool with_roll)
158 SessionEvent *ev =
new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0,
true);
164 Session::request_play_loop (
bool yn,
bool change_transport_roll)
167 Location *location = _locations->auto_loop_location();
170 if (location == 0 && yn) {
171 error <<
_(
"Cannot loop - no loop range defined")
176 if (change_transport_roll) {
177 if (transport_rolling()) {
179 target_speed = transport_speed ();
191 target_speed = transport_speed ();
194 ev =
new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, target_speed, yn);
199 if (!change_transport_roll) {
200 if (!transport_rolling()) {
205 request_locate (location->
start(),
false);
209 if (!change_transport_roll &&
Config->get_seamless_loop() && transport_rolling()) {
212 request_locate (_transport_frame-1,
false);
218 Session::request_play_range (list<AudioRange>* range,
bool leave_rolling)
220 SessionEvent* ev =
new SessionEvent (SessionEvent::SetPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0));
231 Session::request_cancel_play_range ()
233 SessionEvent* ev =
new SessionEvent (SessionEvent::CancelPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, 0);
239 Session::realtime_stop (
bool abort,
bool clear_state)
246 if (_transport_speed < 0.0
f) {
248 _default_transport_speed = 1.0;
257 for (RouteList::iterator i = r->begin (); i != r->end(); ++i) {
258 (*i)->realtime_handle_transport_stopped ();
276 add_post_transport_work (todo);
279 _clear_event_type (SessionEvent::StopOnce);
280 _clear_event_type (SessionEvent::RangeStop);
281 _clear_event_type (SessionEvent::RangeLocate);
284 disable_record (
true, (!
Config->get_latched_record_enable() && clear_state));
286 reset_slave_state ();
288 _transport_speed = 0;
289 _target_transport_speed = 0;
291 g_atomic_int_set (&_playback_load, 100);
292 g_atomic_int_set (&_capture_load, 100);
294 if (config.get_use_video_sync()) {
295 waiting_for_sync_offset =
true;
298 transport_sub_state = 0;
302 Session::realtime_locate ()
305 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
306 (*i)->realtime_locate ();
311 Session::butler_transport_work ()
318 int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
320 ptw = post_transport_work();
324 if (ptw & PostTransportAdjustPlaybackBuffering) {
325 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
331 (*i)->non_realtime_locate (_transport_frame);
336 if (ptw & PostTransportAdjustCaptureBuffering) {
337 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
345 if (ptw & PostTransportCurveRealloc) {
346 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
347 (*i)->curve_reallocate();
351 if (ptw & PostTransportInputChange) {
352 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
360 if (ptw & PostTransportSpeed) {
361 non_realtime_set_speed ();
364 if (ptw & PostTransportReverse) {
367 cumulative_rf_motion = 0;
372 if (!(ptw & PostTransportLocate)) {
374 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
375 (*i)->non_realtime_locate (_transport_frame);
377 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
379 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
386 if (ptw & PostTransportLocate) {
388 non_realtime_locate ();
391 if (ptw & PostTransportStop) {
392 non_realtime_stop (ptw & PostTransportAbort, on_entry, finished);
394 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
399 if (ptw & PostTransportOverWrite) {
400 non_realtime_overwrite (on_entry, finished);
402 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
407 if (ptw & PostTransportAudition) {
408 non_realtime_set_audition ();
411 g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
418 Session::non_realtime_set_speed ()
421 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
430 Session::non_realtime_overwrite (
int on_entry,
bool& finished)
433 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
438 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
447 Session::non_realtime_locate ()
451 if (
Config->get_loop_is_mode() && get_play_loop()) {
453 Location *loc = _locations->auto_loop_location();
455 if (!loc || (_transport_frame < loc->
start() || _transport_frame >= loc->
end())) {
459 set_track_loop (
false);
461 }
else if (loc &&
Config->get_seamless_loop() &&
462 ((loc->
start() <= _transport_frame) ||
463 (loc->
end() > _transport_frame) ) ) {
470 set_track_loop (
true);
473 set_track_loop (
false);
483 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
484 (*i)->non_realtime_locate (_transport_frame);
487 _scene_changer->locate (_transport_frame);
497 Session::non_realtime_stop (
bool abort,
int on_entry,
bool& finished)
509 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
520 now = localtime (&xnow);
523 auditioner->cancel_audition ();
526 cumulative_rf_motion = 0;
531 _have_captured =
true;
536 if (abort && did_record) {
542 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
549 if (abort && did_record) {
550 _state_of_the_state =
StateOfTheState (_state_of_the_state & ~InCleanup);
555 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
556 if (!(*i)->is_auditioner()) {
557 (*i)->set_pending_declick (0);
562 commit_reversible_command ();
564 if (config.get_track_name_take () && !config.get_take_name ().empty()) {
565 string newname = config.get_take_name();
570 if (_engine.running()) {
572 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
573 (*i)->nonrealtime_handle_transport_stopped (abort, (ptw & PostTransportLocate), (!(ptw & PostTransportLocate) || pending_locate_flush));
575 update_latency_compensation ();
578 bool const auto_return_enabled =
579 (!config.get_external_sync() && (config.get_auto_return() || abort));
581 if (auto_return_enabled ||
582 (ptw & PostTransportLocate) ||
583 (_requested_return_frame >= 0) ||
584 synced_to_engine()) {
586 if (pending_locate_flush) {
587 flush_all_inserts ();
590 if ((auto_return_enabled || synced_to_engine() || _requested_return_frame >= 0) &&
591 !(ptw & PostTransportLocate)) {
595 bool do_locate =
false;
597 if (_requested_return_frame >= 0) {
601 _transport_frame = _requested_return_frame;
605 if (config.get_auto_return()) {
611 if (!synced_to_engine()) {
613 Location *location = _locations->auto_loop_location();
616 _transport_frame = location->
start();
618 _transport_frame = _last_roll_location;
623 }
else if (_play_range) {
627 if (!current_audio_range.empty()) {
628 _transport_frame = current_audio_range.front().start;
636 _transport_frame = _last_roll_location;
641 _transport_frame = _last_roll_location;
646 _requested_return_frame = -1;
649 _engine.transport_locate (_transport_frame);
660 if (ptw & PostTransportClearSubstate) {
662 if (!
Config->get_loop_is_mode()) {
670 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
672 (*i)->non_realtime_locate (_transport_frame);
674 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
687 if (_engine.connected() && !_engine.freewheeling()) {
689 _send_timecode_update =
true;
691 if (!dynamic_cast<MTC_Slave*>(_slave)) {
692 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
700 send_mmc_locate (_transport_frame);
704 if ((ptw & PostTransportLocate) && get_record_enabled()) {
712 if (!_slave || !_slave->locked()) {
714 SaveSessionRequested (_current_snapshot_name);
721 remove_pending_capture_state ();
725 if (did_record && !saved) {
726 SaveSessionRequested (_current_snapshot_name);
729 if (ptw & PostTransportStop) {
731 if (!
Config->get_loop_is_mode()) {
736 PositionChanged (_transport_frame);
738 TransportStateChange ();
742 if ((ptw & PostTransportLocate) && !config.get_external_sync() && pending_locate_roll) {
743 request_transport_speed (1.0);
749 pending_locate_roll =
false;
753 Session::check_declick_out ()
755 bool locate_required = transport_sub_state & PendingLocate;
764 if (transport_sub_state & PendingDeclickOut) {
766 if (locate_required) {
767 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
768 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
770 if (!(transport_sub_state & StopPendingCapture)) {
771 stop_transport (pending_abort);
772 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
776 }
else if (transport_sub_state & PendingLoopDeclickOut) {
778 transport_sub_state &= ~PendingLoopDeclickOut;
783 Session::unset_play_loop ()
787 clear_events (SessionEvent::AutoLoop);
788 clear_events (SessionEvent::AutoLoopDeclick);
789 set_track_loop (
false);
792 if (
Config->get_seamless_loop()) {
794 add_post_transport_work (PostTransportLocate);
795 _butler->schedule_transport_work ();
801 Session::set_track_loop (
bool yn)
803 Location* loc = _locations->auto_loop_location ();
811 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
813 if (tr && !tr->
hidden()) {
820 Session::set_play_loop (
bool yn,
double speed)
826 if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) {
831 if (yn &&
Config->get_seamless_loop() && synced_to_engine()) {
833 _(
"Seamless looping cannot be supported while %1 is using JACK transport.\n"
834 "Recommend changing the configured options"), PROGRAM_NAME)
848 if (
Config->get_seamless_loop()) {
849 if (!
Config->get_loop_is_mode()) {
851 set_track_loop (
true);
859 set_track_loop (
false);
869 auto_loop_declick_range (loc, dcp, dcl);
870 merge_event (
new SessionEvent (SessionEvent::AutoLoopDeclick, SessionEvent::Replace, dcp, dcl, 0.0
f));
871 merge_event (
new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->
end(), loc->
start(), 0.0f));
879 if (
Config->get_loop_is_mode()) {
883 if (!transport_rolling() && (speed != 0.0)) {
884 start_locate (loc->
start(),
true,
true,
false,
Config->get_seamless_loop());
888 start_locate (loc->
start(),
true,
true,
false,
Config->get_seamless_loop());
899 TransportStateChange ();
902 Session::flush_all_inserts ()
906 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
907 (*i)->flush_processors ();
912 Session::start_locate (
framepos_t target_frame,
bool with_roll,
bool with_flush,
bool with_loop,
bool force)
914 if (target_frame < 0) {
915 error <<
_(
"Locate called for negative sample position - ignored") <<
endmsg;
919 if (synced_to_engine()) {
924 _slave->speed_and_position (sp, pos);
926 if (target_frame != pos) {
928 if (config.get_jack_time_master()) {
933 locate (target_frame, with_roll, with_flush, with_loop, force);
940 _engine.transport_locate (target_frame);
942 if (sp != 1.0
f && with_roll) {
943 _engine.transport_start ();
949 locate (target_frame, with_roll, with_flush, with_loop, force);
957 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
964 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
971 _transport_frame += distance;
977 Session::locate (
framepos_t target_frame,
bool with_roll,
bool with_flush,
bool for_seamless_loop,
bool force,
bool with_mmc)
979 bool need_butler =
false;
990 target_frame, with_roll, with_flush, for_seamless_loop, force, with_mmc));
992 if (actively_recording() && !for_seamless_loop) {
996 if (!force && _transport_frame == target_frame && !loop_changing && !for_seamless_loop) {
998 set_transport_speed (1.0, 0,
false);
1000 loop_changing =
false;
1005 if (_transport_speed && !for_seamless_loop) {
1011 if (!(transport_sub_state & PendingDeclickOut)) {
1012 transport_sub_state |= (PendingDeclickOut|PendingLocate);
1013 pending_locate_frame = target_frame;
1014 pending_locate_roll = with_roll;
1015 pending_locate_flush = with_flush;
1022 _transport_frame = target_frame;
1023 _last_roll_or_reversal_location = target_frame;
1024 timecode_time(_transport_frame, transmitting_timecode_time);
1025 outbound_mtc_timecode_frame = _transport_frame;
1026 next_quarter_frame_to_send = 0;
1037 bool transport_was_stopped = !transport_rolling();
1039 if (transport_was_stopped && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_engine() && play_loop)) {
1040 realtime_stop (
false,
true);
1041 transport_was_stopped =
true;
1047 if (force || !for_seamless_loop || loop_changing) {
1051 if (with_roll && transport_was_stopped) {
1055 add_post_transport_work (todo);
1062 Glib::Threads::RWLock::WriterLock clickm (click_lock, Glib::Threads::TRY_LOCK);
1064 if (clickm.locked()) {
1066 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
1077 set_track_monitor_input_status (!config.get_auto_input());
1082 set_track_monitor_input_status (
true);
1089 Location* al = _locations->auto_loop_location();
1092 if (_transport_frame < al->
start() || _transport_frame > al->
end()) {
1096 have_looped =
false;
1098 if (!
Config->get_loop_is_mode()) {
1099 set_play_loop (
false, _transport_speed);
1101 if (
Config->get_seamless_loop()) {
1106 set_track_loop (
false);
1110 }
else if (_transport_frame == al->
start()) {
1114 if (for_seamless_loop) {
1118 if (_last_roll_location != al->
start()) {
1123 add_post_transport_work (PostTransportLocate);
1133 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1150 _butler->schedule_transport_work ();
1153 loop_changing =
false;
1155 _send_timecode_update =
true;
1158 send_mmc_locate (_transport_frame);
1161 _last_roll_location = _last_roll_or_reversal_location = _transport_frame;
1170 Session::set_transport_speed (
double speed,
framepos_t destination_frame,
bool abort,
bool clear_state,
bool as_default)
1173 speed, abort, clear_state, _transport_speed, _transport_frame, as_default));
1175 if (_transport_speed == speed) {
1176 if (as_default && speed == 0.0) {
1177 _default_transport_speed = 1.0;
1182 if (actively_recording() && speed != 1.0 && speed != 0.0) {
1185 _transport_speed, _transport_frame));
1189 _target_transport_speed = fabs(speed);
1196 speed = min (8.0, speed);
1197 }
else if (speed < 0) {
1198 speed = max (-8.0, speed);
1201 if (transport_rolling() && speed == 0.0) {
1206 set_track_monitor_input_status (
true);
1209 if (synced_to_engine ()) {
1214 _play_range =
false;
1217 _engine.transport_stop ();
1219 bool const auto_return_enabled = (!config.get_external_sync() && (config.get_auto_return() || abort));
1221 if (!auto_return_enabled) {
1222 _requested_return_frame = destination_frame;
1225 stop_transport (abort);
1228 if (!
Config->get_loop_is_mode()) {
1232 }
else if (transport_stopped() && speed == 1.0) {
1236 if (
Config->get_loop_is_mode() && play_loop) {
1238 Location *location = _locations->auto_loop_location();
1240 if (location != 0) {
1241 if (_transport_frame != location->
start()) {
1243 if (
Config->get_seamless_loop()) {
1245 set_track_loop (
true);
1250 request_locate (location->
start(),
true);
1257 set_track_monitor_input_status (
false);
1260 if (synced_to_engine()) {
1261 _engine.transport_start ();
1270 if ((synced_to_engine()) && speed != 0.0 && speed != 1.0) {
1272 _(
"Global varispeed cannot be supported while %1 is connected to JACK transport control"),
1278 if (actively_recording()) {
1282 if (speed > 0.0 && _transport_frame == current_end_frame()) {
1286 if (speed < 0.0 && _transport_frame == 0) {
1298 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0
f && speed < 0.0
f)) {
1300 _last_roll_or_reversal_location = _transport_frame;
1303 _last_transport_speed = _transport_speed;
1304 _transport_speed = speed;
1307 _default_transport_speed = speed;
1311 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1319 add_post_transport_work (todo);
1320 _butler->schedule_transport_work ();
1337 if (fabsf(_signalled_varispeed - speed) > .002
f
1339 || ( speed == 1.
f && _signalled_varispeed != 1.
f)
1340 || ( speed == 0.
f && _signalled_varispeed != 0.
f)
1343 TransportStateChange ();
1344 _signalled_varispeed = speed;
1352 Session::stop_transport (
bool abort,
bool clear_state)
1354 if (_transport_speed == 0.0
f) {
1358 if (!get_transport_declick_required()) {
1365 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1374 if (actively_recording() &&
1375 worst_input_latency() > current_block_size) {
1388 _transport_frame, _worst_input_latency,
1389 _transport_frame + _worst_input_latency,
1393 _transport_frame + _worst_input_latency,
1403 new_bits =
SubState (PendingDeclickOut|StopPendingCapture);
1409 new_bits = PendingDeclickOut;
1414 transport_sub_state =
SubState (transport_sub_state|new_bits);
1415 pending_abort = abort;
1426 realtime_stop (abort, clear_state);
1427 _butler->schedule_transport_work ();
1433 Session::start_transport ()
1437 _last_roll_location = _transport_frame;
1438 _last_roll_or_reversal_location = _transport_frame;
1440 have_looped =
false;
1446 switch (record_status()) {
1448 if (!config.get_punch_in()) {
1455 disable_record (
false);
1463 transport_sub_state |= PendingDeclickIn;
1465 _transport_speed = _default_transport_speed;
1466 _target_transport_speed = _transport_speed;
1469 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1476 if (!_engine.freewheeling()) {
1477 Timecode::Time time;
1478 timecode_time_subframes (_transport_frame, time);
1479 if (!dynamic_cast<MTC_Slave*>(_slave)) {
1480 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
1485 TransportStateChange ();
1492 Session::post_transport ()
1496 if (ptw & PostTransportAudition) {
1497 if (auditioner && auditioner->auditioning()) {
1498 process_function = &Session::process_audition;
1500 process_function = &Session::process_with_events;
1504 if (ptw & PostTransportStop) {
1506 transport_sub_state = 0;
1509 if (ptw & PostTransportLocate) {
1511 if (((!config.get_external_sync() && (auto_play_legal && config.get_auto_play())) && !_exporting) || (ptw & PostTransportRoll)) {
1514 transport_sub_state = 0;
1528 cumulative_rf_motion += motion;
1530 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1532 }
else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1534 }
else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1546 Session::use_sync_source (
Slave* new_slave)
1550 bool non_rt_required =
false;
1560 _send_timecode_update =
true;
1563 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1565 if (tr && !tr->
hidden()) {
1567 non_rt_required =
true;
1573 if (non_rt_required) {
1574 add_post_transport_work (PostTransportSpeed);
1575 _butler->schedule_transport_work ();
1582 Session::drop_sync_source ()
1584 request_sync_source (0);
1596 if (_slave && dynamic_cast<MTC_Slave*>(_slave)) {
1601 new_slave =
new MTC_Slave (*
this, *_midi_ports->mtc_input_port());
1610 if (_slave && dynamic_cast<LTC_Slave*>(_slave)) {
1625 if (_slave && dynamic_cast<MIDIClock_Slave*>(_slave)) {
1630 new_slave =
new MIDIClock_Slave (*
this, *_midi_ports->midi_clock_input_port(), 24);
1639 if (_slave && dynamic_cast<Engine_Slave*>(_slave)) {
1643 if (config.get_video_pullup() != 0.0f) {
1647 new_slave =
new Engine_Slave (*AudioEngine::instance());
1655 request_sync_source (new_slave);
1659 Session::set_track_speed (
Track* track,
double speed)
1662 add_post_transport_work (PostTransportSpeed);
1663 _butler->schedule_transport_work ();
1669 Session::unset_play_range ()
1671 _play_range =
false;
1672 _clear_event_type (SessionEvent::RangeStop);
1673 _clear_event_type (SessionEvent::RangeLocate);
1677 Session::set_play_range (list<AudioRange>& range,
bool leave_rolling)
1683 unset_play_range ();
1685 if (range.empty()) {
1688 if (!leave_rolling) {
1690 SessionEvent* ev =
new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0
f,
false);
1701 list<AudioRange>::size_type sz = range.size();
1705 list<AudioRange>::iterator i = range.begin();
1706 list<AudioRange>::iterator next;
1708 while (i != range.end()) {
1718 if (requested_frame > current_block_size) {
1719 requested_frame -= current_block_size;
1721 requested_frame = 0;
1724 if (next == range.end()) {
1725 ev =
new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_frame, 0, 0.0
f);
1727 ev =
new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_frame, (*next).start, 0.0f);
1735 }
else if (sz == 1) {
1737 ev =
new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
1744 current_audio_range = range;
1748 ev =
new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f,
false);
1752 TransportStateChange ();
1759 list<AudioRange> lar;
1762 request_play_range (&lar,
true);
1768 _requested_return_frame = return_to;
1774 SessionEvent *ev =
new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
1780 Session::engine_halted ()
1792 g_atomic_int_set (&_butler->should_do_transport_work, 0);
1797 realtime_stop (
false,
true);
1798 non_realtime_stop (
false, 0, ignored);
1799 transport_sub_state = 0;
1802 TransportStateChange ();
1807 Session::xrun_recovery ()
1811 Xrun (_transport_frame);
1813 if (
Config->get_stop_recording_on_xrun() && actively_recording()) {
1826 if (ignore_route_processor_changes) {
1830 if (c.
type == RouteProcessorChange::MeterPointChange) {
1835 if (c.
type == RouteProcessorChange::RealTimeChange) {
1840 update_latency_compensation ();
1847 Session::allow_auto_play (
bool yn)
1849 auto_play_legal = yn;
1855 if ((_transport_speed > 0.0
f && _transport_frame >= limit) || (_transport_speed < 0.0
f && _transport_frame == 0)) {
1856 if (synced_to_engine () && config.get_jack_time_master ()) {
1857 _engine.transport_stop ();
1858 }
else if (!synced_to_engine ()) {
1873 if (!_engine.freewheeling()) {
1874 Timecode::Time time;
1875 timecode_time_subframes (t, time);
1876 send_immediate_mmc (MIDI::MachineControlCommand (time));
1885 Session::request_suspend_timecode_transmission ()
1887 SessionEvent* ev =
new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0,
false);
1892 Session::request_resume_timecode_transmission ()
1894 SessionEvent* ev =
new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0,
true);
1899 Session::timecode_transmission_suspended ()
const
1901 return g_atomic_int_get (&_suspend_timecode_transmission) == 1;
bool pending_overwrite() const
void transport_looped(framepos_t)
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
int overwrite_existing_buffers()
void adjust_capture_buffering()
framecnt_t get_captured_frames(uint32_t n=0) const
LIBPBD_API Transmitter error
LIBPBD_API Transmitter warning
void non_realtime_input_change()
std::ostream & endmsg(std::ostream &ostr)
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
std::list< AudioRange > audio_range
void non_realtime_set_speed()
void prepare_to_stop(framepos_t, framepos_t)
LIBARDOUR_API RCConfiguration * Config
int internal_playback_seek(framecnt_t)
The Slave interface can be used to sync ARDOURs tempo to an external source like MTC, MIDI Clock, etc.
#define DEBUG_TRACE(bits, str)
bool record_enabled() const
void transport_stopped_wallclock(struct tm &, time_t, bool)
LIBARDOUR_API uint64_t Transport
LIBARDOUR_API uint64_t Slave
LIBARDOUR_API std::string bump_name_number(const std::string &s)
int can_internal_playback_seek(framecnt_t)
void adjust_playback_buffering()
bool realtime_set_speed(double, bool)
LIBARDOUR_API uint64_t MTC
LIBARDOUR_API GQuark capture
LIBARDOUR_API uint64_t LTC
std::string string_compose(const std::string &fmt, const T1 &o1)