Sanitize "well-known" ctrl API
[ardour.git] / libs / ardour / route.cc
index e136b7b896096a9d9a6a893697fee61072a8c48a..f3031aa15ada88b9d835f0d3a0499fbb70bd1214 100644 (file)
@@ -89,7 +89,6 @@ Route::Route (Session& sess, string name, PresentationInfo::Flag flag, DataType
        : Stripable (sess, name, PresentationInfo (flag))
        , GraphNode (sess._process_graph)
        , Muteable (sess, name)
-       , Automatable (sess)
        , _active (true)
        , _signal_latency (0)
        , _signal_latency_at_amp_position (0)
@@ -121,7 +120,7 @@ Route::Route (Session& sess, string name, PresentationInfo::Flag flag, DataType
 
 boost::weak_ptr<Route>
 Route::weakroute () {
-       return boost::weak_ptr<Route> (shared_from_this ());
+       return boost::weak_ptr<Route> (boost::dynamic_pointer_cast<Route> (shared_from_this ()));
 }
 
 int
@@ -877,7 +876,7 @@ Route::add_processor_from_xml_2X (const XMLNode& node, int version)
                //A2 uses the "active" flag in the toplevel redirect node, not in the child plugin/IO
                if (i != children.end()) {
                        if ((prop = (*i)->property (X_("active"))) != 0) {
-                               if ( string_is_affirmative (prop->value()) && (!_session.get_bypass_all_loaded_plugins () || !processor->display_to_user () ) )
+                               if ( string_to<bool> (prop->value()) && (!_session.get_bypass_all_loaded_plugins () || !processor->display_to_user () ) )
                                        processor->activate();
                                else
                                        processor->deactivate();
@@ -970,7 +969,7 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
                flags &= mask;
 
                if (flags != None) {
-                       boost::optional<int> rv = PluginSetup (shared_from_this (), pi, flags);  /* EMIT SIGNAL */
+                       boost::optional<int> rv = PluginSetup (boost::dynamic_pointer_cast<Route>(shared_from_this ()), pi, flags);  /* EMIT SIGNAL */
                        int mode = rv.get_value_or (0);
                        switch (mode & 3) {
                                case 1:
@@ -2595,13 +2594,13 @@ Route::set_state_2X (const XMLNode& node, int version)
        Stripable::set_state (node, version);
 
        if ((prop = node.property (X_("denormal-protection"))) != 0) {
-               set_denormal_protection (string_is_affirmative (prop->value()));
+               set_denormal_protection (string_to<bool> (prop->value()));
        }
 
        if ((prop = node.property (X_("muted"))) != 0) {
 
                bool first = true;
-               bool muted = string_is_affirmative (prop->value());
+               bool muted = string_to<bool> (prop->value());
 
                if (muted) {
 
@@ -2609,7 +2608,7 @@ Route::set_state_2X (const XMLNode& node, int version)
 
                        if ((prop = node.property (X_("mute-affects-pre-fader"))) != 0) {
 
-                               if (string_is_affirmative (prop->value())){
+                               if (string_to<bool> (prop->value())){
                                        mute_point = mute_point + "PreFader";
                                        first = false;
                                }
@@ -2617,7 +2616,7 @@ Route::set_state_2X (const XMLNode& node, int version)
 
                        if ((prop = node.property (X_("mute-affects-post-fader"))) != 0) {
 
-                               if (string_is_affirmative (prop->value())){
+                               if (string_to<bool> (prop->value())){
 
                                        if (!first) {
                                                mute_point = mute_point + ",";
@@ -2630,7 +2629,7 @@ Route::set_state_2X (const XMLNode& node, int version)
 
                        if ((prop = node.property (X_("mute-affects-control-outs"))) != 0) {
 
-                               if (string_is_affirmative (prop->value())){
+                               if (string_to<bool> (prop->value())){
 
                                        if (!first) {
                                                mute_point = mute_point + ",";
@@ -2643,7 +2642,7 @@ Route::set_state_2X (const XMLNode& node, int version)
 
                        if ((prop = node.property (X_("mute-affects-main-outs"))) != 0) {
 
-                               if (string_is_affirmative (prop->value())){
+                               if (string_to<bool> (prop->value())){
 
                                        if (!first) {
                                                mute_point = mute_point + ",";
@@ -2685,7 +2684,7 @@ Route::set_state_2X (const XMLNode& node, int version)
                        set_id (*child);
 
                        if ((prop = child->property (X_("active"))) != 0) {
-                               bool yn = string_is_affirmative (prop->value());
+                               bool yn = string_to<bool> (prop->value());
                                _active = !yn; // force switch
                                set_active (yn, this);
                        }
@@ -3283,13 +3282,13 @@ Route::direct_feeds_according_to_reality (boost::shared_ptr<Route> other, bool*
 bool
 Route::direct_feeds_according_to_graph (boost::shared_ptr<Route> other, bool* via_send_only)
 {
-       return _session._current_route_graph.has (shared_from_this (), other, via_send_only);
+       return _session._current_route_graph.has (boost::dynamic_pointer_cast<Route> (shared_from_this ()), other, via_send_only);
 }
 
 bool
 Route::feeds_according_to_graph (boost::shared_ptr<Route> other)
 {
-       return _session._current_route_graph.feeds (shared_from_this (), other);
+       return _session._current_route_graph.feeds (boost::dynamic_pointer_cast<Route> (shared_from_this ()), other);
 }
 
 /** Called from the (non-realtime) butler thread when the transport is stopped */
@@ -3338,7 +3337,7 @@ Route::input_change_handler (IOChange change, void * /*src*/)
                                        continue;
                                }
                                bool sends_only;
-                               bool does_feed = (*i)->direct_feeds_according_to_reality (shared_from_this(), &sends_only);
+                               bool does_feed = (*i)->direct_feeds_according_to_reality (boost::dynamic_pointer_cast<Route> (shared_from_this()), &sends_only);
                                if (does_feed && !sends_only) {
                                        if ((*i)->soloed()) {
                                                ++sbou;
@@ -3452,7 +3451,7 @@ Route::output_change_handler (IOChange change, void * /*src*/)
                                _solo_control->mod_solo_by_others_downstream (delta);
                                // Session::route_solo_changed() does not propagate indirect solo-changes
                                // propagate upstream to tracks
-                               boost::shared_ptr<Route> shared_this = shared_from_this();
+                               boost::shared_ptr<Route> shared_this = boost::dynamic_pointer_cast<Route> (shared_from_this());
                                for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
                                        if ((*i).get() == this || !can_solo()) {
                                                continue;
@@ -4090,7 +4089,7 @@ Route::set_name_in_state (XMLNode& node, string const & name, bool rename_playli
                } else if ((*i)->name() == X_("Diskstream")) {
 
                        if (rename_playlist) {
-                               (*i)->set_property (X_("playlist"), string_compose ("%1.1", name).c_str());
+                               (*i)->set_property (X_("playlist"), name + ".1");
                        }
                        (*i)->set_property (X_("name"), name);
 
@@ -5043,10 +5042,10 @@ Route::eq_freq_controllable (uint32_t band) const
        uint32_t port_number;
 #ifdef MIXBUS32C
        switch (band) {
-               case 0: port_number = 13; break;
-               case 1: port_number = 11; break;
-               case 2: port_number = 9; break;
-               case 3: port_number = 7; break;
+               case 0: port_number = 13; break; // lo
+               case 1: port_number = 11; break; // lo mid
+               case 2: port_number = 9; break; // hi mid
+               case 3: port_number = 7; break; // hi
                default:
                        return boost::shared_ptr<AutomationControl>();
        }
@@ -5075,6 +5074,22 @@ Route::eq_q_controllable (uint32_t band) const
 boost::shared_ptr<AutomationControl>
 Route::eq_shape_controllable (uint32_t band) const
 {
+#ifdef MIXBUS32C
+       boost::shared_ptr<PluginInsert> eq = ch_eq();
+       if (is_master() || mixbus() || !eq) {
+               return boost::shared_ptr<AutomationControl>();
+       }
+       switch (band) {
+               case 0:
+                       return boost::dynamic_pointer_cast<ARDOUR::AutomationControl> (eq->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, 4))); // lo bell
+                       break;
+               case 3:
+                       return boost::dynamic_pointer_cast<ARDOUR::AutomationControl> (eq->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, 3))); // hi bell
+                       break;
+               default:
+                       break;
+       }
+#endif
        return boost::shared_ptr<AutomationControl>();
 }
 
@@ -5095,7 +5110,7 @@ Route::eq_enable_controllable () const
 }
 
 boost::shared_ptr<AutomationControl>
-Route::eq_hpf_controllable () const
+Route::filter_freq_controllable (bool hpf) const
 {
 #ifdef MIXBUS
        boost::shared_ptr<PluginInsert> eq = ch_eq();
@@ -5103,12 +5118,42 @@ Route::eq_hpf_controllable () const
        if (is_master() || mixbus() || !eq) {
                return boost::shared_ptr<AutomationControl>();
        }
+       if (hpf) {
 #ifdef MIXBUS32C
-       return boost::dynamic_pointer_cast<ARDOUR::AutomationControl> (eq->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, 3)));
+               return boost::dynamic_pointer_cast<ARDOUR::AutomationControl> (eq->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, 5))); // HPF freq
 #else
-       return boost::dynamic_pointer_cast<ARDOUR::AutomationControl> (eq->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, 2)));
+               return boost::dynamic_pointer_cast<ARDOUR::AutomationControl> (eq->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, 2)));
 #endif
+       } else {
+#ifdef MIXBUS32C
+               return boost::dynamic_pointer_cast<ARDOUR::AutomationControl> (eq->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, 6))); // LPF freq
+#else
+               return boost::shared_ptr<AutomationControl>();
+#endif
+       }
+
+#else
+       return boost::shared_ptr<AutomationControl>();
+#endif
+}
+
+boost::shared_ptr<AutomationControl>
+Route::filter_slope_controllable (bool) const
+{
+       return boost::shared_ptr<AutomationControl>();
+}
 
+boost::shared_ptr<AutomationControl>
+Route::filter_enable_controllable (bool) const
+{
+#ifdef MIXBUS32C
+       boost::shared_ptr<PluginInsert> eq = ch_eq();
+
+       if (is_master() || mixbus() || !eq) {
+               return boost::shared_ptr<AutomationControl>();
+       }
+
+       return boost::dynamic_pointer_cast<ARDOUR::AutomationControl> (eq->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, 2)));
 #else
        return boost::shared_ptr<AutomationControl>();
 #endif
@@ -5451,3 +5496,23 @@ Route::clear_all_solo_state ()
 {
        _solo_control->clear_all_solo_state ();
 }
+
+boost::shared_ptr<AutomationControl>
+Route::automation_control_recurse (PBD::ID const & id) const
+{
+       boost::shared_ptr<AutomationControl> ac = Automatable::automation_control (id);
+
+       if (ac) {
+               return ac;
+       }
+
+       Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
+
+       for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
+               if ((ac = (*i)->automation_control (id))) {
+                       return ac;
+               }
+       }
+
+       return boost::shared_ptr<AutomationControl> ();
+}