1 /*
2 * Copyright (C) 2018-2021 Alexandros Theodotou <alex at zrythm dot org>
3 *
4 * This file is part of Zrythm
5 *
6 * Zrythm is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Zrythm is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include <math.h>
21
22 #include "audio/control_port.h"
23 #include "audio/engine.h"
24 #include "audio/port.h"
25 #include "audio/track.h"
26 #include "gui/backend/event.h"
27 #include "gui/backend/event_manager.h"
28 #include "plugins/plugin.h"
29 #include "project.h"
30 #include "utils/flags.h"
31 #include "utils/math.h"
32 #include "zrythm.h"
33 #include "zrythm_app.h"
34
35 /**
36 * Get the current real value of the control.
37 */
38 float
control_port_get_val(Port * self)39 control_port_get_val (
40 Port * self)
41 {
42 return self->control;
43 }
44
45 /**
46 * Get the current real value of the control.
47 */
48 float
control_port_get_normalized_val(Port * self)49 control_port_get_normalized_val (
50 Port * self)
51 {
52 return
53 control_port_real_val_to_normalized (
54 self, self->control);
55 }
56
57 /**
58 * Get the current real unsnapped value of the
59 * control.
60 */
61 float
control_port_get_unsnapped_val(Port * self)62 control_port_get_unsnapped_val (
63 Port * self)
64 {
65 return self->unsnapped_control;
66 }
67
68 /**
69 * Get the default real value of the control.
70 */
71 float
control_port_get_default_val(Port * self)72 control_port_get_default_val (
73 Port * self)
74 {
75 return self->deff;
76 }
77
78 /**
79 * Get the default real value of the control.
80 */
81 void
control_port_set_real_val(Port * self,float val)82 control_port_set_real_val (
83 Port * self,
84 float val)
85 {
86 g_return_if_fail (IS_PORT (self));
87 port_set_control_value (
88 self, val, F_NOT_NORMALIZED,
89 F_NO_PUBLISH_EVENTS);
90 }
91
92 /**
93 * Get the default real value of the control and
94 * sends UI events.
95 */
96 void
control_port_set_real_val_w_events(Port * self,float val)97 control_port_set_real_val_w_events (
98 Port * self,
99 float val)
100 {
101 g_return_if_fail (IS_PORT (self));
102 port_set_control_value (
103 self, val, F_NOT_NORMALIZED,
104 F_PUBLISH_EVENTS);
105 }
106
107 void
control_port_set_toggled(Port * self,bool toggled,bool forward_events)108 control_port_set_toggled (
109 Port * self,
110 bool toggled,
111 bool forward_events)
112 {
113 g_return_if_fail (IS_PORT (self));
114 port_set_control_value (
115 self, toggled ? 1.f : 0.f, F_NOT_NORMALIZED,
116 forward_events);
117 }
118
119 /**
120 * Gets the control value for an integer port.
121 */
122 int
control_port_get_int(Port * self)123 control_port_get_int (
124 Port * self)
125 {
126 return
127 control_port_get_int_from_val (self->control);
128 }
129
130 /**
131 * Gets the control value for an integer port.
132 */
133 int
control_port_get_int_from_val(float val)134 control_port_get_int_from_val (
135 float val)
136 {
137 return math_round_float_to_int (val);
138 }
139
140 /**
141 * Returns the snapped value (eg, if toggle,
142 * returns 0.f or 1.f).
143 */
144 float
control_port_get_snapped_val(Port * self)145 control_port_get_snapped_val (
146 Port * self)
147 {
148 float val = control_port_get_val (self);
149
150 return
151 control_port_get_snapped_val_from_val (
152 self, val);
153 }
154
155 /**
156 * Returns the snapped value (eg, if toggle,
157 * returns 0.f or 1.f).
158 */
159 float
control_port_get_snapped_val_from_val(Port * self,float val)160 control_port_get_snapped_val_from_val (
161 Port * self,
162 float val)
163 {
164 PortFlags flags = self->id.flags;
165 if (flags & PORT_FLAG_TOGGLE)
166 {
167 return
168 control_port_is_val_toggled (val) ?
169 1.f : 0.f;
170 }
171 else if (flags & PORT_FLAG_INTEGER)
172 {
173 return
174 (float) control_port_get_int_from_val (val);
175 }
176
177 return val;
178 }
179
180 /**
181 * Converts normalized value (0.0 to 1.0) to
182 * real value (eg. -10.0 to 100.0).
183 */
184 float
control_port_normalized_val_to_real(const Port * const self,float normalized_val)185 control_port_normalized_val_to_real (
186 const Port * const self,
187 float normalized_val)
188 {
189 const PortIdentifier * const id = &self->id;
190 if (id->flags & PORT_FLAG_PLUGIN_CONTROL)
191 {
192 if (id->flags & PORT_FLAG_LOGARITHMIC)
193 {
194 /* make sure none of the values is 0 */
195 float minf =
196 math_floats_equal (self->minf, 0.f) ?
197 1e-20f : self->minf;
198 float maxf =
199 math_floats_equal (self->maxf, 0.f) ?
200 1e-20f : self->maxf;
201 normalized_val =
202 math_floats_equal (normalized_val, 0.f) ?
203 1e-20f : normalized_val;
204
205 /* see http://lv2plug.in/ns/ext/port-props/port-props.html#rangeSteps */
206 return
207 minf *
208 powf (maxf / minf, normalized_val);
209 }
210 else if (id->flags & PORT_FLAG_TOGGLE)
211 {
212 return
213 normalized_val >= 0.001f ? 1.f : 0.f;
214 }
215 else
216 {
217 return
218 self->minf +
219 normalized_val *
220 (self->maxf - self->minf);
221 }
222 }
223 else if (id->flags & PORT_FLAG_TOGGLE)
224 {
225 return normalized_val > 0.0001f;
226 }
227 else if (id->flags & PORT_FLAG_CHANNEL_FADER)
228 {
229 return
230 (float) math_get_amp_val_from_fader (
231 normalized_val);
232 }
233 else
234 {
235 return
236 self->minf +
237 normalized_val * (self->maxf - self->minf);
238 }
239 g_return_val_if_reached (normalized_val);
240 }
241
242 /**
243 * Converts real value (eg. -10.0 to 100.0) to
244 * normalized value (0.0 to 1.0).
245 *
246 * @note This behaves differently from
247 * \ref port_set_control_value() and
248 * \ref port_get_control_value() and should be
249 * used in widgets.
250 */
251 float
control_port_real_val_to_normalized(const Port * const self,float real_val)252 control_port_real_val_to_normalized (
253 const Port * const self,
254 float real_val)
255 {
256 const PortIdentifier * const id = &self->id;
257 if (id->flags & PORT_FLAG_PLUGIN_CONTROL)
258 {
259 if (self->id.flags & PORT_FLAG_LOGARITHMIC)
260 {
261 /* make sure none of the values is 0 */
262 float minf =
263 math_floats_equal (self->minf, 0.f) ?
264 1e-20f : self->minf;
265 float maxf =
266 math_floats_equal (self->maxf, 0.f) ?
267 1e-20f : self->maxf;
268 real_val =
269 math_floats_equal (real_val, 0.f) ?
270 1e-20f : real_val;
271
272 /* see http://lv2plug.in/ns/ext/port-props/port-props.html#rangeSteps */
273 return
274 logf (real_val / minf) /
275 logf (maxf / minf);
276 }
277 else if (self->id.flags & PORT_FLAG_TOGGLE)
278 {
279 return real_val;
280 }
281 else
282 {
283 float sizef = self->maxf - self->minf;
284 return
285 (sizef - (self->maxf - real_val)) /
286 sizef;
287 }
288 }
289 else if (id->flags & PORT_FLAG_TOGGLE)
290 {
291 return real_val;
292 }
293 else if (id->flags & PORT_FLAG_CHANNEL_FADER)
294 {
295 return
296 (float)
297 math_get_fader_val_from_amp (real_val);
298 }
299 else
300 {
301 float sizef = self->maxf - self->minf;
302 return
303 (sizef - (self->maxf - real_val)) /
304 sizef;
305 }
306 g_return_val_if_reached (0.f);
307 }
308
309 /**
310 * Updates the actual value.
311 *
312 * The given value is always a normalized 0.0-1.0
313 * value and must be translated to the actual value
314 * before setting it.
315 *
316 * @param automating Whether this is from an
317 * automation event. This will set Lv2Port's
318 * automating field to true, which will cause the
319 * plugin to receive a UI event for this change.
320 */
321 void
control_port_set_val_from_normalized(Port * self,float val,bool automating)322 control_port_set_val_from_normalized (
323 Port * self,
324 float val,
325 bool automating)
326 {
327 PortIdentifier * id = &self->id;
328 if (id->flags & PORT_FLAG_PLUGIN_CONTROL)
329 {
330 float real_val =
331 control_port_normalized_val_to_real (
332 self, val);
333 if (!math_floats_equal (
334 self->control, real_val))
335 {
336 EVENTS_PUSH (
337 ET_AUTOMATION_VALUE_CHANGED, self);
338 }
339
340 port_set_control_value (
341 self, real_val, F_NOT_NORMALIZED,
342 F_PUBLISH_EVENTS);
343 self->automating = automating;
344 self->base_value = real_val;
345 }
346 else if (id->flags & PORT_FLAG_TOGGLE)
347 {
348 float real_val =
349 control_port_normalized_val_to_real (
350 self, val);
351 if (!math_floats_equal (self->control, real_val))
352 {
353 EVENTS_PUSH (
354 ET_AUTOMATION_VALUE_CHANGED, self);
355 self->control =
356 control_port_is_val_toggled (real_val) ?
357 1.f : 0.f;
358 }
359
360 if (id->flags & PORT_FLAG_FADER_MUTE)
361 {
362 Track * track = port_get_track (self, 1);
363 track_set_muted (
364 track,
365 control_port_is_toggled (self),
366 F_NO_TRIGGER_UNDO, F_NO_AUTO_SELECT,
367 F_PUBLISH_EVENTS);
368 }
369 }
370 else if (id->flags & PORT_FLAG_CHANNEL_FADER)
371 {
372 Track * track = port_get_track (self, 1);
373 Channel * ch = track_get_channel (track);
374 if (!math_floats_equal (
375 fader_get_fader_val (
376 ch->fader), val))
377 {
378 EVENTS_PUSH (
379 ET_AUTOMATION_VALUE_CHANGED, self);
380 }
381 fader_set_amp (
382 ch->fader,
383 (float)
384 math_get_amp_val_from_fader (val));
385 }
386 else if (id->flags & PORT_FLAG_STEREO_BALANCE)
387 {
388 Track * track = port_get_track (self, true);
389 Channel * ch = track_get_channel (track);
390 if (!math_floats_equal (
391 channel_get_balance_control (ch), val))
392 {
393 EVENTS_PUSH (
394 ET_AUTOMATION_VALUE_CHANGED, self);
395 }
396 channel_set_balance_control (ch, val);
397 }
398 else if (id->flags & PORT_FLAG_MIDI_AUTOMATABLE)
399 {
400 float real_val =
401 self->minf +
402 val * (self->maxf - self->minf);
403 if (!math_floats_equal (val, self->control))
404 {
405 EVENTS_PUSH (
406 ET_AUTOMATION_VALUE_CHANGED, self);
407 }
408 port_set_control_value (
409 self, real_val, 0, 0);
410 }
411 else if (id->flags & PORT_FLAG_AUTOMATABLE)
412 {
413 float real_val =
414 control_port_normalized_val_to_real (
415 self, val);
416 if (!math_floats_equal (
417 real_val, self->control))
418 {
419 EVENTS_PUSH (
420 ET_AUTOMATION_VALUE_CHANGED, self);
421 }
422 port_set_control_value (
423 self, real_val, F_NOT_NORMALIZED,
424 F_NO_PUBLISH_EVENTS);
425 }
426 else if (id->flags & PORT_FLAG_AMPLITUDE)
427 {
428 float real_val =
429 control_port_normalized_val_to_real (
430 self, val);
431 port_set_control_value (
432 self, real_val, F_NOT_NORMALIZED,
433 F_NO_PUBLISH_EVENTS);
434 }
435 else
436 {
437 g_return_if_reached ();
438 }
439 }
440