Mercurial > hg > pub > prymula > com
comparison DPF-Prymula-audioplugins/dpf/distrho/src/clap/ext/params.h @ 3:84e66ea83026
DPF-Prymula-audioplugins-0.231015-2
author | prymula <prymula76@outlook.com> |
---|---|
date | Mon, 16 Oct 2023 21:53:34 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2:cf2cb71d31dd | 3:84e66ea83026 |
---|---|
1 #pragma once | |
2 | |
3 #include "../plugin.h" | |
4 #include "../string-sizes.h" | |
5 | |
6 /// @page Parameters | |
7 /// @brief parameters management | |
8 /// | |
9 /// Main idea: | |
10 /// | |
11 /// The host sees the plugin as an atomic entity; and acts as a controller on top of its parameters. | |
12 /// The plugin is responsible for keeping its audio processor and its GUI in sync. | |
13 /// | |
14 /// The host can at any time read parameters' value on the [main-thread] using | |
15 /// @ref clap_plugin_params.value(). | |
16 /// | |
17 /// There are two options to communicate parameter value changes, and they are not concurrent. | |
18 /// - send automation points during clap_plugin.process() | |
19 /// - send automation points during clap_plugin_params.flush(), for parameter changes | |
20 /// without processing audio | |
21 /// | |
22 /// When the plugin changes a parameter value, it must inform the host. | |
23 /// It will send @ref CLAP_EVENT_PARAM_VALUE event during process() or flush(). | |
24 /// If the user is adjusting the value, don't forget to mark the begining and end | |
25 /// of the gesture by sending CLAP_EVENT_PARAM_GESTURE_BEGIN and CLAP_EVENT_PARAM_GESTURE_END | |
26 /// events. | |
27 /// | |
28 /// @note MIDI CCs are tricky because you may not know when the parameter adjustment ends. | |
29 /// Also if the host records incoming MIDI CC and parameter change automation at the same time, | |
30 /// there will be a conflict at playback: MIDI CC vs Automation. | |
31 /// The parameter automation will always target the same parameter because the param_id is stable. | |
32 /// The MIDI CC may have a different mapping in the future and may result in a different playback. | |
33 /// | |
34 /// When a MIDI CC changes a parameter's value, set the flag CLAP_EVENT_DONT_RECORD in | |
35 /// clap_event_param.header.flags. That way the host may record the MIDI CC automation, but not the | |
36 /// parameter change and there won't be conflict at playback. | |
37 /// | |
38 /// Scenarios: | |
39 /// | |
40 /// I. Loading a preset | |
41 /// - load the preset in a temporary state | |
42 /// - call @ref clap_host_params.rescan() if anything changed | |
43 /// - call @ref clap_host_latency.changed() if latency changed | |
44 /// - invalidate any other info that may be cached by the host | |
45 /// - if the plugin is activated and the preset will introduce breaking changes | |
46 /// (latency, audio ports, new parameters, ...) be sure to wait for the host | |
47 /// to deactivate the plugin to apply those changes. | |
48 /// If there are no breaking changes, the plugin can apply them them right away. | |
49 /// The plugin is resonsible for updating both its audio processor and its gui. | |
50 /// | |
51 /// II. Turning a knob on the DAW interface | |
52 /// - the host will send an automation event to the plugin via a process() or flush() | |
53 /// | |
54 /// III. Turning a knob on the Plugin interface | |
55 /// - the plugin is responsible for sending the parameter value to its audio processor | |
56 /// - call clap_host_params->request_flush() or clap_host->request_process(). | |
57 /// - when the host calls either clap_plugin->process() or clap_plugin_params->flush(), | |
58 /// send an automation event and don't forget to set begin_adjust, | |
59 /// end_adjust and should_record flags | |
60 /// | |
61 /// IV. Turning a knob via automation | |
62 /// - host sends an automation point during clap_plugin->process() or clap_plugin_params->flush(). | |
63 /// - the plugin is responsible for updating its GUI | |
64 /// | |
65 /// V. Turning a knob via plugin's internal MIDI mapping | |
66 /// - the plugin sends a CLAP_EVENT_PARAM_SET output event, set should_record to false | |
67 /// - the plugin is responsible to update its GUI | |
68 /// | |
69 /// VI. Adding or removing parameters | |
70 /// - if the plugin is activated call clap_host->restart() | |
71 /// - once the plugin isn't active: | |
72 /// - apply the new state | |
73 /// - if a parameter is gone or is created with an id that may have been used before, | |
74 /// call clap_host_params.clear(host, param_id, CLAP_PARAM_CLEAR_ALL) | |
75 /// - call clap_host_params->rescan(CLAP_PARAM_RESCAN_ALL) | |
76 | |
77 static CLAP_CONSTEXPR const char CLAP_EXT_PARAMS[] = "clap.params"; | |
78 | |
79 #ifdef __cplusplus | |
80 extern "C" { | |
81 #endif | |
82 | |
83 enum { | |
84 // Is this param stepped? (integer values only) | |
85 // if so the double value is converted to integer using a cast (equivalent to trunc). | |
86 CLAP_PARAM_IS_STEPPED = 1 << 0, | |
87 | |
88 // Useful for for periodic parameters like a phase | |
89 CLAP_PARAM_IS_PERIODIC = 1 << 1, | |
90 | |
91 // The parameter should not be shown to the user, because it is currently not used. | |
92 // It is not necessary to process automation for this parameter. | |
93 CLAP_PARAM_IS_HIDDEN = 1 << 2, | |
94 | |
95 // The parameter can't be changed by the host. | |
96 CLAP_PARAM_IS_READONLY = 1 << 3, | |
97 | |
98 // This parameter is used to merge the plugin and host bypass button. | |
99 // It implies that the parameter is stepped. | |
100 // min: 0 -> bypass off | |
101 // max: 1 -> bypass on | |
102 CLAP_PARAM_IS_BYPASS = 1 << 4, | |
103 | |
104 // When set: | |
105 // - automation can be recorded | |
106 // - automation can be played back | |
107 // | |
108 // The host can send live user changes for this parameter regardless of this flag. | |
109 // | |
110 // If this parameters affect the internal processing structure of the plugin, ie: max delay, fft | |
111 // size, ... and the plugins needs to re-allocate its working buffers, then it should call | |
112 // host->request_restart(), and perform the change once the plugin is re-activated. | |
113 CLAP_PARAM_IS_AUTOMATABLE = 1 << 5, | |
114 | |
115 // Does this parameter support per note automations? | |
116 CLAP_PARAM_IS_AUTOMATABLE_PER_NOTE_ID = 1 << 6, | |
117 | |
118 // Does this parameter support per key automations? | |
119 CLAP_PARAM_IS_AUTOMATABLE_PER_KEY = 1 << 7, | |
120 | |
121 // Does this parameter support per channel automations? | |
122 CLAP_PARAM_IS_AUTOMATABLE_PER_CHANNEL = 1 << 8, | |
123 | |
124 // Does this parameter support per port automations? | |
125 CLAP_PARAM_IS_AUTOMATABLE_PER_PORT = 1 << 9, | |
126 | |
127 // Does this parameter support the modulation signal? | |
128 CLAP_PARAM_IS_MODULATABLE = 1 << 10, | |
129 | |
130 // Does this parameter support per note modulations? | |
131 CLAP_PARAM_IS_MODULATABLE_PER_NOTE_ID = 1 << 11, | |
132 | |
133 // Does this parameter support per key modulations? | |
134 CLAP_PARAM_IS_MODULATABLE_PER_KEY = 1 << 12, | |
135 | |
136 // Does this parameter support per channel modulations? | |
137 CLAP_PARAM_IS_MODULATABLE_PER_CHANNEL = 1 << 13, | |
138 | |
139 // Does this parameter support per port modulations? | |
140 CLAP_PARAM_IS_MODULATABLE_PER_PORT = 1 << 14, | |
141 | |
142 // Any change to this parameter will affect the plugin output and requires to be done via | |
143 // process() if the plugin is active. | |
144 // | |
145 // A simple example would be a DC Offset, changing it will change the output signal and must be | |
146 // processed. | |
147 CLAP_PARAM_REQUIRES_PROCESS = 1 << 15, | |
148 }; | |
149 typedef uint32_t clap_param_info_flags; | |
150 | |
151 /* This describes a parameter */ | |
152 typedef struct clap_param_info { | |
153 // stable parameter identifier, it must never change. | |
154 clap_id id; | |
155 | |
156 clap_param_info_flags flags; | |
157 | |
158 // This value is optional and set by the plugin. The host will | |
159 // set it on all subsequent events regarding this param_id | |
160 // or set the cookie to nullptr if the host chooses to | |
161 // not implement cookies. | |
162 // | |
163 // The plugin must gracefully handle the case of a cookie | |
164 // which is nullptr, but can safely assume any cookie | |
165 // which is not nullptr is the value it issued. | |
166 // | |
167 // It is very strongly recommended that the host implement | |
168 // cookies. Some plugins may have noticably reduced | |
169 // performance when addressing params in hosts without cookies. | |
170 // | |
171 // The cookie's purpose is to provide a fast access to the | |
172 // plugin parameter objects. For instance: | |
173 // | |
174 // in clap_plugin_params.get_info | |
175 // Parameter *p = findParameter(param_id); | |
176 // param_info->cookie = p; | |
177 // | |
178 // later, in clap_plugin.process: | |
179 // | |
180 // Parameter *p{nullptr}; | |
181 // if (evt->cookie) [[likely]] | |
182 // p = (Parameter *)evt->cookie; | |
183 // else | |
184 // p = -- alternate mechanism -- | |
185 // | |
186 // where "alternate mechanism" is a mechanism the plugin implements | |
187 // to map parameter ids to internal objects. | |
188 // | |
189 // The host should make no assumption about the | |
190 // value of the cookie other than passing it back to the plugin or | |
191 // replacing it with nullptr. | |
192 // | |
193 // Once set, the cookie is valid until invalidated by a call to | |
194 // clap_host_params->rescan(CLAP_PARAM_RESCAN_ALL) or when the plugin is | |
195 // destroyed. | |
196 void *cookie; | |
197 | |
198 // the display name | |
199 char name[CLAP_NAME_SIZE]; | |
200 | |
201 // the module path containing the param, eg:"oscillators/wt1" | |
202 // '/' will be used as a separator to show a tree like structure. | |
203 char module[CLAP_PATH_SIZE]; | |
204 | |
205 double min_value; // minimum plain value | |
206 double max_value; // maximum plain value | |
207 double default_value; // default plain value | |
208 } clap_param_info_t; | |
209 | |
210 typedef struct clap_plugin_params { | |
211 // Returns the number of parameters. | |
212 // [main-thread] | |
213 uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin); | |
214 | |
215 // Copies the parameter's info to param_info and returns true on success. | |
216 // [main-thread] | |
217 bool(CLAP_ABI *get_info)(const clap_plugin_t *plugin, | |
218 uint32_t param_index, | |
219 clap_param_info_t *param_info); | |
220 | |
221 // Gets the parameter plain value. | |
222 // [main-thread] | |
223 bool(CLAP_ABI *get_value)(const clap_plugin_t *plugin, clap_id param_id, double *value); | |
224 | |
225 // Formats the display text for the given parameter value. | |
226 // The host should always format the parameter value to text using this function | |
227 // before displaying it to the user. | |
228 // [main-thread] | |
229 bool(CLAP_ABI *value_to_text)( | |
230 const clap_plugin_t *plugin, clap_id param_id, double value, char *display, uint32_t size); | |
231 | |
232 // Converts the display text to a parameter value. | |
233 // [main-thread] | |
234 bool(CLAP_ABI *text_to_value)(const clap_plugin_t *plugin, | |
235 clap_id param_id, | |
236 const char *display, | |
237 double *value); | |
238 | |
239 // Flushes a set of parameter changes. | |
240 // This method must not be called concurrently to clap_plugin->process(). | |
241 // | |
242 // Note: if the plugin is processing, then the process() call will already achieve the | |
243 // parameter update (bi-directionnal), so a call to flush isn't required, also be aware | |
244 // that the plugin may use the sample offset in process(), while this information would be | |
245 // lost within flush(). | |
246 // | |
247 // [active ? audio-thread : main-thread] | |
248 void(CLAP_ABI *flush)(const clap_plugin_t *plugin, | |
249 const clap_input_events_t *in, | |
250 const clap_output_events_t *out); | |
251 } clap_plugin_params_t; | |
252 | |
253 enum { | |
254 // The parameter values did change, eg. after loading a preset. | |
255 // The host will scan all the parameters value. | |
256 // The host will not record those changes as automation points. | |
257 // New values takes effect immediately. | |
258 CLAP_PARAM_RESCAN_VALUES = 1 << 0, | |
259 | |
260 // The value to text conversion changed, and the text needs to be rendered again. | |
261 CLAP_PARAM_RESCAN_TEXT = 1 << 1, | |
262 | |
263 // The parameter info did change, use this flag for: | |
264 // - name change | |
265 // - module change | |
266 // - is_periodic (flag) | |
267 // - is_hidden (flag) | |
268 // New info takes effect immediately. | |
269 CLAP_PARAM_RESCAN_INFO = 1 << 2, | |
270 | |
271 // Invalidates everything the host knows about parameters. | |
272 // It can only be used while the plugin is deactivated. | |
273 // If the plugin is activated use clap_host->restart() and delay any change until the host calls | |
274 // clap_plugin->deactivate(). | |
275 // | |
276 // You must use this flag if: | |
277 // - some parameters were added or removed. | |
278 // - some parameters had critical changes: | |
279 // - is_per_note (flag) | |
280 // - is_per_channel (flag) | |
281 // - is_readonly (flag) | |
282 // - is_bypass (flag) | |
283 // - is_stepped (flag) | |
284 // - is_modulatable (flag) | |
285 // - min_value | |
286 // - max_value | |
287 // - cookie | |
288 CLAP_PARAM_RESCAN_ALL = 1 << 3, | |
289 }; | |
290 typedef uint32_t clap_param_rescan_flags; | |
291 | |
292 enum { | |
293 // Clears all possible references to a parameter | |
294 CLAP_PARAM_CLEAR_ALL = 1 << 0, | |
295 | |
296 // Clears all automations to a parameter | |
297 CLAP_PARAM_CLEAR_AUTOMATIONS = 1 << 1, | |
298 | |
299 // Clears all modulations to a parameter | |
300 CLAP_PARAM_CLEAR_MODULATIONS = 1 << 2, | |
301 }; | |
302 typedef uint32_t clap_param_clear_flags; | |
303 | |
304 typedef struct clap_host_params { | |
305 // Rescan the full list of parameters according to the flags. | |
306 // [main-thread] | |
307 void(CLAP_ABI *rescan)(const clap_host_t *host, clap_param_rescan_flags flags); | |
308 | |
309 // Clears references to a parameter. | |
310 // [main-thread] | |
311 void(CLAP_ABI *clear)(const clap_host_t *host, clap_id param_id, clap_param_clear_flags flags); | |
312 | |
313 // Request a parameter flush. | |
314 // | |
315 // The host will then schedule a call to either: | |
316 // - clap_plugin.process() | |
317 // - clap_plugin_params.flush() | |
318 // | |
319 // This function is always safe to use and should not be called from an [audio-thread] as the | |
320 // plugin would already be within process() or flush(). | |
321 // | |
322 // [thread-safe,!audio-thread] | |
323 void(CLAP_ABI *request_flush)(const clap_host_t *host); | |
324 } clap_host_params_t; | |
325 | |
326 #ifdef __cplusplus | |
327 } | |
328 #endif |