Optimize plugin-processing for non-automated params
[ardour.git] / libs / ardour / plugin_manager.cc
index a7ab1f3318f76e9124c0441dde8f5a8341a371b8..06a7e0ee774fed5f0773b7037f5782f179141e6e 100644 (file)
@@ -509,7 +509,7 @@ PluginManager::lua_refresh ()
        for (LuaScriptList::const_iterator s = _scripts.begin(); s != _scripts.end(); ++s) {
                LuaPluginInfoPtr lpi (new LuaPluginInfo(*s));
                _lua_plugin_info->push_back (lpi);
-               set_tags (lpi->name, lpi->type, lpi->unique_id, lpi->category, true);
+               set_tags (lpi->type, lpi->unique_id, lpi->category, lpi->name, FromPlug);
        }
 }
 
@@ -733,6 +733,7 @@ PluginManager::ladspa_discover (string path)
 
                if(!found){
                    _ladspa_plugin_info->push_back (info);
+                       set_tags (info->type, info->unique_id, info->category, info->name, FromPlug);
                }
 
                DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Found LADSPA plugin, name: %1, Inputs: %2, Outputs: %3\n", info->name, info->n_inputs, info->n_outputs));
@@ -819,7 +820,7 @@ PluginManager::lv2_refresh ()
        _lv2_plugin_info = LV2PluginInfo::discover();
 
        for (PluginInfoList::iterator i = _lv2_plugin_info->begin(); i != _lv2_plugin_info->end(); ++i) {
-               set_tags ((*i)->name, (*i)->type, (*i)->unique_id, (*i)->category, true);
+               set_tags ((*i)->type, (*i)->unique_id, (*i)->category, (*i)->name, FromPlug);
        }
 }
 #endif
@@ -843,7 +844,7 @@ PluginManager::au_refresh (bool cache_only)
        Config->save_state();
 
        for (PluginInfoList::iterator i = _au_plugin_info->begin(); i != _au_plugin_info->end(); ++i) {
-               set_tags ((*i)->name, (*i)->type, (*i)->unique_id, (*i)->category, true);
+               set_tags ((*i)->type, (*i)->unique_id, (*i)->category, (*i)->name, FromPlug);
        }
 }
 
@@ -992,7 +993,6 @@ PluginManager::windows_vst_discover (string path, bool cache_only)
        uint32_t discovered = 0;
        for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
                VSTInfo* finfo = *x;
-               char buf[32];
 
                if (!finfo->canProcessReplacing) {
                        warning << string_compose (_("VST plugin %1 does not support processReplacing, and cannot be used in %2 at this time"),
@@ -1001,31 +1001,16 @@ PluginManager::windows_vst_discover (string path, bool cache_only)
                        continue;
                }
 
-               PluginInfoPtr info (new WindowsVSTPluginInfo);
+               PluginInfoPtr info (new WindowsVSTPluginInfo (finfo));
+               info->path = path;
 
                /* what a joke freeware VST is */
-
                if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
                        info->name = PBD::basename_nosuffix (path);
-               } else {
-                       info->name = finfo->name;
                }
 
-
-               snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
-               info->unique_id = buf;
-               info->category = finfo->Category;
-               info->path = path;
-               info->creator = finfo->creator;
-               info->index = 0;
-               info->n_inputs.set_audio (finfo->numInputs);
-               info->n_outputs.set_audio (finfo->numOutputs);
-               info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
-               info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
-               info->type = ARDOUR::Windows_VST;
-
                /* if we don't have any tags for this plugin, make some up. */
-               set_tags ((*i)->name, info->type, info->unique_id, info->category, true);
+               set_tags (info->type, info->unique_id, info->category, info->name, FromPlug);
 
                // TODO: check dup-IDs (lxvst AND windows vst)
                bool duplicate = false;
@@ -1139,7 +1124,6 @@ PluginManager::mac_vst_discover (string path, bool cache_only)
        uint32_t discovered = 0;
        for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
                VSTInfo* finfo = *x;
-               char buf[32];
 
                if (!finfo->canProcessReplacing) {
                        warning << string_compose (_("Mac VST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
@@ -1148,24 +1132,11 @@ PluginManager::mac_vst_discover (string path, bool cache_only)
                        continue;
                }
 
-               PluginInfoPtr info (new MacVSTPluginInfo);
-
-               info->name = finfo->name;
-
-               snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
-               info->unique_id = buf;
-               info->category = finfo->Category;
+               PluginInfoPtr info (new MacVSTPluginInfo (finfo));
                info->path = path;
-               info->creator = finfo->creator;
-               info->index = 0;
-               info->n_inputs.set_audio (finfo->numInputs);
-               info->n_outputs.set_audio (finfo->numOutputs);
-               info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
-               info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
-               info->type = ARDOUR::MacVST;
 
                /* if we don't have any tags for this plugin, make some up. */
-               set_tags (info->name, info->type, info->unique_id, info->category, true);
+               set_tags (info->type, info->unique_id, info->category, info->name, FromPlug);
 
                bool duplicate = false;
                if (!_mac_vst_plugin_info->empty()) {
@@ -1256,7 +1227,6 @@ PluginManager::lxvst_discover (string path, bool cache_only)
        uint32_t discovered = 0;
        for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
                VSTInfo* finfo = *x;
-               char buf[32];
 
                if (!finfo->canProcessReplacing) {
                        warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
@@ -1265,28 +1235,14 @@ PluginManager::lxvst_discover (string path, bool cache_only)
                        continue;
                }
 
-               PluginInfoPtr info(new LXVSTPluginInfo);
+               PluginInfoPtr info(new LXVSTPluginInfo (finfo));
+               info->path = path;
 
                if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
                        info->name = PBD::basename_nosuffix (path);
-               } else {
-                       info->name = finfo->name;
                }
 
-
-               snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
-               info->unique_id = buf;
-               info->category = finfo->Category;
-               info->path = path;
-               info->creator = finfo->creator;
-               info->index = 0;
-               info->n_inputs.set_audio (finfo->numInputs);
-               info->n_outputs.set_audio (finfo->numOutputs);
-               info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
-               info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
-               info->type = ARDOUR::LXVST;
-
-               set_tags (info->name, info->type, info->unique_id, info->category, true);
+               set_tags (info->type, info->unique_id, info->category, info->name, FromPlug);
 
                /* Make sure we don't find the same plugin in more than one place along
                 * the LXVST_PATH We can't use a simple 'find' because the path is included
@@ -1502,7 +1458,7 @@ PluginManager::get_tags (const PluginInfoPtr& pi) const
 {
        vector<std::string> tags;
 
-       PluginTag ps (pi->name, to_generic_vst(pi->type), pi->unique_id, "", false);
+       PluginTag ps (to_generic_vst(pi->type), pi->unique_id, "", "", FromPlug);
        PluginTagList::const_iterator i = find (ptags.begin(), ptags.end(), ps);
        if (i != ptags.end ()) {
                PBD::tokenize (i->tags, string(" "), std::back_inserter (tags), true);
@@ -1536,32 +1492,62 @@ PluginManager::user_plugin_metadata_dir () const
        return dir;
 }
 
+bool
+PluginManager::load_plugin_order_file (XMLNode &n) const
+{
+       std::string path = Glib::build_filename (user_plugin_metadata_dir(), "plugin_order");
+
+       info << string_compose (_("Loading plugin order file %1"), path) << endmsg;
+       if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
+               return false;
+       }
+
+       XMLTree tree;
+       if (tree.read (path)) {
+               n = *(tree.root());
+               return true;
+       } else {
+               error << string_compose (_("Cannot parse Plugin Order info from %1"), path) << endmsg;
+               return false;
+       }
+}
+
+
 void
-PluginManager::save_tags ()
+PluginManager::save_plugin_order_file (XMLNode &elem) const
 {
-       //backdoor way to generate an initial plugin-tag file, with names appended
-       bool init = false;
-       std::string ipath = Glib::build_filename (user_plugin_metadata_dir(), "init_plugin_tags");
-       if (Glib::file_test (ipath, Glib::FILE_TEST_EXISTS)) {
-               init = true;
+       std::string path = Glib::build_filename (user_plugin_metadata_dir(), "plugin_order");
+
+       info << string_compose (_("Saving plugin order file %1"), path) << endmsg;
+
+       XMLTree tree;
+       tree.set_root (&elem);
+       if (!tree.write (path)) {
+               error << string_compose (_("Could not save Plugin Order info to %1"), path) << endmsg;
        }
+       tree.set_root (0);  //note: must disconnect the elem from XMLTree, or it will try to delete memory it didn't allocate
+}
+
 
+void
+PluginManager::save_tags ()
+{
        std::string path = Glib::build_filename (user_plugin_metadata_dir(), "plugin_tags");
        XMLNode* root = new XMLNode (X_("PluginTags"));
 
        for (PluginTagList::iterator i = ptags.begin(); i != ptags.end(); ++i) {
-               if (!(*i).user_set && !init) {
+               if ( (*i).tagtype == FromFactoryFile || (*i).tagtype == FromUserFile ) {
+                       /* user file should contain only plugins that are (a) newly user-tagged or (b) previously unknown */
                        continue;
                }
                XMLNode* node = new XMLNode (X_("Plugin"));
                node->set_property (X_("type"), to_generic_vst ((*i).type));
                node->set_property (X_("id"), (*i).unique_id);
                node->set_property (X_("tags"), (*i).tags);
-               node->set_property (X_("user-set"), (*i).user_set);
-               if (init) {
-                       node->set_property (X_("name"), (*i).name);
+               node->set_property (X_("name"), (*i).name);
+               if ( (*i).tagtype >= FromUserFile ) {
+                       node->set_property (X_("user-set"), "1");
                }
-
                root->add_child_nocopy (*node);
        }
 
@@ -1578,7 +1564,8 @@ PluginManager::load_tags ()
        vector<std::string> tmp;
        find_files_matching_pattern (tmp, plugin_metadata_search_path (), "plugin_tags");
 
-       for (vector<std::string>::const_reverse_iterator p = tmp.rbegin (); p != tmp.rend(); ++p) {
+       for (vector<std::string>::const_reverse_iterator p = tmp.rbegin ();
+                       p != (vector<std::string>::const_reverse_iterator)tmp.rend(); ++p) {
                std::string path = *p;
                info << string_compose (_("Loading plugin meta data file %1"), path) << endmsg;
                if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
@@ -1595,34 +1582,36 @@ PluginManager::load_tags ()
                        PluginType type;
                        string id;
                        string tags;
+                       string name;
                        bool user_set;
                        if (!(*i)->get_property (X_("type"), type) ||
                                        !(*i)->get_property (X_("id"), id) ||
-                                       !(*i)->get_property (X_("tags"), tags)) {
+                                       !(*i)->get_property (X_("tags"), tags) ||
+                                       !(*i)->get_property (X_("name"), name)) {
                        }
                        if (!(*i)->get_property (X_("user-set"), user_set)) {
                                user_set = false;
                        }
                        strip_whitespace_edges (tags);
-                       set_tags ("", type, id, tags, !user_set);
+                       set_tags (type, id, tags, name, user_set ? FromUserFile : FromFactoryFile );
                }
        }
 }
 
 void
-PluginManager::set_tags (string name, PluginType t, string id, string tag, bool factory, bool force)
+PluginManager::set_tags (PluginType t, string id, string tag, std::string name, TagType ttype )
 {
        string sanitized = sanitize_tag (tag);
 
-       PluginTag ps (name, to_generic_vst (t), id, sanitized, !factory);
+       PluginTag ps (to_generic_vst (t), id, sanitized, name, ttype );
        PluginTagList::const_iterator i = find (ptags.begin(), ptags.end(), ps);
        if (i == ptags.end()) {
                ptags.insert (ps);
-       } else if (!factory || force || !(*i).user_set) {
+       } else if ( (uint32_t) ttype >=  (uint32_t) (*i).tagtype ) {  // only overwrite if we are more important than the existing. Gui > UserFile > FactoryFile > Plugin
                ptags.erase (ps);
                ptags.insert (ps);
        }
-       if (!factory || force) {
+       if ( ttype == FromGui ) {
                PluginTagChanged (t, id, sanitized); /* EMIT SIGNAL */
        }
 }
@@ -1630,7 +1619,13 @@ PluginManager::set_tags (string name, PluginType t, string id, string tag, bool
 void
 PluginManager::reset_tags (PluginInfoPtr const& pi)
 {
-       set_tags (pi->name, pi->type, pi->unique_id, pi->category, true, true);
+       PluginTag ps (pi->type, pi->unique_id, pi->category, pi->name, FromPlug);
+
+       PluginTagList::const_iterator i = find (ptags.begin(), ptags.end(), ps);
+       if (i != ptags.end()) {
+               ptags.erase (ps);
+               ptags.insert (ps);
+       }
 }
 
 std::string