VST3: fetch midi mappings all at once, use it for note/sound-off
[carla.git] / source / utils / CarlaJsfxUtils.hpp
bloba8cc5f85fe2eaec6b95059381dd7acea16637906
1 /*
2 * Carla JSFX utils
3 * Copyright (C) 2021 Jean Pierre Cimalando
4 * Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
19 #ifndef CARLA_JSFX_UTILS_HPP_INCLUDED
20 #define CARLA_JSFX_UTILS_HPP_INCLUDED
22 #include "CarlaDefines.h"
23 #include "CarlaBackend.h"
24 #include "CarlaUtils.hpp"
25 #include "CarlaJuceUtils.hpp"
27 #include "water/files/File.h"
28 #include "water/text/String.h"
30 #ifdef YSFX_API
31 # error YSFX_API is not private
32 #endif
33 #include "ysfx/include/ysfx.h"
35 #include <memory>
37 CARLA_BACKEND_START_NAMESPACE
39 // --------------------------------------------------------------------------------------------------------------------
41 struct CarlaJsfxLogging
43 static void logAll(intptr_t, const ysfx_log_level level, const char* const message)
45 switch (level)
47 case ysfx_log_info:
48 carla_stdout("%s: %s", ysfx_log_level_string(level), message);
49 break;
50 case ysfx_log_warning:
51 carla_stderr("%s: %s", ysfx_log_level_string(level), message);
52 break;
53 case ysfx_log_error:
54 carla_stderr2("%s: %s", ysfx_log_level_string(level), message);
55 break;
59 static void logErrorsOnly(intptr_t, const ysfx_log_level level, const char* const message)
61 switch (level)
63 case ysfx_log_info:
64 break;
65 case ysfx_log_warning:
66 carla_stderr("%s: %s", ysfx_log_level_string(level), message);
67 break;
68 case ysfx_log_error:
69 carla_stderr2("%s: %s", ysfx_log_level_string(level), message);
70 break;
75 // --------------------------------------------------------------------------------------------------------------------
77 struct CarlaJsfxCategories
79 static PluginCategory getFromEffect(ysfx_t* effect)
81 PluginCategory category = PLUGIN_CATEGORY_OTHER;
83 if (const uint32_t tagCount = ysfx_get_tags(effect, nullptr, 0))
85 std::vector<const char*> tags;
86 tags.resize(tagCount);
87 ysfx_get_tags(effect, tags.data(), tagCount);
89 for (uint32_t i=0; i<tagCount && category == PLUGIN_CATEGORY_OTHER; ++i)
91 water::CharPointer_UTF8 tag(tags[i]);
92 PluginCategory current = getFromTag(tag);
93 if (current != PLUGIN_CATEGORY_NONE)
94 category = current;
98 return category;
101 static PluginCategory getFromTag(const water::CharPointer_UTF8 tag)
103 if (tag.compareIgnoreCase(water::CharPointer_UTF8("synthesis")) == 0)
104 return PLUGIN_CATEGORY_SYNTH;
106 if (tag.compareIgnoreCase(water::CharPointer_UTF8("delay")) == 0)
107 return PLUGIN_CATEGORY_DELAY;
109 if (tag.compareIgnoreCase(water::CharPointer_UTF8("equalizer")) == 0)
110 return PLUGIN_CATEGORY_EQ;
112 if (tag.compareIgnoreCase(water::CharPointer_UTF8("filter")) == 0)
113 return PLUGIN_CATEGORY_FILTER;
115 if (tag.compareIgnoreCase(water::CharPointer_UTF8("distortion")) == 0)
116 return PLUGIN_CATEGORY_DISTORTION;
118 if (tag.compareIgnoreCase(water::CharPointer_UTF8("dynamics")) == 0)
119 return PLUGIN_CATEGORY_DYNAMICS;
121 if (tag.compareIgnoreCase(water::CharPointer_UTF8("modulation")) == 0)
122 return PLUGIN_CATEGORY_MODULATOR;
124 if (tag.compareIgnoreCase(water::CharPointer_UTF8("utility")) == 0)
125 return PLUGIN_CATEGORY_UTILITY;
127 return PLUGIN_CATEGORY_NONE;
131 // --------------------------------------------------------------------------------------------------------------------
133 class CarlaJsfxUnit
135 static water::String createFileId(const water::File& rootPath, const water::File& filePath)
137 water::String fileId(filePath.getRelativePathFrom(rootPath));
138 #ifdef CARLA_OS_WIN
139 fileId.replaceCharacter('\\', '/');
140 #endif
141 return fileId;
144 public:
145 CarlaJsfxUnit() noexcept
146 : fFileId(),
147 fFilePath(),
148 fRootPath() {}
150 CarlaJsfxUnit(const water::File& rootPath, const water::File& filePath)
151 : fFileId(createFileId(rootPath, filePath)),
152 fFilePath(rootPath.getChildFile(fFileId).getFullPathName()),
153 fRootPath(rootPath.getFullPathName()) {}
155 explicit operator bool() const noexcept
157 return fFileId.isNotEmpty();
160 const water::String& getFileId() const noexcept
162 return fFileId;
165 const water::String& getFilePath() const noexcept
167 return fFilePath;
170 const water::String& getRootPath() const noexcept
172 return fRootPath;
175 private:
176 water::String fFileId;
177 water::String fFilePath;
178 water::String fRootPath;
181 // --------------------------------------------------------------------------------------------------------------------
183 CARLA_BACKEND_END_NAMESPACE
185 #endif // CARLA_JSFX_UTILS_HPP_INCLUDED