Zrythm
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
port.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: © 2018-2023 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
11#ifndef __AUDIO_PORTS_H__
12#define __AUDIO_PORTS_H__
13
14#include "zrythm-config.h"
15
16#include "dsp/port_identifier.h"
17#include "utils/types.h"
18
19#include "zix/sem.h"
20
21#ifdef HAVE_RTMIDI
22# include <rtmidi_c.h>
23#endif
24
25#ifdef HAVE_RTAUDIO
26# include <rtaudio_c.h>
27#endif
28
29typedef struct Plugin Plugin;
30typedef struct MidiEvents MidiEvents;
31typedef struct Fader Fader;
32typedef struct ZixRingImpl ZixRing;
33typedef struct WindowsMmeDevice WindowsMmeDevice;
34typedef struct Channel Channel;
35typedef struct AudioEngine AudioEngine;
36typedef struct Track Track;
37typedef struct PortConnection PortConnection;
38typedef struct TrackProcessor TrackProcessor;
40typedef struct RtMidiDevice RtMidiDevice;
41typedef struct RtAudioDevice RtAudioDevice;
42typedef struct AutomationTrack AutomationTrack;
43typedef struct TruePeakDsp TruePeakDsp;
44typedef struct ExtPort ExtPort;
45typedef struct AudioClip AudioClip;
46typedef struct ChannelSend ChannelSend;
47typedef struct Transport Transport;
50enum class PanAlgorithm;
51enum class PanLaw;
52
59#define PORT_SCHEMA_VERSION 1
60#define STEREO_PORTS_SCHEMA_VERSION 1
61
62#define PORT_MAGIC 456861194
63#define IS_PORT(_p) (((Port *) (_p))->magic == PORT_MAGIC)
64#define IS_PORT_AND_NONNULL(x) ((x) && IS_PORT (x))
65
66#define TIME_TO_RESET_PEAK 4800000
67
72#define PORT_NOT_OWNED -1
73
74#define port_is_owner_active(self, _owner_type, owner) \
75 ((self->id.owner_type == _owner_type) && (self->owner != NULL) \
76 && owner##_is_in_active_project (self->owner))
77
78#define port_is_in_active_project(self) \
79 (port_is_owner_active ( \
80 self, PortIdentifier::OwnerType::PORT_OWNER_TYPE_AUDIO_ENGINE, engine) \
81 || port_is_owner_active (self, PortIdentifier::OwnerType::PLUGIN, plugin) \
82 || port_is_owner_active (self, PortIdentifier::OwnerType::TRACK, track) \
83 || port_is_owner_active (self, PortIdentifier::OwnerType::CHANNEL, track) \
84 || port_is_owner_active (self, PortIdentifier::OwnerType::FADER, fader) \
85 || port_is_owner_active ( \
86 self, PortIdentifier::OwnerType::CHANNEL_SEND, channel_send) \
87 || port_is_owner_active ( \
88 self, PortIdentifier::OwnerType::TRACK_PROCESSOR, track) \
89 || port_is_owner_active ( \
90 self, PortIdentifier::OwnerType::MODULATOR_MACRO_PROCESSOR, \
91 modulator_macro_processor) \
92 || port_is_owner_active (self, PortIdentifier::OwnerType::HW, ext_port))
93
98{
99 None,
100
102 Lv2Port,
103
105 JackPort,
106
109
112};
113
117typedef struct PortScalePoint
118{
119 float val;
120 char * label;
122
123int
124port_scale_point_cmp (const void * _a, const void * _b);
125
126NONNULL PortScalePoint *
127port_scale_point_new (const float val, const char * label);
128
129NONNULL void
130port_scale_point_free (PortScalePoint * self);
131
135typedef struct Port
136{
137 int schema_version;
138
140
146
153 float * buf;
154
159
162 struct Port ** srcs;
163 int num_srcs;
164 size_t srcs_size;
165
168 struct Port ** dests;
169 int num_dests;
170 size_t dests_size;
171
174 int num_src_connections;
175 size_t src_connections_size;
176
180 int num_dest_connections;
181 size_t dest_connections_size;
182
188
196 float minf;
197 float maxf;
198
206 float zerof;
207
209 float deff;
210
214
223 void * data;
224
225#ifdef _WIN32
234 WindowsMmeDevice * mme_connections[40];
235 int num_mme_connections;
236#else
237 void * mme_connections[40];
238 int num_mme_connections;
239#endif
240
244
252
253#ifdef HAVE_RTMIDI
260 RtMidiDevice * rtmidi_ins[128];
261 int num_rtmidi_ins;
262
264 RtMidiDevice * rtmidi_outs[128];
265 int num_rtmidi_outs;
266#else
267 void * rtmidi_ins[128];
268 int num_rtmidi_ins;
269 void * rtmidi_outs[128];
270 int num_rtmidi_outs;
271#endif
272
273#ifdef HAVE_RTAUDIO
279 RtAudioDevice * rtaudio_ins[128];
280 int num_rtaudio_ins;
281#else
282 void * rtaudio_ins[128];
283 int num_rtaudio_ins;
284#endif
285
288 int num_scale_points;
289
301 float control;
302
305
309
316
319
322
325
328
331
339
343
344 /* ====== flags to indicate port owner ====== */
345
352
355
363
371
379
382
392
395
399
410 ZixRing * audio_ring;
411
425 ZixRing * midi_ring;
426
429 float peak;
430
433
443
450
461
464
471
472 /*
473 * Next 2 objects are MIDI CC info, if MIDI CC in track processor.
474 *
475 * Used as a cache.
476 */
477
480
483
486
488 int magic;
489
493} Port;
494
500typedef struct StereoPorts
501{
502 int schema_version;
503 Port * l;
504 Port * r;
506
514NONNULL void
515port_init_loaded (Port * self, void * owner);
516
517void
518port_set_owner (Port * self, PortIdentifier::OwnerType owner_type, void * owner);
519
520NONNULL Port *
521port_find_from_identifier (const PortIdentifier * const id);
522
523NONNULL static inline void
524stereo_ports_init_loaded (StereoPorts * sp, void * owner)
525{
526 port_init_loaded (sp->l, owner);
527 port_init_loaded (sp->r, owner);
528}
529
530NONNULL_ARGS (1)
531static inline void stereo_ports_set_owner (
532 StereoPorts * sp,
533 PortIdentifier::OwnerType owner_type,
534 void * owner)
535{
536 port_set_owner (sp->l, owner_type, owner);
537 port_set_owner (sp->r, owner_type, owner);
538}
539
543WARN_UNUSED_RESULT NONNULL Port *
544port_new_with_type (ZPortType type, ZPortFlow flow, const char * label);
545
546WARN_UNUSED_RESULT NONNULL Port *
547port_new_with_type_and_owner (
548 ZPortType type,
549 ZPortFlow flow,
550 const char * label,
551 PortIdentifier::OwnerType owner_type,
552 void * owner);
553
560NONNULL void
562
569NONNULL void
571
575NONNULL StereoPorts *
577
587 int in,
588 const char * name,
589 const char * symbol,
590 PortIdentifier::OwnerType owner_type,
591 void * owner);
592
601NONNULL void
602stereo_ports_connect (StereoPorts * src, StereoPorts * dest, int locked);
603
604NONNULL void
605stereo_ports_disconnect (StereoPorts * self);
606
608stereo_ports_clone (const StereoPorts * src);
609
610NONNULL void
611stereo_ports_free (StereoPorts * self);
612
621const void *
623 const char * port_sym,
624 void * user_data,
625 uint32_t * size,
626 uint32_t * type);
627
628#ifdef HAVE_JACK
633NONNULL void
634port_receive_midi_events_from_jack (
635 Port * self,
636 const nframes_t start_frames,
637 const nframes_t nframes);
638
643NONNULL void
644port_receive_audio_data_from_jack (
645 Port * self,
646 const nframes_t start_frames,
647 const nframes_t nframes);
648#endif
649
655NONNULL bool
657
663NONNULL void
664port_get_full_designation (Port * const self, char * buf);
665
666NONNULL void
667port_print_full_designation (Port * const self);
668
673void
674port_get_all (GPtrArray * ports);
675
676NONNULL Track *
677port_get_track (const Port * const self, int warn_if_fail);
678
679NONNULL Plugin *
680port_get_plugin (Port * const self, const bool warn_if_fail);
681
694void
696 Port * self,
697 const PortIdentifier * prev_id,
698 Track * track,
699 bool update_automation_track);
700
701#ifdef HAVE_RTMIDI
706NONNULL void
707port_prepare_rtmidi_events (Port * self);
708
713NONNULL void
714port_sum_data_from_rtmidi (
715 Port * self,
716 const nframes_t start_frame,
717 const nframes_t nframes);
718#endif
719
720#ifdef HAVE_RTAUDIO
725NONNULL void
726port_prepare_rtaudio_data (Port * self);
727
732NONNULL void
733port_sum_data_from_rtaudio (
734 Port * self,
735 const nframes_t start_frame,
736 const nframes_t nframes);
737#endif
738
742NONNULL void
744
752NONNULL void
753port_set_expose_to_backend (Port * self, int expose);
754
758NONNULL static inline bool
759port_is_exposed_to_backend (const Port * self)
760{
763 || self->id.owner_type == PortIdentifier::OwnerType::PORT_OWNER_TYPE_AUDIO_ENGINE
764 || self->exposed_to_backend;
765}
766
770NONNULL void
772
773#ifdef HAVE_ALSA
774
779Port *
780port_find_by_alsa_seq_id (const int id);
781#endif
782
800NONNULL void
802 Port * self,
803 const float val,
804 const bool is_normalized,
805 const bool forward_event);
806
814NONNULL HOT float
815port_get_control_value (Port * self, const bool normalize);
816
823#define port_connect(a, b, locked) \
824 port_connections_manager_ensure_connect ( \
825 PORT_CONNECTIONS_MGR, &((a)->id), &((b)->id), 1.f, locked, true)
826
830#define port_disconnect(a, b) \
831 port_connections_manager_ensure_disconnect ( \
832 PORT_CONNECTIONS_MGR, &((a)->id), &((b)->id))
833
838NONNULL int
840
845NONNULL int
847
855void
856port_update_track_name_hash (Port * self, Track * track, unsigned int new_hash);
857
865NONNULL static inline void
866port_apply_fader (
867 Port * port,
868 float amp,
869 nframes_t start_frame,
870 const nframes_t nframes)
871{
872 nframes_t end = start_frame + nframes;
873 while (start_frame < end)
874 {
875 port->buf[start_frame++] *= amp;
876 }
877}
878
884HOT NONNULL void
886 Port * port,
887 const EngineProcessTimeInfo time_nfo,
888 const bool noroll);
889
890#define ports_connected(a, b) \
891 (port_connections_manager_find_connection ( \
892 PORT_CONNECTIONS_MGR, &(a)->id, &(b)->id) \
893 != NULL)
894
900NONNULL bool
901ports_can_be_connected (const Port * src, const Port * dest);
902
906NONNULL void
907ports_disconnect (Port ** ports, int num_ports, int deleting);
908
916NONNULL void
918
926NONNULL void
927port_copy_values (Port * self, const Port * other);
928
939NONNULL void
941
948#define port_clear_buffer(engine_, _port) \
949 { \
950 if ( \
951 _port->id.type == ZPortType::Z_PORT_TYPE_AUDIO \
952 || _port->id.type == ZPortType::Z_PORT_TYPE_CV) \
953 { \
954 if (_port->buf) \
955 { \
956 dsp_fill ( \
957 _port->buf, DENORMAL_PREVENTION_VAL (engine_), \
958 engine_->block_length); \
959 } \
960 } \
961 else if (_port->id.type == ZPortType::Z_PORT_TYPE_EVENT) \
962 { \
963 if (_port->midi_events) \
964 _port->midi_events->num_events = 0; \
965 } \
966 }
967
971HOT NONNULL OPTIMIZE_O3 void
973
977NONNULL int
979
983NONNULL void
985 Port * l,
986 Port * r,
987 float pan,
988 PanLaw pan_law,
989 PanAlgorithm pan_algo);
990
998NONNULL void
1000 Port * port,
1001 float pan,
1002 PanLaw pan_law,
1003 PanAlgorithm pan_algo,
1004 nframes_t start_frame,
1005 const nframes_t nframes);
1006
1010NONNULL uint32_t
1011port_get_hash (const void * ptr);
1012
1016Port *
1017port_clone (const Port * src);
1018
1022NONNULL void
1024
1029#endif
NONNULL_ARGS(1) int undo_manager_undo(UndoManager *self
Undo last action.
NONNULL void port_init_loaded(Port *self, void *owner)
This function finds the Ports corresponding to the PortIdentifiers for srcs and dests.
NONNULL void port_set_expose_to_backend(Port *self, int expose)
Sets whether to expose the port to the backend and exposes it or removes it.
NONNULL int port_disconnect_all(Port *port)
Disconnects all srcs and dests from port.
NONNULL bool ports_can_be_connected(const Port *src, const Port *dest)
Returns whether the Port's can be connected (if the connection will be valid and won't break the acyc...
HOT NONNULL OPTIMIZE_O3 void port_clear_external_buffer(Port *port)
Clears the backend's port buffer.
NONNULL void port_copy_values(Port *self, const Port *other)
Copies the port values from other to self.
NONNULL void port_apply_pan(Port *port, float pan, PanLaw pan_law, PanAlgorithm pan_algo, nframes_t start_frame, const nframes_t nframes)
Applies the pan to the given port.
NONNULL int port_get_num_unlocked_srcs(const Port *self)
Returns the number of unlocked (user-editable) sources.
ZPortType
Type of signals the Port handles.
HOT NONNULL void port_process(Port *port, const EngineProcessTimeInfo time_nfo, const bool noroll)
First sets port buf to 0, then sums the given port signal from its inputs.
NONNULL StereoPorts * stereo_ports_new_from_existing(Port *l, Port *r)
Creates blank stereo ports.
void port_update_identifier(Port *self, const PortIdentifier *prev_id, Track *track, bool update_automation_track)
To be called when the port's identifier changes to update corresponding identifiers.
Port * port_clone(const Port *src)
To be used during serialization.
void port_get_all(GPtrArray *ports)
Gathers all ports in the project and appends them in the given array.
NONNULL void port_apply_pan_stereo(Port *l, Port *r, float pan, PanLaw pan_law, PanAlgorithm pan_algo)
Applies the pan to the given L/R ports.
NONNULL void stereo_ports_connect(StereoPorts *src, StereoPorts *dest, int locked)
Connects the internal ports using port_connect().
PortInternalType
What the internal data is.
Definition port.h:98
NONNULL void port_allocate_bufs(Port *self)
Allocates buffers used during DSP.
NONNULL void port_free_bufs(Port *self)
Frees buffers.
StereoPorts * stereo_ports_new_generic(int in, const char *name, const char *symbol, PortIdentifier::OwnerType owner_type, void *owner)
Creates stereo ports for generic use.
void port_update_track_name_hash(Port *self, Track *track, unsigned int new_hash)
Updates the track name hash on a track port and all its source/destination identifiers.
NONNULL void ports_disconnect(Port **ports, int num_ports, int deleting)
Disconnects all the given ports.
ZPortFlow
Direction of the signal.
WARN_UNUSED_RESULT NONNULL Port * port_new_with_type(ZPortType type, ZPortFlow flow, const char *label)
Creates port.
NONNULL void port_restore_from_non_project(Port *self, Port *non_project)
Reverts the data on the corresponding project port for the given non-project port.
NONNULL HOT float port_get_control_value(Port *self, const bool normalize)
Gets the given control value from the corresponding underlying structure in the Port.
NONNULL void port_get_full_designation(Port *const self, char *buf)
Copies a full designation of self in the format "Track/Port" or "Track/Plugin/Port" in buf.
NONNULL bool port_has_sound(Port *self)
If MIDI port, returns if there are any events, if audio port, returns if there is sound in the buffer...
NONNULL void port_copy_metadata_from_project(Port *self, Port *project_port)
Copies the metadata from a project port to the given port.
NONNULL void port_rename_backend(Port *self)
Renames the port on the backend side.
NONNULL void port_free(Port *port)
Deletes port, doing required cleanup and updating counters.
NONNULL int port_get_num_unlocked_dests(const Port *self)
Returns the number of unlocked (user-editable) destinations.
const void * port_get_value_from_symbol(const char *port_sym, void *user_data, uint32_t *size, uint32_t *type)
Function to get a port's value from its string symbol.
NONNULL void port_disconnect_hw_inputs(Port *self)
Disconnects all hardware inputs from the port.
NONNULL void port_set_control_value(Port *self, const float val, const bool is_normalized, const bool forward_event)
Sets the given control value to the corresponding underlying structure in the Port.
NONNULL uint32_t port_get_hash(const void *ptr)
Generates a hash for a given port.
@ Lv2Port
Pointer to Lv2Port.
@ AlsaSequencerPort
Pointer to snd_seq_port_info_t.
@ JackPort
Pointer to jack_port_t.
uint32_t nframes_t
Frame count.
Definition types.h:39
uint8_t midi_byte_t
MIDI byte.
Definition types.h:36
PanAlgorithm
See https://www.harmonycentral.com/articles/the-truth-about-panning-laws.
Definition pan.h:53
PanLaw
These are only useful when changing mono to stereo.
Definition pan.h:30
Port identifier.
Audio clips for the pool.
Definition clip.h:31
The audio engine.
Definition engine.h:353
Channel send.
A Channel is part of a Track (excluding Tracks that don't have Channels) and contains information rel...
Definition channel.h:57
Common struct to pass around during processing to avoid repeating the data in function arguments.
Definition types.h:142
External port.
Definition ext_port.h:69
A Fader is a processor that is used for volume controls and pan.
Definition fader.h:91
Container for passing midi events through ports.
Definition midi_event.h:62
Modulator macro button processor.
Widget for a control.
Definition plugin_gtk.h:29
The base plugin Inheriting plugins must have this as a child.
Definition plugin.h:74
A connection between two ports.
Struct used to identify Ports in the project.
OwnerType
Type of owner.
PortIdentifier::OwnerType owner_type
Owner type.
Scale point.
Definition port.h:118
Must ONLY be created via port_new()
Definition port.h:136
int initialized
used when loading projects FIXME needed?
Definition port.h:354
int exposed_to_backend
Flag to indicate that this port is exposed to the backend.
Definition port.h:145
ExtPort * ext_port
Pointer to ExtPort, if hw.
Definition port.h:485
ZixRing * midi_ring
Ring buffer for saving MIDI events to be used in the UI instead of directly accessing the events.
Definition port.h:425
float minf
Minimum, maximum and zero values for this port.
Definition port.h:196
ZixSem mme_connections_sem
Semaphore for changing the connections atomically.
Definition port.h:243
gint64 last_midi_event_time
Used by the UI to detect when unprocessed MIDI events exist.
Definition port.h:398
int magic
Magic number to identify that this is a Port.
Definition port.h:488
midi_byte_t last_midi_status
Last known MIDI status byte received.
Definition port.h:442
AudioEngine * engine
Pointer to owner engine, if any.
Definition port.h:327
gint64 last_change
Last timestamp the control changed.
Definition port.h:315
float * buf
Buffer to be reallocated every time the buffer size changes.
Definition port.h:153
MidiEvents * midi_events
Contains raw MIDI data (MIDI ports only)
Definition port.h:158
midi_byte_t midi_cc_no
MIDI CC number, if not pitchbend/poly key/channel pressure.
Definition port.h:482
PortInternalType internal_type
Indicates whether data or lv2_port should be used.
Definition port.h:187
const PortConnection ** dest_connections
Caches filled when recalculating the graph.
Definition port.h:179
Transport * transport
Pointer to owner transport, if any.
Definition port.h:321
midi_byte_t midi_channel
MIDI channel, starting from 1.
Definition port.h:479
float base_value
For control ports, when a modulator is attached to the port the previous value will be saved here.
Definition port.h:362
size_t last_buf_sz
Last allocated buffer size (used for audio ports).
Definition port.h:492
ModulatorMacroProcessor * modulator_macro_processor
Pointer to owner modulator macro processor, if any.
Definition port.h:342
ZixRing * audio_ring
Ring buffer for saving the contents of the audio buffer to be used in the UI instead of directly acce...
Definition port.h:410
float control
The control value if control port, otherwise 0.0f.
Definition port.h:301
AutomationTrack * at
Automation track this port is attached to.
Definition port.h:470
const PortConnection ** src_connections
Caches filled when recalculating the graph.
Definition port.h:173
int has_midi_events
Whether the port has midi events not yet processed by the UI.
Definition port.h:394
gint64 last_midi_dequeue
Last time the port finished dequeueing MIDI events.
Definition port.h:251
Fader * fader
Pointer to owner fader, if any.
Definition port.h:330
ChannelSend * channel_send
Pointer to owner channel send, if any.
Definition port.h:324
long playback_latency
Playback latency.
Definition port.h:378
float unsnapped_control
Unsnapped value, used by widgets.
Definition port.h:304
Plugin * plugin
Pointer to owner plugin, if any.
Definition port.h:318
struct Port ** srcs
Caches filled when recalculating the graph.
Definition port.h:162
float zerof
The zero position of the port.
Definition port.h:206
struct Port ** dests
Caches filled when recalculating the graph.
Definition port.h:168
PluginGtkController * widget
Control widget, if applicable.
Definition port.h:449
bool received_ui_event
Whether the port received a UI event from the plugin UI in this cycle.
Definition port.h:460
int carla_param_id
Index of the control parameter (for Carla plugin ports).
Definition port.h:213
bool write_ring_buffers
Flag to indicate if the ring buffers below should be filled or not.
Definition port.h:391
bool automating
Whether this value was set via automation.
Definition port.h:463
Plugin * tmp_plugin
Temporary plugin pointer (used when the plugin doesn't exist yet in its supposed slot).
Definition port.h:351
long capture_latency
Capture latency.
Definition port.h:370
Track * track
Pointer to owner track, if any.
Definition port.h:338
int deleting
Port undergoing deletion.
Definition port.h:381
float deff
Default value, only used for controls.
Definition port.h:209
gint64 peak_timestamp
Last time Port.max_amp was set.
Definition port.h:432
PortScalePoint ** scale_points
Scale points.
Definition port.h:287
bool value_changed_from_reading
Flag that the value of the port changed from reading automation.
Definition port.h:308
float peak
Max amplitude during processing, if audio (fabsf).
Definition port.h:429
void * data
Pointer to arbitrary data.
Definition port.h:223
L & R port, for convenience.
Definition port.h:501
A TrackProcessor is a processor that is used as the first entry point when processing a track.
Track to be inserted into the Project's Tracklist.
Definition track.h:177
The transport.
Definition transport.h:151
Custom types.