Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
juce_plugin.h
1// SPDX-FileCopyrightText: © 2025-2026 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include "plugins/plugin.h"
7
8#include <juce_audio_processors_headless/juce_audio_processors_headless.h>
9
10namespace zrythm::plugins
11{
12
19class JucePlugin : public Plugin
20{
21 Q_OBJECT
22 QML_ELEMENT
23 QML_UNCREATABLE ("")
24
25public:
26 using CreatePluginInstanceAsyncFunc = std::function<void (
27 const juce::PluginDescription &,
28 double,
29 int,
30 juce::AudioPluginFormat::AudioPluginFormat::PluginCreationCallback)>;
31
44 CreatePluginInstanceAsyncFunc create_plugin_instance_async_func,
45 std::function<units::sample_rate_t ()> sample_rate_provider,
46 std::function<units::sample_u32_t ()> buffer_size_provider,
47 PluginHostWindowFactory top_level_window_provider,
48 QObject * parent = nullptr);
49
50 ~JucePlugin () override;
51
52 // ============================================================================
53 // Plugin Interface Implementation
54 // ============================================================================
55
56 units::sample_u32_t get_single_playback_latency () const override;
57
58protected:
59 void prepare_for_processing_impl (
60 units::sample_rate_t sample_rate,
61 units::sample_u32_t max_block_length) override;
62
63 void
64 process_impl (dsp::graph::EngineProcessTimeInfo time_info) noexcept override;
65
66 std::string save_state_impl () const override;
67 void load_state_impl (const std::string &base64_state) override;
68
69private Q_SLOTS:
73 void on_configuration_changed (
74 PluginConfiguration * configuration,
75 bool generateNewPluginPortsAndParams);
76
80 void on_ui_visibility_changed ();
81
82private:
88 void initialize_juce_plugin_async (bool generateNewPluginPortsAndParams);
89
93 void create_ports_from_juce_plugin ();
94
98 void create_parameters_from_juce_plugin ();
99
107 void sync_changed_params_to_juce () noexcept [[clang::nonblocking]];
108
112 void show_editor ();
113
117 void hide_editor ();
118
119 static constexpr auto kStateKey = "state"sv;
120 friend void to_json (nlohmann::json &j, const JucePlugin &p);
121 friend void from_json (const nlohmann::json &j, JucePlugin &p);
122
123private:
124 // ============================================================================
125 // JUCE-specific members
126 // ============================================================================
127
128 CreatePluginInstanceAsyncFunc create_plugin_instance_async_func_;
129
130 std::unique_ptr<juce::AudioPluginInstance> juce_plugin_;
131 std::unique_ptr<juce::AudioProcessorEditor> editor_;
132 std::unique_ptr<plugins::IPluginHostWindow> top_level_window_;
133
134 std::function<units::sample_rate_t ()> sample_rate_provider_;
135 std::function<units::sample_u32_t ()> buffer_size_provider_;
136
137 juce::AudioBuffer<float> juce_audio_buffer_;
138 juce::MidiBuffer juce_midi_buffer_;
139
140 class JuceParamListener : public juce::AudioProcessorParameter::Listener
141 {
142 public:
143 JuceParamListener (JucePlugin &parent) : parent_ (parent) { }
144
145 void parameterValueChanged (int parameterIndex, float newValue)
146 [[clang::blocking]] override;
147 void parameterGestureChanged (int parameterIndex, bool gestureIsStarting)
148 [[clang::blocking]] override;
149
150 private:
151 JucePlugin &parent_;
152 };
153
154 // Parameter mapping between JUCE and Zrythm
155 struct ParameterMapping
156 {
157 juce::AudioProcessorParameter * juce_param;
158 dsp::ProcessorParameter * zrythm_param;
159 int juce_param_index;
160 size_t zrythm_param_index;
161 std::unique_ptr<JuceParamListener> juce_param_listener;
162 };
163
164 std::vector<ParameterMapping> parameter_mappings_;
165
170 std::unordered_map<int, size_t> juce_param_index_to_mapping_;
171
177 std::unordered_map<size_t, size_t> zrythm_param_index_to_mapping_;
178
179 // Audio/MIDI buffer management
180 std::vector<float *> input_channels_;
181 std::vector<float *> output_channels_;
182
183 bool juce_initialized_ = false;
184 bool editor_visible_ = false;
185 bool plugin_loading_ = false;
186
187 // Optional state to apply on instantiation (this is mainly used as a
188 // temporary space to store the restored state temporarily until the plugin is
189 // instantiated).
190 std::optional<juce::MemoryBlock> state_to_apply_;
191
192 PluginHostWindowFactory top_level_window_provider_;
193};
194
195} // namespace zrythm::plugins
Processor parameter that accepts automation and modulation sources and integrates with QML and the DS...
Definition parameter.h:167
Interface for top-level plugin hosting windows.
JUCE-based plugin host implementation.
Definition juce_plugin.h:20
JucePlugin(dsp::ProcessorBase::ProcessorBaseDependencies dependencies, CreatePluginInstanceAsyncFunc create_plugin_instance_async_func, std::function< units::sample_rate_t()> sample_rate_provider, std::function< units::sample_u32_t()> buffer_size_provider, PluginHostWindowFactory top_level_window_provider, QObject *parent=nullptr)
Constructor for JucePlugin.
units::sample_u32_t get_single_playback_latency() const override
Returns the latency of only the given processable, without adding the previous/next latencies (zero l...
Configuration for instantiating a plugin descriptor.
Plugin(ProcessorBaseDependencies dependencies, QObject *parent)
Creates/initializes a plugin and its internal plugin (LV2, etc.) using the given setting.
Common struct to pass around during processing to avoid repeating the data in function arguments.
Definition graph_node.h:51