Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
channel_send.h
1// SPDX-FileCopyrightText: © 2020-2021, 2024-2025 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include "dsp/port_connection.h"
7#include "gui/dsp/audio_port.h"
8#include "gui/dsp/control_port.h"
9#include "gui/dsp/midi_port.h"
10#include "gui/dsp/track.h"
11#include "plugins/plugin_slot.h"
12#include "utils/icloneable.h"
13
14class ChannelTrack;
15
21
26
41
46{
47 ChannelSendTargetType type = {};
48
49 int track_pos = 0;
50
51 gui::old_dsp::plugins::Plugin::Uuid pl_id;
52
53 utils::Utf8String port_group;
54
59
60 utils::Utf8String get_icon () const;
61
62 static void free_func (void * target) { delete (ChannelSendTarget *) target; }
63};
64
70class ChannelSend final
71 : public ICloneable<ChannelSend>,
73 public IPortOwner
74{
75public:
76 using PortType = dsp::PortType;
77 using PortConnection = dsp::PortConnection;
78
79 struct SlotTag
80 {
81 int value_{};
82 };
83
84public:
85 // FIXME confusing constructors - maybe use a builder
86
91 ChannelTrack &track,
92 TrackRegistry &track_registry,
93 PortRegistry &port_registry,
94 int slot)
95 : ChannelSend (track_registry, port_registry, track, slot, true)
96 {
97 }
98
103 ChannelTrack &track,
104 TrackRegistry &track_registry,
105 PortRegistry &port_registry)
106 : ChannelSend (track_registry, port_registry, track, std::nullopt, false)
107 {
108 }
109
113 ChannelSend (TrackRegistry &track_registry, PortRegistry &port_registry)
114 : ChannelSend (track_registry, port_registry, std::nullopt, std::nullopt, false)
115 {
116 }
117
118private:
123 TrackRegistry &track_registry,
124 PortRegistry &port_registry,
126 std::optional<int> slot,
127 bool new_identity);
128
129private:
130 auto &get_port_registry () { return port_registry_; }
131 auto &get_port_registry () const { return port_registry_; }
132
133public:
134 void init_loaded (ChannelTrack * track);
135
136 bool is_in_active_project () const override;
137
139 const override;
140
142 get_full_designation_for_port (const dsp::PortIdentifier &id) const override;
143
144 bool is_prefader () const
145 {
147 }
148
153
155
156 bool is_enabled () const;
157
158 bool is_empty () const { return !is_enabled (); }
159
165
170
175
179 void set_amount_from_widget (float val);
180
181 float get_amount_value () const { return get_amount_port ().control_; }
182
189 AudioPort &l,
190 AudioPort &r,
191 bool sidechain,
192 bool recalc_graph,
193 bool validate);
194
200 bool connect_midi (MidiPort &port, bool recalc_graph, bool validate);
201
205 void disconnect (bool recalc_graph);
206
207 void set_amount (float amount);
208
209 std::pair<AudioPort &, AudioPort &> get_stereo_in_ports () const
210 {
211 if (!stereo_in_left_id_.has_value ())
212 {
213 throw ZrythmException ("stereo_in_left_id_ not set");
214 }
215 auto * l = std::get<AudioPort *> (stereo_in_left_id_->get_object ());
216 auto * r = std::get<AudioPort *> (stereo_in_right_id_->get_object ());
217 return { *l, *r };
218 }
219 MidiPort &get_midi_in_port () const
220 {
221 return *std::get<MidiPort *> (midi_in_id_->get_object ());
222 }
223 std::pair<AudioPort &, AudioPort &> get_stereo_out_ports () const
224 {
225 if (!stereo_out_left_id_.has_value ())
226 {
227 throw ZrythmException ("stereo_out_left_id_ not set");
228 }
229 auto * l = std::get<AudioPort *> (stereo_out_left_id_->get_object ());
230 auto * r = std::get<AudioPort *> (stereo_out_right_id_->get_object ());
231 return { *l, *r };
232 }
233 MidiPort &get_midi_out_port () const
234 {
235 return *std::get<MidiPort *> (midi_out_id_->get_object ());
236 }
237 ControlPort &get_amount_port () const
238 {
239 return *std::get<ControlPort *> (amount_id_->get_object ());
240 }
241 ControlPort &get_enabled_port () const
242 {
243 return *std::get<ControlPort *> (enabled_id_->get_object ());
244 }
245
250
251 void copy_values_from (const ChannelSend &other);
252
253 void init_after_cloning (const ChannelSend &other, ObjectCloneType clone_type)
254 override;
255
262
263 void append_ports (std::vector<Port *> &ports);
264
271 std::vector<PortConnection *> &arr) const;
272
273 void prepare_process (std::size_t block_length);
274
275 void process_block (EngineProcessTimeInfo time_nfo) override;
276
277 bool is_connected_to (std::pair<PortUuid, PortUuid> stereo) const
278 {
279 return is_connected_to (stereo, std::nullopt);
280 }
281 bool is_connected_to (const PortUuid &midi) const
282 {
283 return is_connected_to (std::nullopt, midi);
284 }
285
290
291 bool is_audio () const { return get_signal_type () == PortType::Audio; }
292 bool is_midi () const { return get_signal_type () == PortType::Event; }
293
294 bool validate ();
295
296private:
297 static constexpr auto kSlotKey = "slot"sv;
298 static constexpr auto kAmountKey = "amount"sv;
299 static constexpr auto kEnabledKey = "enabled"sv;
300 static constexpr auto kIsSidechainKey = "isSidechain"sv;
301 static constexpr auto kMidiInKey = "midiIn"sv;
302 static constexpr auto kStereoInLKey = "stereoInL"sv;
303 static constexpr auto kStereoInRKey = "stereoInR"sv;
304 static constexpr auto kMidiOutKey = "midiOut"sv;
305 static constexpr auto kStereoOutLKey = "stereoOutL"sv;
306 static constexpr auto kStereoOutRKey = "stereoOutR"sv;
307 static constexpr auto kTrackIdKey = "trackId"sv;
308 friend void to_json (nlohmann::json &j, const ChannelSend &p)
309 {
310 j = nlohmann::json{
311 { kSlotKey, p.slot_ },
312 { kAmountKey, p.amount_id_ },
313 { kEnabledKey, p.enabled_id_ },
314 { kIsSidechainKey, p.is_sidechain_ },
315 { kMidiInKey, p.midi_in_id_ },
316 { kStereoInLKey, p.stereo_in_left_id_ },
317 { kStereoInRKey, p.stereo_in_right_id_ },
318 { kMidiOutKey, p.midi_out_id_ },
319 { kStereoOutLKey, p.stereo_out_left_id_ },
320 { kStereoOutRKey, p.stereo_out_right_id_ },
321 { kTrackIdKey, p.track_id_ },
322 };
323 }
324 friend void from_json (const nlohmann::json &j, ChannelSend &p)
325 {
326 j.at (kSlotKey).get_to (p.slot_);
327 j.at (kAmountKey).get_to (p.amount_id_);
328 j.at (kEnabledKey).get_to (p.enabled_id_);
329 j.at (kIsSidechainKey).get_to (p.is_sidechain_);
330 j.at (kMidiInKey).get_to (p.midi_in_id_);
331 j.at (kStereoInLKey).get_to (p.stereo_in_left_id_);
332 j.at (kStereoInRKey).get_to (p.stereo_in_right_id_);
333 j.at (kMidiOutKey).get_to (p.midi_out_id_);
334 j.at (kStereoOutLKey).get_to (p.stereo_out_left_id_);
335 j.at (kStereoOutRKey).get_to (p.stereo_out_right_id_);
336 j.at (kTrackIdKey).get_to (p.track_id_);
337 }
338
339 PortType get_signal_type () const;
340
341 void disconnect_midi ();
342 void disconnect_audio ();
343
344 void construct_for_slot (ChannelTrack &track, int slot);
345
346 dsp::PortConnectionsManager * get_port_connections_manager () const;
347
351 bool is_connected_to (
352 std::optional<std::pair<PortUuid, PortUuid>> stereo,
353 std::optional<PortUuid> midi) const;
354
355public:
356 PortRegistry &port_registry_;
357 TrackRegistry &track_registry_;
358
360 int slot_ = 0;
361
367 std::optional<PortUuidReference> stereo_in_left_id_;
368 std::optional<PortUuidReference> stereo_in_right_id_;
369
375 std::optional<PortUuidReference> midi_in_id_;
376
382 std::optional<PortUuidReference> stereo_out_left_id_;
383 std::optional<PortUuidReference> stereo_out_right_id_;
384
390 std::optional<PortUuidReference> midi_out_id_;
391
394 std::optional<PortUuidReference> amount_id_;
395
402 std::optional<PortUuidReference> enabled_id_;
403
405 bool is_sidechain_ = false;
406
408 // ChannelTrack * track_ = nullptr;
409
411 TrackUuid track_id_;
412
417};
418
Audio port specifics.
Definition audio_port.h:25
std::optional< PortUuidReference > midi_in_id_
MIDI input if MIDI send.
bool connect_midi(MidiPort &port, bool recalc_graph, bool validate)
Connects a send to a midi port.
std::optional< PortUuidReference > enabled_id_
Whether the send is currently enabled.
ChannelSend(ChannelTrack &track, TrackRegistry &track_registry, PortRegistry &port_registry)
To be used when deserializing.
bool connect_stereo(AudioPort &l, AudioPort &r, bool sidechain, bool recalc_graph, bool validate)
Connects a send to stereo ports.
TrackUuid track_id_
Pointer back to owner track.
void disconnect(bool recalc_graph)
Removes the connection at the given send.
int append_connection(const zrythm::dsp::PortConnectionsManager *mgr, std::vector< PortConnection * > &arr) const
Appends the connection(s), if non-empty, to the given array (if not nullptr) and returns the number o...
OptionalRef< ChannelTrack > track_
Use this if set (via the new identity constructo).
std::optional< PortUuidReference > midi_out_id_
MIDI output if MIDI send.
bool is_sidechain_
If the send is a sidechain.
ChannelSend * find_in_project() const
Finds the project send from a given send instance.
utils::Utf8String get_node_name() const override
Returns a human friendly name of the node.
Track * get_target_track()
Gets the target track.
int slot_
Slot index in the channel sends.
void set_amount_from_widget(float val)
Sets the amount from a widget amount (0.0-1.0).
utils::Utf8String get_dest_name() const
Get the name of the destination, or a placeholder text if empty.
ChannelTrack * get_track() const
Gets the owner track.
std::optional< PortUuidReference > stereo_in_left_id_
Stereo input if audio send.
void init_after_cloning(const ChannelSend &other, ObjectCloneType clone_type) override
Initializes the cloned object.
ChannelSend(ChannelTrack &track, TrackRegistry &track_registry, PortRegistry &port_registry, int slot)
To be used when creating a new (identity) ChannelSend.
std::optional< PortUuidReference > amount_id_
Send amount (amplitude), 0 to 2 for audio, velocity multiplier for MIDI.
void connect_to_owner()
Connects the ports to the owner track if not connected.
void set_port_metadata_from_owner(dsp::PortIdentifier &id, PortRange &range) const override
Function that will be called by the Port to update the identifier's relevant members based on this po...
bool is_target_sidechain()
Returns whether the channel send target is a sidechain port (rather than a target track).
ChannelSend(TrackRegistry &track_registry, PortRegistry &port_registry)
To be used when instantiating or cloning an existing identity.
float get_amount_for_widgets() const
Gets the amount to be used in widgets (0.0-1.0).
std::optional< PortUuidReference > stereo_out_left_id_
Stereo output if audio send.
Abstract class for a track that has a channel in the mixer.
MIDI port specifics.
Definition midi_port.h:19
Represents a track in the project.
Definition track.h:282
A connection between two ports.
Struct used to identify Ports in the project.
Interface for objects that can be processed in the DSP graph.
Definition graph_node.h:50
Lightweight UTF-8 string wrapper with safe conversions.
Definition string.h:39
Base class for exceptions in Zrythm.
Definition exceptions.h:20
constexpr int CHANNEL_SEND_POST_FADER_START_SLOT
The slot where post-fader sends begin (starting from 0).
ChannelSendTargetType
Target type.
@ Track
Send to track inputs.
@ PluginSidechain
Send to plugin sidechain inputs.
ObjectCloneType
Definition icloneable.h:25
@ None
Invalid cursor.
Definition arranger.h:32
Send target (used in list views).
utils::Utf8String describe() const
Returns a string describing this target (track/plugin name/etc.).
Common struct to pass around during processing to avoid repeating the data in function arguments.
Definition types.h:176
Wrapper around std::optional<std::reference_wrapper<T>> that provides a more convenient API.
Definition types.h:324