X-Git-Url: https://main.carlh.net/gitweb/?p=ardour.git;a=blobdiff_plain;f=libs%2Fardour%2Fsession.cc;h=61bfce14b6bfc995f0203b44e42bdf17652e60d8;hp=74f20306d2e54a9e6133d69c1b1a828a46b69a1d;hb=c8c6bca6587450ff64303dbc994a4cd28d6ce7aa;hpb=0d050de94e3ae5a1a0dc36114df1995b042f3b80 diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 74f20306d2..61bfce14b6 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -114,7 +114,7 @@ #include "LuaBridge/LuaBridge.h" -#include "i18n.h" +#include "pbd/i18n.h" #include @@ -178,6 +178,7 @@ Session::Session (AudioEngine &eng, , _record_status (Disabled) , _transport_frame (0) , _session_range_location (0) + , _session_range_end_is_free (true) , _slave (0) , _silent (false) , _transport_speed (0) @@ -212,7 +213,9 @@ Session::Session (AudioEngine &eng, , post_export_position (0) , _exporting (false) , _export_rolling (false) + , _realtime_export (false) , _export_preroll (0) + , _export_latency (0) , _pre_export_mmc_enabled (false) , _name (snapshot_name) , _is_new (true) @@ -249,6 +252,7 @@ Session::Session (AudioEngine &eng, , _rt_thread_active (false) , _rt_emit_pending (false) , _ac_thread_active (false) + , _latency_recompute_pending (0) , step_speed (0) , outbound_mtc_timecode_frame (0) , next_quarter_frame_to_send (-1) @@ -279,7 +283,6 @@ Session::Session (AudioEngine &eng, , _reconnecting_routes_in_progress (false) , _route_deletion_in_progress (false) , destructive_index (0) - , _latency_recompute_pending (0) , _track_number_decimals(1) , default_fade_steepness (0) , default_fade_msecs (0) @@ -2027,59 +2030,55 @@ framepos_t Session::audible_frame () const { framepos_t ret; - framepos_t tf; - framecnt_t offset; - offset = worst_playback_latency (); + frameoffset_t offset = worst_playback_latency (); // - _engine.samples_since_cycle_start (); + offset *= transport_speed (); if (synced_to_engine()) { /* Note: this is basically just sync-to-JACK */ - tf = _engine.transport_frame(); + ret = _engine.transport_frame(); } else { - tf = _transport_frame; + ret = _transport_frame; } - ret = tf; - - if (!non_realtime_work_pending()) { - - /* MOVING */ + if (transport_rolling()) { + ret -= offset; /* Check to see if we have passed the first guaranteed - audible frame past our last start position. if not, - return that last start point because in terms - of audible frames, we have not moved yet. - - `Start position' in this context means the time we last - either started, located, or changed transport direction. - */ + * audible frame past our last start position. if not, + * return that last start point because in terms + * of audible frames, we have not moved yet. + * + * `Start position' in this context means the time we last + * either started, located, or changed transport direction. + */ if (_transport_speed > 0.0f) { if (!play_loop || !have_looped) { - if (tf < _last_roll_or_reversal_location + offset) { + if (ret < _last_roll_or_reversal_location) { return _last_roll_or_reversal_location; } + } else { + // latent loops + Location *location = _locations->auto_loop_location(); + frameoffset_t lo = location->start() - ret; + if (lo > 0) { + ret = location->end () - lo; + } } - - /* forwards */ - ret -= offset; - } else if (_transport_speed < 0.0f) { /* XXX wot? no backward looping? */ - if (tf > _last_roll_or_reversal_location - offset) { + if (ret > _last_roll_or_reversal_location) { return _last_roll_or_reversal_location; - } else { - /* backwards */ - ret += offset; } } } - return ret; + return std::max ((framepos_t)0, ret); } void @@ -3452,7 +3451,7 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool if (order == PresentationInfo::max_order) { /* just add to the end */ - r->set_presentation_order_explicit (n_routes + added); + r->set_presentation_order (n_routes + added, false); DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("group order not set, set to NR %1 + %2 = %3\n", n_routes, added, n_routes + added)); } else { r->set_presentation_order (order + added); @@ -3900,6 +3899,8 @@ Session::route_solo_changed (bool self_solo_changed, Controllable::GroupControlD if ((*i)->solo_isolate_control()->solo_isolated() || !(*i)->can_solo()) { /* route does not get solo propagated to it */ + DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 excluded from solo because iso = %2 can_solo = %3\n", (*i)->name(), (*i)->solo_isolate_control()->solo_isolated(), + (*i)->can_solo())); continue; } @@ -4243,6 +4244,24 @@ Session::get_remote_nth_stripable (PresentationInfo::order_t n, PresentationInfo sl.sort (Stripable::PresentationOrderSorter()); for (StripableList::const_iterator s = sl.begin(); s != sl.end(); ++s) { + + if ((*s)->presentation_info().hidden()) { + /* if the caller didn't explicitly ask for hidden + stripables, ignore hidden ones. This matches + the semantics of the pre-PresentationOrder + "get by RID" logic of Ardour 4.x and earlier. + + XXX at some point we should likely reverse + the logic of the flags, because asking for "the + hidden stripables" is not going to be common, + whereas asking for visible ones is normal. + */ + + if (! (flags & PresentationInfo::Hidden)) { + continue; + } + } + if ((*s)->presentation_info().flag_match (flags)) { if (match_cnt++ == n) { return *s; @@ -4388,12 +4407,18 @@ Session::maybe_update_session_range (framepos_t a, framepos_t b) _session_range_location->set_start (a); } - if (b > _session_range_location->end()) { + if (_session_range_end_is_free && (b > _session_range_location->end())) { _session_range_location->set_end (b); } } } +void +Session::set_end_is_free (bool yn) +{ + _session_range_end_is_free = yn; +} + void Session::playlist_ranges_moved (list > const & ranges) { @@ -7015,11 +7040,32 @@ Session::auto_connect_thread_run () } } - while (g_atomic_int_and (&_latency_recompute_pending, 0)) { - update_latency_compensation (); + if (!actively_recording ()) { // might not be needed, + /* this is only used for updating plugin latencies, the + * graph does not change. so it's safe in general. + * BUT.. + * .. update_latency_compensation () entails set_capture_offset() + * which calls Diskstream::set_capture_offset () which + * modifies the capture offset... which can be a proplem + * in "prepare_to_stop" + */ + while (g_atomic_int_and (&_latency_recompute_pending, 0)) { + update_latency_compensation (); + } } pthread_cond_wait (&_auto_connect_cond, &_auto_connect_mutex); } pthread_mutex_unlock (&_auto_connect_mutex); } + +void +Session::cancel_all_solo () +{ + StripableList sl; + + get_stripables (sl); + + set_controls (stripable_list_to_control_list (sl, &Stripable::solo_control), 0.0, Controllable::NoGroup); + clear_all_solo_state (routes.reader()); +}