8#include "dsp/processor_base.h"
9#include "dsp/tempo_map_qml_adapter.h"
10#include "structure/arrangement/arranger_object_owner.h"
11#include "structure/arrangement/automation_region.h"
12#include "structure/arrangement/timeline_data_provider.h"
13#include "structure/tracks/playback_cache_activity_tracker.h"
14#include "utils/playback_cache_scheduler.h"
15#include "utils/units.h"
17#include <QtQmlIntegration/qqmlintegration.h>
19namespace zrythm::structure::tracks
30 AutomationMode automationMode READ getAutomationMode WRITE setAutomationMode
31 NOTIFY automationModeChanged)
33 AutomationRecordMode recordMode READ getRecordMode WRITE setRecordMode
34 NOTIFY recordModeChanged)
35 DEFINE_ARRANGER_OBJECT_OWNER_QML_PROPERTIES (
41 playbackCacheActivityTracker READ playbackCacheActivityTracker CONSTANT)
49 static constexpr int AUTOMATION_RECORDING_TOUCH_REL_MS = 800;
51 enum class AutomationMode : uint8_t
57 Q_ENUM (AutomationMode)
59 enum class AutomationRecordMode : uint8_t
64 Q_ENUM (AutomationRecordMode)
71 dsp::ProcessorParameterUuidReference param_id,
72 QObject * parent =
nullptr);
81 AutomationMode getAutomationMode ()
const {
return automation_mode_.load (); }
82 void setAutomationMode (AutomationMode automation_mode);
83 Q_SIGNAL
void automationModeChanged (AutomationMode automation_mode);
85 AutomationRecordMode getRecordMode ()
const {
return record_mode_; }
86 void setRecordMode (AutomationRecordMode record_mode);
87 Q_INVOKABLE
void swapRecordMode ();
88 Q_SIGNAL
void recordModeChanged (AutomationRecordMode record_mode);
107 playbackCacheActivityTracker ()
const
109 return playback_cache_activity_tracker_.get ();
145 units::precise_tick_t position_ticks,
146 units::precise_tick_t delta_ticks,
147 bool search_only_backwards =
false);
159 units::sample_t timeline_position,
160 bool search_only_regions_enclosing_position)
const;
172 units::sample_t pos_samples,
173 bool search_only_regions_enclosing_position)
const -> AutomationRegion *;
184 units::sample_t timeline_frames,
185 bool search_only_regions_enclosing_position)
const;
187 bool contains_automation ()
const {
return !get_children_vector ().empty (); }
190 get_field_name_for_serialization (
const AutomationRegion *)
const override
196 static constexpr auto kParameterKey =
"parameter"sv;
199 static constexpr auto kAutomationModeKey =
"automationMode"sv;
200 static constexpr auto kRecordModeKey =
"recordMode"sv;
202 friend void from_json (
const nlohmann::json &j,
AutomationTrack &track);
204 friend void init_from (
214 dsp::ProcessorParameterUuidReference param_id_;
217 std::atomic<AutomationMode> automation_mode_{ AutomationMode::Read };
220 AutomationRecordMode record_mode_{};
225 utils::QObjectUniquePtr<arrangement::AutomationTimelineDataProvider>
226 automation_data_provider_;
231 utils::QObjectUniquePtr<utils::PlaybackCacheScheduler>
232 automation_cache_request_debouncer_;
234 utils::QObjectUniquePtr<PlaybackCacheActivityTracker>
235 playback_cache_activity_tracker_;
242generate_automation_tracks_for_processor (
243 std::vector<utils::QObjectUniquePtr<AutomationTrack>> &ret,
244 const dsp::ProcessorBase &processor,
245 const dsp::TempoMapWrapper &tempo_map,
246 utils::IObjectRegistry ®istry)
248 z_debug (
"generating automation tracks for {}...", processor.get_node_name ());
249 for (
const auto ¶m_ref : processor.get_parameters ())
251 auto *
const param = param_ref.get ();
252 if (!param->automatable ())
256 utils::make_qobject_unique<AutomationTrack> (
257 tempo_map, registry, param_ref));
262DEFINE_ENUM_FORMATTER (
263 zrythm::structure::tracks::AutomationTrack::AutomationRecordMode,
264 AutomationRecordMode,
265 QT_TR_NOOP_UTF8 (
"Touch"),
266 QT_TR_NOOP_UTF8 (
"Latch"));
268DEFINE_ENUM_FORMATTER (
269 zrythm::structure::tracks::AutomationTrack::AutomationMode,
Processor parameter that accepts automation and modulation sources and integrates with QML and the DS...
An automation point inside an AutomationTrack.
Represents an automation region, which contains a collection of automation points.
Q_SIGNAL void automationObjectsNeedRecache(utils::ExpandableTickRange affectedRange)
Fired when a new cache is required.
AutomationTrack(const dsp::TempoMapWrapper &tempo_map, utils::IObjectRegistry ®istry, dsp::ProcessorParameterUuidReference param_id, QObject *parent=nullptr)
Creates an automation track for the given parameter.
bool should_read_automation() const
Returns whether the automation in the automation track should be read.
std::optional< float > get_normalized_value(units::sample_t timeline_frames, bool search_only_regions_enclosing_position) const
Returns the normalized parameter value at the given timeline position.
bool should_be_recording(bool record_aps) const
Returns if the automation track should currently be recording data.
AutomationPoint * get_automation_point_before(units::sample_t timeline_position, bool search_only_regions_enclosing_position) const
Returns the last automation point before the given timeline position.
AutomationPoint * get_automation_point_around(units::precise_tick_t position_ticks, units::precise_tick_t delta_ticks, bool search_only_backwards=false)
Find an automation point near the given position position_ticks with a tolerance of delta_ticks.
Q_INVOKABLE void regeneratePlaybackCaches(utils::ExpandableTickRange affectedRange)
To be connected to to notify of any changes to the automation content.
auto get_region_before(units::sample_t pos_samples, bool search_only_regions_enclosing_position) const -> AutomationRegion *
Returns the active region at a given position, if any.
Helper that manages cache activity state for a cache-holding object.
Abstract interface for a UUID-keyed object registry.