Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
port.h
1// SPDX-FileCopyrightText: © 2018-2024 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#ifndef ZRYTHM_GUI_DSP_PORT_H
5#define ZRYTHM_GUI_DSP_PORT_H
6
7#include "zrythm-config.h"
8
9#include "dsp/graph_node.h"
10#include "dsp/port_identifier.h"
11#include "gui/dsp/port_backend.h"
12#include "gui/dsp/port_connection.h"
13#include "utils/audio.h"
14#include "utils/ring_buffer.h"
15#include "utils/types.h"
16#include "utils/uuid_identifiable_object.h"
17
18class AudioEngine;
19class Track;
20class PortConnection;
22
28
29constexpr int TIME_TO_RESET_PEAK = 4800000;
30
31template <typename T>
32concept FinalPortSubclass = std::derived_from<T, Port> && FinalClass<T>;
33
34class PortRange
35{
36public:
37 PortRange () = default;
38
39 PortRange (float min, float max, float zero = 0.f)
40 : minf_ (min), maxf_ (max), zerof_ (zero)
41 {
42 }
43
44 float clamp_to_range (float val) { return std::clamp (val, minf_, maxf_); }
45
46private:
47 static constexpr std::string_view kMinKey = "minf";
48 static constexpr std::string_view kMaxKey = "maxf";
49 static constexpr std::string_view kZeroKey = "zerof";
50 friend void to_json (nlohmann::json &j, const PortRange &p)
51 {
52 j[kMinKey] = p.minf_;
53 j[kMaxKey] = p.maxf_;
54 j[kZeroKey] = p.zerof_;
55 }
56 friend void from_json (const nlohmann::json &j, PortRange &p)
57 {
58 j.at (kMinKey).get_to (p.minf_);
59 j.at (kMaxKey).get_to (p.maxf_);
60 j.at (kZeroKey).get_to (p.zerof_);
61 }
62
63public:
70 float minf_ = 0.f;
71 float maxf_ = 1.f;
72
79 float zerof_ = 0.f;
80};
81
83{
84public:
85 using TrackUuid = dsp::PortIdentifier::TrackUuid;
86 using PluginUuid = dsp::PortIdentifier::PluginUuid;
87 using PortUuid = dsp::PortIdentifier::PortUuid;
88
89 virtual ~IPortOwner () = default;
90
91 virtual bool is_in_active_project () const = 0;
92
99 virtual void
101 const = 0;
102
103 virtual utils::Utf8String
104 get_full_designation_for_port (const dsp::PortIdentifier &id) const
105 {
106 return id.get_label ();
107 };
108
117 const PortUuid &port_uuid,
118 const dsp::PortIdentifier &id,
119 float val) { };
120
124 virtual void on_midi_activity (const dsp::PortIdentifier &id) { }
125
134 virtual bool should_sum_data_from_backend () const { return true; }
135
146 virtual bool should_bounce_to_master (utils::audio::BounceStep step) const
147 {
148 return false;
149 }
150
159 {
160 return true;
161 }
162};
163
165{
166 virtual ~IPortConnectionManager () = default;
167};
168
180class Port : public dsp::IProcessable, public utils::UuidIdentifiableObject<Port>
181{
182 Q_DISABLE_COPY_MOVE (Port)
183public:
184 using PortIdentifier = dsp::PortIdentifier;
185 using PortType = dsp::PortType;
186 using PortFlow = dsp::PortFlow;
187
188 ~Port () override { disconnect_all (); }
189
190 static std::unique_ptr<Port> create_unique_from_type (PortType type);
191
198 void init_loaded (IPortOwner &owner) { set_owner (owner); }
199
204 {
205 return owner_ && owner_->is_in_active_project ();
206 }
207
208 void set_owner (IPortOwner &owner);
209
210 utils::Utf8String get_label () const;
211
212 bool is_control () const { return id_->is_control (); }
213 bool is_audio () const { return id_->type_ == PortType::Audio; }
214 bool is_cv () const { return id_->type_ == PortType::CV; }
215 bool is_event () const { return id_->type_ == PortType::Event; }
216 bool is_midi () const { return is_event (); }
217 bool is_input () const { return id_->flow_ == PortFlow::Input; }
218 bool is_output () const { return id_->flow_ == PortFlow::Output; }
219
225 virtual void allocate_bufs () = 0;
226
228 {
229 return get_full_designation ();
230 }
231
232 nframes_t get_single_playback_latency () const override { return 0; }
233
234 [[gnu::hot]] void process_block (EngineProcessTimeInfo time_nfo) override;
235
242 virtual void clear_buffer (AudioEngine &engine) = 0;
243
248 virtual bool has_sound () const { return false; };
249
255 {
256 return (owner_ != nullptr)
257 ? owner_->get_full_designation_for_port (*id_)
258 : get_label ();
259 }
260
261 void print_full_designation () const;
262
270 void set_expose_to_backend (AudioEngine &engine, bool expose);
271
276
281
286
291
295 void change_track (IPortOwner::TrackUuid new_track_id);
296
302 [[gnu::hot]] virtual void
303 process (EngineProcessTimeInfo time_nfo, bool noroll) = 0;
304
310 virtual void copy_metadata_from_project (const Port &project_port) { };
311
320 virtual void restore_from_non_project (const Port &non_project) { };
321
325 [[gnu::hot]] void clear_external_buffer () override;
326
327 bool needs_external_buffer_clear_on_early_return () const override;
328
333
337 size_t get_hash () const;
338
339 bool has_label () const { return !id_->label_.empty (); }
340 PortType get_type () const { return id_->type_; }
341 PortFlow get_flow () const { return id_->flow_; }
342
343protected:
344 Port ();
345
346 Port (
347 utils::Utf8String label,
348 PortType type = {},
349 PortFlow flow = {},
350 float minf = 0.f,
351 float maxf = 1.f,
352 float zerof = 0.f);
353
354 void copy_members_from (const Port &other, ObjectCloneType clone_type);
355
356 int get_num_unlocked (bool sources) const;
357
358private:
359 static constexpr std::string_view kIdKey = "id";
360 static constexpr std::string_view kExposedToBackendKey = "exposedToBackend";
361 friend void to_json (nlohmann::json &j, const Port &p)
362 {
363 j[kIdKey] = p.id_;
364 j[kExposedToBackendKey] = p.exposed_to_backend_;
365 }
366 friend void from_json (const nlohmann::json &j, Port &p)
367 {
368 j.at (kIdKey).get_to (p.id_);
369 j.at (kExposedToBackendKey).get_to (p.exposed_to_backend_);
370 }
371
372public:
376 std::unique_ptr<PortIdentifier> id_;
377
378protected:
385
386public:
388 std::vector<Port *> srcs_;
389
391 std::vector<Port *> dests_;
392
397 std::vector<std::unique_ptr<PortConnection>> src_connections_;
398 std::vector<std::unique_ptr<PortConnection>> dest_connections_;
399
400 PortRange range_;
401
409
417
419 bool deleting_ = false;
420
429
437 std::vector<float> buf_;
438
450 std::unique_ptr<RingBuffer<float>> audio_ring_;
451
453 size_t last_buf_sz_ = 0;
454
458 std::unique_ptr<PortBackend> backend_;
459
460 IPortOwner * owner_{};
461};
462
463class MidiPort;
464class AudioPort;
465class CVPort;
466class ControlPort;
467using PortVariant = std::variant<MidiPort, AudioPort, CVPort, ControlPort>;
468using PortPtrVariant = to_pointer_variant<PortVariant>;
469using PortRefVariant = to_reference_variant<PortVariant>;
470
472using PortRegistryRef = std::reference_wrapper<PortRegistry>;
473using PortUuidReference = utils::UuidReference<PortRegistry>;
474
475void
476from_json (const nlohmann::json &j, PortRegistry &registry);
477
481
482#endif
The audio engine.
Definition engine.h:168
Audio port specifics.
Definition audio_port.h:23
CV port specifics.
Definition cv_port.h:20
Control port specifics.
virtual void on_midi_activity(const dsp::PortIdentifier &id)
Called during processing if the MIDI port contains new MIDI events.
Definition port.h:124
virtual bool are_events_on_midi_channel_approved(midi_byte_t channel) const
Returns whether MIDI events on this channel on an input port should be processed (not ignored).
Definition port.h:158
virtual void on_control_change_event(const PortUuid &port_uuid, const dsp::PortIdentifier &id, float val)
Will be called when a control port's value changes.
Definition port.h:116
virtual bool should_bounce_to_master(utils::audio::BounceStep step) const
Whether the port should add its data to the master output when bouncing.
Definition port.h:146
virtual bool should_sum_data_from_backend() const
Whether during processing, the port should sum the data from its backend buffers coming in.
Definition port.h:134
virtual void set_port_metadata_from_owner(dsp::PortIdentifier &id, PortRange &range) const =0
Function that will be called by the Port to update the identifier's relevant members based on this po...
MIDI port specifics.
Definition midi_port.h:19
A connection between two ports.
float minf_
Minimum, maximum and zero values for this port.
Definition port.h:70
float zerof_
The zero position of the port.
Definition port.h:79
nframes_t get_single_playback_latency() const override
Returns the latency of only the given processable, without adding the previous/next latencies.
Definition port.h:232
utils::Utf8String get_node_name() const override
Returns a human friendly name of the node.
Definition port.h:227
void disconnect_all()
Disconnects all srcs and dests from port.
size_t get_hash() const
Generates a hash for a given port.
bool is_exposed_to_backend() const
Returns if the port is exposed to the backend.
void set_expose_to_backend(AudioEngine &engine, bool expose)
Sets whether to expose the port to the backend and exposes it or removes it.
bool deleting_
Port undergoing deletion.
Definition port.h:419
bool is_in_active_project() const
Returns whether the port is in the active project.
Definition port.h:203
std::vector< float > buf_
Buffer to be reallocated every time the buffer size changes.
Definition port.h:437
long capture_latency_
Capture latency.
Definition port.h:408
virtual void restore_from_non_project(const Port &non_project)
Reverts the data on the corresponding project port for the given non-project port.
Definition port.h:320
virtual void process(EngineProcessTimeInfo time_nfo, bool noroll)=0
Process the port for the given time range.
bool write_ring_buffers_
Flag to indicate if the ring buffers below should be filled or not.
Definition port.h:428
bool exposed_to_backend_
Flag to indicate that this port is exposed to the backend.
Definition port.h:384
std::unique_ptr< RingBuffer< float > > 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:450
void clear_external_buffer() override
Clears the backend's port buffer.
virtual void copy_metadata_from_project(const Port &project_port)
Copies the metadata from a project port to the given port.
Definition port.h:310
std::unique_ptr< PortIdentifier > id_
Owned pointer.
Definition port.h:376
virtual bool has_sound() const
If MIDI port, returns if there are any events, if audio port, returns if there is sound in the buffer...
Definition port.h:248
virtual void allocate_bufs()=0
Allocates buffers used during DSP.
std::vector< std::unique_ptr< PortConnection > > src_connections_
Caches filled when recalculating the graph.
Definition port.h:397
void init_loaded(IPortOwner &owner)
This function finds the Ports corresponding to the PortIdentifiers for srcs and dests.
Definition port.h:198
void change_track(IPortOwner::TrackUuid new_track_id)
Updates the owner track identifier.
utils::Utf8String get_full_designation() const
Gets a full designation of the port in the format "Track/Port" or "Track/Plugin/Port".
Definition port.h:254
std::vector< Port * > srcs_
Caches filled when recalculating the graph.
Definition port.h:388
void rename_backend(AudioEngine &engine)
Renames the port on the backend side.
int get_num_unlocked_dests() const
Returns the number of unlocked (user-editable) destinations.
virtual void clear_buffer(AudioEngine &engine)=0
Clears the port buffer.
std::unique_ptr< PortBackend > backend_
Backend functionality.
Definition port.h:458
long playback_latency_
Playback latency.
Definition port.h:416
int get_num_unlocked_srcs() const
Returns the number of unlocked (user-editable) sources.
size_t last_buf_sz_
Last allocated buffer size (used for audio ports).
Definition port.h:453
std::vector< Port * > dests_
Caches filled when recalculating the graph.
Definition port.h:391
Represents a track in the project.
Definition track.h:281
Interface for objects that can be processed in the DSP graph.
Definition graph_node.h:51
Struct used to identify Ports in the project.
A registry that owns and manages objects identified by a UUID.
Lightweight UTF-8 string wrapper with safe conversions.
Definition string.h:39
Base class for objects that need to be uniquely identified by UUID.
A reference-counted RAII wrapper for a UUID in a registry.
uint32_t nframes_t
Frame count.
Definition types.h:62
ObjectCloneType
Definition icloneable.h:25
uint8_t midi_byte_t
MIDI byte.
Definition types.h:59
Common struct to pass around during processing to avoid repeating the data in function arguments.
Definition types.h:176
Custom types.