Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
juce_plugin.h
1// SPDX-FileCopyrightText: © 2025 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_wrapper.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 StateDirectoryParentPathProvider state_path_provider,
45 CreatePluginInstanceAsyncFunc create_plugin_instance_async_func,
46 std::function<units::sample_rate_t ()> sample_rate_provider,
47 std::function<nframes_t ()> buffer_size_provider,
48 PluginHostWindowFactory top_level_window_provider,
49 QObject * parent = nullptr);
50
51 ~JucePlugin () override;
52
53 // ============================================================================
54 // Plugin Interface Implementation
55 // ============================================================================
56
57 void save_state (std::optional<fs::path> abs_state_dir) override;
58 void load_state (std::optional<fs::path> abs_state_dir) override;
59
61
62protected:
63 void prepare_for_processing_impl (
64 units::sample_rate_t sample_rate,
65 nframes_t max_block_length) override;
66
67 void process_impl (EngineProcessTimeInfo time_info) noexcept override;
68
69private Q_SLOTS:
73 void on_configuration_changed ();
74
78 void on_ui_visibility_changed ();
79
80private:
86 void initialize_juce_plugin_async ();
87
91 void create_ports_from_juce_plugin ();
92
96 void create_parameters_from_juce_plugin ();
97
101 void update_parameter_values ();
102
106 void sync_parameters_to_juce ();
107
111 void show_editor ();
112
116 void hide_editor ();
117
118 static constexpr auto kStateKey = "state"sv;
119 friend void to_json (nlohmann::json &j, const JucePlugin &p);
120 friend void from_json (const nlohmann::json &j, JucePlugin &p);
121
122private:
123 // ============================================================================
124 // JUCE-specific members
125 // ============================================================================
126
127 CreatePluginInstanceAsyncFunc create_plugin_instance_async_func_;
128
129 std::unique_ptr<juce::AudioPluginInstance> juce_plugin_;
130 std::unique_ptr<juce::AudioProcessorEditor> editor_;
131 std::unique_ptr<plugins::IPluginHostWindow> top_level_window_;
132
133 std::function<units::sample_rate_t ()> sample_rate_provider_;
134 std::function<nframes_t ()> buffer_size_provider_;
135
136 juce::AudioBuffer<float> juce_audio_buffer_;
137 juce::MidiBuffer juce_midi_buffer_;
138
139 class JuceParamListener : public juce::AudioProcessorParameter::Listener
140 {
141 public:
142 JuceParamListener (dsp::ProcessorParameter &zrythm_param)
143 : zrythm_param_ (zrythm_param)
144 {
145 }
146
147 void parameterValueChanged (int parameterIndex, float newValue)
148 [[clang::blocking]] override
149 {
150 // FIXME: this may get called from the audio thread, according to the
151 // docs
152 // The logic here is not realtime-safe, and currently no test hits this
153 z_debug (
154 "{}: Parameter on JUCE side changed to {}",
155 zrythm_param_.get_node_name (), newValue);
156 zrythm_param_.setBaseValue (newValue);
157 }
158 void parameterGestureChanged (int parameterIndex, bool gestureIsStarting)
159 [[clang::blocking]] override
160 {
161 // FIXME: this may get called from the audio thread, according to the
162 // docs
163 // The logic here is not realtime-safe, and currently no test hits this
164 }
165
166 private:
167 dsp::ProcessorParameter &zrythm_param_;
168 };
169
170 // Parameter mapping between JUCE and Zrythm
171 struct ParameterMapping
172 {
173 juce::AudioProcessorParameter * juce_param;
174 dsp::ProcessorParameter * zrythm_param;
175 int juce_param_index;
176 std::unique_ptr<JuceParamListener> juce_param_listener;
177 };
178
179 std::vector<ParameterMapping> parameter_mappings_;
180
181 // Audio/MIDI buffer management
182 std::vector<float *> input_channels_;
183 std::vector<float *> output_channels_;
184
185 bool juce_initialized_ = false;
186 bool editor_visible_ = false;
187 bool plugin_loading_ = false;
188
189 // Optional state to apply on instantiation (this is mainly used as a
190 // temporary space to store the restored state temporarily until the plugin is
191 // instantiated).
192 std::optional<juce::MemoryBlock> state_to_apply_;
193
194 PluginHostWindowFactory top_level_window_provider_;
195};
196
197} // namespace zrythm::plugins
Processor parameter that accepts automation and modulation sources and integrates with QML and the DS...
Definition parameter.h:220
utils::Utf8String get_node_name() const override
Returns a human friendly name of the node.
JucePlugin(dsp::ProcessorBase::ProcessorBaseDependencies dependencies, StateDirectoryParentPathProvider state_path_provider, CreatePluginInstanceAsyncFunc create_plugin_instance_async_func, std::function< units::sample_rate_t()> sample_rate_provider, std::function< nframes_t()> buffer_size_provider, PluginHostWindowFactory top_level_window_provider, QObject *parent=nullptr)
Constructor for JucePlugin.
void save_state(std::optional< fs::path > abs_state_dir) override
Saves the state inside the standard state directory.
void load_state(std::optional< fs::path > abs_state_dir) override
Load the state from the default directory or from abs_state_dir if given.
nframes_t get_single_playback_latency() const override
Returns the latency of only the given processable, without adding the previous/next latencies.
Plugin(ProcessorBaseDependencies dependencies, StateDirectoryParentPathProvider state_path_provider, QObject *parent)
Creates/initializes a plugin and its internal plugin (LV2, etc.) using the given setting.
std::function< fs::path()> StateDirectoryParentPathProvider
Returns the parent path where the plugin should save its state directory in (or load it).
Definition plugin.h:48
uint32_t nframes_t
Frame count.
Definition types.h:58
Common struct to pass around during processing to avoid repeating the data in function arguments.
Definition types.h:133