Zrythm
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
port_identifier.h
Go to the documentation of this file.
1// clang-format off
2// SPDX-FileCopyrightText: © 2018-2021, 2023 Alexandros Theodotou <alex@zrythm.org>
3// SPDX-License-Identifier: LicenseRef-ZrythmLicense
4// clang-format on
5
12#ifndef __AUDIO_PORT_IDENTIFIER_H__
13#define __AUDIO_PORT_IDENTIFIER_H__
14
15#include "zrythm-config.h"
16
17#include <stdbool.h>
18
20#include "utils/string.h"
21#include "utils/yaml.h"
22
29#define PORT_IDENTIFIER_SCHEMA_VERSION 1
30
31#define PORT_IDENTIFIER_MAGIC 3411841
32#define IS_PORT_IDENTIFIER(tr) \
33 (tr && ((PortIdentifier *) tr)->magic == PORT_IDENTIFIER_MAGIC)
34
38typedef enum PortFlow
39{
40 FLOW_UNKNOWN,
41 FLOW_INPUT,
42 FLOW_OUTPUT
43} PortFlow;
44
45static const cyaml_strval_t port_flow_strings[] = {
46 {"unknown", FLOW_UNKNOWN},
47 { "input", FLOW_INPUT },
48 { "output", FLOW_OUTPUT },
49};
50
54typedef enum PortType
55{
56 TYPE_UNKNOWN,
57 TYPE_CONTROL,
58 TYPE_AUDIO,
59 TYPE_EVENT,
60 TYPE_CV
61} PortType;
62
63static const cyaml_strval_t port_type_strings[] = {
64 {"unknown", TYPE_UNKNOWN},
65 { "control", TYPE_CONTROL},
66 { "audio", TYPE_AUDIO },
67 { "event", TYPE_EVENT },
68 { "cv", TYPE_CV },
69};
70
74typedef enum PortUnit
75{
76 PORT_UNIT_NONE,
77 PORT_UNIT_HZ,
78 PORT_UNIT_MHZ,
79 PORT_UNIT_DB,
80 PORT_UNIT_DEGREES,
81 PORT_UNIT_SECONDS,
82
85
88} PortUnit;
89
90static const cyaml_strval_t port_unit_strings[] = {
91 {"none", PORT_UNIT_NONE },
92 { "Hz", PORT_UNIT_HZ },
93 { "MHz", PORT_UNIT_MHZ },
94 { "dB", PORT_UNIT_DB },
95 { "°", PORT_UNIT_DEGREES},
96 { "s", PORT_UNIT_SECONDS},
97 { "ms", PORT_UNIT_MS },
98 { "μs", PORT_UNIT_US },
99};
100
104typedef enum PortOwnerType
105{
106 /* PORT_OWNER_TYPE_NONE, */
107 PORT_OWNER_TYPE_AUDIO_ENGINE,
108
111
114
117
120
128
129 /* TrackProcessor. */
130 PORT_OWNER_TYPE_TRACK_PROCESSOR,
131
134
137
141
142static const cyaml_strval_t port_owner_type_strings[] = {
143 {"audio engine", PORT_OWNER_TYPE_AUDIO_ENGINE },
144 { "plugin", PORT_OWNER_TYPE_PLUGIN },
145 { "track", PORT_OWNER_TYPE_TRACK },
146 { "channel", PORT_OWNER_TYPE_CHANNEL },
147 { "fader", PORT_OWNER_TYPE_FADER },
148 { "channel send", PORT_OWNER_TYPE_CHANNEL_SEND },
149 { "track processor", PORT_OWNER_TYPE_TRACK_PROCESSOR },
150 { "hw", PORT_OWNER_TYPE_HW },
151 { "transport", PORT_OWNER_TYPE_TRANSPORT },
152 { "modulator macro processor", PORT_OWNER_TYPE_MODULATOR_MACRO_PROCESSOR},
153};
154
158typedef enum PortFlags
159{
160 PORT_FLAG_STEREO_L = 1 << 0,
161 PORT_FLAG_STEREO_R = 1 << 1,
162 PORT_FLAG_PIANO_ROLL = 1 << 2,
168 PORT_FLAG_MANUAL_PRESS = 1 << 5,
169
172
180
188
197
200
203
207
210
213
216
219
222
225
233
237
242
244 PORT_FLAG_BPM = 1 << 22,
245
254
257
260
263
265 PORT_FLAG_HW = 1 << 27,
266
274
277
289} PortFlags;
290
291static const cyaml_bitdef_t port_flags_bitvals[] = {
292 {.name = "stereo_l", .offset = 0, .bits = 1},
293 { .name = "stereo_r", .offset = 1, .bits = 1},
294 { .name = "piano_roll", .offset = 2, .bits = 1},
295 { .name = "sidechain", .offset = 3, .bits = 1},
296 { .name = "main_port", .offset = 4, .bits = 1},
297 { .name = "manual_press", .offset = 5, .bits = 1},
298 { .name = "amplitude", .offset = 6, .bits = 1},
299 { .name = "stereo_balance", .offset = 7, .bits = 1},
300 { .name = "want_position", .offset = 8, .bits = 1},
301 { .name = "trigger", .offset = 9, .bits = 1},
302 { .name = "toggle", .offset = 10, .bits = 1},
303 { .name = "integer", .offset = 11, .bits = 1},
304 { .name = "freewheel", .offset = 12, .bits = 1},
305 { .name = "reports_latency", .offset = 13, .bits = 1},
306 { .name = "not_on_gui", .offset = 14, .bits = 1},
307 { .name = "plugin_enabled", .offset = 15, .bits = 1},
308 { .name = "plugin_control", .offset = 16, .bits = 1},
309 { .name = "fader_mute", .offset = 17, .bits = 1},
310 { .name = "channel_fader", .offset = 18, .bits = 1},
311 { .name = "automatable", .offset = 19, .bits = 1},
312 { .name = "midi_automatable", .offset = 20, .bits = 1},
313 { .name = "send_receivable", .offset = 21, .bits = 1},
314 { .name = "bpm", .offset = 22, .bits = 1},
315 { .name = "generic_plugin_port", .offset = 23, .bits = 1},
316 { .name = "plugin_gain", .offset = 24, .bits = 1},
317 { .name = "tp_mono", .offset = 25, .bits = 1},
318 { .name = "tp_input_gain", .offset = 26, .bits = 1},
319 { .name = "hw", .offset = 27, .bits = 1},
320 { .name = "modulator_macro", .offset = 28, .bits = 1},
321 { .name = "logarithmic", .offset = 29, .bits = 1},
322 { .name = "is_property", .offset = 30, .bits = 1},
323};
324
325typedef enum PortFlags2
326{
329 PORT_FLAG2_TRANSPORT_STOP = 1 << 1,
330 PORT_FLAG2_TRANSPORT_BACKWARD = 1 << 2,
331 PORT_FLAG2_TRANSPORT_FORWARD = 1 << 3,
332 PORT_FLAG2_TRANSPORT_LOOP_TOGGLE = 1 << 4,
333 PORT_FLAG2_TRANSPORT_REC_TOGGLE = 1 << 5,
334
338
342
345
348
351
354
357
360
363
366
369
372
375
378
381
384
387
390
393
396
399
402
407
410
413} PortFlags2;
414
415static const cyaml_bitdef_t port_flags2_bitvals[] = {
416 YAML_BITVAL ("transport_roll", 0),
417 YAML_BITVAL ("transport_stop", 1),
418 YAML_BITVAL ("transport_backward", 2),
419 YAML_BITVAL ("transport_forward", 3),
420 YAML_BITVAL ("transport_loop_toggle", 4),
421 YAML_BITVAL ("transport_rec_toggle", 5),
422 YAML_BITVAL ("patch_message", 6),
423 YAML_BITVAL ("enumeration", 7),
424 YAML_BITVAL ("uri_param", 8),
425 YAML_BITVAL ("sequence", 9),
426 YAML_BITVAL ("supports_midi", 10),
427 YAML_BITVAL ("output_gain", 11),
428 YAML_BITVAL ("pitch_bend", 12),
429 YAML_BITVAL ("poly_key_pressure", 13),
430 YAML_BITVAL ("channel_pressure", 14),
431 YAML_BITVAL ("ch_send_enabled", 15),
432 YAML_BITVAL ("ch_send_amount", 16),
433 YAML_BITVAL ("beats_per_bar", 17),
434 YAML_BITVAL ("beat_unit", 18),
435 YAML_BITVAL ("fader_solo", 19),
436 YAML_BITVAL ("fader_listen", 20),
437 YAML_BITVAL ("fader_mono_compat", 21),
438 YAML_BITVAL ("track_recording", 22),
439 YAML_BITVAL ("tp_monitor_audio", 23),
440 YAML_BITVAL ("prefader", 24),
441 YAML_BITVAL ("postfader", 25),
442 YAML_BITVAL ("monitor_fader", 26),
443 YAML_BITVAL ("sample_processor_fader", 27),
444 YAML_BITVAL ("sample_processor_track", 28),
445 YAML_BITVAL ("fader_swap_phase", 29),
446 YAML_BITVAL ("midi_clock", 30),
447};
448
459typedef struct PortIdentifier
460{
461 int schema_version;
462
464 char * label;
465
467 char * sym;
468
470 char * uri;
471
473 char * comment;
474
483 PortFlags2 flags2;
484
487
490
494
497
499 unsigned int track_name_hash;
500
504
505static const cyaml_schema_field_t port_identifier_fields_schema[] = {
506 YAML_FIELD_INT (PortIdentifier, schema_version),
507 YAML_FIELD_STRING_PTR_OPTIONAL (PortIdentifier, label),
508 YAML_FIELD_STRING_PTR_OPTIONAL (PortIdentifier, sym),
509 YAML_FIELD_STRING_PTR_OPTIONAL (PortIdentifier, uri),
510 YAML_FIELD_STRING_PTR_OPTIONAL (PortIdentifier, comment),
511 YAML_FIELD_ENUM (PortIdentifier, owner_type, port_owner_type_strings),
512 YAML_FIELD_ENUM (PortIdentifier, type, port_type_strings),
513 YAML_FIELD_ENUM (PortIdentifier, flow, port_flow_strings),
514 YAML_FIELD_ENUM (PortIdentifier, unit, port_unit_strings),
515 YAML_FIELD_BITFIELD (PortIdentifier, flags, port_flags_bitvals),
516 YAML_FIELD_BITFIELD (PortIdentifier, flags2, port_flags2_bitvals),
517 YAML_FIELD_UINT (PortIdentifier, track_name_hash),
520 plugin_id,
521 plugin_identifier_fields_schema),
522 YAML_FIELD_STRING_PTR_OPTIONAL (PortIdentifier, port_group),
523 YAML_FIELD_STRING_PTR_OPTIONAL (PortIdentifier, ext_port_id),
524 YAML_FIELD_INT (PortIdentifier, port_index),
525
526 CYAML_FIELD_END,
527};
528
529static const cyaml_schema_value_t port_identifier_schema = {
530 YAML_VALUE_PTR (PortIdentifier, port_identifier_fields_schema),
531};
532
533static const cyaml_schema_value_t port_identifier_schema_default = {
534 YAML_VALUE_DEFAULT (PortIdentifier, port_identifier_fields_schema),
535};
536
537void
538port_identifier_init (PortIdentifier * self);
539
540static inline const char *
541port_identifier_get_label (PortIdentifier * self)
542{
543 return self->label;
544}
545
550int
551port_identifier_port_group_cmp (const void * p1, const void * p2);
552
558static inline int
559port_identifier_get_midi_channel (const PortIdentifier * self)
560{
561 if (
562 self->flags2 & PORT_FLAG2_MIDI_PITCH_BEND
563 || self->flags2 & PORT_FLAG2_MIDI_POLY_KEY_PRESSURE
564 || self->flags2 & PORT_FLAG2_MIDI_CHANNEL_PRESSURE)
565 {
566 return self->port_index + 1;
567 }
568 else if (self->flags & PORT_FLAG_MIDI_AUTOMATABLE)
569 {
570 return self->port_index / 128 + 1;
571 }
572 return -1;
573}
574
581NONNULL void
583
590WARN_UNUSED_RESULT NONNULL bool
592 const PortIdentifier * src,
593 const PortIdentifier * dest);
594
598int
599port_identifier_is_equal_func (const void * a, const void * b);
600
601NONNULL void
602port_identifier_print_to_str (
603 const PortIdentifier * self,
604 char * buf,
605 size_t buf_sz);
606
607NONNULL void
608port_identifier_print (const PortIdentifier * self);
609
610NONNULL bool
611port_identifier_validate (PortIdentifier * self);
612
613NONNULL uint32_t
614port_identifier_get_hash (const void * self);
615
616NONNULL PortIdentifier *
617port_identifier_clone (const PortIdentifier * src);
618
619NONNULL void
620port_identifier_free_members (PortIdentifier * self);
621
622NONNULL void
623port_identifier_free (PortIdentifier * self);
624
628void
630
635#endif
void port_identifier_free_func(void *self)
Compatible with GDestroyNotify.
PortFlags2
WARN_UNUSED_RESULT NONNULL bool port_identifier_is_equal(const PortIdentifier *src, const PortIdentifier *dest)
Returns if the 2 PortIdentifier's are equal.
PortType
Type of signals the Port handles.
int port_identifier_port_group_cmp(const void *p1, const void *p2)
Port group comparator function where p1 and p2 are pointers to Port.
PortFlow
Direction of the signal.
PortFlags
Port flags.
NONNULL void port_identifier_copy(PortIdentifier *dest, const PortIdentifier *src)
Copy the identifier content from src to dest.
PortUnit
Port unit to be displayed in the UI.
PortOwnerType
Type of owner.
int port_identifier_is_equal_func(const void *a, const void *b)
To be used as GEqualFunc.
@ PORT_FLAG2_MIDI_PITCH_BEND
MIDI pitch bend.
@ PORT_FLAG2_MIDI_CHANNEL_PRESSURE
MIDI channel pressure.
@ PORT_FLAG2_FADER_MONO_COMPAT
Fader mono compat.
@ PORT_FLAG2_ENUMERATION
Port's only reasonable values are its scale points.
@ PORT_FLAG2_TRACK_RECORDING
Track recording.
@ PORT_FLAG2_BEAT_UNIT
Beat unit.
@ PORT_FLAG2_SAMPLE_PROCESSOR_FADER
Port is owned by the sample processor fader.
@ PORT_FLAG2_CHANNEL_SEND_AMOUNT
Channel send amount.
@ PORT_FLAG2_PREFADER
Port is owned by prefader.
@ PORT_FLAG2_SEQUENCE
Atom port buffer type is sequence.
@ PORT_FLAG2_CHANNEL_SEND_ENABLED
Channel send enabled.
@ PORT_FLAG2_FADER_SOLO
Fader solo.
@ PORT_FLAG2_SAMPLE_PROCESSOR_TRACK
Port is owned by sample processor track/channel (including faders owned by those tracks/channels).
@ PORT_FLAG2_BEATS_PER_BAR
Beats per bar.
@ PORT_FLAG2_MONITOR_FADER
Port is owned by monitor fader.
@ PORT_FLAG2_FADER_SWAP_PHASE
Fader swap phase.
@ PORT_FLAG2_TP_OUTPUT_GAIN
Track processor output gain.
@ PORT_FLAG2_SUPPORTS_MIDI
Atom or event port supports MIDI.
@ PORT_FLAG2_MIDI_CLOCK
MIDI clock.
@ PORT_FLAG2_POSTFADER
Port is owned by postfader.
@ PORT_FLAG2_TP_MONITOR_AUDIO
Track processor monitor audio.
@ PORT_FLAG2_FADER_LISTEN
Fader listen.
@ PORT_FLAG2_TRANSPORT_ROLL
Transport ports.
@ PORT_FLAG2_MIDI_POLY_KEY_PRESSURE
MIDI poly key pressure.
@ PORT_FLAG2_URI_PARAM
Parameter port's value type is URI.
@ PORT_FLAG2_SUPPORTS_PATCH_MESSAGE
LV2 control atom port supports patch messages.
@ PORT_FLAG_CHANNEL_FADER
Port is for channel fader.
@ PORT_FLAG_PLUGIN_CONTROL
Port is a plugin control.
@ PORT_FLAG_MIDI_AUTOMATABLE
MIDI automatable control, such as modwheel or pitch bend.
@ PORT_FLAG_AUTOMATABLE
Port has an automation track.
@ PORT_FLAG_WANT_POSITION
Whether the port wants to receive position events.
@ PORT_FLAG_SIDECHAIN
See http://lv2plug.in/ns/ext/port-groups/port-groups.html#sideChainOf.
@ PORT_FLAG_TRIGGER
Trigger ports will be set to 0 at the end of each cycle.
@ PORT_FLAG_PLUGIN_ENABLED
Port is a switch for plugin enabled.
@ PORT_FLAG_REPORTS_LATENCY
Used for plugin ports.
@ PORT_FLAG_NOT_ON_GUI
Port should not be visible to users.
@ PORT_FLAG_TP_MONO
Track processor input mono switch.
@ PORT_FLAG_TOGGLE
Whether the port is a toggle (on/off).
@ PORT_FLAG_STEREO_BALANCE
Port controls the stereo balance.
@ PORT_FLAG_SEND_RECEIVABLE
Channels can send to this port (ie, this port is a track processor midi/stereo in or a plugin sidecha...
@ PORT_FLAG_FREEWHEEL
Whether port is for letting the plugin know that we are in freewheeling (export) mode.
@ PORT_FLAG_GENERIC_PLUGIN_PORT
Generic plugin port not belonging to the underlying plugin.
@ PORT_FLAG_TP_INPUT_GAIN
Track processor input gain.
@ PORT_FLAG_MAIN_PORT
See http://lv2plug.in/ns/ext/port-groups/port-groups.html#mainInput and http://lv2plug....
@ PORT_FLAG_MODULATOR_MACRO
Port is part of a modulator macro processor.
@ PORT_FLAG_LOGARITHMIC
Logarithmic.
@ PORT_FLAG_PLUGIN_GAIN
This is the plugin gain.
@ PORT_FLAG_HW
Port is a hardware port.
@ PORT_FLAG_INTEGER
Whether the port is an integer.
@ PORT_FLAG_AMPLITUDE
Amplitude port.
@ PORT_FLAG_FADER_MUTE
Port is for fader mute.
@ PORT_FLAG_BPM
This is a BPM port.
@ PORT_FLAG_IS_PROPERTY
Plugin control is a property (changes are set via atom message on the plugin's control port),...
@ PORT_UNIT_MS
Milliseconds.
@ PORT_UNIT_US
Microseconds.
@ PORT_OWNER_TYPE_TRACK
Track owner.
@ PORT_OWNER_TYPE_HW
Port is part of a HardwareProcessor.
@ PORT_OWNER_TYPE_PLUGIN
Plugin owner.
@ PORT_OWNER_TYPE_MODULATOR_MACRO_PROCESSOR
Modulator macro processor owner.
@ PORT_OWNER_TYPE_CHANNEL
Channel owner.
@ PORT_OWNER_TYPE_CHANNEL_SEND
Channel send.
@ PORT_OWNER_TYPE_TRANSPORT
Port is owned by engine transport.
@ PORT_OWNER_TYPE_FADER
Fader.
#define YAML_FIELD_MAPPING_EMBEDDED(owner, member, schema)
Mapping embedded inside the struct.
Definition yaml.h:31
#define YAML_VALUE_DEFAULT(cc, fields_schema)
Schema to be used for arrays of structs directly (not as pointers).
Definition yaml.h:218
#define YAML_VALUE_PTR(cc, fields_schema)
Schema to be used as a pointer.
Definition yaml.h:202
Plugin identifier.
String utilities.
Plugin identifier.
Struct used to identify Ports in the project.
PortOwnerType owner_type
Owner type.
char * label
Human readable label.
PortFlags flags
Flags (e.g.
char * port_group
Port group this port is part of (only applicable for LV2 plugin ports).
char * sym
Unique symbol.
PortUnit unit
Port unit.
unsigned int track_name_hash
Track name hash (0 for non-track ports).
char * uri
URI, if LV2 property.
char * comment
Comment, if any.
int port_index
Index (e.g.
PluginIdentifier plugin_id
Identifier of plugin.
char * ext_port_id
ExtPort ID (type + full name), if hw port.
PortType type
Data type (e.g.
PortFlow flow
Flow (IN/OUT).
YAML utils.