diff --git a/source/backend/utils/CachedPlugins.cpp b/source/backend/utils/CachedPlugins.cpp index be2ce6480..08a11a44c 100644 --- a/source/backend/utils/CachedPlugins.cpp +++ b/source/backend/utils/CachedPlugins.cpp @@ -670,7 +670,8 @@ static const CarlaCachedPluginInfo* get_cached_plugin_jsfx(const CarlaJsfxUnit& CarlaJsusFx effect(pathLibrary); effect.setQuiet(true); - static CarlaString name, label; + static CarlaString name, label, maker; + CB::PluginCategory category = CB::PLUGIN_CATEGORY_OTHER; const water::File unitFilePath = unit.getFilePath(); label = unit.getFileId().toRawUTF8(); @@ -688,6 +689,15 @@ static const CarlaCachedPluginInfo* get_cached_plugin_jsfx(const CarlaJsfxUnit& info.valid = false; return &info; } + { + water::String author; + if (!CarlaJsusFx::parsePseudoTags(unitFilePath, author, category)) + { + info.valid = false; + return &info; + } + maker = author.toRawUTF8(); + } info.valid = true; @@ -711,7 +721,7 @@ static const CarlaCachedPluginInfo* get_cached_plugin_jsfx(const CarlaJsfxUnit& ++info.parameterIns; } - info.category = CB::PLUGIN_CATEGORY_NONE; + info.category = category; info.hints = 0; #if 0 // TODO(jsfx) when supporting custom graphics @@ -722,7 +732,7 @@ static const CarlaCachedPluginInfo* get_cached_plugin_jsfx(const CarlaJsfxUnit& info.name = name.buffer(); info.label = label.buffer(); - info.maker = gCachedPluginsNullCharPtr; + info.maker = maker.buffer(); info.copyright = gCachedPluginsNullCharPtr; return &info; diff --git a/source/discovery/carla-discovery.cpp b/source/discovery/carla-discovery.cpp index 351f36931..1cb762af0 100644 --- a/source/discovery/carla-discovery.cpp +++ b/source/discovery/carla-discovery.cpp @@ -1704,6 +1704,15 @@ static void do_jsfx_check(const char* const filename, bool doInit) return; } + // extract author and category from the pseudo-tags + water::String author; + CB::PluginCategory category = CB::PLUGIN_CATEGORY_OTHER; + if (!CarlaJsusFx::parsePseudoTags(water::File(water::CharPointer_UTF8(filename)), author, category)) + { + DISCOVERY_OUT("error", "Cannot scan the JSFX file for pseudo-tags"); + return; + } + // NOTE: count can be -1 in case of "none" uint32_t audioIns = (effect.numInputs == -1) ? 0 : (uint32_t)effect.numInputs; uint32_t audioOuts = (effect.numOutputs == -1) ? 0 : (uint32_t)effect.numOutputs; @@ -1721,7 +1730,9 @@ static void do_jsfx_check(const char* const filename, bool doInit) DISCOVERY_OUT("init", "-----------"); DISCOVERY_OUT("build", BINARY_NATIVE); DISCOVERY_OUT("hints", hints); + DISCOVERY_OUT("category", getPluginCategoryAsString(category)); DISCOVERY_OUT("name", effect.desc); + DISCOVERY_OUT("maker", author); DISCOVERY_OUT("label", filename); DISCOVERY_OUT("audio.ins", audioIns); DISCOVERY_OUT("audio.outs", audioOuts); diff --git a/source/utils/CarlaJsfxUtils.hpp b/source/utils/CarlaJsfxUtils.hpp index 4769db229..b28a528c5 100644 --- a/source/utils/CarlaJsfxUtils.hpp +++ b/source/utils/CarlaJsfxUtils.hpp @@ -19,11 +19,14 @@ #define CARLA_JSFX_UTILS_HPP_INCLUDED #include "CarlaDefines.h" +#include "CarlaBackend.h" #include "CarlaUtils.hpp" #include "CarlaString.hpp" #include "CarlaBase64Utils.hpp" +#include "CarlaJuceUtils.hpp" #include "water/files/File.h" +#include "water/files/FileInputStream.h" #include "water/xml/XmlElement.h" #include "water/xml/XmlDocument.h" #include "water/streams/MemoryInputStream.h" @@ -81,6 +84,78 @@ public: } } + static bool parsePseudoTags(const water::File& jsfxFile, water::String& author, CarlaBackend::PluginCategory& category) + { + namespace CB = CarlaBackend; + + water::FileInputStream stream(jsfxFile); + + if (stream.failedToOpen()) + return false; + + author.clear(); + category = CB::PLUGIN_CATEGORY_NONE; + + while ((author.isEmpty() || category == CB::PLUGIN_CATEGORY_NONE) && !stream.isExhausted()) + { + const water::String line = stream.readNextLine().trim(); + + const water::StringRef authorPrefix = "//author:"; + const water::StringRef tagsPrefix = "//tags:"; + + if (author.isEmpty() && line.startsWith(authorPrefix)) + { + author = line.substring(authorPrefix.length()).trim(); + } + else if (category == CB::PLUGIN_CATEGORY_NONE && line.startsWith(tagsPrefix)) + { + water::StringArray tags; + tags.addTokens(line.substring(tagsPrefix.length()), " ", ""); + + for (int i = 0; i < tags.size() && category == CB::PLUGIN_CATEGORY_NONE; ++i) + { + CB::PluginCategory currentCategory = getCategoryFromTag(tags[i]); + if (currentCategory != CB::PLUGIN_CATEGORY_NONE) + category = currentCategory; + } + } + } + + if (category == CB::PLUGIN_CATEGORY_NONE) + category = CB::PLUGIN_CATEGORY_OTHER; + + return true; + } + + static CarlaBackend::PluginCategory getCategoryFromTag(const water::String& tag) + { + if (tag.equalsIgnoreCase("synthesis")) + return CarlaBackend::PLUGIN_CATEGORY_SYNTH; + + if (tag.equalsIgnoreCase("delay")) + return CarlaBackend::PLUGIN_CATEGORY_DELAY; + + if (tag.equalsIgnoreCase("equalizer")) + return CarlaBackend::PLUGIN_CATEGORY_EQ; + + if (tag.equalsIgnoreCase("filter")) + return CarlaBackend::PLUGIN_CATEGORY_FILTER; + + if (tag.equalsIgnoreCase("distortion")) + return CarlaBackend::PLUGIN_CATEGORY_DISTORTION; + + if (tag.equalsIgnoreCase("dynamics")) + return CarlaBackend::PLUGIN_CATEGORY_DYNAMICS; + + if (tag.equalsIgnoreCase("modulation")) + return CarlaBackend::PLUGIN_CATEGORY_MODULATOR; + + if (tag.equalsIgnoreCase("utility")) + return CarlaBackend::PLUGIN_CATEGORY_UTILITY; + + return CarlaBackend::PLUGIN_CATEGORY_NONE; + } + private: bool fQuiet = false; };