Loading...
Searching...
No Matches
score-plugin-clap/Clap/EffectModel.hpp
1#pragma once
2#include <Process/GenericProcessFactory.hpp>
3#include <Process/Process.hpp>
4#include <Process/ProcessMetadata.hpp>
5
6#include <Control/DefaultEffectItem.hpp>
7#include <Effect/EffectFactory.hpp>
8
10#include <score/serialization/JSONVisitor.hpp>
11
12#include <ossia/detail/hash_map.hpp>
13
14#include <QSocketNotifier>
15
16#include <clap/all.h>
17
18#include <memory>
19#include <verdigris>
20
21namespace Clap
22{
23class Model;
24}
25
26PROCESS_METADATA(
27 , Clap::Model, "10e8d26d-1d82-4bfc-a9fb-d85ffdf04e5f", "CLAP", "CLAP",
28 Process::ProcessCategory::Other, "Plugins", "CLever Audio Plug-in", "ossia score",
29 {}, {}, {},
30 QUrl(
31 "https://ossia.io/score-docs/processes/"
32 "audio-plugins.html#common-formats-vst-vst3-lv2-jsfx"),
33 Process::ProcessFlags::ExternalEffect)
34DESCRIPTION_METADATA(, Clap::Model, "Clap")
35
36namespace Clap
37{
38class Window;
39class Model;
40struct PluginHandle
41{
42 PluginHandle();
43 PluginHandle(const PluginHandle&) = delete;
44 PluginHandle(PluginHandle&&) = delete;
45 PluginHandle& operator=(const PluginHandle&) = delete;
46 PluginHandle& operator=(PluginHandle&&) = delete;
47 ~PluginHandle();
48
49 void load(Model& context, QByteArray path, QByteArray id);
50 void* library{};
51 const clap_plugin_entry_t* entry{};
52 const clap_plugin_factory_t* factory{};
53 const clap_plugin_t* plugin{};
54 const clap_plugin_descriptor_t* desc{};
55
56 clap_host_t host;
57
58 // Common plugin extensions
59 const clap_plugin_params_t* ext_params{};
60 const clap_plugin_timer_support_t* ext_timer_support{};
61
62 bool activated{};
63};
64
65class Model final : public Process::ProcessModel
66{
67 W_OBJECT(Model)
68 SCORE_SERIALIZE_FRIENDS
69
70public:
71 MODEL_METADATA_IMPL(Model)
72
73 Model(
74 const TimeVal& duration, const QString& pluginPath,
75 const Id<Process::ProcessModel>& id, QObject* parent);
76
77 Model(DataStream::Deserializer& vis, QObject* parent);
78 Model(JSONObject::Deserializer& vis, QObject* parent);
79 Model(DataStream::Deserializer&& vis, QObject* parent);
80 Model(JSONObject::Deserializer&& vis, QObject* parent);
81
82 ~Model() override;
83
84 QString prettyShortName() const noexcept override
85 {
87 }
88 QString category() const noexcept override
89 {
91 }
92 QStringList tags() const noexcept override { return Metadata<Tags_k, Model>::get(); }
93 Process::ProcessFlags flags() const noexcept override;
94 bool hasExternalUI() const noexcept;
95 PluginHandle* handle() const noexcept { return m_plugin.get(); }
96
97 void closeUI() const;
98
99 const QString& pluginId() const noexcept { return m_pluginId; }
100 bool supports64() const noexcept { return m_supports64; }
101 bool executing() const noexcept { return m_executing; }
102
103 const std::vector<clap_param_info_t>& parameterInputs() const noexcept
104 {
105 return m_parameters_ins;
106 }
107 const std::vector<clap_param_info_t>& parameterOutputs() const noexcept
108 {
109 return m_parameters_outs;
110 }
111 const std::vector<clap_note_port_info_t>& midiInputs() const noexcept
112 {
113 return m_midi_ins;
114 }
115 const std::vector<clap_note_port_info_t>& midiOutputs() const noexcept
116 {
117 return m_midi_outs;
118 }
119 const std::vector<clap_audio_port_info_t>& audioInputs() const noexcept
120 {
121 return m_audio_ins;
122 }
123 const std::vector<clap_audio_port_info_t>& audioOutputs() const noexcept
124 {
125 return m_audio_outs;
126 }
127
128 // Preset functionality
129 void loadPreset(const Process::Preset& preset) override;
130 Process::Preset savePreset() const noexcept override;
131 std::vector<Process::Preset> builtinPresets() const noexcept override;
132
133 void restartPlugin() W_SIGNAL(restartPlugin);
134 Clap::Window* window{};
135 std::vector<std::pair<clap_id, QTimer*>> timers;
136
137 struct FdNotifiers
138 {
139 std::unique_ptr<QSocketNotifier> read;
140 std::unique_ptr<QSocketNotifier> write;
141 std::unique_ptr<QSocketNotifier> error;
142 };
143 ossia::hash_map<int, std::unique_ptr<FdNotifiers>> fd_notifiers;
144
145private:
146 void loadPlugin();
147 void createControls(bool loading);
148 void setupControlInlet(
149 const clap_plugin_params_t&, const clap_param_info_t& info, int index,
151 void setupControlOutlet(
152 const clap_plugin_params_t&, const clap_param_info_t& info, int index,
154
155 QString m_pluginPath;
156 QString m_pluginId;
157
158 std::unique_ptr<PluginHandle> m_plugin;
159 QByteArray m_loadedState;
160
161 std::vector<clap_param_info_t> m_parameters_ins;
162 std::vector<clap_param_info_t> m_parameters_outs;
163 std::vector<clap_audio_port_info_t> m_audio_ins;
164 std::vector<clap_audio_port_info_t> m_audio_outs;
165 std::vector<clap_note_port_info_t> m_midi_ins;
166 std::vector<clap_note_port_info_t> m_midi_outs;
167
168 bool m_supports64{};
169 bool m_executing{};
170};
171}
172
173namespace Process
174{
175template <>
176QString EffectProcessFactory_T<Clap::Model>::customConstructionData() const noexcept;
177
178template <>
179Process::Descriptor
180EffectProcessFactory_T<Clap::Model>::descriptor(QString d) const noexcept;
181}
182
183namespace Clap
184{
185class Window;
187using EffectLayerFactory = Process::EffectLayerFactory_T<
188 Clap::Model,
190 Window>;
191}
Definition DataStreamVisitor.hpp:202
Definition JSONVisitor.hpp:423
Definition Port.hpp:203
Definition Port.hpp:425
Definition DefaultEffectItem.hpp:26
Definition EffectFactory.hpp:67
Definition EffectFactory.hpp:14
The Process class.
Definition score-lib-process/Process/Process.hpp:61
The id_base_t class.
Definition Identifier.hpp:59
Base classes and tools to implement processes and layers.
Definition JSONVisitor.hpp:1115
ProcessFlags
Various settings for processes.
Definition ProcessFlags.hpp:17
STL namespace.
Static metadata implementation.
Definition lib/score/tools/Metadata.hpp:36
Definition Preset.hpp:32
Definition TimeValue.hpp:21