Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
channel.h
1// SPDX-FileCopyrightText: © 2018-2022, 2024-2025 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include "zrythm-config.h"
7
8#include "dsp/channel.h"
9#include "gui/dsp/channel_send.h"
10#include "gui/dsp/ext_port.h"
11#include "gui/dsp/fader.h"
12#include "gui/dsp/plugin.h"
13#include "gui/dsp/plugin_span.h"
14#include "gui/dsp/track.h"
15#include "utils/icloneable.h"
16
17class AutomationTrack;
18class ChannelTrack;
20class ExtPort;
21
22class Track;
23
24namespace zrythm::gui
25{
26
27static constexpr float MAX_FADER_AMP = 1.42f;
28
29struct PluginImportData;
30
43class Channel final : public QObject, public ICloneable<Channel>, public IPortOwner
44{
45 Q_OBJECT
46 QML_ELEMENT
47 Q_PROPERTY (Fader * fader READ getFader CONSTANT)
48 Q_PROPERTY (Fader * preFader READ getPreFader CONSTANT)
49 Q_PROPERTY (AudioPort * leftAudioOut READ getLeftAudioOut CONSTANT)
50 Q_PROPERTY (AudioPort * rightAudioOut READ getRightAudioOut CONSTANT)
51 Q_PROPERTY (MidiPort * midiOut READ getMidiOut CONSTANT)
52
53public:
54 static constexpr auto STRIP_SIZE = zrythm::dsp::STRIP_SIZE;
55 using PortType = zrythm::dsp::PortType;
56 using PortIdentifier = dsp::PortIdentifier;
58 using Plugin = gui::old_dsp::plugins::Plugin;
59 using PluginDescriptor = zrythm::plugins::PluginDescriptor;
60 using PluginSlot = zrythm::plugins::PluginSlot;
61 using PluginSlotType = zrythm::plugins::PluginSlotType;
62 using PluginPtrVariant = gui::old_dsp::plugins::PluginPtrVariant;
63 using PluginUuid = Plugin::Uuid;
64
65 // FIXME: leftover from C port, fix/refactor how import works in channel.cpp
66 friend struct PluginImportData;
67
68public:
78 explicit Channel (
79 TrackRegistry &track_registry,
80 PluginRegistry &plugin_registry,
81 PortRegistry &port_registry,
83
87 explicit Channel (
88 TrackRegistry &track_registry,
89 PluginRegistry &plugin_registry,
90 PortRegistry &port_registry)
91 : Channel (track_registry, plugin_registry, port_registry, {})
92 {
93 }
94
95private:
96 auto &get_track_registry () { return track_registry_; }
97 auto &get_track_registry () const { return track_registry_; }
98 auto &get_plugin_registry () { return plugin_registry_; }
99 auto &get_plugin_registry () const { return plugin_registry_; }
100 auto &get_port_registry () { return port_registry_; }
101 auto &get_port_registry () const { return port_registry_; }
102
103public:
104 // ============================================================================
105 // QML Interface
106 // ============================================================================
107
108 Fader * getFader () const { return fader_; }
109 Fader * getPreFader () const { return prefader_; }
110 AudioPort * getLeftAudioOut () const
111 {
112 return stereo_out_left_id_.has_value ()
113 ? std::addressof (get_stereo_out_ports ().first)
114 : nullptr;
115 }
116 AudioPort * getRightAudioOut () const
117 {
118 return stereo_out_left_id_.has_value ()
119 ? std::addressof (get_stereo_out_ports ().second)
120 : nullptr;
121 }
122 MidiPort * getMidiOut () const
123 {
124 return midi_out_id_.has_value () ? std::addressof (get_midi_out_port ()) : nullptr;
125 }
126
127 // ============================================================================
128
133 void init ();
134
135 bool is_in_active_project () const override;
136
138 const override;
139
141 get_full_designation_for_port (const dsp::PortIdentifier &id) const override;
142
143 bool should_bounce_to_master (utils::audio::BounceStep step) const override;
144
145 MidiPort &get_midi_out_port () const
146 {
147 return *std::get<MidiPort *> (midi_out_id_->get_object ());
148 }
149 std::pair<AudioPort &, AudioPort &> get_stereo_out_ports () const
150 {
151 auto * l = std::get<AudioPort *> (stereo_out_left_id_->get_object ());
152 auto * r = std::get<AudioPort *> (stereo_out_right_id_->get_object ());
153 return { *l, *r };
154 }
155
159 void reset_fader (bool fire_events);
160
172 const Plugin * pl,
173 std::optional<PluginSpan> plugins,
174 const PluginDescriptor * descr,
175 PluginSlot slot,
176 bool copy,
177 bool ask_if_overwrite);
178
185
192 void process ();
193
211 PluginPtrVariant add_plugin (
212 PluginUuidReference plugin_id,
213 PluginSlot slot,
214 bool confirm,
215 bool moving_plugin,
216 bool gen_automatables,
217 bool recalc_graph,
218 bool pub_events);
219
220 ChannelTrack &get_track () const { return *track_; }
221
222 GroupTargetTrack * get_output_track () const;
223
228
235
248 PluginSlot slot,
249 bool moving_plugin,
250 bool deleting_plugin);
251
257 void get_plugins (std::vector<Plugin *> &pls);
258
265 void paste_plugins_to_slot (PluginSpan plugins, PluginSlot slot);
266
271
275 void set_mono_compat_enabled (bool enabled, bool fire_events);
276
281
285 void set_swap_phase (bool enabled, bool fire_events);
286
287 std::optional<PluginPtrVariant> get_plugin_at_slot (PluginSlot slot) const;
288
289 auto get_plugin_slot (const PluginUuid &plugin_id) const -> PluginSlot;
290
291 std::optional<PluginPtrVariant> get_plugin_from_id (PluginUuid id) const;
292
293 std::optional<PluginPtrVariant> get_instrument () const
294 {
295 return instrument_ ? std::make_optional (instrument_->get_object ()) : std::nullopt;
296 }
297
301 void select_all (PluginSlotType type, bool select);
302
306 void set_caches ();
307
308 void
309 init_after_cloning (const Channel &other, ObjectCloneType clone_type) override;
310
316
323
324 void init_loaded ();
325
334 void handle_recording (long g_frames_start, nframes_t nframes);
335
339 void append_ports (std::vector<Port *> &ports, bool include_plugins);
340
345
346 void set_phase (float phase);
347
348 float get_phase () const;
349
350 void set_balance_control (float val);
351
355 void add_balance_control (float pan);
356
357 float get_balance_control () const;
358
369
370 bool has_output () const { return output_track_uuid_.has_value (); }
371
372 Fader &get_post_fader () const { return *fader_; }
373 Fader &get_pre_fader () const { return *prefader_; }
374
375 auto &get_sends () const { return sends_; }
376
377private:
378 static constexpr auto kMidiFxKey = "midiFx"sv;
379 static constexpr auto kInsertsKey = "inserts"sv;
380 static constexpr auto kSendsKey = "sends"sv;
381 static constexpr auto kInstrumentKey = "instrument"sv;
382 static constexpr auto kPrefaderKey = "prefader"sv;
383 static constexpr auto kFaderKey = "fader"sv;
384 static constexpr auto kMidiOutKey = "midiOut"sv;
385 static constexpr auto kStereoOutLKey = "stereoOutL"sv;
386 static constexpr auto kStereoOutRKey = "stereoOutR"sv;
387 static constexpr auto kOutputIdKey = "outputId"sv;
388 static constexpr auto kTrackIdKey = "trackId"sv;
389 static constexpr auto kExtMidiInputsKey = "extMidiIns"sv;
390 static constexpr auto kAllMidiInputsKey = "allMidiIns"sv;
391 static constexpr auto kMidiChannelsKey = "midiChannels"sv;
392 static constexpr auto kAllMidiChannelsKey = "allMidiChannels"sv;
393 static constexpr auto kExtStereoLInputsKey = "extStereoLIns"sv;
394 static constexpr auto kAllStereoLInputsKey = "allStereoLIns"sv;
395 static constexpr auto kExtStereoRInputsKey = "extStereoRIns"sv;
396 static constexpr auto kAllStereoRInputsKey = "allStereoRIns"sv;
397 static constexpr auto kWidthKey = "width"sv;
398
399 friend void to_json (nlohmann::json &j, const Channel &c)
400 {
401 j[kMidiFxKey] = c.midi_fx_;
402 j[kInsertsKey] = c.inserts_;
403 j[kSendsKey] = c.sends_;
404 j[kInstrumentKey] = c.instrument_;
405 j[kPrefaderKey] = c.prefader_;
406 j[kFaderKey] = c.fader_;
407 j[kMidiOutKey] = c.midi_out_id_;
408 j[kStereoOutLKey] = c.stereo_out_left_id_;
409 j[kStereoOutRKey] = c.stereo_out_right_id_;
410 j[kOutputIdKey] = c.output_track_uuid_;
411 j[kTrackIdKey] = c.track_uuid_;
412 if (!c.all_midi_ins_)
413 {
414 j[kExtMidiInputsKey] = c.ext_midi_ins_;
415 }
416 j[kAllMidiInputsKey] = c.all_midi_ins_;
417 if (!c.all_midi_channels_)
418 {
419 j[kMidiChannelsKey] = c.midi_channels_;
420 }
421 j[kAllMidiChannelsKey] = c.all_midi_channels_;
422 if (!c.all_stereo_l_ins_)
423 {
424 j[kExtStereoLInputsKey] = c.ext_stereo_l_ins_;
425 }
426 j[kAllStereoLInputsKey] = c.all_stereo_l_ins_;
427 if (!c.all_stereo_r_ins_)
428 {
429 j[kExtStereoRInputsKey] = c.ext_stereo_r_ins_;
430 }
431 j[kAllStereoRInputsKey] = c.all_stereo_r_ins_;
432 j[kWidthKey] = c.width_;
433 }
434 friend void from_json (const nlohmann::json &j, Channel &c);
435
439 void connect_no_prev_no_next (Plugin &pl);
440
444 void connect_no_prev_next (Plugin &pl, Plugin &next_pl);
445
449 void connect_prev_no_next (Plugin &prev_pl, Plugin &pl);
450
454 void connect_prev_next (Plugin &prev_pl, Plugin &pl, Plugin &next_pl);
455
459 void disconnect_no_prev_no_next (Plugin &pl);
460
464 void disconnect_no_prev_next (Plugin &pl, Plugin &next_pl);
465
469 void disconnect_prev_no_next (Plugin &prev_pl, Plugin &pl);
470
474 void disconnect_prev_next (Plugin &prev_pl, Plugin &pl, Plugin &next_pl);
475
482 void connect_plugin_to_prefader (Plugin &pl);
483
488 void disconnect_plugin_from_prefader (Plugin &pl);
489
490 void connect_plugins ();
491
500 // void init_stereo_out_ports (bool loading);
501
502 void disconnect_plugin_from_strip (PluginSlot slot, Plugin &pl);
503
507 void disconnect_port_hardware_inputs (Port &port);
508
509 // void disconnect_port_hardware_inputs (StereoPorts &ports);
510
511public:
512 TrackRegistry &track_registry_;
513 PortRegistry &port_registry_;
514 PluginRegistry &plugin_registry_;
515
521 std::array<std::optional<PluginUuidReference>, STRIP_SIZE> midi_fx_;
522
524 std::array<std::optional<PluginUuidReference>, STRIP_SIZE> inserts_;
525
527 std::optional<PluginUuidReference> instrument_;
528
536 std::array<std::unique_ptr<ChannelSend>, STRIP_SIZE> sends_;
537
547 std::vector<std::unique_ptr<ExtPort>> ext_midi_ins_;
548
550 bool all_midi_ins_ = true;
551
561 std::vector<std::unique_ptr<ExtPort>> ext_stereo_l_ins_;
562
564 bool all_stereo_l_ins_ = false;
565
575 std::vector<std::unique_ptr<ExtPort>> ext_stereo_r_ins_;
576
578 bool all_stereo_r_ins_ = false;
579
585 std::array<bool, 16> midi_channels_{};
586
590
592 Fader * fader_ = nullptr;
593
599 Fader * prefader_ = nullptr;
600
605 std::optional<PortUuidReference> midi_out_id_;
606
607 /*
608 * Ports for direct (track-to-track) routing with the exception of
609 * master, which will route the output to monitor in.
610 */
611 std::optional<PortUuidReference> stereo_out_left_id_;
612 std::optional<PortUuidReference> stereo_out_right_id_;
613
619 // bool has_output_ = false;
620
622 std::optional<TrackUuid> output_track_uuid_;
623
625 std::optional<TrackUuid> track_uuid_;
626
628 int width_ = 0;
629
632};
633
634}; // namespace zrythm::gui
The audio engine.
Definition engine.h:111
Audio port specifics.
Definition audio_port.h:25
Abstract class for a track that has a channel in the mixer.
External port.
Definition ext_port.h:36
A Fader is a processor that is used for volume controls and pan.
Definition fader.h:51
Abstract base class for a track that can be routed to.
MIDI port specifics.
Definition midi_port.h:19
Span of plugins that offers helper methods.
Definition plugin_span.h:15
Represents a track in the project.
Definition track.h:282
Struct used to identify Ports in the project.
std::array< std::optional< PluginUuidReference >, STRIP_SIZE > inserts_
The channel insert strip.
Definition channel.h:524
bool get_mono_compat_enabled()
Gets whether mono compatibility is enabled.
void init()
Initializes the Channel (performs logic that needs the object to be constructed).
bool all_midi_channels_
If true, the channel will accept MIDI messages from all MIDI channels.
Definition channel.h:589
void handle_plugin_import(const Plugin *pl, std::optional< PluginSpan > plugins, const PluginDescriptor *descr, PluginSlot slot, bool copy, bool ask_if_overwrite)
Handles import (paste/drop) of plugins or plugin descriptors or mixer selections.
bool all_stereo_r_ins_
If true, the channel will connect to all stereo R ins found.
Definition channel.h:578
ChannelTrack * track_
Owner track.
Definition channel.h:631
std::array< bool, 16 > midi_channels_
1 or 0 flags for each channel to enable it or disable it.
Definition channel.h:585
std::optional< PortUuidReference > midi_out_id_
MIDI output for sending MIDI signals to other destinations, such as other channels when directly rout...
Definition channel.h:605
std::array< std::optional< PluginUuidReference >, STRIP_SIZE > midi_fx_
The MIDI effect strip on instrument/MIDI tracks.
Definition channel.h:521
void paste_plugins_to_slot(PluginSpan plugins, PluginSlot slot)
Paste the selections starting at the slot in the given channel.
std::vector< std::unique_ptr< ExtPort > > ext_stereo_l_ins_
External audio L inputs that are currently connected to this channel as official inputs,...
Definition channel.h:561
std::optional< TrackUuid > output_track_uuid_
Whether or not output_pos corresponds to a Track or not.
Definition channel.h:622
void disconnect_channel()
Disconnects the channel from the processing chain and removes any plugins it contains.
std::optional< TrackUuid > track_uuid_
Track associated with this channel.
Definition channel.h:625
void add_balance_control(float pan)
Adds to (or subtracts from) the pan.
void handle_recording(long g_frames_start, nframes_t nframes)
Handles the recording logic inside the process cycle.
void process()
Perform processing of the audio signal.
void connect_channel(dsp::PortConnectionsManager &mgr, AudioEngine &engine)
Connects the channel's ports.
void select_all(PluginSlotType type, bool select)
Selects/deselects all plugins in the given slot type.
void reset_fader(bool fire_events)
Sets fader to 0.0.
int width_
Channel widget width - reserved for future use.
Definition channel.h:628
std::optional< PluginUuidReference > instrument_
The instrument plugin, if instrument track.
Definition channel.h:527
bool should_bounce_to_master(utils::audio::BounceStep step) const override
Whether the port should add its data to the master output when bouncing.
void set_track_ptr(ChannelTrack &track)
Set the track ptr to the channel and all its internals that reference a track (Plugin,...
void expose_ports_to_backend(AudioEngine &engine)
Exposes the channel's ports to the backend.
std::vector< std::unique_ptr< ExtPort > > ext_midi_ins_
External MIDI inputs that are currently connected to this channel as official inputs,...
Definition channel.h:547
Fader * fader_
The channel fader.
Definition channel.h:592
void append_ports(std::vector< Port * > &ports, bool include_plugins)
Appends all channel ports and optionally plugin ports to the array.
bool get_swap_phase()
Gets whether mono compatibility is enabled.
void reconnect_ext_input_ports(AudioEngine &engine)
Called when the input has changed for Midi, Instrument or Audio tracks.
std::array< std::unique_ptr< ChannelSend >, STRIP_SIZE > sends_
The sends strip.
Definition channel.h:536
PluginUuid remove_plugin_from_channel(PluginSlot slot, bool moving_plugin, bool deleting_plugin)
Removes a plugin at the given slot from the channel.
Channel(TrackRegistry &track_registry, PluginRegistry &plugin_registry, PortRegistry &port_registry, OptionalRef< ChannelTrack > track)
Main constructor used by the others.
std::vector< std::unique_ptr< ExtPort > > ext_stereo_r_ins_
External audio R inputs that are currently connected to this channel as official inputs,...
Definition channel.h:575
PluginPtrVariant add_plugin(PluginUuidReference plugin_id, PluginSlot slot, bool confirm, bool moving_plugin, bool gen_automatables, bool recalc_graph, bool pub_events)
Adds given plugin to given position in the strip.
void set_mono_compat_enabled(bool enabled, bool fire_events)
Sets whether mono compatibility is enabled.
AutomationTrack * get_automation_track(PortIdentifier::Flags port_flags) const
Convenience function to get the automation track of the given type for the channel.
bool all_stereo_l_ins_
If true, the channel will connect to all stereo L ins found.
Definition channel.h:564
void set_caches()
Sets caches for processing.
void get_plugins(std::vector< Plugin * > &pls)
Returns all existing plugins in the channel.
Fader * prefader_
Prefader.
Definition channel.h:599
void prepare_process(nframes_t nframes)
Prepares the channel for processing.
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 all_midi_ins_
If true, the channel will connect to all MIDI ins found.
Definition channel.h:550
void set_swap_phase(bool enabled, bool fire_events)
Sets whether mono compatibility is enabled.
Channel(TrackRegistry &track_registry, PluginRegistry &plugin_registry, PortRegistry &port_registry)
To be used when deserializing or cloning an existing identity.
Definition channel.h:87
This class provides the core functionality for managing a plugin, including creating/initializing the...
Definition plugin.h:43
The PluginDescriptor class provides a set of static utility functions and member functions to work wi...
Lightweight UTF-8 string wrapper with safe conversions.
Definition string.h:39
External ports.
uint32_t nframes_t
Frame count.
Definition types.h:62
ObjectCloneType
Definition icloneable.h:25
@ Fader
0 to 1, suitable for drawing.
Definition types.h:168
Wrapper around std::optional<std::reference_wrapper<T>> that provides a more convenient API.
Definition types.h:324