better safe than sorry
[ardour.git] / libs / ardour / session.cc
index 8ec63f57141916973273ed910bc5f92b668a2910..2073ab58714de3a6cef0f2847fb28c1268bf9a31 100644 (file)
@@ -237,7 +237,7 @@ Session::Session (AudioEngine &eng,
        , pending_locate_flush (false)
        , pending_abort (false)
        , pending_auto_loop (false)
-       , _mempool ("Session", 1048576)
+       , _mempool ("Session", 2097152)
        , lua (lua_newstate (&PBD::ReallocPool::lalloc, &_mempool))
        , _n_lua_scripts (0)
        , _butler (new Butler (*this))
@@ -279,6 +279,7 @@ 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)
@@ -2580,6 +2581,7 @@ Session::new_midi_route (RouteGroup* route_group, uint32_t how_many, string name
                                route_group->add (bus);
                        }
 
+                       bus->add_internal_return ();
                        ret.push_back (bus);
                }
 
@@ -2938,17 +2940,18 @@ Session::ensure_route_presentation_info_gap (PresentationInfo::order_t first_new
        /* create a gap in the presentation info to accomodate @param how_many
         * new objects.
         */
-       boost::shared_ptr <RouteList> rd = routes.reader();
+       StripableList sl;
+       get_stripables (sl);
 
-       for (RouteList::iterator ri = rd->begin(); ri != rd->end(); ++ri) {
-               boost::shared_ptr<Route> rt (*ri);
+       for (StripableList::iterator si = sl.begin(); si != sl.end(); ++si) {
+               boost::shared_ptr<Stripable> s (*si);
 
-               if (rt->presentation_info().special()) {
+               if (s->is_monitor() || s->is_auditioner()) {
                        continue;
                }
 
-               if (rt->presentation_info().order () >= first_new_order) {
-                       rt->set_presentation_order (rt->presentation_info().order () + how_many);
+               if (s->presentation_info().order () >= first_new_order) {
+                       s->set_presentation_order (s->presentation_info().order () + how_many);
                }
        }
 }
@@ -3416,6 +3419,7 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
 
                r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
                r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
+               r->processor_latency_changed.connect_same_thread (*this, boost::bind (&Session::queue_latency_recompute, this));
 
                if (r->is_master()) {
                        _master_out = r;
@@ -5168,6 +5172,7 @@ Session::try_run_lua (pframes_t nframes)
        Glib::Threads::Mutex::Lock tm (lua_lock, Glib::Threads::TRY_LOCK);
        if (tm.locked ()) {
                try { (*_lua_run)(nframes); } catch (luabridge::LuaException const& e) { }
+               lua.collect_garbage_step ();
        }
 }
 
@@ -5177,6 +5182,7 @@ Session::setup_lua ()
 #ifndef NDEBUG
        lua.Print.connect (&_lua_print);
 #endif
+       lua.tweak_rt_gc ();
        lua.do_command (
                        "function ArdourSession ()"
                        "  local self = { scripts = {}, instances = {} }"
@@ -6834,6 +6840,16 @@ Session::auto_connect_route (boost::shared_ptr<Route> route, bool connect_inputs
        }
 }
 
+void
+Session::queue_latency_recompute ()
+{
+       g_atomic_int_inc (&_latency_recompute_pending);
+       if (pthread_mutex_trylock (&_auto_connect_mutex) == 0) {
+               pthread_cond_signal (&_auto_connect_cond);
+               pthread_mutex_unlock (&_auto_connect_mutex);
+       }
+}
+
 void
 Session::auto_connect (const AutoConnectRequest& ar)
 {
@@ -6999,6 +7015,20 @@ Session::auto_connect_thread_run ()
                        }
                }
 
+               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);