make i18n build work ; add mackie dir back to build ; token work on amp for MIDI...
[ardour.git] / libs / ardour / route.cc
index af80fd6c8961a7ca13c9922bc1d6a04b49e4b14c..56311c975db1063cb0fe929bbfd11cab0ec59c83 100644 (file)
@@ -321,7 +321,7 @@ Route::set_gain (gain_t val, void *src)
 void
 Route::process_output_buffers (BufferSet& bufs,
                               sframes_t start_frame, sframes_t end_frame, nframes_t nframes,
-                              bool with_processors, int declick)
+                              bool /*with_processors*/, int declick)
 {
        bool monitor;
 
@@ -619,22 +619,10 @@ Route::add_processor (boost::shared_ptr<Processor> processor, Placement placemen
 
        if (placement == PreFader) {
                /* generic pre-fader: insert immediately before the amp */
-               loc = find(_processors.begin(), _processors.end(), _amp);
+               loc = find (_processors.begin(), _processors.end(), _amp);
        } else {
-               /* generic post-fader: insert at end */
-               loc = _processors.end();
-
-               if (processor->visible() && !_processors.empty()) {
-                       /* check for invisible processors stacked at the end and leave them there */
-                       ProcessorList::iterator p;
-                       p = _processors.end();
-                       --p;
-                       while (!(*p)->visible() && p != _processors.begin()) {
-                               --p;
-                       }
-                       ++p;
-                       loc = p;
-               }
+               /* generic post-fader: insert right before the main outs */
+               loc = find (_processors.begin(), _processors.end(), _main_outs);
        }
 
        return add_processor (processor, loc, err);
@@ -707,9 +695,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::ite
                }
                
                // XXX: do we want to emit the signal here ? change call order.
-               if (!boost::dynamic_pointer_cast<InternalSend>(processor)) {
-                       processor->activate ();
-               }
+               processor->activate ();
                processor->ActiveChanged.connect (bind (mem_fun (_session, &Session::update_latency_compensation), false, false));
 
                _output->set_user_latency (0);
@@ -725,154 +711,125 @@ Route::add_processor_from_xml (const XMLNode& node, ProcessorList::iterator iter
 {
        const XMLProperty *prop;
 
-       // legacy sessions use a different node name for sends
-       if (node.name() == "Send") {
-       
-               try {
-                       boost::shared_ptr<Send> send (new Send (_session, _mute_master, node));
-                       add_processor (send, iter); 
-                       return true;
-               } 
-               
-               catch (failed_constructor &err) {
-                       error << _("Send construction failed") << endmsg;
-                       return false;
-               }
-               
-       } else if (node.name() == "Processor") {
+       if (node.name() != "Processor") {
+               return false;
+       }
                
-               try {
-                       if ((prop = node.property ("type")) != 0) {
-
-                               boost::shared_ptr<Processor> processor;
+       try {
+               if ((prop = node.property ("type")) != 0) {
+                       
+                       boost::shared_ptr<Processor> processor;
 
-                               if (prop->value() == "ladspa" || prop->value() == "Ladspa" || 
-                                   prop->value() == "lv2" ||
-                                   prop->value() == "vst" ||
-                                   prop->value() == "audiounit") {
+                       if (prop->value() == "ladspa" || prop->value() == "Ladspa" || 
+                           prop->value() == "lv2" ||
+                           prop->value() == "vst" ||
+                           prop->value() == "audiounit") {
                                        
-                                       processor.reset (new PluginInsert(_session, node));
+                               processor.reset (new PluginInsert(_session, node));
                                        
-                               } else if (prop->value() == "port") {
+                       } else if (prop->value() == "port") {
 
-                                       processor.reset (new PortInsert (_session, _mute_master, node));
+                               processor.reset (new PortInsert (_session, _mute_master, node));
                                
-                               } else if (prop->value() == "send") {
-
-                                       processor.reset (new Send (_session, _mute_master, node));
+                       } else if (prop->value() == "send") {
 
-                               } else if (prop->value() == "meter") {
+                               processor.reset (new Send (_session, _mute_master, node));
 
-                                       if (_meter) {
-                                               if (_meter->set_state (node)) {
-                                                       return false;
-                                               } else {
-                                                       return true;
-                                               }
-                                       }
-
-                                       _meter.reset (new PeakMeter (_session, node));                                          
-                                       processor = _meter;
-                               
-                               } else if (prop->value() == "amp") {
+                       } else if (prop->value() == "meter") {
 
-                                       /* amp always exists */
-                                       
-                                       processor = _amp;
-                                       if (processor->set_state (node)) {
+                               if (_meter) {
+                                       if (_meter->set_state (node)) {
                                                return false;
                                        } else {
-                                               /* never any reason to add it */
                                                return true;
                                        }
-                                       
-                               } else if (prop->value() == "listen" || prop->value() == "deliver") {
+                               }
 
-                                       /* XXX need to generalize */
+                               _meter.reset (new PeakMeter (_session, node));                                          
+                               processor = _meter;
+                               
+                       } else if (prop->value() == "amp") {
 
-                               } else if (prop->value() == "intsend") {
+                               /* amp always exists */
+                                       
+                               processor = _amp;
+                               if (processor->set_state (node)) {
+                                       return false;
+                               } else {
+                                       /* never any reason to add it */
+                                       return true;
+                               }
+                                       
+                       } else if (prop->value() == "intsend") {
 
-                                       processor.reset (new InternalSend (_session, _mute_master, node));
+                               processor.reset (new InternalSend (_session, _mute_master, node));
 
-                               } else if (prop->value() == "intreturn") {
+                       } else if (prop->value() == "intreturn") {
                                        
-                                       if (_intreturn) {
-                                               if (_intreturn->set_state (node)) {
-                                                       return false;
-                                               } else {
-                                                       return true;
-                                               }
+                               if (_intreturn) {
+                                       if (_intreturn->set_state (node)) {
+                                               return false;
+                                       } else {
+                                               return true;
                                        }
-                                       _intreturn.reset (new InternalReturn (_session, node));
-                                       processor = _intreturn;
+                               }
+                               _intreturn.reset (new InternalReturn (_session, node));
+                               processor = _intreturn;
 
-                               } else if (prop->value() == "main-outs") {
+                       } else if (prop->value() == "main-outs") {
                                        
-                                       if (_main_outs) {
-                                               if (_main_outs->set_state (node)) {
-                                                       return false;
-                                               } else {
-                                                       return true;
-                                               }
+                               if (_main_outs) {
+                                       if (_main_outs->set_state (node)) {
+                                               return false;
+                                       } else {
+                                               return true;
                                        }
+                               }
 
-                                       _main_outs.reset (new Delivery (_session, _output, _mute_master, node));
-                                       processor = _main_outs;
+                               _main_outs.reset (new Delivery (_session, _output, _mute_master, node));
+                               processor = _main_outs;
 
-                               } else {
-                                       error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
-                               }
+                       } else {
+                               error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
+                               return false;
+                       }
                                
-                               if (iter == _processors.end() && processor->visible() && !_processors.empty()) {
-                                       /* check for invisible processors stacked at the end and leave them there */
-                                       ProcessorList::iterator p;
-                                       p = _processors.end();
+                       if (iter == _processors.end() && processor->visible() && !_processors.empty()) {
+                               /* check for invisible processors stacked at the end and leave them there */
+                               ProcessorList::iterator p;
+                               p = _processors.end();
+                               --p;
+                               while (!(*p)->visible() && p != _processors.begin()) {
                                        --p;
-                                       while (!(*p)->visible() && p != _processors.begin()) {
-                                               --p;
-                                       }
-                                       ++p;
-                                       iter = p;
                                }
-
-                               return (add_processor (processor, iter) == 0);
-                               
-                       } else {
-                               error << _("Processor XML node has no type property") << endmsg;
+                               ++p;
+                               iter = p;
                        }
-               }
 
-               catch (failed_constructor &err) {
-                       warning << _("processor could not be created. Ignored.") << endmsg;
+                       return (add_processor (processor, iter) == 0);
+                               
+               } else {
+                       error << _("Processor XML node has no type property") << endmsg;
                        return false;
                }
        }
-       return false;
+
+       catch (failed_constructor &err) {
+               warning << _("processor could not be created. Ignored.") << endmsg;
+               return false;
+       }
 }
 
 int
-Route::add_processors (const ProcessorList& others, Placement placement, ProcessorStreams* err)
+Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor> before, ProcessorStreams* err)
 {
        ProcessorList::iterator loc;
-       if (placement == PreFader) {
-               /* generic pre-fader: insert immediately before the amp */
-               loc = find(_processors.begin(), _processors.end(), _amp);
-       } else {
-               /* generic post-fader: insert at end */
-               loc = _processors.end();
 
-               if (!_processors.empty()) {
-                       /* check for invisible processors stacked at the end and leave them there */
-                       ProcessorList::iterator p;
-                       p = _processors.end();
-                       --p;
-                       cerr << "Let's check " << (*p)->name() << " vis ? " << (*p)->visible() << endl;
-                       while (!(*p)->visible() && p != _processors.begin()) {
-                               --p;
-                       }
-                       ++p;
-                       loc = p;
-               }
+       if (before) {
+               loc = find(_processors.begin(), _processors.end(), before);
+       } else {
+               /* nothing specified - at end but before main outs */
+               loc = find (_processors.begin(), _processors.end(), _main_outs);
        }
 
        return add_processors (others, loc, err);
@@ -918,9 +875,11 @@ Route::add_processors (const ProcessorList& others, ProcessorList::iterator iter
                        if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
                                pi->set_count (1);
                                
-                               ChanCount m = max(pi->input_streams(), pi->output_streams());
-                               if (m > potential_max_streams)
+                               ChanCount m = max (pi->input_streams(), pi->output_streams());
+
+                               if (m > potential_max_streams) {
                                        potential_max_streams = m;
+                               }
                        }
 
                        _processors.insert (iter, *i);
@@ -1092,26 +1051,43 @@ Route::clear_processors (Placement p)
                Glib::RWLock::WriterLock lm (_processor_lock);
                ProcessorList new_list;
                ProcessorStreams err;
+               bool seen_amp = false;
 
-               ProcessorList::iterator amp_loc = find(_processors.begin(), _processors.end(), _amp);
-               if (p == PreFader) {
-                       // Get rid of PreFader processors
-                       for (ProcessorList::iterator i = _processors.begin(); i != amp_loc; ++i) {
-                               (*i)->drop_references ();
-                       }
-                       // Keep the rest
-                       for (ProcessorList::iterator i = amp_loc; i != _processors.end(); ++i) {
-                               new_list.push_back (*i);
+               for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
+
+                       if (*i == _amp) {
+                               seen_amp = true;
                        }
-               } else {
-                       // Keep PreFader processors
-                       for (ProcessorList::iterator i = _processors.begin(); i != amp_loc; ++i) {
+
+                       if ((*i) == _amp || (*i) == _meter || (*i) == _main_outs) {
+                               
+                               /* you can't remove these */
+
                                new_list.push_back (*i);
-                       }
-                       new_list.push_back (_amp);
-                       // Get rid of PostFader processors
-                       for (ProcessorList::iterator i = amp_loc; i != _processors.end(); ++i) {
-                               (*i)->drop_references ();
+
+                       } else {
+                               if (seen_amp) {
+
+                                       switch (p) {
+                                       case PreFader:
+                                               new_list.push_back (*i);
+                                               break;
+                                       case PostFader:
+                                               (*i)->drop_references ();
+                                               break;
+                                       }
+
+                               } else {
+
+                                       switch (p) {
+                                       case PreFader:
+                                               (*i)->drop_references ();
+                                               break;
+                                       case PostFader:
+                                               new_list.push_back (*i);
+                                               break;
+                                       }
+                               }
                        }
                }
 
@@ -1217,6 +1193,99 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
        return 0;
 }
 
+int
+Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams* err)
+{
+       ProcessorList deleted;
+       ProcessorList as_we_were;
+
+       if (!_session.engine().connected()) {
+               return 1;
+       }
+
+       processor_max_streams.reset();
+
+       {
+               Glib::RWLock::WriterLock lm (_processor_lock);
+               ProcessorList::iterator i;
+               boost::shared_ptr<Processor> processor;
+
+               as_we_were = _processors;
+
+               for (i = _processors.begin(); i != _processors.end(); ) {
+                       
+                       processor = *i;
+
+                       /* these can never be removed */
+
+                       if (processor == _amp || processor == _meter || processor == _main_outs) {
+                               ++i;
+                               continue;
+                       }
+                       
+                       /* see if its in the list of processors to delete */
+                       
+                       if (find (to_be_deleted.begin(), to_be_deleted.end(), processor) == to_be_deleted.end()) {
+                               ++i;
+                               continue;
+                       }
+
+                       /* stop IOProcessors that send to JACK ports
+                          from causing noise as a result of no longer being
+                          run.
+                       */
+                       
+                       boost::shared_ptr<IOProcessor> iop;
+                       
+                       if ((iop = boost::dynamic_pointer_cast<IOProcessor> (processor)) != 0) {
+                               iop->disconnect ();
+                       }
+
+                       deleted.push_back (processor);
+                       i = _processors.erase (i);
+               }
+
+               if (deleted.empty()) {
+                       /* none of those in the requested list were found */
+                       return 0;
+               }
+
+               _output->set_user_latency (0);
+
+               if (configure_processors_unlocked (err)) {
+                       /* get back to where we where */
+                       _processors = as_we_were;
+                       /* we know this will work, because it worked before :) */
+                       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->is_generator()) {
+                                       _have_internal_generator = true;
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       /* now try to do what we need to so that those that were removed will be deleted */
+
+       for (ProcessorList::iterator i = deleted.begin(); i != deleted.end(); ++i) {
+               (*i)->drop_references ();
+       }
+
+       processors_changed (); /* EMIT SIGNAL */
+
+       return 0;
+}
+
+
 int
 Route::configure_processors (ProcessorStreams* err)
 {
@@ -1270,6 +1339,7 @@ Route::configure_processors_unlocked (ProcessorStreams* err)
 
        // Ensure route outputs match last processor's outputs
        if (out != _output->n_ports ()) {
+               cerr << "For " << _name << " out/last mismatch - out = " << out << " vs. " << _output->n_ports() << endl;
                _output->ensure_io (out, false, this);
        }
 
@@ -1526,7 +1596,7 @@ Route::set_state (const XMLNode& node)
 }
 
 int
-Route::_set_state (const XMLNode& node, bool call_base)
+Route::_set_state (const XMLNode& node, bool /*call_base*/)
 {
 
        XMLNodeList nlist;
@@ -1885,7 +1955,7 @@ Route::release_return_buffer () const
 }
 
 int
-Route::listen_via (boost::shared_ptr<Route> route, bool active)
+Route::listen_via (boost::shared_ptr<Route> route, Placement placement, bool /*active*/, bool aux)
 {
        vector<string> ports;
        vector<string>::const_iterator i;
@@ -1917,7 +1987,7 @@ Route::listen_via (boost::shared_ptr<Route> route, bool active)
        boost::shared_ptr<InternalSend> listener;
 
        try {
-               listener.reset (new InternalSend (_session, _mute_master, route));
+               listener.reset (new InternalSend (_session, _mute_master, route, (aux ? Delivery::Aux : Delivery::Listen)));
 
        } catch (failed_constructor& err) {
                return -1;
@@ -1927,7 +1997,7 @@ Route::listen_via (boost::shared_ptr<Route> route, bool active)
                _control_outs = listener;
        }
 
-       add_processor (listener, (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader));
+       add_processor (listener, placement);
        
        return 0;
 }      
@@ -2030,7 +2100,7 @@ Route::feeds (boost::shared_ptr<Route> other)
 }
 
 void
-Route::handle_transport_stopped (bool abort_ignored, bool did_locate, bool can_flush_processors)
+Route::handle_transport_stopped (bool /*abort_ignored*/, bool did_locate, bool can_flush_processors)
 {
        nframes_t now = _session.transport_frame();
 
@@ -2056,7 +2126,7 @@ Route::handle_transport_stopped (bool abort_ignored, bool did_locate, bool can_f
 }
 
 void
-Route::input_change_handler (IOChange change, void *src)
+Route::input_change_handler (IOChange change, void * /*src*/)
 {
        if ((change & ConfigurationChanged)) {
                configure_processors (0);
@@ -2064,7 +2134,7 @@ Route::input_change_handler (IOChange change, void *src)
 }
 
 void
-Route::output_change_handler (IOChange change, void *src)
+Route::output_change_handler (IOChange change, void * /*src*/)
 {
        if ((change & ConfigurationChanged)) {
                
@@ -2086,7 +2156,7 @@ Route::pans_required () const
 
 int 
 Route::no_roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame,  
-               bool session_state_changing, bool can_record, bool rec_monitors_input)
+               bool session_state_changing, bool /*can_record*/, bool /*rec_monitors_input*/)
 {
        if (n_outputs().n_total() == 0) {
                return 0;
@@ -2132,7 +2202,7 @@ Route::check_initial_delay (nframes_t nframes, nframes_t& transport_frame)
 
 int
 Route::roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame, int declick,
-            bool can_record, bool rec_monitors_input)
+            bool /*can_record*/, bool /*rec_monitors_input*/)
 {
        {
                // automation snapshot can also be called from the non-rt context
@@ -2167,8 +2237,8 @@ Route::roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame, int
 }
 
 int
-Route::silent_roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame
-                   bool can_record, bool rec_monitors_input)
+Route::silent_roll (nframes_t nframes, sframes_t /*start_frame*/, sframes_t /*end_frame*/
+                   bool /*can_record*/, bool /*rec_monitors_input*/)
 {
        silence (nframes);
        return 0;
@@ -2424,7 +2494,7 @@ Route::set_pending_declick (int declick)
  */
 
 void
-Route::shift (nframes64_t pos, nframes64_t frames)
+Route::shift (nframes64_t /*pos*/, nframes64_t /*frames*/)
 {
 #ifdef THIS_NEEDS_FIXING_FOR_V3
 
@@ -2575,7 +2645,22 @@ void
 Route::meter ()
 {
        Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
+
+       assert (_meter);
+
        _meter->meter ();
+
+       for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
+
+               boost::shared_ptr<Send> s;
+               boost::shared_ptr<Return> r;
+
+               if ((s = boost::dynamic_pointer_cast<Send> (*i)) != 0) {
+                       s->meter()->meter();
+               } else if ((r = boost::dynamic_pointer_cast<Return> (*i)) != 0) {
+                       r->meter()->meter ();
+               }
+       }
 }
 
 boost::shared_ptr<Panner>