Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
automation_point.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 "dsp/curve.h"
7#include "dsp/position.h"
8#include "gui/dsp/arranger_object.h"
9#include "gui/dsp/bounded_object.h"
10#include "gui/dsp/control_port.h"
11#include "gui/dsp/region_owned_object.h"
12#include "utils/icloneable.h"
13#include "utils/math.h"
14#include "utils/types.h"
15
16class Port;
18class AutomationTrack;
19
20using namespace zrythm;
21
27
31class AutomationPoint final
32 : public QObject,
33 public RegionOwnedObject,
34 public ICloneable<AutomationPoint>
35{
36 Q_OBJECT
37 QML_ELEMENT
38 DEFINE_ARRANGER_OBJECT_QML_PROPERTIES (AutomationPoint)
39 Q_PROPERTY (double value READ getValue WRITE setValue NOTIFY valueChanged)
40public:
41 using RegionT = AutomationRegion;
42
43 DECLARE_FINAL_ARRANGER_OBJECT_CONSTRUCTORS (AutomationPoint)
44 Q_DISABLE_COPY_MOVE (AutomationPoint)
45 ~AutomationPoint () override;
46
47 // ========================================================================
48 // QML Interface
49 // ========================================================================
50
51 double getValue () const { return fvalue_; }
52
53 void setValue (double dval)
54 {
55 const auto val = static_cast<float> (dval);
57 {
58 set_fvalue (val, false);
59 Q_EMIT valueChanged (dval);
60 }
61 }
62 Q_SIGNAL void valueChanged (double);
63
64 // ========================================================================
65
72 void set_fvalue (float real_val, bool is_normalized);
73
75 std::string get_fvalue_as_string () const;
76
78 void set_fvalue_with_action (const std::string &fval_str);
79
90 [[gnu::hot]] double
91 get_normalized_value_in_curve (AutomationRegion * region, double x) const;
92
96 void set_curviness (curviness_t curviness);
97
103
109
114 bool curves_up () const;
115
116 void
118 override;
119
120 ArrangerObjectPtrVariant
121 add_clone_to_project (bool fire_events) const override;
122
123 ArrangerObjectPtrVariant insert_clone_to_project () const override;
124
125 bool
126 validate (bool is_project, dsp::FramesPerTick frames_per_tick) const override;
127
128 friend bool operator< (const AutomationPoint &a, const AutomationPoint &b)
129 {
130#if 0
131 if (a.pos_ == b.pos_) [[unlikely]]
132 {
133 return a.index_ < b.index_;
134 }
135#endif
136
137 return a.pos_ < b.pos_;
138 }
139
140 friend bool operator== (const AutomationPoint &a, const AutomationPoint &b)
141 {
142 /* note: we don't care about the index, only the position and the value */
143 /* note2: previously, this code was comparing position ticks, now it only
144 * compares frames. TODO: if no problems are caused delete this note */
145 return a.pos_ == b.pos_
146 && utils::math::floats_near (a.fvalue_, b.fvalue_, 0.001f);
147 }
148
149private:
150 static constexpr std::string_view kValueKey = "value";
151 static constexpr std::string_view kNormalizedValueKey = "normalized_value";
152 static constexpr std::string_view kCurveOptionsKey = "curve_options";
153 friend void to_json (nlohmann::json &j, const AutomationPoint &point)
154 {
155 to_json (j, static_cast<const ArrangerObject &> (point));
156 to_json (j, static_cast<const RegionOwnedObject &> (point));
157 j[kValueKey] = point.fvalue_;
158 j[kNormalizedValueKey] = point.normalized_val_;
159 j[kCurveOptionsKey] = point.curve_opts_;
160 }
161 friend void from_json (const nlohmann::json &j, AutomationPoint &point)
162 {
163 from_json (j, static_cast<ArrangerObject &> (point));
164 from_json (j, static_cast<RegionOwnedObject &> (point));
165 j.at (kValueKey).get_to (point.fvalue_);
166 j.at (kNormalizedValueKey).get_to (point.normalized_val_);
167 j.at (kCurveOptionsKey).get_to (point.curve_opts_);
168 }
169
170public:
172 float fvalue_ = 0.f;
173
175 float normalized_val_ = 0.f;
176
177 dsp::CurveOptions curve_opts_{};
178};
179
185{
186 Read,
187 Record,
188 Off,
189 NUM_AUTOMATION_MODES,
190};
191
192constexpr size_t NUM_AUTOMATION_MODES =
193 static_cast<size_t> (AutomationMode::NUM_AUTOMATION_MODES);
194
195DEFINE_ENUM_FORMATTER (
198 QT_TR_NOOP ("On"),
199 QT_TR_NOOP ("Rec"),
200 QT_TR_NOOP ("Off"));
201
205 [] (const AutomationPoint &ap) {
206 return fmt::format (
207 "AutomationPoint [{}]: val {}, normalized val {}", ap.get_position (),
208 ap.fvalue_, ap.normalized_val_);
209 });
210
auto get_position() const
Getter.
PositionProxy * pos_
Position (or start Position if the object has length).
An automation point inside an AutomationTrack.
AutomationTrack * get_automation_track() const
Convenience function to return the AutomationTrack that this AutomationPoint is in.
void set_curviness(curviness_t curviness)
Sets the curviness of the AutomationPoint.
std::string get_fvalue_as_string() const
String getter for the value.
ControlPort * get_port() const
Convenience function to return the control port that this AutomationPoint is for.
ArrangerObjectPtrVariant add_clone_to_project(bool fire_events) const override
Appends the ArrangerObject to where it belongs in the project (eg, a Track), without taking into acco...
void set_fvalue_with_action(const std::string &fval_str)
String setter.
float fvalue_
Float value (real).
bool validate(bool is_project, dsp::FramesPerTick frames_per_tick) const override
Validates the arranger object.
void init_after_cloning(const AutomationPoint &other, ObjectCloneType clone_type) override
Initializes the cloned object.
bool curves_up() const
Returns if the curve of the AutomationPoint curves upwards as you move right on the x axis.
void set_fvalue(float real_val, bool is_normalized)
Sets the value from given real or normalized value and notifies interested parties.
ArrangerObjectPtrVariant insert_clone_to_project() const override
Inserts the object where it belongs in the project (eg, a Track).
double get_normalized_value_in_curve(AutomationRegion *region, double x) const
The function to return a point on the curve.
float normalized_val_
Normalized value (0 to 1) used as a cache.
Represents an automation region, which contains a collection of automation points.
Control port specifics.
The Port class represents a port in the audio processing graph.
Definition port.h:180
Curve options.
Definition curve.h:23
AutomationMode
FIXME: move to a more appropriate place.
#define DEFINE_OBJECT_FORMATTER(obj_type, function_prefix, formatter_func)
Defines a formatter for the given object type.
Definition format.h:80
ObjectCloneType
Definition icloneable.h:25
constexpr bool floats_equal(T a, T b)
Checks if 2 floating point numbers are equal.
Definition math.h:77
constexpr bool floats_near(T a, T b, T e)
Returns whether 2 floating point numbers are equal.
Definition math.h:67
Custom types.