11#ifndef __AUDIO_PORTS_H__
12#define __AUDIO_PORTS_H__
14#include "zrythm-config.h"
19#include "plugins/lv2/lv2_evbuf.h"
26# include "weak_libjack.h"
34# include <rtaudio_c.h>
40typedef struct ZixRingImpl ZixRing;
41typedef struct WindowsMmeDevice WindowsMmeDevice;
48typedef struct RtMidiDevice RtMidiDevice;
49typedef struct RtAudioDevice RtAudioDevice;
67#define PORT_SCHEMA_VERSION 1
68#define STEREO_PORTS_SCHEMA_VERSION 1
70#define PORT_MAGIC 456861194
71#define IS_PORT(_p) (((Port *) (_p))->magic == PORT_MAGIC)
72#define IS_PORT_AND_NONNULL(x) ((x) && IS_PORT (x))
74#define TIME_TO_RESET_PEAK 4800000
80#define PORT_NOT_OWNED -1
82#define port_is_owner_active(self, _owner_type, owner) \
83 ((self->id.owner_type == _owner_type) \
84 && (self->owner != NULL) \
85 && owner##_is_in_active_project (self->owner))
87#define port_is_in_active_project(self) \
88 (port_is_owner_active ( \
89 self, PORT_OWNER_TYPE_AUDIO_ENGINE, engine) \
90 || port_is_owner_active ( \
91 self, PORT_OWNER_TYPE_PLUGIN, plugin) \
92 || port_is_owner_active ( \
93 self, PORT_OWNER_TYPE_TRACK, track) \
94 || port_is_owner_active ( \
95 self, PORT_OWNER_TYPE_CHANNEL, track) \
96 || port_is_owner_active ( \
97 self, PORT_OWNER_TYPE_FADER, fader) \
98 || port_is_owner_active ( \
99 self, PORT_OWNER_TYPE_CHANNEL_SEND, channel_send) \
100 || port_is_owner_active ( \
101 self, PORT_OWNER_TYPE_TRACK_PROCESSOR, track) \
102 || port_is_owner_active ( \
103 self, PORT_OWNER_TYPE_MODULATOR_MACRO_PROCESSOR, \
104 modulator_macro_processor) \
105 || port_is_owner_active ( \
106 self, PORT_OWNER_TYPE_HW, ext_port))
138port_scale_point_cmp (
const void * _a,
const void * _b);
141port_scale_point_new (
const float val,
const char * label);
189 int num_src_connections;
190 size_t src_connections_size;
195 int num_dest_connections;
196 size_t dest_connections_size;
249 WindowsMmeDevice * mme_connections[40];
250 int num_mme_connections;
252 void * mme_connections[40];
253 int num_mme_connections;
275 RtMidiDevice * rtmidi_ins[128];
279 RtMidiDevice * rtmidi_outs[128];
282 void * rtmidi_ins[128];
284 void * rtmidi_outs[128];
294 RtAudioDevice * rtaudio_ins[128];
297 void * rtaudio_ins[128];
303 int num_scale_points;
545static const cyaml_schema_field_t port_fields_schema[] = {
546 YAML_FIELD_INT (
Port, schema_version),
550 port_identifier_fields_schema),
554 YAML_FIELD_FLOAT (
Port, maxf),
562static const cyaml_schema_value_t port_schema = {
578static const cyaml_schema_field_t stereo_ports_fields_schema[] = {
586static const cyaml_schema_value_t stereo_ports_schema = {
609NONNULL
static inline void
610stereo_ports_init_loaded (
StereoPorts * sp,
void * owner)
617static inline
void stereo_ports_set_owner (
622 port_set_owner (sp->l, owner_type, owner);
623 port_set_owner (sp->r, owner_type, owner);
629WARN_UNUSED_RESULT NONNULL
Port *
635WARN_UNUSED_RESULT NONNULL
Port *
636port_new_with_type_and_owner (
715 const char * port_sym,
726port_receive_midi_events_from_jack (
736port_receive_audio_data_from_jack (
759port_print_full_designation (
Port *
const self);
769port_get_track (
const Port *
const self,
int warn_if_fail);
772port_get_plugin (
Port *
const self,
const bool warn_if_fail);
791 bool update_automation_track);
799port_prepare_rtmidi_events (
Port * self);
806port_sum_data_from_rtmidi (
818port_prepare_rtaudio_data (
Port * self);
825port_sum_data_from_rtaudio (
850NONNULL PURE
static inline bool
851port_is_exposed_to_backend (
const Port * self)
855 || self->id.
owner_type == PORT_OWNER_TYPE_AUDIO_ENGINE
872port_find_by_alsa_seq_id (
const int id);
896 const bool is_normalized,
897 const bool forward_event);
915#define port_connect(a, b, locked) \
916 port_connections_manager_ensure_connect ( \
917 PORT_CONNECTIONS_MGR, &((a)->id), &((b)->id), 1.f, \
923#define port_disconnect(a, b) \
924 port_connections_manager_ensure_disconnect ( \
925 PORT_CONNECTIONS_MGR, &((a)->id), &((b)->id))
952 unsigned int new_hash);
961NONNULL
static inline void
969 while (start_frame < end)
971 port->
buf[start_frame++] *= amp;
988#define ports_connected(a, b) \
989 (port_connections_manager_find_connection ( \
990 PORT_CONNECTIONS_MGR, &(a)->id, &(b)->id) \
1017 Port * project_port);
1048#define port_clear_buffer(_port) \
1050 if (_port->id.type == TYPE_AUDIO || _port->id.type == TYPE_CV) \
1055 _port->buf, DENORMAL_PREVENTION_VAL, \
1056 AUDIO_ENGINE->block_length); \
1059 else if (_port->id.type == TYPE_EVENT) \
1061 if (_port->midi_events) \
1062 _port->midi_events->num_events = 0; \
1069HOT NONNULL OPTIMIZE_O3
void
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.
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.
PortType
Type of signals the Port handles.
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().
PortFlow
Direction of the signal.
PortInternalType
What the internal data is.
NONNULL void port_allocate_bufs(Port *self)
Allocates buffers used during DSP.
NONNULL void port_free_bufs(Port *self)
Frees buffers.
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.
StereoPorts * stereo_ports_new_generic(int in, const char *name, const char *symbol, PortOwnerType owner_type, void *owner)
Creates stereo ports for generic use.
NONNULL void ports_disconnect(Port **ports, int num_ports, int deleting)
Disconnects all the given ports.
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.
PortOwnerType
Type of owner.
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.
COLD NONNULL_ARGS(1) void automation_track_init_loaded(AutomationTrack *self
Inits a loaded AutomationTracklist.
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.
WARN_UNUSED_RESULT NONNULL Port * port_new_with_type(PortType type, PortFlow flow, const char *label)
Creates port.
NONNULL uint32_t port_get_hash(const void *ptr)
Generates a hash for a given port.
@ INTERNAL_LV2_PORT
Pointer to Lv2Port.
@ INTERNAL_JACK_PORT
Pointer to jack_port_t.
@ INTERNAL_ALSA_SEQ_PORT
Pointer to snd_seq_port_info_t.
#define YAML_FIELD_MAPPING_EMBEDDED(owner, member, schema)
Mapping embedded inside the struct.
uint32_t nframes_t
Frame count.
uint8_t midi_byte_t
MIDI byte.
#define YAML_FIELD_MAPPING_PTR(owner, member, schema)
Mapping pointer to a struct.
#define YAML_VALUE_PTR(cc, fields_schema)
Schema to be used as a pointer.
#define YAML_VALUE_PTR_NULLABLE(cc, fields_schema)
Schema to be used as a pointer that can be NULL.
PanAlgorithm
See https://www.harmonycentral.com/articles/the-truth-about-panning-laws.
PanLaw
These are only useful when changing mono to stereo.
Audio clips for the pool.
A Channel is part of a Track (excluding Tracks that don't have Channels) and contains information rel...
Common struct to pass around during processing to avoid repeating the data in function arguments.
A Fader is a processor that is used for volume controls and pan.
Container for passing midi events through ports.
Modulator macro button processor.
The base plugin Inheriting plugins must have this as a child.
A connection between two ports.
Struct used to identify Ports in the project.
PortOwnerType owner_type
Owner type.
Must ONLY be created via port_new()
int initialized
used when loading projects FIXME needed?
int exposed_to_backend
Flag to indicate that this port is exposed to the backend.
ExtPort * ext_port
Pointer to ExtPort, if hw.
ZixRing * midi_ring
Ring buffer for saving MIDI events to be used in the UI instead of directly accessing the events.
float minf
Minimum, maximum and zero values for this port.
ZixSem mme_connections_sem
Semaphore for changing the connections atomically.
gint64 last_midi_event_time
Used by the UI to detect when unprocessed MIDI events exist.
int magic
Magic number to identify that this is a Port.
midi_byte_t last_midi_status
Last known MIDI status byte received.
AudioEngine * engine
Pointer to owner engine, if any.
gint64 last_change
Last timestamp the control changed.
float * buf
Buffer to be reallocated every time the buffer size changes.
MidiEvents * midi_events
Contains raw MIDI data (MIDI ports only)
PortInternalType internal_type
Indicates whether data or lv2_port should be used.
const PortConnection ** dest_connections
Caches filled when recalculating the graph.
Transport * transport
Pointer to owner transport, if any.
float base_value
For control ports, when a modulator is attached to the port the previous value will be saved here.
bool old_api
True for event, false for atom.
size_t last_buf_sz
Last allocated buffer size (used for audio ports).
ModulatorMacroProcessor * modulator_macro_processor
Pointer to owner modulator macro processor, if any.
LV2_URID value_type
Float for LV2 control ports, declared type for LV2 parameters.
ZixRing * audio_ring
Ring buffer for saving the contents of the audio buffer to be used in the UI instead of directly acce...
float control
The control value if control port, otherwise 0.0f.
AutomationTrack * at
Automation track this port is attached to.
const PortConnection ** src_connections
Caches filled when recalculating the graph.
gint64 last_midi_dequeue
Last time the port finished dequeueing MIDI events.
Fader * fader
Pointer to owner fader, if any.
volatile int has_midi_events
Whether the port has midi events not yet processed by the UI.
ChannelSend * channel_send
Pointer to owner channel send, if any.
size_t min_buf_size
Minimum buffer size that the port wants, or 0.
long playback_latency
Playback latency.
float unsnapped_control
Unsnapped value, used by widgets.
Plugin * plugin
Pointer to owner plugin, if any.
struct Port ** srcs
Caches filled when recalculating the graph.
float zerof
The zero position of the port.
int lilv_port_index
Port index in the lilv plugin, if non-parameter.
struct Port ** dests
Caches filled when recalculating the graph.
PluginGtkController * widget
Control widget, if applicable.
bool received_ui_event
Whether the port received a UI event from the plugin UI in this cycle.
const LilvPort * lilv_port
LV2 port.
int carla_param_id
Index of the control parameter (for Carla plugin ports).
bool write_ring_buffers
Flag to indicate if the ring buffers below should be filled or not.
bool automating
Whether this value was set via automation.
Plugin * tmp_plugin
Temporary plugin pointer (used when the plugin doesn't exist yet in its supposed slot).
long capture_latency
Capture latency.
float last_sent_control
The last known control value sent to the UI (if control).
Track * track
Pointer to owner track, if any.
LV2_Evbuf * evbuf
For MIDI ports, otherwise NULL.
int deleting
Port undergoing deletion.
float deff
Default value, only used for controls.
gint64 peak_timestamp
Last time Port.max_amp was set.
PortScalePoint ** scale_points
Scale points.
bool value_changed_from_reading
Flag that the value of the port changed from reading automation.
float peak
Max amplitude during processing, if audio (fabsf).
void * data
Pointer to arbitrary data.
L & R port, for convenience.
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.