Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
control_port.h
1// SPDX-FileCopyrightText: © 2018-2022, 2024-2025 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5#include <utility>
6
7#include "gui/dsp/port.h"
8#include "utils/icloneable.h"
9#include "utils/math.h"
10#include "utils/monotonic_time_provider.h"
11
15class ControlPort final
16 : public QObject,
17 public Port,
18 public PortConnectionsCacheMixin<CVPort>
19{
20 Q_OBJECT
21 QML_ELEMENT
22
23public:
35 std::function<std::optional<float> (signed_frame_t global_frame)>;
36
43 {
49 PortIdentifier::Flags flag{};
50
52 float real_val = 0.0f;
53
55 int ival = 0;
56 };
57
61 struct ScalePoint
62 {
63 float val_;
64 utils::Utf8String label_;
65
66 ScalePoint (float val, utils::Utf8String label)
67 : val_ (val), label_ (std::move (label))
68 {
69 }
70
71 friend auto operator<=> (const ScalePoint &lhs, const ScalePoint &rhs)
72 {
73 return lhs.val_ <=> rhs.val_;
74 }
75
76 friend bool operator== (const ScalePoint &lhs, const ScalePoint &rhs)
77 {
78 return utils::math::floats_equal (lhs.val_, rhs.val_);
79 }
80 };
81
82public:
83 ControlPort (utils::Utf8String label = {});
84
94 float normalized_val_to_real (float normalized_val) const;
95
105 float real_val_to_normalized (float real_val) const;
106
110 static bool is_val_toggled (float val) { return val > 0.001f; }
111
115 bool is_toggled () const { return is_val_toggled (control_); }
116
120 int get_int () const { return get_int_from_val (control_); }
121
126
130 static int get_int_from_val (float val)
131 {
132 const auto s32 = utils::math::round_to_signed_32 (val);
133 assert (
134 s32 >= std::numeric_limits<int>::min ()
135 && s32 <= std::numeric_limits<int>::max ());
136 return static_cast<int> (s32);
137 }
138
142 float get_snapped_val () const
143 {
145 }
146
150 float get_snapped_val_from_val (float val) const;
151
157 float get_val () const { return control_; }
158
162 float get_normalized_val () const
163 {
165 }
166
171 float get_unsnapped_val () const { return unsnapped_control_; }
172
176 float get_default_val () const { return deff_; }
177
181 void set_real_val (float val) { set_control_value (val, false, false); }
182
186 void set_real_val_w_events (float val)
187 {
188 set_control_value (val, false, true);
189 }
190
194 void set_toggled (bool toggled, bool forward_events)
195 {
196 set_control_value (toggled ? 1.f : 0.f, false, forward_events);
197 }
198
209 [[gnu::hot]] void set_val_from_normalized (float val, bool automating);
210
225 void
226 set_control_value (float val, bool is_normalized, bool forward_event_to_plugin);
227
235 {
236 automation_reader_ = reader;
237 }
238
239 RtTimePoint ms_since_last_change () const
240 {
241 return time_provider_->get_monotonic_time_usecs () - last_change_time_;
242 }
243
250 [[gnu::hot]] float get_control_value (bool normalize) const;
251
252 [[gnu::hot]] void process_block (EngineProcessTimeInfo time_nfo) override;
253
254 void clear_buffer (std::size_t block_length) override { }
255
256 friend void init_from (
257 ControlPort &obj,
258 const ControlPort &other,
259 utils::ObjectCloneType clone_type);
260
261private:
262 static constexpr std::string_view kControlKey = "control";
263 static constexpr std::string_view kRangeKey = "range";
264 static constexpr std::string_view kDefaultValueKey = "defaultValue";
265 static constexpr std::string_view kCarlaParameterIdKey = "carlaParameterId";
266 static constexpr std::string_view kBaseValueKey = "baseValue";
267 friend void to_json (nlohmann::json &j, const ControlPort &p)
268 {
269 to_json (j, static_cast<const Port &> (p));
270 j[kControlKey] = p.control_;
271 j[kRangeKey] = p.range_;
272 j[kDefaultValueKey] = p.deff_;
273 j[kCarlaParameterIdKey] = p.carla_param_id_;
274 j[kBaseValueKey] = p.base_value_;
275 }
276 friend void from_json (const nlohmann::json &j, ControlPort &p)
277 {
278 from_json (j, static_cast<Port &> (p));
279 j.at (kControlKey).get_to (p.control_);
280 j.at (kRangeKey).get_to (p.range_);
281 j.at (kDefaultValueKey).get_to (p.deff_);
282 j.at (kCarlaParameterIdKey).get_to (p.carla_param_id_);
283 j.at (kBaseValueKey).get_to (p.base_value_);
284 }
285
290 // void forward_control_change_event ();
291
292public:
301 float control_ = 0.f;
302
309 float base_value_ = 0.f;
310
312 std::vector<ScalePoint> scale_points_;
313
314 /* --- MIDI CC info --- */
315
316 /*
317 * Next 2 objects are MIDI CC info, if MIDI CC in track processor.
318 *
319 * Used as a cache.
320 */
321
324
327
328 /* --- end MIDI CC info --- */
329
331 float deff_ = 0.f;
332
335
337 bool automating_ = false;
338
341
344
351
352private:
358 RtTimePoint last_change_time_{};
359
360 std::optional<AutomationValueGetter> automation_reader_;
361
362 std::unique_ptr<utils::QElapsedTimeProvider> time_provider_;
363};
Control port specifics.
midi_byte_t midi_channel_
MIDI channel, starting from 1.
float normalized_val_to_real(float normalized_val) const
Converts normalized value (0.0 to 1.0) to real value (eg.
float get_control_value(bool normalize) const
Gets the given control value from the corresponding underlying structure in the Port.
float get_snapped_val_from_val(float val) const
Returns the snapped value (eg, if toggle, returns 0.f or 1.f).
bool automating_
Whether this value was set via automation.
static bool is_val_toggled(float val)
Checks if the given value is toggled.
static int get_int_from_val(float val)
Gets the control value for an integer port.
float control_
To be called when a control's value changes so that a message can be sent to the plugin UI.
int get_int() const
Gets the control value for an integer port.
float real_val_to_normalized(float real_val) const
Converts real value (eg.
float deff_
Default value.
float get_val() const
Get the current real value of the control.
void set_toggled(bool toggled, bool forward_events)
Wrapper over port_set_control_value() for toggles.
void set_real_val_w_events(float val)
Set the default real value of the control and sends UI events.
float get_default_val() const
Get the default real value of the control.
bool is_toggled() const
Returns if the control port is toggled.
int carla_param_id_
Index of the control parameter (for Carla plugin ports).
bool value_changed_from_reading_
Flag that the value of the port changed from reading automation.
std::function< std::optional< float >(signed_frame_t global_frame)> AutomationValueGetter
Gets the current automation value if available (eg, from an automation track).
void set_val_from_normalized(float val, bool automating)
Updates the actual value.
float unsnapped_control_
Unsnapped value, used by widgets.
float get_unsnapped_val() const
Get the current real unsnapped value of the control.
void set_unit_from_str(const utils::Utf8String &str)
Set the identifier's port unit from the given string.
std::vector< ScalePoint > scale_points_
Scale points.
void set_automation_value_reader(AutomationValueGetter reader)
Sets the automation value reader.
void clear_buffer(std::size_t block_length) override
Clears the port buffer.
void set_real_val(float val)
Get the default real value of the control.
midi_byte_t midi_cc_no_
MIDI CC number, if not pitchbend/poly key/channel pressure.
bool received_ui_event_
Whether the port received a UI event from the plugin UI in this cycle.
float get_snapped_val() const
Returns the snapped value (eg, if toggle, returns 0.f or 1.f).
float get_normalized_val() const
Get the current normalized value of the control.
void set_control_value(float val, bool is_normalized, bool forward_event_to_plugin)
Sets the given control value to the corresponding underlying structure in the Port.
float base_value_
For control ports, when a modulator is attached to the port the previous value will be saved here.
The Port class represents a port in the audio processing graph.
Definition port.h:169
Lightweight UTF-8 string wrapper with safe conversions.
Definition string.h:39
int_fast64_t signed_frame_t
Signed type for frame index.
Definition types.h:78
uint8_t midi_byte_t
MIDI byte.
Definition types.h:55
constexpr bool floats_equal(T a, T b)
Checks if 2 floating point numbers are equal.
Definition math.h:77
constexpr long round_to_signed_32(T x)
Rounds a double to a (minimum) signed 32-bit integer.
Definition math.h:87
Used for queueing changes to be applied during processing.
PortIdentifier::Flags flag
Flag to identify the port the change is for.
float real_val
Real (not normalized) value to set.
Common struct to pass around during processing to avoid repeating the data in function arguments.
Definition types.h:172