prepare Instrument slots -- replace processor in place
authorRobin Gareus <robin@gareus.org>
Sat, 19 Mar 2016 15:36:20 +0000 (16:36 +0100)
committerRobin Gareus <robin@gareus.org>
Sat, 19 Mar 2016 15:41:59 +0000 (16:41 +0100)
libs/ardour/ardour/route.h
libs/ardour/route.cc

index 92e073e81a3e78a13d03fd66a7dee2b386f19071..bb6bc4816a2461a260994053cdcdb787d214e84a 100644 (file)
@@ -263,6 +263,7 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
        boost::shared_ptr<Processor> before_processor_for_index (int);
        bool processors_reorder_needs_configure (const ProcessorList& new_order);
        int remove_processor (boost::shared_ptr<Processor>, ProcessorStreams* err = 0, bool need_process_lock = true);
+       int replace_processor (boost::shared_ptr<Processor>, boost::shared_ptr<Processor>, ProcessorStreams* err = 0);
        int remove_processors (const ProcessorList&, ProcessorStreams* err = 0);
        int reorder_processors (const ProcessorList& new_order, ProcessorStreams* err = 0);
        void disable_processors (Placement);
index 74b3a87fcf96985adacca1b9981f8236f1cac14e..30e901cfba5900b54e8b3689f49576bbb89cf4d1 100644 (file)
@@ -1813,6 +1813,92 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
        return 0;
 }
 
+int
+Route::replace_processor (boost::shared_ptr<Processor> old, boost::shared_ptr<Processor> sub, ProcessorStreams* err)
+{
+       /* these can never be removed */
+       if (old == _amp || old == _meter || old == _main_outs || old == _delayline || old == _trim) {
+               return 1;
+       }
+       /* and can't be used as substitute, either */
+       if (sub == _amp || sub == _meter || sub == _main_outs || sub == _delayline || sub == _trim) {
+               return 1;
+       }
+
+       /* I/Os are out, too */
+       if (boost::dynamic_pointer_cast<IOProcessor> (old) || boost::dynamic_pointer_cast<IOProcessor> (sub)) {
+               return 1;
+       }
+
+       /* this function cannot be used to swap/reorder processors */
+       if (find (_processors.begin(), _processors.end(), sub) != _processors.end ()) {
+               return 1;
+       }
+
+       if (!AudioEngine::instance()->connected() || !old || !sub) {
+               return 1;
+       }
+
+       {
+               Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
+               Glib::Threads::RWLock::WriterLock lm (_processor_lock);
+               ProcessorState pstate (this);
+
+               assert (find (_processors.begin(), _processors.end(), sub) == _processors.end ());
+
+               ProcessorList::iterator i;
+               bool replaced = false;
+               bool enable = old->active ();
+
+               for (i = _processors.begin(); i != _processors.end(); ) {
+                       if (*i == old) {
+                               i = _processors.erase (i);
+                               _processors.insert (i, sub);
+                               sub->set_owner (this);
+                               replaced = true;
+                               break;
+                       } else {
+                               ++i;
+                       }
+               }
+
+               if (!replaced) {
+                       return 1;
+               }
+
+               if (configure_processors_unlocked (err)) {
+                       pstate.restore ();
+                       configure_processors_unlocked (0);
+                       return -1;
+               }
+
+               _have_internal_generator = false;
+
+               for (i = _processors.begin(); i != _processors.end(); ++i) {
+                       boost::shared_ptr<PluginInsert> pi;
+                       if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
+                               if (pi->has_no_inputs ()) {
+                                       _have_internal_generator = true;
+                                       break;
+                               }
+                       }
+               }
+
+               if (enable) {
+                       sub->activate ();
+               }
+
+               sub->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false));
+               _output->set_user_latency (0);
+       }
+
+       reset_instrument_info ();
+       old->drop_references ();
+       processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
+       set_processor_positions ();
+       return 0;
+}
+
 int
 Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams* err)
 {