@@ -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; | |||
@@ -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); | |||
@@ -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; | |||
}; | |||