allow auditioning via the monitor section to work.
[ardour.git] / libs / ardour / route.cc
index 2f69c3340aca6c9caaee31fa17905e2d5645c207..046bf7998e520ca0e557227301e4ac1bb2527431 100644 (file)
@@ -51,6 +51,7 @@
 #include "ardour/midi_port.h"
 #include "ardour/monitor_processor.h"
 #include "ardour/pannable.h"
+#include "ardour/panner.h"
 #include "ardour/panner_shell.h"
 #include "ardour/plugin_insert.h"
 #include "ardour/port.h"
@@ -96,6 +97,7 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type)
        , _have_internal_generator (false)
        , _solo_safe (false)
        , _default_type (default_type)
+       , _order_key (0)
        , _has_order_key (false)
        , _remote_control_id (0)
        , _in_configure_processors (false)
@@ -178,8 +180,7 @@ Route::init ()
        Metering::Meter.connect_same_thread (*this, (boost::bind (&Route::meter, this)));
 
        {
-               /* run a configure so that the invisible processors get set up */
-               Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
+               Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
                configure_processors (0);
        }
 
@@ -418,7 +419,8 @@ Route::process_output_buffers (BufferSet& bufs,
                               framepos_t start_frame, framepos_t end_frame, pframes_t nframes,
                               int declick, bool gain_automation_ok)
 {
-       bufs.set_is_silent (false);
+       Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
+       assert(lm.locked());
 
        /* figure out if we're going to use gain automation */
        if (gain_automation_ok) {
@@ -542,6 +544,7 @@ Route::monitor_run (framepos_t start_frame, framepos_t end_frame, pframes_t nfra
 {
        assert (is_monitor());
        BufferSet& bufs (_session.get_route_buffers (n_process_buffers()));
+       fill_buffers_with_input (bufs, _input, nframes);
        passthru (bufs, start_frame, end_frame, nframes, declick);
 }
 
@@ -945,6 +948,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, boost::shared_ptr<
        }
 
        {
+               Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
                Glib::Threads::RWLock::WriterLock lm (_processor_lock);
                ProcessorState pstate (this);
 
@@ -986,8 +990,6 @@ Route::add_processor (boost::shared_ptr<Processor> processor, boost::shared_ptr<
                // configure redirect ports properly, etc.
 
                {
-                       Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
-
                        if (configure_processors_unlocked (err)) {
                                pstate.restore ();
                                configure_processors_unlocked (0); // it worked before we tried to add it ...
@@ -1115,6 +1117,7 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
        }
 
        {
+               Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
                Glib::Threads::RWLock::WriterLock lm (_processor_lock);
                ProcessorState pstate (this);
 
@@ -1137,8 +1140,8 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
                                (*i)->activate ();
                        }
 
+                       /* Think: does this really need to be called for every processor in the loop? */
                        {
-                               Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
                                if (configure_processors_unlocked (err)) {
                                        pstate.restore ();
                                        configure_processors_unlocked (0); // it worked before we tried to add it ...
@@ -1314,6 +1317,7 @@ Route::clear_processors (Placement p)
        }
 
        {
+               Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
                Glib::Threads::RWLock::WriterLock lm (_processor_lock);
                ProcessorList new_list;
                ProcessorStreams err;
@@ -1358,11 +1362,7 @@ Route::clear_processors (Placement p)
                }
 
                _processors = new_list;
-
-               {
-                       Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
-                       configure_processors_unlocked (&err); // this can't fail
-               }
+               configure_processors_unlocked (&err); // this can't fail
        }
 
        processor_max_streams.reset();
@@ -1398,6 +1398,10 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
        processor_max_streams.reset();
 
        {
+               Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock (), Glib::Threads::NOT_LOCK);
+               if (need_process_lock) {
+                       lx.acquire();
+               }
                Glib::Threads::RWLock::WriterLock lm (_processor_lock);
                ProcessorState pstate (this);
 
@@ -1438,22 +1442,11 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
                        return 1;
                } 
 
-               if (need_process_lock) {
-                       Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
-
-                       if (configure_processors_unlocked (err)) {
-                               pstate.restore ();
-                               /* we know this will work, because it worked before :) */
-                               configure_processors_unlocked (0);
-                               return -1;
-                       }
-               } else {
-                       if (configure_processors_unlocked (err)) {
-                               pstate.restore ();
-                               /* we know this will work, because it worked before :) */
-                               configure_processors_unlocked (0);
-                               return -1;
-                       }
+               if (configure_processors_unlocked (err)) {
+                       pstate.restore ();
+                       /* we know this will work, because it worked before :) */
+                       configure_processors_unlocked (0);
+                       return -1;
                }
 
                _have_internal_generator = false;
@@ -1468,6 +1461,9 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
                                }
                        }
                }
+               if (need_process_lock) {
+                       lx.release();
+               }
        }
 
        reset_instrument_info ();
@@ -1490,6 +1486,7 @@ Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams*
        processor_max_streams.reset();
 
        {
+               Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
                Glib::Threads::RWLock::WriterLock lm (_processor_lock);
                ProcessorState pstate (this);
 
@@ -1536,16 +1533,13 @@ Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams*
 
                _output->set_user_latency (0);
 
-               {
-                       Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
-
-                       if (configure_processors_unlocked (err)) {
-                               pstate.restore ();
-                               /* we know this will work, because it worked before :) */
-                               configure_processors_unlocked (0);
-                               return -1;
-                       }
+               if (configure_processors_unlocked (err)) {
+                       pstate.restore ();
+                       /* we know this will work, because it worked before :) */
+                       configure_processors_unlocked (0);
+                       return -1;
                }
+               //lx.unlock();
 
                _have_internal_generator = false;
 
@@ -1574,6 +1568,63 @@ Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams*
        return 0;
 }
 
+#if 0
+/* currently unused (again) -- but will come in handy soon (again)
+ * once there is an option to link route + delivery panner settings
+ */
+void
+Route::set_custom_panner_uri (std::string const panner_uri)
+{
+       if (_in_configure_processors) {
+               DEBUG_TRACE (DEBUG::Panning, string_compose (_("Route::set_custom_panner_uri '%1' -- called while in_configure_processors\n"), name()));
+               return;
+       }
+
+       if (!_main_outs->panner_shell()->set_user_selected_panner_uri(panner_uri)) {
+               DEBUG_TRACE (DEBUG::Panning, string_compose (_("Route::set_custom_panner_uri '%1 '%2' -- no change needed\n"), name(), panner_uri));
+               /* no change needed */
+               return;
+       }
+
+       DEBUG_TRACE (DEBUG::Panning, string_compose (_("Route::set_custom_panner_uri '%1 '%2' -- reconfigure I/O\n"), name(), panner_uri));
+
+       /* reconfigure I/O -- re-initialize panner modules */
+       {
+               Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
+               Glib::Threads::RWLock::WriterLock lm (_processor_lock);
+
+               for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p) {
+                       boost::shared_ptr<Delivery> dl;
+                       boost::shared_ptr<Panner> panner;
+                       if ((dl = boost::dynamic_pointer_cast<Delivery> (*p)) == 0) {
+                               continue;
+                       }
+                       if (!dl->panner_shell()) {
+                               continue;
+                       }
+                       if (!(panner = dl->panner_shell()->panner())) {
+                               continue;
+                       }
+                       /* _main_outs has already been set before the loop.
+                        * Ignore the return status here. It need reconfiguration */
+                       if (dl->panner_shell() != _main_outs->panner_shell()) {
+                               if (!dl->panner_shell()->set_user_selected_panner_uri(panner_uri)) {
+                                       continue;
+                               }
+                       }
+
+                       ChanCount in = panner->in();
+                       ChanCount out = panner->out();
+                       dl->panner_shell()->configure_io(in, out);
+                       dl->panner_shell()->pannable()->set_panner(dl->panner_shell()->panner());
+               }
+       }
+
+       processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
+       _session.set_dirty ();
+}
+#endif
+
 void
 Route::reset_instrument_info ()
 {
@@ -1588,7 +1639,6 @@ int
 Route::configure_processors (ProcessorStreams* err)
 {
        assert (!AudioEngine::instance()->process_lock().trylock());
-
        if (!_in_configure_processors) {
                Glib::Threads::RWLock::WriterLock lm (_processor_lock);
                return configure_processors_unlocked (err);
@@ -1759,6 +1809,7 @@ Route::reorder_processors (const ProcessorList& new_order, ProcessorStreams* err
        */
 
        {
+               Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
                Glib::Threads::RWLock::WriterLock lm (_processor_lock);
                ProcessorState pstate (this);
 
@@ -1820,13 +1871,9 @@ Route::reorder_processors (const ProcessorList& new_order, ProcessorStreams* err
                /* If the meter is in a custom position, find it and make a rough note of its position */
                maybe_note_meter_position ();
 
-               {
-                       Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
-
-                       if (configure_processors_unlocked (err)) {
-                               pstate.restore ();
-                               return -1;
-                       }
+               if (configure_processors_unlocked (err)) {
+                       pstate.restore ();
+                       return -1;
                }
        }
 
@@ -2506,7 +2553,7 @@ Route::set_processor_state (const XMLNode& node)
 
                                if (prop->value() == "intsend") {
 
-                                       processor.reset (new InternalSend (_session, _pannable, _mute_master, boost::shared_ptr<Route>(), Delivery::Role (0)));
+                                       processor.reset (new InternalSend (_session, _pannable, _mute_master, boost::shared_ptr<Route>(), Delivery::Aux));
 
                                } else if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
                                           prop->value() == "lv2" ||
@@ -2553,11 +2600,11 @@ Route::set_processor_state (const XMLNode& node)
        }
 
        {
+               Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
                Glib::Threads::RWLock::WriterLock lm (_processor_lock);
                _processors = new_order;
 
                if (must_configure) {
-                       Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
                        configure_processors_unlocked (0);
                }
 
@@ -2671,6 +2718,7 @@ Route::enable_monitor_send ()
 
        /* master never sends to monitor section via the normal mechanism */
        assert (!is_master ());
+       assert (!is_monitor ());
 
        /* make sure we have one */
        if (!_monitor_send) {
@@ -3138,17 +3186,14 @@ void
 Route::listen_position_changed ()
 {
        {
+               Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
                Glib::Threads::RWLock::WriterLock lm (_processor_lock);
                ProcessorState pstate (this);
 
-               {
-                       Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
-
-                       if (configure_processors_unlocked (0)) {
-                               pstate.restore ();
-                               configure_processors_unlocked (0); // it worked before we tried to add it ...
-                               return;
-                       }
+               if (configure_processors_unlocked (0)) {
+                       pstate.restore ();
+                       configure_processors_unlocked (0); // it worked before we tried to add it ...
+                       return;
                }
        }
 
@@ -3164,10 +3209,7 @@ Route::add_export_point()
                _capturing_processor.reset (new CapturingProcessor (_session));
                _capturing_processor->activate ();
 
-               {
-                       Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
-                       configure_processors (0);
-               }
+               configure_processors (0);
 
        }
 
@@ -4118,7 +4160,7 @@ Route::has_external_redirects () const
 boost::shared_ptr<Processor>
 Route::the_instrument () const
 {
-       Glib::Threads::RWLock::WriterLock lm (_processor_lock);
+       Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
        return the_instrument_unlocked ();
 }
 
@@ -4146,6 +4188,7 @@ Route::non_realtime_locate (framepos_t pos)
        }
 
        {
+               //Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
                Glib::Threads::RWLock::WriterLock lm (_processor_lock);
                
                for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {