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