Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
plugin_descriptor.h
1// SPDX-FileCopyrightText: © 2018-2021, 2024-2025 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include "zrythm-config.h"
7
8#include "plugins/plugin_protocol.h"
9#include "utils/icloneable.h"
10#include "utils/serialization.h"
11#include "utils/utf8_string.h"
12
13#include <QObject>
14
15#include <boost/describe.hpp>
16#include <nlohmann/json_fwd.hpp>
17
23
24namespace zrythm::plugins
25{
26
30enum class PluginCategory : std::uint8_t
31{
33 None,
34 Delay,
35 REVERB,
36 DISTORTION,
37 WAVESHAPER,
38 DYNAMICS,
39 AMPLIFIER,
40 COMPRESSOR,
41 ENVELOPE,
42 EXPANDER,
43 GATE,
44 LIMITER,
45 FILTER,
46 ALLPASS_FILTER,
47 BANDPASS_FILTER,
48 COMB_FILTER,
49 EQ,
50 MULTI_EQ,
51 PARA_EQ,
52 HIGHPASS_FILTER,
53 LOWPASS_FILTER,
54 GENERATOR,
55 CONSTANT,
56 Instrument,
57 OSCILLATOR,
58 MIDI,
59 MODULATOR,
60 CHORUS,
61 FLANGER,
62 PHASER,
63 SIMULATOR,
64 SIMULATOR_REVERB,
65 SPATIAL,
66 SPECTRAL,
67 PITCH,
68 UTILITY,
69 ANALYZER,
70 CONVERTER,
71 FUNCTION,
72 MIXER,
73};
74
78enum class PluginArchitecture : std::uint8_t
79{
80 ARCH_32_BIT,
81 ARCH_64_BIT
82};
83
87enum class BridgeMode : std::uint8_t
88{
89 None,
90 UI,
91 Full,
92};
93
113class PluginDescriptor : public QObject
114{
115 Q_OBJECT
116 QML_ELEMENT
117 Q_PROPERTY (QString name READ name CONSTANT FINAL)
118 Q_PROPERTY (QString vendor READ vendor CONSTANT FINAL)
119 Q_PROPERTY (QString format READ format CONSTANT FINAL)
120 Q_PROPERTY (QString category READ category CONSTANT FINAL)
121 QML_UNCREATABLE ("")
122
123public:
124 static std::unique_ptr<PluginDescriptor>
125 from_juce_description (const juce::PluginDescription &juce_desc);
126
127 std::unique_ptr<juce::PluginDescription> to_juce_description () const;
128
129 static PluginCategory string_to_category (const utils::Utf8String &str);
130 static utils::Utf8String category_to_string (PluginCategory category);
131
132 // =========================================================
133 // QML interface
134 // =========================================================
135
136 [[nodiscard]] QString name () const { return name_.to_qstring (); }
137 QString format () const;
138 QString vendor () const;
139 QString category () const;
140
146 Q_INVOKABLE QString serializeToString () const;
147
148 Q_INVOKABLE bool isInstrument () const;
149 Q_INVOKABLE bool isEffect () const;
150 Q_INVOKABLE bool isModulator () const;
151 Q_INVOKABLE bool isMidiModifier () const;
152
153 // =========================================================
154
159 bool is_same_plugin (const PluginDescriptor &other) const;
160
164 bool has_custom_ui () const;
165
169 BridgeMode get_min_bridge_mode () const;
170
175
176 // GMenuModel * generate_context_menu () const;
177
178 friend void init_from (
179 PluginDescriptor &obj,
180 const PluginDescriptor &other,
181 utils::ObjectCloneType clone_type);
182
183private:
184 static constexpr auto kAuthorKey = "author"sv;
185 static constexpr auto kNameKey = "name"sv;
186 static constexpr auto kWebsiteKey = "website"sv;
187 static constexpr auto kCategoryKey = "category"sv;
188 static constexpr auto kCategoryStringKey = "categoryString"sv;
189 static constexpr auto kNumAudioInsKey = "numAudioIns"sv;
190 static constexpr auto kNumAudioOutsKey = "numAudioOuts"sv;
191 static constexpr auto kNumMidiInsKey = "numMidiIns"sv;
192 static constexpr auto kNumMidiOutsKey = "numMidiOuts"sv;
193 static constexpr auto kNumCtrlInsKey = "numCtrlIns"sv;
194 static constexpr auto kNumCtrlOutsKey = "numCtrlOuts"sv;
195 static constexpr auto kNumCvInsKey = "numCvIns"sv;
196 static constexpr auto kNumCvOutsKey = "numCvOuts"sv;
197 static constexpr auto kUniqueIdKey = "uniqueId"sv;
198 static constexpr auto kDeprecatedUniqueIdKey = "deprecatedUniqueId"sv;
199 static constexpr auto kArchitectureKey = "architecture"sv;
200 static constexpr auto kProtocolKey = "protocol"sv;
201 static constexpr auto kPathOrIdKey = "pathOrId"sv;
202 static constexpr auto kMinBridgeModeKey = "minBridgeMode"sv;
203 static constexpr auto kHasCustomUIKey = "hasCustomUI"sv;
204 friend void to_json (nlohmann::json &j, const PluginDescriptor &p)
205 {
206 j = nlohmann::json{
207 { kAuthorKey, p.author_ },
208 { kNameKey, p.name_ },
209 { kWebsiteKey, p.website_ },
210 { kCategoryKey, p.category_ },
211 { kCategoryStringKey, p.category_str_ },
212 { kNumAudioInsKey, p.num_audio_ins_ },
213 { kNumAudioOutsKey, p.num_audio_outs_ },
214 { kNumMidiInsKey, p.num_midi_ins_ },
215 { kNumMidiOutsKey, p.num_midi_outs_ },
216 { kNumCtrlInsKey, p.num_ctrl_ins_ },
217 { kNumCtrlOutsKey, p.num_ctrl_outs_ },
218 { kNumCvInsKey, p.num_cv_ins_ },
219 { kNumCvOutsKey, p.num_cv_outs_ },
220 { kUniqueIdKey, p.unique_id_ },
221 { kDeprecatedUniqueIdKey, p.juce_compat_deprecated_unique_id_ },
222 { kArchitectureKey, p.arch_ },
223 { kProtocolKey, p.protocol_ },
224 { kPathOrIdKey, p.path_or_id_ },
225 { kMinBridgeModeKey, p.min_bridge_mode_ },
226 { kHasCustomUIKey, p.has_custom_ui_ },
227 };
228 }
229 friend void from_json (const nlohmann::json &j, PluginDescriptor &p)
230 {
231 j.at (kAuthorKey).get_to (p.author_);
232 j.at (kNameKey).get_to (p.name_);
233 j.at (kWebsiteKey).get_to (p.website_);
234 j.at (kCategoryKey).get_to (p.category_);
235 j.at (kCategoryStringKey).get_to (p.category_str_);
236 j.at (kNumAudioInsKey).get_to (p.num_audio_ins_);
237 j.at (kNumAudioOutsKey).get_to (p.num_audio_outs_);
238 j.at (kNumMidiInsKey).get_to (p.num_midi_ins_);
239 j.at (kNumMidiOutsKey).get_to (p.num_midi_outs_);
240 j.at (kNumCtrlInsKey).get_to (p.num_ctrl_ins_);
241 j.at (kNumCtrlOutsKey).get_to (p.num_ctrl_outs_);
242 j.at (kNumCvInsKey).get_to (p.num_cv_ins_);
243 j.at (kNumCvOutsKey).get_to (p.num_cv_outs_);
244 j.at (kUniqueIdKey).get_to (p.unique_id_);
245 j.at (kArchitectureKey).get_to (p.arch_);
246 j.at (kProtocolKey).get_to (p.protocol_);
247 {
248 const auto val = j.at (kPathOrIdKey);
249 if (val[zrythm::utils::serialization::kVariantIndexKey] == 0)
250 {
251 p.path_or_id_ =
252 val[zrythm::utils::serialization::kVariantValueKey].get<fs::path> ();
253 }
254 else
255 {
256 p.path_or_id_ =
257 val[zrythm::utils::serialization::kVariantValueKey]
258 .get<utils::Utf8String> ();
259 }
260 }
261 j.at (kMinBridgeModeKey).get_to (p.min_bridge_mode_);
262 j.at (kHasCustomUIKey).get_to (p.has_custom_ui_);
263 }
264
265 friend bool operator== (const PluginDescriptor &a, const PluginDescriptor &b)
266 {
267 constexpr auto tie = [] (const auto &p) {
268 return std::tie (
269 p.arch_, p.protocol_, p.path_or_id_, p.unique_id_,
270 p.juce_compat_deprecated_unique_id_, p.min_bridge_mode_,
271 p.has_custom_ui_);
272 };
273 return tie (a) == tie (b);
274 }
275
276public:
277 utils::Utf8String author_;
278 utils::Utf8String name_;
279 utils::Utf8String website_;
280 PluginCategory category_ = PluginCategory::None;
296 int num_cv_ins_ = 0;
300 PluginArchitecture arch_ = PluginArchitecture::ARCH_64_BIT;
303
308 std::variant<fs::path, utils::Utf8String> path_or_id_;
309
311 int64_t unique_id_{};
312
315
317 BridgeMode min_bridge_mode_ = BridgeMode::None;
318
319 bool has_custom_ui_{};
320
321 BOOST_DESCRIBE_CLASS (
323 (),
324 (author_,
325 name_,
326 website_,
327 category_,
329 protocol_,
335 arch_,
337 has_custom_ui_),
338 (),
339 ())
340};
341
342} // namespace zrythm::plugins
343
344namespace std
345{
346template <> struct hash<zrythm::plugins::PluginDescriptor>
347{
348 size_t operator() (const zrythm::plugins::PluginDescriptor &d) const
349 {
350 size_t h{};
351 h = h ^ qHash (d.protocol_);
352 h = h ^ qHash (d.arch_);
353 if (std::holds_alternative<fs::path> (d.path_or_id_))
354 {
355 h = h ^ qHash (std::get<fs::path> (d.path_or_id_).string ());
356 }
357 else
358 {
359 h =
360 h ^ qHash (std::get<zrythm::utils::Utf8String> (d.path_or_id_).str ());
361 }
362 h = h ^ qHash (d.unique_id_);
363 h = h ^ qHash (d.juce_compat_deprecated_unique_id_);
364 return h;
365 }
366};
367}
368
The PluginDescriptor class provides a set of static utility functions and member functions to work wi...
int num_midi_ins_
Number of MIDI input ports.
int num_ctrl_outs_
Number of output control (plugin param) ports.
int juce_compat_deprecated_unique_id_
This is additionally needed by JUCE for some plugin formats.
Protocol::ProtocolType protocol_
Plugin protocol (Lv2/DSSI/LADSPA/VST/etc.).
int64_t unique_id_
Used by some plugin formats to uniquely identify the plugin.
bool has_custom_ui() const
Returns if the Plugin has a supported custom UI.
PluginArchitecture arch_
Architecture (32/64bit).
bool is_same_plugin(const PluginDescriptor &other) const
Returns whether the two descriptors describe the same plugin, ignoring irrelevant fields.
BridgeMode min_bridge_mode_
Minimum required bridge mode.
BridgeMode get_min_bridge_mode() const
Returns the minimum bridge mode required for this plugin.
int num_midi_outs_
Number of MIDI output ports.
int num_audio_ins_
Number of audio input ports.
int num_ctrl_ins_
Number of input control (plugin param) ports.
int num_cv_outs_
Number of output CV ports.
Q_INVOKABLE QString serializeToString() const
Serializes the descriptor to a string.
int num_audio_outs_
Number of audio output ports.
int num_cv_ins_
Number of input CV ports.
utils::Utf8String category_str_
Lv2 plugin subcategory.
utils::Utf8String get_icon_name() const
Gets an appropriate icon name.
std::variant< fs::path, utils::Utf8String > path_or_id_
Identifier, for plugin formats that use unique identifiers, or path otherwise.
@ Internal
Dummy protocol for tests.
Lightweight UTF-8 string wrapper with safe conversions.
Definition utf8_string.h:38