Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
plugin.h
1// SPDX-FileCopyrightText: © 2018-2022, 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 <memory>
9#include <string>
10#include <vector>
11
12#include "gui/dsp/port.h"
13#include "gui/dsp/port_span.h"
14#include "gui/dsp/track_fwd.h"
15#include "plugins/plugin_configuration.h"
16#include "plugins/plugin_descriptor.h"
17#include "plugins/plugin_slot.h"
18#include "utils/types.h"
19
20namespace zrythm::gui::old_dsp::plugins
21{
22
28
37class Plugin
38 : public dsp::IProcessable,
39 public IPortOwner,
41{
42public:
43 using PortIdentifier = dsp::PortIdentifier;
44 using PluginSlot = zrythm::plugins::PluginSlot;
45 using PluginSlotType = zrythm::plugins::PluginSlotType;
46 using PluginSlotNo = PluginSlot::SlotNo;
47 using PluginDescriptor = zrythm::plugins::PluginDescriptor;
48 using Protocol = zrythm::plugins::Protocol;
49 using PluginCategory = zrythm::plugins::PluginCategory;
50 using PluginConfiguration = zrythm::plugins::PluginConfiguration;
51
52 using TrackResolver =
53 utils::UuidIdentifiablObjectResolver<TrackPtrVariant, TrackUuid>;
54
59 {
60 // Rule of 0
61
63 int idx_ = 0;
64
66 int bank_idx_ = 0;
67
69 PluginUuid plugin_id_;
70
71 NLOHMANN_DEFINE_TYPE_INTRUSIVE (PresetIdentifier, idx_, bank_idx_, plugin_id_)
72 };
73
77 struct Preset
78 {
81
84
87
89
90 NLOHMANN_DEFINE_TYPE_INTRUSIVE (Preset, name_, uri_, carla_program_, id_)
91 };
92
99 struct Bank
100 {
101 // Rule of 0
102
103 void add_preset (Preset &&preset);
104
106 std::vector<Preset> presets_;
107
110
113
115
116 NLOHMANN_DEFINE_TYPE_INTRUSIVE (Bank, name_, presets_, uri_, id_)
117 };
118
119 constexpr static auto DEFAULT_BANK_URI = "https://lv2.zrythm.org#default-bank";
120 constexpr static auto INIT_PRESET_URI = "https://lv2.zrythm.org#init-preset";
121
125 constexpr static float MIN_REFRESH_RATE = 30.f;
126 constexpr static float MAX_REFRESH_RATE = 121.f;
127
131 constexpr static float MIN_SCALE_FACTOR = 0.5f;
132 constexpr static float MAX_SCALE_FACTOR = 4.f;
133
134public:
135 ~Plugin () override;
136
137 PluginDescriptor &get_descriptor () { return *setting_->descr_; }
138 utils::Utf8String get_name () const { return setting_->descr_->name_; }
139 Protocol::ProtocolType get_protocol () const
140 {
141 return setting_->descr_->protocol_;
142 }
143
144 static Plugin * from_variant (const auto &variant)
145 {
146 return std::visit ([&] (auto &&pl) -> Plugin * { return pl; }, variant);
147 }
148
149 static auto name_projection (const auto &var)
150 {
151 return std::visit ([&] (auto &&val) { return val->get_name (); }, var);
152 }
153
154 auto get_input_port_span () const { return PortSpan{ in_ports_ }; }
155 auto get_output_port_span () const { return PortSpan{ out_ports_ }; }
156
164 void init_loaded ();
165
166 bool is_in_active_project () const override;
167
169 get_full_designation_for_port (const dsp::PortIdentifier &id) const override;
170
172 const override;
173
175 const dsp::PortIdentifier::PortUuid &port_uuid,
176 const dsp::PortIdentifier &id,
177 float val) override;
178
179 bool should_bounce_to_master (utils::audio::BounceStep step) const override;
180
182 bool is_auditioner () const;
183
188
193
197 bool validate () const;
198
202 std::string print () const;
203
212 void remove_ats_from_automation_tracklist (bool free_ats, bool fire_events);
213
215 get_full_port_group_designation (const utils::Utf8String &port_group) const;
216
217 Port *
218 get_port_in_group (const utils::Utf8String &port_group, bool left) const;
219
225
232 void activate (bool activate = true);
233
234 auto get_slot_type () const
235 {
236 const auto slot = get_slot ();
237 assert (slot.has_value ());
238 if (slot->has_slot_index ())
239 {
240 return slot->get_slot_with_index ().first;
241 }
242
243 return slot->get_slot_type_only ();
244 }
245
249 void append_ports (std::vector<Port *> &ports);
250
258 void
259 expose_ports (AudioEngine &engine, bool expose, bool inputs, bool outputs);
260
266 std::optional<PortPtrVariant>
268
282 const Plugin &src,
283 bool is_backup,
284 std::optional<fs::path> abs_state_dir);
285
293 fs::path get_abs_state_dir (bool is_backup, bool create_if_not_exists);
294
299 fs::path get_abs_state_dir (bool is_backup) const
300 {
301 return get_abs_state_dir (state_dir_, is_backup);
302 }
303
308 static fs::path
309 get_abs_state_dir (const fs::path &plugin_state_dir, bool is_backup);
310
317 void ensure_state_dir (bool is_backup);
318
319 std::optional<TrackPtrVariant> get_track () const;
320
321 void set_track (const TrackUuid &track_id)
322 {
323 track_id_ = track_id;
325 }
326
327 TrackUuid get_track_id () const
328 {
329 assert (has_track ());
330 return *track_id_;
331 }
332
333 bool has_track () const { return track_id_.has_value (); }
334
340
347 // void update_latency ();
348
352 [[gnu::hot]] void prepare_process ();
353
359 void instantiate ();
360
366 auto get_slot () const -> std::optional<PluginSlot>;
367
371 [[gnu::hot]] void process_block (EngineProcessTimeInfo time_nfo) override;
372
373 utils::Utf8String get_node_name () const override;
374
375 utils::Utf8String generate_window_title () const;
376
380 void open_ui ();
381
382 bool is_selected () const { return selected_; }
383
384 void set_selected (bool selected) { selected_ = selected; }
385
386#if 0
394 void select (bool select, bool exclusive);
395#endif
396
403 bool is_enabled (bool check_track) const;
404
405 void set_enabled (bool enabled, bool fire_events);
406
412 [[gnu::hot]] void process_passthrough (EngineProcessTimeInfo time_nfo);
413
417 void close_ui ();
418
423
424 void set_selected_bank_from_index (int idx);
425
426 void set_selected_preset_from_index (int idx);
427
428 void set_selected_preset_by_name (const utils::Utf8String &name);
429
433 void set_caches ();
434
442 void connect_to_plugin (Plugin &dest);
443
448 void disconnect_from_plugin (Plugin &dest);
449
457 void disconnect ();
458
466
473 void cleanup ();
474
475protected:
479 void add_in_port (const PortUuidReference &port_id);
480
484 void add_out_port (const PortUuidReference &port_id);
485
488 std::optional<utils::Utf8String> uri,
489 const utils::Utf8String &name);
490
498 void copy_members_from (Plugin &other);
499
500protected:
501 Plugin () = default;
502
503private:
504 void set_stereo_outs_and_midi_in ();
505 void set_enabled_and_gain ();
506 void init ();
507 void set_port_index (PortUuidReference port_id);
508
509 virtual void populate_banks () = 0;
510
514 virtual void set_selected_preset_from_index_impl (int idx) = 0;
515
516 virtual void cleanup_impl () = 0;
517
525 virtual void instantiate_impl (bool loading, bool use_state_file) = 0;
526
538 virtual void
539 save_state (bool is_backup, std::optional<fs::path> abs_state_dir) = 0;
540
545 virtual void open_custom_ui (bool show) = 0;
546
547 virtual void activate_impl (bool activate = true) = 0;
548
549 virtual void process_impl (EngineProcessTimeInfo time_info) = 0;
550
556 virtual void close () = 0;
557
558protected:
565 Plugin (PortRegistry &port_registry, const PluginConfiguration &setting);
566
567private:
568 static constexpr auto kTrackIdKey = "trackId"sv;
569 static constexpr auto kSettingKey = "setting"sv;
570 static constexpr auto kInPortsKey = "inPorts"sv;
571 static constexpr auto kOutPortsKey = "outPorts"sv;
572 static constexpr auto kBanksKey = "banks"sv;
573 static constexpr auto kSelectedBankKey = "selectedBank"sv;
574 static constexpr auto kSelectedPresetKey = "selectedPreset"sv;
575 static constexpr auto kVisibleKey = "visible"sv;
576 static constexpr auto kStateDirectoryKey = "stateDir"sv;
577 friend void to_json (nlohmann::json &j, const Plugin &p)
578 {
579 to_json (j, static_cast<const UuidIdentifiableObject &> (p));
580 j[kTrackIdKey] = p.track_id_;
581 j[kSettingKey] = p.setting_;
582 j[kInPortsKey] = p.in_ports_;
583 j[kOutPortsKey] = p.out_ports_;
584 j[kBanksKey] = p.banks_;
585 j[kSelectedBankKey] = p.selected_bank_;
586 j[kSelectedPresetKey] = p.selected_preset_;
587 j[kVisibleKey] = p.visible_;
588 j[kStateDirectoryKey] = p.state_dir_;
589 }
590 friend void from_json (const nlohmann::json &j, Plugin &p)
591 {
592 from_json (j, static_cast<UuidIdentifiableObject &> (p));
593 j.at (kTrackIdKey).get_to (p.track_id_);
594 j.at (kSettingKey).get_to (p.setting_);
595 j.at (kInPortsKey).get_to (p.in_ports_);
596 j.at (kOutPortsKey).get_to (p.out_ports_);
597 j.at (kBanksKey).get_to (p.banks_);
598 j.at (kSelectedBankKey).get_to (p.selected_bank_);
599 j.at (kSelectedPresetKey).get_to (p.selected_preset_);
600 j.at (kVisibleKey).get_to (p.visible_);
601 j.at (kStateDirectoryKey).get_to (p.state_dir_);
602 }
603
604public:
605 OptionalRef<PortRegistry> port_registry_;
606 std::optional<TrackResolver> track_resolver_;
607
608 std::optional<TrackUuid> track_id_;
609
611 std::unique_ptr<PluginConfiguration> setting_;
612
614 std::vector<PortUuidReference> in_ports_;
615
616 /* Caches - avoid shared_ptr due to performance cost */
617 std::vector<ControlPort *> ctrl_in_ports_;
618 std::vector<AudioPort *> audio_in_ports_;
619 std::vector<CVPort *> cv_in_ports_;
620 std::vector<MidiPort *> midi_in_ports_;
621
624
626 std::vector<PortUuidReference> out_ports_;
627
634
641
647 ControlPort * gain_ = nullptr;
648
654 AudioPort * l_out_ = nullptr;
655 AudioPort * r_out_ = nullptr;
656
657 std::vector<Bank> banks_;
658
659 PresetIdentifier selected_bank_;
660 PresetIdentifier selected_preset_;
661
663 bool visible_ = false;
664
666 // nframes_t latency_ = 0;
667
670
674
676 bool activated_ = false;
677
679 float ui_update_hz_ = 0.f;
680
682 float ui_scale_factor_ = 0.f;
683
692 fs::path state_dir_;
693
695 bool deleting_ = false;
696
702
708
712 bool selected_{};
713
720
723 bool deactivating_ = false;
724
729 std::atomic<bool> state_changed_event_sent_ = false;
730
732 bool is_function_ = false;
733};
734
735inline bool
736operator< (const Plugin &lhs, const Plugin &rhs)
737{
738 return lhs.get_slot () < rhs.get_slot ();
739}
740
741class CarlaNativePlugin;
742
743using PluginVariant = std::variant<CarlaNativePlugin>;
744using PluginPtrVariant = to_pointer_variant<PluginVariant>;
745using PluginUniquePtrVariant = to_unique_ptr_variant<PluginVariant>;
747using PluginRegistryRef = std::reference_wrapper<PluginRegistry>;
748using PluginUuidReference = utils::UuidReference<PluginRegistry>;
749
750} // namespace zrythm::gui::old_dsp::plugins
751
752void
753from_json (
754 const nlohmann::json &j,
755 gui::old_dsp::plugins::PluginRegistry &registry);
The audio engine.
Definition engine.h:168
Audio port specifics.
Definition audio_port.h:23
Control port specifics.
MIDI port specifics.
Definition midi_port.h:19
The Port class represents a port in the audio processing graph.
Definition port.h:181
Interface for objects that can be processed in the DSP graph.
Definition graph_node.h:51
Struct used to identify Ports in the project.
This class provides the core functionality for managing a plugin, including creating/initializing the...
Definition plugin.h:41
Configuration for instantiating a plugin descriptor.
The PluginDescriptor class provides a set of static utility functions and member functions to work wi...
A registry that owns and manages objects identified by a UUID.
Lightweight UTF-8 string wrapper with safe conversions.
Definition string.h:39
Base class for objects that need to be uniquely identified by UUID.
A reference-counted RAII wrapper for a UUID in a registry.
ControlPort * own_enabled_port_
Whether the plugin has a custom "enabled" port (LV2).
Definition plugin.h:640
void process_passthrough(EngineProcessTimeInfo time_nfo)
Processes the plugin by passing through the input to its output.
std::vector< PortUuidReference > in_ports_
Ports coming in as input.
Definition plugin.h:614
utils::Utf8String uri_
URI if LV2.
Definition plugin.h:109
std::atomic< bool > state_changed_event_sent_
Set to true to avoid sending multiple ET_PLUGIN_STATE_CHANGED for the same plugin.
Definition plugin.h:729
int idx_
Index in bank, or -1 if this is used for a bank.
Definition plugin.h:63
void cleanup()
Cleans up resources of an instantiated but not activated plugin.
Bank * add_bank_if_not_exists(std::optional< utils::Utf8String > uri, const utils::Utf8String &name)
Adds a bank to the plugin's list and returns a reference to it.
void update_automatables()
(re)Generates automatables for the plugin.
bool instantiated_
Latency reported by the Lv2Plugin, if any, in samples.
Definition plugin.h:669
void add_in_port(const PortUuidReference &port_id)
Adds an in port to the plugin's list and returns a reference to it.
void remove_ats_from_automation_tracklist(bool free_ats, bool fire_events)
Removes the automation tracks associated with this plugin from the automation tracklist in the corres...
bool is_function_
Whether the plugin is used for functions.
Definition plugin.h:732
void update_identifier()
To be called when changes to the plugin identifier were made, so we can update all children recursive...
utils::Utf8String uri_
URI if LV2.
Definition plugin.h:83
static constexpr float MIN_REFRESH_RATE
UI refresh rate limits.
Definition plugin.h:125
utils::Utf8String name_
Human readable name.
Definition plugin.h:80
std::vector< Preset > presets_
Presets in this bank.
Definition plugin.h:106
bool deactivating_
Temporary variable to check if plugin is currently undergoing deactivation.
Definition plugin.h:723
ControlPort * get_enabled_port()
Gets the enable/disable port for this plugin.
int carla_program_
Carla program index.
Definition plugin.h:86
void set_port_metadata_from_owner(dsp::PortIdentifier &id, PortRange &range) const override
Function that will be called by the Port to update the identifier's relevant members based on this po...
Plugin(PortRegistry &port_registry, const PluginConfiguration &setting)
Creates/initializes a plugin and its internal plugin (LV2, etc.) using the given setting.
void connect_to_plugin(Plugin &dest)
Connect the output Ports of the given source Plugin to the input Ports of the given destination Plugi...
void init_loaded()
Initializes a plugin after deserialization.
ControlPort * enabled_
Control for plugin enabled, for convenience.
Definition plugin.h:633
bool selected_
Whether selected in the slot owner (mixer for example).
Definition plugin.h:712
utils::Utf8String get_node_name() const override
Returns a human friendly name of the node.
std::unique_ptr< PluginConfiguration > setting_
Setting this plugin was instantiated with.
Definition plugin.h:611
std::vector< PortUuidReference > out_ports_
Outgoing ports.
Definition plugin.h:626
void delete_state_files()
Deletes any state files associated with this plugin.
bool is_enabled(bool check_track) const
Returns whether the plugin is enabled.
void instantiate()
Instantiates the plugin (e.g.
ulong close_request_id_
ID of the close-request signal for Plugin.window so that we can deactivate before freeing the plugin.
Definition plugin.h:707
void prepare_process()
Updates the plugin's latency.
static fs::path get_abs_state_dir(const fs::path &plugin_state_dir, bool is_backup)
Constructs the absolute path to the plugin state dir based on the given relative path given.
void append_ports(std::vector< Port * > &ports)
Appends this plugin's ports to the given vector.
void disconnect()
To be called immediately when a channel or plugin is deleted.
float ui_update_hz_
Update frequency of the UI, in Hz (times per second).
Definition plugin.h:679
bool should_bounce_to_master(utils::audio::BounceStep step) const override
Whether the port should add its data to the master output when bouncing.
AudioPort * l_out_
Instrument left stereo output, for convenience.
Definition plugin.h:654
ulong destroy_window_id_
ID of the destroy signal for Plugin.window so that we can deactivate before freeing the plugin.
Definition plugin.h:701
float ui_scale_factor_
Scale factor for drawing UIs in scale of the monitor.
Definition plugin.h:682
bool instantiation_failed_
Set to true if instantiation failed and the plugin will be treated as disabled.
Definition plugin.h:673
void ensure_state_dir(bool is_backup)
Ensures the state dir exists or creates it.
Port * get_port_in_same_group(const Port &port)
Finds the corresponding port in the same port group (eg, if this is left, find right and vice versa).
bool visible_
Whether plugin UI is opened or not.
Definition plugin.h:663
bool validate() const
Verifies that the plugin identifiers are valid.
void copy_state_dir(const Plugin &src, bool is_backup, std::optional< fs::path > abs_state_dir)
Copies the state directory from the given source plugin to this plugin's state directory.
auto get_slot() const -> std::optional< PluginSlot >
Returns the slot this number is inserted at in the owner.
void set_ui_refresh_rate()
Sets the UI refresh rate on the Plugin.
fs::path state_dir_
State directory (only basename).
Definition plugin.h:692
void activate(bool activate=true)
Activates or deactivates the plugin.
bool activated_
Whether the plugin is currently activated or not.
Definition plugin.h:676
ControlPort * gain_
Control for plugin gain, for convenience.
Definition plugin.h:647
void set_caches()
Sets caches for processing.
utils::Utf8String name_
Human readable name.
Definition plugin.h:112
uint update_ui_source_id_
ID of GSource (if > 0).
Definition plugin.h:719
fs::path get_abs_state_dir(bool is_backup, bool create_if_not_exists)
Returns the state dir as an absolute path.
void on_control_change_event(const dsp::PortIdentifier::PortUuid &port_uuid, const dsp::PortIdentifier &id, float val) override
Will be called when a control port's value changes.
void add_out_port(const PortUuidReference &port_id)
Adds an out port to the plugin's list and returns a reference to it.
bool deleting_
Whether the plugin is currently being deleted.
Definition plugin.h:695
void expose_ports(AudioEngine &engine, bool expose, bool inputs, bool outputs)
Exposes or unexposes plugin ports to the backend.
std::optional< PortPtrVariant > get_port_by_symbol(const utils::Utf8String &sym)
Gets a port by its symbol.
void process_block(EngineProcessTimeInfo time_nfo) override
Process plugin.
static constexpr float MIN_SCALE_FACTOR
UI scale factor limits.
Definition plugin.h:131
fs::path get_abs_state_dir(bool is_backup) const
Simply gets the absolute state directory path, without attempting to create it.
Definition plugin.h:299
bool is_auditioner() const
Whether the plugin is used for MIDI auditioning in SampleProcessor.
std::string print() const
Prints the plugin to string.
void disconnect_from_plugin(Plugin &dest)
Disconnect the automatic connections from the given source Plugin to the given destination Plugin.
String utilities.
Definition algorithms.h:12
Common struct to pass around during processing to avoid repeating the data in function arguments.
Definition types.h:176
Wrapper around std::optional<std::reference_wrapper<T>> that provides a more convenient API.
Definition types.h:324
A plugin bank containing presets.
Definition plugin.h:100
Custom types.