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 /**
21  * \file
22  *
23  * Port identifier.
24  */
25 
26 #ifndef __AUDIO_PORT_IDENTIFIER_H__
27 #define __AUDIO_PORT_IDENTIFIER_H__
28 
29 #include "zrythm-config.h"
30 
31 #include <stdbool.h>
32 
33 #include "plugins/plugin_identifier.h"
34 #include "utils/yaml.h"
35 
36 /**
37  * @addtogroup audio
38  *
39  * @{
40  */
41 
42 #define PORT_IDENTIFIER_SCHEMA_VERSION 1
43 
44 #define PORT_IDENTIFIER_MAGIC 3411841
45 #define IS_PORT_IDENTIFIER(tr) \
46   (tr && \
47    ((PortIdentifier *) tr)->magic == \
48      PORT_IDENTIFIER_MAGIC)
49 
50 /**
51  * Direction of the signal.
52  */
53 typedef enum PortFlow {
54   FLOW_UNKNOWN,
55   FLOW_INPUT,
56   FLOW_OUTPUT
57 } PortFlow;
58 
59 static const cyaml_strval_t
60 port_flow_strings[] =
61 {
62   { "unknown",       FLOW_UNKNOWN    },
63   { "input",         FLOW_INPUT   },
64   { "output",        FLOW_OUTPUT   },
65 };
66 
67 /**
68  * Type of signals the Port handles.
69  */
70 typedef enum PortType {
71   TYPE_UNKNOWN,
72   TYPE_CONTROL,
73   TYPE_AUDIO,
74   TYPE_EVENT,
75   TYPE_CV
76 } PortType;
77 
78 static const cyaml_strval_t
79 port_type_strings[] =
80 {
81   { "unknown",       TYPE_UNKNOWN    },
82   { "control",       TYPE_CONTROL   },
83   { "audio",         TYPE_AUDIO   },
84   { "event",         TYPE_EVENT   },
85   { "cv",            TYPE_CV   },
86 };
87 
88 /**
89  * Port unit to be displayed in the UI.
90  */
91 typedef enum PortUnit
92 {
93   PORT_UNIT_NONE,
94   PORT_UNIT_HZ,
95   PORT_UNIT_MHZ,
96   PORT_UNIT_DB,
97   PORT_UNIT_DEGREES,
98   PORT_UNIT_SECONDS,
99 
100   /** Milliseconds. */
101   PORT_UNIT_MS,
102 } PortUnit;
103 
104 static const cyaml_strval_t
105 port_unit_strings[] =
106 {
107   { "none", PORT_UNIT_NONE     },
108   { "Hz",   PORT_UNIT_HZ       },
109   { "MHz",  PORT_UNIT_MHZ      },
110   { "dB",   PORT_UNIT_DB       },
111   { "°",    PORT_UNIT_DEGREES  },
112   { "s",    PORT_UNIT_SECONDS  },
113   { "ms",   PORT_UNIT_MS       },
114 };
115 
116 /**
117  * Type of owner.
118  */
119 typedef enum PortOwnerType
120 {
121   /* PORT_OWNER_TYPE_NONE, */
122   PORT_OWNER_TYPE_AUDIO_ENGINE,
123 
124   /** Plugin owner. */
125   PORT_OWNER_TYPE_PLUGIN,
126 
127   /** Track owner. */
128   PORT_OWNER_TYPE_TRACK,
129 
130   /** Channel owner. */
131   PORT_OWNER_TYPE_CHANNEL,
132 
133   /** Fader. */
134   PORT_OWNER_TYPE_FADER,
135 
136   /**
137    * Channel send.
138    *
139    * PortIdentifier.port_index will contain the
140    * send index on the port's track's channel.
141    */
142   PORT_OWNER_TYPE_CHANNEL_SEND,
143 
144   /* TrackProcessor. */
145   PORT_OWNER_TYPE_TRACK_PROCESSOR,
146 
147   /** Port is part of a HardwareProcessor. */
148   PORT_OWNER_TYPE_HW,
149 
150   /** Port is owned by engine transport. */
151   PORT_OWNER_TYPE_TRANSPORT,
152 
153   /** Modulator macro processor owner. */
154   PORT_OWNER_TYPE_MODULATOR_MACRO_PROCESSOR,
155 } PortOwnerType;
156 
157 static const cyaml_strval_t
158 port_owner_type_strings[] =
159 {
160   { "audio engine", PORT_OWNER_TYPE_AUDIO_ENGINE  },
161   { "plugin",    PORT_OWNER_TYPE_PLUGIN   },
162   { "track",     PORT_OWNER_TYPE_TRACK   },
163   { "channel",   PORT_OWNER_TYPE_CHANNEL   },
164   { "fader",     PORT_OWNER_TYPE_FADER   },
165   { "channel send", PORT_OWNER_TYPE_CHANNEL_SEND  },
166   { "track processor",
167     PORT_OWNER_TYPE_TRACK_PROCESSOR   },
168   { "hw",        PORT_OWNER_TYPE_HW },
169   { "transport", PORT_OWNER_TYPE_TRANSPORT },
170   { "modulator macro processor", PORT_OWNER_TYPE_MODULATOR_MACRO_PROCESSOR },
171 };
172 
173 /**
174  * Port flags.
175  */
176 typedef enum PortFlags
177 {
178   PORT_FLAG_STEREO_L = 1 << 0,
179   PORT_FLAG_STEREO_R = 1 << 1,
180   PORT_FLAG_PIANO_ROLL = 1 << 2,
181   /** See http://lv2plug.in/ns/ext/port-groups/port-groups.html#sideChainOf. */
182   PORT_FLAG_SIDECHAIN = 1 << 3,
183   /** See http://lv2plug.in/ns/ext/port-groups/port-groups.html#mainInput
184    * and http://lv2plug.in/ns/ext/port-groups/port-groups.html#mainOutput. */
185   PORT_FLAG_MAIN_PORT = 1 << 4,
186   PORT_FLAG_MANUAL_PRESS = 1 << 5,
187 
188   /** Amplitude port. */
189   PORT_FLAG_AMPLITUDE = 1 << 6,
190 
191   /**
192    * Port controls the stereo balance.
193    *
194    * This is used in channels for the balance
195    * control.
196    */
197   PORT_FLAG_STEREO_BALANCE = 1 << 7,
198 
199   /**
200    * Whether the port wants to receive position
201    * events.
202    *
203    * This is only applicable for LV2 Atom ports.
204    */
205   PORT_FLAG_WANT_POSITION = 1 << 8,
206 
207   /**
208    * Trigger ports will be set to 0 at the end of
209    * each cycle.
210    *
211    * This mostly applies to LV2 Control Input
212    * ports.
213    */
214   PORT_FLAG_TRIGGER = 1 << 9,
215 
216   /** Whether the port is a toggle (on/off). */
217   PORT_FLAG_TOGGLE = 1 << 10,
218 
219   /** Whether the port is an integer. */
220   PORT_FLAG_INTEGER = 1 << 11,
221 
222   /** Whether port is for letting the plugin know
223    * that we are in freewheeling (export) mode. */
224   PORT_FLAG_FREEWHEEL = 1 << 12,
225 
226   /** Used for plugin ports. */
227   PORT_FLAG_REPORTS_LATENCY = 1 << 13,
228 
229   /** Port should not be visible to users. */
230   PORT_FLAG_NOT_ON_GUI = 1 << 14,
231 
232   /** Port is a switch for plugin enabled. */
233   PORT_FLAG_PLUGIN_ENABLED = 1 << 15,
234 
235   /** Port is a plugin control. */
236   PORT_FLAG_PLUGIN_CONTROL = 1 << 16,
237 
238   /** Port is for fader mute. */
239   PORT_FLAG_FADER_MUTE = 1 << 17,
240 
241   /** Port is for channel fader. */
242   PORT_FLAG_CHANNEL_FADER = 1 << 18,
243 
244   /**
245    * Port has an automation track.
246    *
247    * If this is set, it is assumed that the
248    * automation track at
249    * \ref PortIdentifier.port_index is for this
250    * port.
251    */
252   PORT_FLAG_AUTOMATABLE = 1 << 19,
253 
254   /** MIDI automatable control, such as modwheel or
255    * pitch bend. */
256   PORT_FLAG_MIDI_AUTOMATABLE = 1 << 20,
257 
258   /** Channels can send to this port (ie, this port
259    * is a track procesor midi/stereo in or a plugin
260    * sidechain in). */
261   PORT_FLAG_SEND_RECEIVABLE = 1 << 21,
262 
263   /** This is a BPM port. */
264   PORT_FLAG_BPM = 1 << 22,
265 
266   /**
267    * Generic plugin port not belonging to the
268    * underlying plugin.
269    *
270    * This is for ports that are added by Zrythm
271    * such as Enabled and Gain.
272    */
273   PORT_FLAG_GENERIC_PLUGIN_PORT = 1 << 23,
274 
275   /** This is the plugin gain. */
276   PORT_FLAG_PLUGIN_GAIN = 1 << 24,
277 
278   /** Track processor input mono switch. */
279   PORT_FLAG_TP_MONO = 1 << 25,
280 
281   /** Track processor input gain. */
282   PORT_FLAG_TP_INPUT_GAIN = 1 << 26,
283 
284   /** Port is a hardware port. */
285   PORT_FLAG_HW = 1 << 27,
286 
287   /**
288    * Port is part of a modulator macro processor.
289    *
290    * Which of the ports it is can be determined
291    * by checking flow/type.
292    */
293   PORT_FLAG_MODULATOR_MACRO = 1 << 28,
294 
295   /** Logarithmic. */
296   PORT_FLAG_LOGARITHMIC = 1 << 29,
297 
298   /**
299    * Plugin control is a property (changes are set
300    * via atom message on the plugin's control port),
301    * as opposed to conventional float control ports.
302    *
303    * An input Port is created for each parameter
304    * declared as either writable or readable (or
305    * both).
306    *
307    * @seealso http://lv2plug.in/ns/lv2core#Parameter. */
308   PORT_FLAG_IS_PROPERTY = 1 << 30,
309 } PortFlags;
310 
311 static const cyaml_bitdef_t
312 port_flags_bitvals[] =
313 {
314   { .name = "stereo_l", .offset =  0, .bits =  1 },
315   { .name = "stereo_r", .offset =  1, .bits =  1 },
316   { .name = "piano_roll", .offset = 2, .bits = 1 },
317   { .name = "sidechain", .offset = 3, .bits =  1 },
318   { .name = "main_port", .offset = 4, .bits = 1 },
319   { .name = "manual_press", .offset = 5, .bits = 1 },
320   { .name = "amplitude", .offset = 6, .bits = 1 },
321   { .name = "stereo_balance", .offset = 7, .bits = 1 },
322   { .name = "want_position", .offset = 8, .bits = 1 },
323   { .name = "trigger", .offset = 9, .bits = 1 },
324   { .name = "toggle", .offset = 10, .bits = 1 },
325   { .name = "integer", .offset = 11, .bits = 1 },
326   { .name = "freewheel", .offset = 12, .bits = 1 },
327   { .name = "reports_latency", .offset = 13, .bits = 1 },
328   { .name = "not_on_gui", .offset = 14, .bits = 1 },
329   { .name = "plugin_enabled", .offset = 15, .bits = 1 },
330   { .name = "plugin_control", .offset = 16, .bits = 1 },
331   { .name = "fader_mute", .offset = 17, .bits = 1 },
332   { .name = "channel_fader", .offset = 18, .bits = 1 },
333   { .name = "automatable", .offset = 19, .bits = 1 },
334   { .name = "midi_automatable", .offset = 20, .bits = 1 },
335   { .name = "send_receivable", .offset = 21, .bits = 1 },
336   { .name = "bpm", .offset = 22, .bits = 1 },
337   { .name = "generic_plugin_port", .offset = 23, .bits = 1 },
338   { .name = "plugin_gain", .offset = 24, .bits = 1 },
339   { .name = "tp_mono", .offset = 25, .bits = 1 },
340   { .name = "tp_input_gain", .offset = 26, .bits = 1 },
341   { .name = "hw", .offset = 27, .bits = 1 },
342   { .name = "modulator_macro", .offset = 28, .bits = 1 },
343   { .name = "logarithmic", .offset = 29, .bits = 1 },
344   { .name = "is_property", .offset = 30, .bits = 1 },
345 };
346 
347 typedef enum PortFlags2
348 {
349   /** Transport ports. */
350   PORT_FLAG2_TRANSPORT_ROLL = 1 << 0,
351   PORT_FLAG2_TRANSPORT_STOP = 1 << 1,
352   PORT_FLAG2_TRANSPORT_BACKWARD = 1 << 2,
353   PORT_FLAG2_TRANSPORT_FORWARD = 1 << 3,
354   PORT_FLAG2_TRANSPORT_LOOP_TOGGLE = 1 << 4,
355   PORT_FLAG2_TRANSPORT_REC_TOGGLE = 1 << 5,
356 
357   /** LV2 control atom port supports patch
358    * messages. */
359   PORT_FLAG2_SUPPORTS_PATCH_MESSAGE = 1 << 6,
360 
361   /** Port's only reasonable values are its scale
362    * points. */
363   PORT_FLAG2_ENUMERATION = 1 << 7,
364 
365   /** Parameter port's value type is URI. */
366   PORT_FLAG2_URI_PARAM = 1 << 8,
367 
368   /** Atom port buffer type is sequence. */
369   PORT_FLAG2_SEQUENCE = 1 << 9,
370 
371   /** Atom or event port supports MIDI. */
372   PORT_FLAG2_SUPPORTS_MIDI = 1 << 10,
373 
374   /** Track processor output gain. */
375   PORT_FLAG2_TP_OUTPUT_GAIN = 1 << 11,
376 
377   /** MIDI pitch bend. */
378   PORT_FLAG2_MIDI_PITCH_BEND = 1 << 12,
379 
380   /** MIDI poly key pressure. */
381   PORT_FLAG2_MIDI_POLY_KEY_PRESSURE = 1 << 13,
382 
383   /** MIDI channel pressure. */
384   PORT_FLAG2_MIDI_CHANNEL_PRESSURE = 1 << 14,
385 
386   /** Channel send enabled. */
387   PORT_FLAG2_CHANNEL_SEND_ENABLED = 1 << 15,
388 
389   /** Channel send amount. */
390   PORT_FLAG2_CHANNEL_SEND_AMOUNT = 1 << 16,
391 
392   /** Beats per bar. */
393   PORT_FLAG2_BEATS_PER_BAR = 1 << 17,
394 
395   /** Beat unit. */
396   PORT_FLAG2_BEAT_UNIT = 1 << 18,
397 
398   /** Fader solo. */
399   PORT_FLAG2_FADER_SOLO = 1 << 19,
400 
401   /** Fader listen. */
402   PORT_FLAG2_FADER_LISTEN = 1 << 20,
403 
404   /** Fader mono compat. */
405   PORT_FLAG2_FADER_MONO_COMPAT = 1 << 21,
406 
407   /** Track recording. */
408   PORT_FLAG2_TRACK_RECORDING = 1 << 22,
409 
410   /** Track processor monitor audio. */
411   PORT_FLAG2_TP_MONITOR_AUDIO = 1 << 23,
412 
413   /** Port is owned by prefader. */
414   PORT_FLAG2_PREFADER = 1 << 24,
415 
416   /** Port is owned by postfader. */
417   PORT_FLAG2_POSTFADER = 1 << 25,
418 
419   /** Port is owned by monitor fader. */
420   PORT_FLAG2_MONITOR_FADER = 1 << 26,
421 
422   /** Port is owned by the sample processor fader. */
423   PORT_FLAG2_SAMPLE_PROCESSOR_FADER = 1 << 27,
424 
425   /** Port is owned by sample processor
426    * track/channel (including faders owned by those
427    * tracks/channels). */
428   PORT_FLAG2_SAMPLE_PROCESSOR_TRACK = 1 << 28,
429 } PortFlags2;
430 
431 static const cyaml_bitdef_t
432 port_flags2_bitvals[] =
433 {
434   YAML_BITVAL ("transport_roll", 0),
435   YAML_BITVAL ("transport_stop", 1),
436   YAML_BITVAL ("transport_backward", 2),
437   YAML_BITVAL ("transport_forward", 3),
438   YAML_BITVAL ("transport_loop_toggle", 4),
439   YAML_BITVAL ("transport_rec_toggle", 5),
440   YAML_BITVAL ("patch_message", 6),
441   YAML_BITVAL ("enumeration", 7),
442   YAML_BITVAL ("uri_param", 8),
443   YAML_BITVAL ("sequence", 9),
444   YAML_BITVAL ("supports_midi", 10),
445   YAML_BITVAL ("output_gain", 11),
446   YAML_BITVAL ("pitch_bend", 12),
447   YAML_BITVAL ("poly_key_pressure", 13),
448   YAML_BITVAL ("channel_pressure", 14),
449   YAML_BITVAL ("ch_send_enabled", 15),
450   YAML_BITVAL ("ch_send_amount", 16),
451   YAML_BITVAL ("beats_per_bar", 17),
452   YAML_BITVAL ("beat_unit", 18),
453   YAML_BITVAL ("fader_solo", 19),
454   YAML_BITVAL ("fader_listen", 20),
455   YAML_BITVAL ("fader_mono_compat", 21),
456   YAML_BITVAL ("track_recording", 22),
457   YAML_BITVAL ("tp_monitor_audio", 23),
458   YAML_BITVAL ("prefader", 24),
459   YAML_BITVAL ("postfader", 25),
460   YAML_BITVAL ("monitor_fader", 26),
461   YAML_BITVAL ("sample_processor_fader", 27),
462   YAML_BITVAL ("sample_processor_track", 28),
463 };
464 
465 /**
466  * Struct used to identify Ports in the project.
467  *
468  * This should include some members of the original
469  * struct enough to identify the port. To be used
470  * for sources and dests.
471  *
472  * This must be filled in before saving and read from
473  * while loading to fill in the srcs/dests.
474  */
475 typedef struct PortIdentifier
476 {
477   int                 schema_version;
478 
479   /** Human readable label. */
480   char *              label;
481 
482   /** Symbol, if LV2. */
483   char *              sym;
484 
485   /** URI, if LV2 property. */
486   char *              uri;
487 
488   /** Comment, if any. */
489   char *              comment;
490 
491   /** Owner type. */
492   PortOwnerType       owner_type;
493   /** Data type (e.g. AUDIO). */
494   PortType            type;
495   /** Flow (IN/OUT). */
496   PortFlow            flow;
497   /** Flags (e.g. is side chain). */
498   PortFlags           flags;
499   PortFlags2          flags2;
500 
501   /** Port unit. */
502   PortUnit            unit;
503 
504   /** Identifier of plugin. */
505   PluginIdentifier    plugin_id;
506 
507   /** Port group this port is part of (only
508    * applicable for LV2 plugin ports). */
509   char *              port_group;
510 
511   /** ExtPort ID (type + full name), if hw port. */
512   char *              ext_port_id;
513 
514   /** Track name hash (0 for non-track ports). */
515   unsigned int        track_name_hash;
516 
517   /** Index (e.g. in plugin's output ports). */
518   int                 port_index;
519 } PortIdentifier;
520 
521 static const cyaml_schema_field_t
522 port_identifier_fields_schema[] =
523 {
524   YAML_FIELD_INT (
525     PortIdentifier, schema_version),
526   YAML_FIELD_STRING_PTR_OPTIONAL (
527     PortIdentifier, label),
528   YAML_FIELD_STRING_PTR_OPTIONAL (
529     PortIdentifier, sym),
530   YAML_FIELD_STRING_PTR_OPTIONAL (
531     PortIdentifier, uri),
532   YAML_FIELD_STRING_PTR_OPTIONAL (
533     PortIdentifier, comment),
534   YAML_FIELD_ENUM (
535     PortIdentifier, owner_type,
536     port_owner_type_strings),
537   YAML_FIELD_ENUM (
538     PortIdentifier, type, port_type_strings),
539   YAML_FIELD_ENUM (
540     PortIdentifier, flow, port_flow_strings),
541   YAML_FIELD_ENUM (
542     PortIdentifier, unit, port_unit_strings),
543   YAML_FIELD_BITFIELD (
544     PortIdentifier, flags, port_flags_bitvals),
545   YAML_FIELD_BITFIELD (
546     PortIdentifier, flags2, port_flags2_bitvals),
547   YAML_FIELD_UINT (
548     PortIdentifier, track_name_hash),
549   YAML_FIELD_MAPPING_EMBEDDED (
550     PortIdentifier, plugin_id,
551     plugin_identifier_fields_schema),
552   YAML_FIELD_STRING_PTR_OPTIONAL (
553     PortIdentifier, port_group),
554   YAML_FIELD_STRING_PTR_OPTIONAL (
555     PortIdentifier, ext_port_id),
556   YAML_FIELD_INT (
557     PortIdentifier, port_index),
558 
559   CYAML_FIELD_END,
560 };
561 
562 static const cyaml_schema_value_t
563 port_identifier_schema = {
564   YAML_VALUE_PTR (
565     PortIdentifier, port_identifier_fields_schema),
566 };
567 
568 static const cyaml_schema_value_t
569 port_identifier_schema_default = {
570   YAML_VALUE_DEFAULT (
571     PortIdentifier, port_identifier_fields_schema),
572 };
573 
574 void
575 port_identifier_init (
576   PortIdentifier * self);
577 
578 static inline const char *
port_identifier_get_label(PortIdentifier * self)579 port_identifier_get_label (
580   PortIdentifier * self)
581 {
582   return self->label;
583 }
584 
585 /**
586  * Port group comparator function where @ref p1 and
587  * @ref p2 are pointers to Port.
588  */
589 int
590 port_identifier_port_group_cmp (
591   const void* p1, const void* p2);
592 
593 /**
594  * Copy the identifier content from \ref src to
595  * \ref dest.
596  *
597  * @note This frees/allocates memory on \ref dest.
598  */
599 NONNULL
600 void
601 port_identifier_copy (
602   PortIdentifier *       dest,
603   const PortIdentifier * src);
604 
605 /**
606  * Returns if the 2 PortIdentifier's are equal.
607  */
608 WARN_UNUSED_RESULT
609 HOT
610 NONNULL
611 bool
612 port_identifier_is_equal (
613   const PortIdentifier * src,
614   const PortIdentifier * dest);
615 
616 /**
617  * To be used as GEqualFunc.
618  */
619 int
620 port_identifier_is_equal_func (
621   const void * a,
622   const void * b);
623 
624 NONNULL
625 void
626 port_identifier_print_to_str (
627   const PortIdentifier * self,
628   char *                 buf,
629   size_t                 buf_sz);
630 
631 NONNULL
632 void
633 port_identifier_print (
634   const PortIdentifier * self);
635 
636 NONNULL
637 bool
638 port_identifier_validate (
639   PortIdentifier * self);
640 
641 NONNULL
642 unsigned int
643 port_identifier_get_hash (
644   const void * self);
645 
646 NONNULL
647 PortIdentifier *
648 port_identifier_clone (
649   const PortIdentifier * src);
650 
651 NONNULL
652 void
653 port_identifier_free_members (
654   PortIdentifier * self);
655 
656 NONNULL
657 void
658 port_identifier_free (
659   PortIdentifier * self);
660 
661 /**
662  * Compatible with GDestroyNotify.
663  */
664 void
665 port_identifier_free_func (
666   void * self);
667 
668 /**
669  * @}
670  */
671 
672 #endif
673