Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
processor_base.h
1// SPDX-FileCopyrightText: © 2025-2026 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include "dsp/graph.h"
7#include "dsp/graph_node.h"
8#include "dsp/parameter.h"
9#include "dsp/port_all.h"
10
11#include <QObject>
12
13namespace zrythm::dsp
14{
15
22class ProcessorBase : public dsp::graph::IProcessable
23{
24public:
35 {
36 struct Change
37 {
38 size_t index{};
39 float base_value{};
40 float automated_value{};
41 float modulated_value{};
43 };
44
46 const auto &changes () const { return changes_; }
47
48 private:
49 friend class ProcessorBase;
50
52 std::vector<Change> changes_;
53
55 std::vector<float> prev_values_;
56
59 void prepare (size_t count)
60 {
61 prev_values_.assign (count, -1.f);
62 changes_.clear ();
63 changes_.reserve (count);
64 }
65
68 void record_if_changed (size_t i, dsp::ProcessorParameter * param)
69 {
70 float modulated = param->currentValue ();
71 if (!utils::math::floats_equal (prev_values_[i], modulated))
72 {
73 changes_.push_back (
74 { i, param->baseValue (), param->valueAfterAutomationApplied (),
75 modulated, param });
76 prev_values_[i] = modulated;
77 }
78 }
79
81 void clear () { changes_.clear (); }
82 };
83
84private:
85 struct BaseProcessingCache
86 {
87 units::sample_rate_t sample_rate_;
88 units::sample_u32_t max_block_length_{};
89
90 std::vector<dsp::ProcessorParameter *> live_params_;
91 std::vector<dsp::PortPtrVariant> live_input_ports_;
92 std::vector<dsp::PortPtrVariant> live_output_ports_;
93
94 ParameterChangeTracker change_tracker_;
95
103 bool is_processing_ = false;
104 };
105
106public:
108 {
109 dsp::PortRegistry &port_registry_;
110 dsp::ProcessorParameterRegistry &param_registry_;
111 };
112
113 ProcessorBase (
114 ProcessorBaseDependencies dependencies,
115 utils::Utf8String name = { u8"ProcessorBase" });
116
117 ~ProcessorBase () override;
118
122 void set_name (const utils::Utf8String &name);
123
124 void add_input_port (const dsp::PortUuidReference &uuid);
125 void add_output_port (const dsp::PortUuidReference &uuid);
126 void add_parameter (const dsp::ProcessorParameterUuidReference &uuid);
127
128 auto &get_input_ports () const { return input_ports_; }
129 auto &get_output_ports () const { return output_ports_; }
130 auto &get_parameters () const { return params_; }
131
138 const ParameterChangeTracker &change_tracker () const noexcept
139 {
140 assert (processing_caches_ && processing_caches_->is_processing_);
141 return processing_caches_->change_tracker_;
142 }
143
144 // ============================================================================
145 // IProcessable Interface
146 // ============================================================================
147
148 utils::Utf8String get_node_name () const final { return name_; }
149
160 const dsp::ITransport &transport,
161 const dsp::TempoMap &tempo_map) noexcept final;
163 const graph::GraphNode * node,
164 units::sample_rate_t sample_rate,
165 units::sample_u32_t max_block_length) final;
166 void release_resources () final;
167
168 // ============================================================================
169
170protected:
176 virtual void custom_process_block (
177 dsp::graph::EngineProcessTimeInfo time_nfo,
178 const dsp::ITransport &transport,
179 const dsp::TempoMap &tempo_map) noexcept [[clang::nonblocking]];
180
181 virtual void custom_prepare_for_processing (
182 const graph::GraphNode * node,
183 units::sample_rate_t sample_rate,
184 units::sample_u32_t max_block_length)
185 {
186 }
187
188 virtual void custom_release_resources () { }
189
190 auto dependencies () const { return dependencies_; }
191
192private:
193 static constexpr auto kProcessorNameKey = "processorName"sv;
194 static constexpr auto kInputPortsKey = "inputPorts"sv;
195 static constexpr auto kOutputPortsKey = "outputPorts"sv;
196 static constexpr auto kParametersKey = "parameters"sv;
197 friend void to_json (nlohmann::json &j, const ProcessorBase &p);
198 friend void from_json (const nlohmann::json &j, ProcessorBase &p);
199
200private:
201 ProcessorBaseDependencies dependencies_;
202 utils::Utf8String name_;
203 std::vector<dsp::PortUuidReference> input_ports_;
204 std::vector<dsp::PortUuidReference> output_ports_;
205 std::vector<dsp::ProcessorParameterUuidReference> params_;
206
207 // Caches
208 std::unique_ptr<BaseProcessingCache> processing_caches_;
209
210 BOOST_DESCRIBE_CLASS (ProcessorBase, (), (), (), (name_))
211};
212
222{
223public:
224 static void add_nodes (dsp::graph::Graph &graph, ProcessorBase &processor);
225 static void
226 add_connections (dsp::graph::Graph &graph, ProcessorBase &processor);
227};
228} // namespace zrythm::dsp
Interface for transport.
Definition itransport.h:16
A base class for processors in the DSP graph.
void process_block(dsp::graph::EngineProcessTimeInfo time_nfo, const dsp::ITransport &transport, const dsp::TempoMap &tempo_map) noexcept final
Calls custom_process_block() internally after processing all the parameters.
const ParameterChangeTracker & change_tracker() const noexcept
Returns the change tracker.
void release_resources() final
Called to release resources allocated by prepare_for_processing().
void prepare_for_processing(const graph::GraphNode *node, units::sample_rate_t sample_rate, units::sample_u32_t max_block_length) final
Called to allocate resources required for processing.
void set_name(const utils::Utf8String &name)
Set a custom name to be used in the DSP graph.
utils::Utf8String get_node_name() const final
Returns a human friendly name of the node.
virtual void custom_process_block(dsp::graph::EngineProcessTimeInfo time_nfo, const dsp::ITransport &transport, const dsp::TempoMap &tempo_map) noexcept
Custom processor logic after processing all owned parameters.
Helper class to insert nodes and connections pertaining to a ProcessorBase instance to a graph.
Wrapper over a Uuid registry that provides (slow) lookup by unique ID.
Definition parameter.h:449
Processor parameter that accepts automation and modulation sources and integrates with QML and the DS...
Definition parameter.h:167
Q_INVOKABLE float currentValue() const
Returns the current (normalized) value after any automation and modulation has been applied.
Definition parameter.h:248
Q_INVOKABLE float valueAfterAutomationApplied() const
Returns the value after automation, but before modulation has been applied.
Definition parameter.h:256
Represents a node in a DSP graph.
Definition graph_node.h:160
The Graph class represents a graph of DSP nodes.
Definition graph.h:20
Interface for objects that can be processed in the DSP graph.
Definition graph_node.h:86
Lightweight UTF-8 string wrapper with safe conversions.
Definition utf8_string.h:37
constexpr bool floats_equal(T a, T b)
Checks if 2 floating point numbers are equal.
Definition math_utils.h:74
Tracks parameter value changes across processing cycles.
const auto & changes() const
Returns the changes accumulated during the current cycle.
Common struct to pass around during processing to avoid repeating the data in function arguments.
Definition graph_node.h:51