Safe-guard non-rt-safe sidechain operations
[ardour.git] / libs / ardour / route.cc
index b57002abab7df9fe60214b1ee18595207a0cee1e..41a14b096e5127835941a95c26f18c88b4ecc14a 100644 (file)
@@ -2168,6 +2168,10 @@ Route::reorder_processors (const ProcessorList& new_order, ProcessorStreams* err
 bool
 Route::add_remove_sidechain (boost::shared_ptr<Processor> proc, bool add)
 {
+       if (_session.actively_recording ()) {
+               return false;
+       }
+
        boost::shared_ptr<PluginInsert> pi;
        if ((pi = boost::dynamic_pointer_cast<PluginInsert>(proc)) == 0) {
                return false;
@@ -2230,6 +2234,10 @@ Route::add_remove_sidechain (boost::shared_ptr<Processor> proc, bool add)
 bool
 Route::plugin_preset_output (boost::shared_ptr<Processor> proc, ChanCount outs)
 {
+       if (_session.actively_recording ()) {
+               return false;
+       }
+
        boost::shared_ptr<PluginInsert> pi;
        if ((pi = boost::dynamic_pointer_cast<PluginInsert>(proc)) == 0) {
                return false;
@@ -2276,6 +2284,9 @@ Route::reset_plugin_insert (boost::shared_ptr<Processor> proc)
 bool
 Route::customize_plugin_insert (boost::shared_ptr<Processor> proc, uint32_t count, ChanCount outs, ChanCount sinks)
 {
+       if (_session.actively_recording ()) {
+               return false;
+       }
        boost::shared_ptr<PluginInsert> pi;
        if ((pi = boost::dynamic_pointer_cast<PluginInsert>(proc)) == 0) {
                return false;
@@ -3192,6 +3203,44 @@ Route::add_aux_send (boost::shared_ptr<Route> route, boost::shared_ptr<Processor
        return 0;
 }
 
+int
+Route::add_personal_send (boost::shared_ptr<Route> route)
+{
+       assert (route != _session.monitor_out ());
+       boost::shared_ptr<Processor> before = before_processor_for_placement (PreFader);
+
+       {
+               Glib::Threads::RWLock::ReaderLock rm (_processor_lock);
+
+               for (ProcessorList::iterator x = _processors.begin(); x != _processors.end(); ++x) {
+
+                       boost::shared_ptr<InternalSend> d = boost::dynamic_pointer_cast<InternalSend> (*x);
+
+                       if (d && d->target_route() == route) {
+                               /* already listening via the specified IO: do nothing */
+                               return 0;
+                       }
+               }
+       }
+
+       try {
+
+               boost::shared_ptr<InternalSend> listener;
+
+               {
+                       Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
+                       listener.reset (new InternalSend (_session, _pannable, _mute_master, boost::dynamic_pointer_cast<ARDOUR::Route>(shared_from_this()), route, Delivery::Personal));
+               }
+
+               add_processor (listener, before);
+
+       } catch (failed_constructor& err) {
+               return -1;
+       }
+
+       return 0;
+}
+
 void
 Route::remove_aux_or_listen (boost::shared_ptr<Route> route)
 {
@@ -4656,15 +4705,20 @@ Route::setup_invisible_processors ()
         */
 
        ProcessorList new_processors;
+       ProcessorList personal_sends;
        ProcessorList::iterator dr;
        ProcessorList::iterator dw;
 
        /* find visible processors */
 
        for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
+               boost::shared_ptr<Send> auxsnd = boost::dynamic_pointer_cast<Send> ((*i));
                if ((*i)->display_to_user ()) {
                        new_processors.push_back (*i);
                }
+               else if (auxsnd && auxsnd->is_personal ()) {
+                       personal_sends.push_back (*i);
+               }
        }
 
        /* find the amp */
@@ -4716,6 +4770,12 @@ Route::setup_invisible_processors ()
                new_processors.insert (meter_point, _meter);
        }
 
+       /* Personal Sends */
+
+       for (ProcessorList::iterator i = personal_sends.begin(); i != personal_sends.end(); ++i) {
+               new_processors.insert (amp, (*i));
+       }
+
        /* MONITOR SEND */
 
        if (_monitor_send && !is_monitor ()) {
@@ -5642,7 +5702,7 @@ Route::send_pan_azi_controllable (uint32_t n) const
                }
        }
 #endif
-       
+
        return boost::shared_ptr<AutomationControl>();
 }
 
@@ -5772,13 +5832,15 @@ boost::shared_ptr<AutomationControl>
 Route::master_send_enable_controllable () const
 {
 #ifdef  MIXBUS
-       boost::shared_ptr<ARDOUR::PluginInsert> plug = ch_post();
+       if (is_master() || is_monitor() || is_auditioner()) {
+               return boost::shared_ptr<AutomationControl>();
+       }
+
+       boost::shared_ptr<ARDOUR::PluginInsert> plug = mixbus() ? ch_pre () : ch_post();
        if (!plug) {
                return boost::shared_ptr<AutomationControl>();
        }
-# undef MIXBUS_PORTS_H
-# include "../../gtk2_ardour/mixbus_ports.h"
-       return boost::dynamic_pointer_cast<ARDOUR::AutomationControl> (plug->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, port_channel_post_mstr_assign)));
+       return boost::dynamic_pointer_cast<ARDOUR::AutomationControl> (plug->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, mixbus() ? 3 : 19)));
 #else
        return boost::shared_ptr<AutomationControl>();
 #endif