Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
graph_node.h
1// SPDX-FileCopyrightText: © 2019-2021, 2024-2025 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3/*
4 * This file incorporates work covered by the following copyright and
5 * permission notice:
6 *
7 * ---
8 *
9 * Copyright (C) 2017, 2019 Robin Gareus <robin@gareus.org>
10 *
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <https://www.gnu.org/licenses/>.
23 *
24 * SPDX-License-Identifier: GPL-2.0-or-later
25 *
26 * ---
27 */
28
29#pragma once
30
31#include "dsp/itransport.h"
32#include "utils/utf8_string.h"
33
34#include <QObject>
35
36namespace zrythm::dsp::graph
37{
38class GraphNode;
39
53{
54public:
55 virtual ~IProcessable () { release_resources (); }
56
60 virtual utils::Utf8String get_node_name () const = 0;
61
66 [[gnu::hot]] virtual nframes_t get_single_playback_latency () const
67 {
68 return 0;
69 }
70
80 const GraphNode * node,
81 units::sample_rate_t sample_rate,
82 nframes_t max_block_length)
83 {
84 }
85
86 [[gnu::hot]] virtual void process_block (
87 EngineProcessTimeInfo time_nfo,
88 const dsp::ITransport &transport) noexcept [[clang::nonblocking]] { };
89
96 virtual void release_resources () { }
97};
98
99class InitialProcessor final : public QObject, public IProcessable
100{
101 Q_OBJECT
102
103public:
105 {
106 return u8"Initial Processor";
107 }
108};
109
128class GraphNode
129{
130public:
131 using NodeId = int;
132
133 GraphNode (NodeId id, IProcessable &processable);
134 Z_DISABLE_COPY_MOVE (GraphNode)
135 ~GraphNode () noexcept = default;
136
138 std::string print_node_to_str () const;
139
140 void print_node () const;
141
142 // For debugging purposes.
143 NodeId get_id () const { return node_id_; }
144
155 [[gnu::hot]] void process (
156 EngineProcessTimeInfo time_nfo,
157 nframes_t remaining_preroll_frames,
158 const dsp::ITransport &transport) const;
159
160 nframes_t get_single_playback_latency () const
161 {
162 return processable_.get_single_playback_latency ();
163 }
164
173
174 void connect_to (GraphNode &target);
175
184 void set_skip_processing (bool skip) { bypass_ = skip; }
185
186 IProcessable &get_processable () { return processable_; }
187
191 auto &feeds () const { return childnodes_; }
192
196 auto &depends () const { return parentnodes_; }
197
198 bool remove_feed (const GraphNode &feed);
199 bool remove_depend (const GraphNode &depend);
200
201private:
202 void add_feeds (GraphNode &dest);
203 void add_depends (GraphNode &src);
204
215 [[gnu::hot]] void compensate_latency (
216 EngineProcessTimeInfo &time_nfo,
217 nframes_t remaining_preroll_frames,
218 const dsp::ITransport &transport) const;
219
229 [[gnu::hot]] void process_chunks_after_splitting_at_loop_points (
230 EngineProcessTimeInfo &time_nfo,
231 const dsp::ITransport &transport) const;
232
233public:
235 std::atomic<int> refcount_ = 0;
236
244
245 // TODO
253
256
259
260 /* For debugging. These are set by
261 * GraphNodeCollection.set_initial_and_terminal_nodes(). */
262 bool terminal_ = false;
263 bool initial_ = false;
264
265private:
266 NodeId node_id_ = 0;
267
274 std::vector<std::reference_wrapper<GraphNode>> parentnodes_;
275
281 std::vector<std::reference_wrapper<GraphNode>> childnodes_;
282
283 IProcessable &processable_;
284
288 bool bypass_ = false;
289};
290
298{
299public:
306
311
316
323
324 GraphNode * find_node_for_processable (const IProcessable &processable) const;
325
326public:
330 std::vector<std::unique_ptr<GraphNode>> graph_nodes_;
331
338 std::vector<std::reference_wrapper<GraphNode>> trigger_nodes_;
339
345 std::vector<std::reference_wrapper<GraphNode>> terminal_nodes_;
346
347 std::unique_ptr<InitialProcessor> initial_processor_;
348};
349
350} // namespace zrythm::dsp::graph
Interface for transport.
Definition itransport.h:17
Manages the collection of graph nodes.
Definition graph_node.h:298
void update_latencies()
Updates the latencies of all nodes.
nframes_t get_max_route_playback_latency() const
Returns the max playback latency of the trigger nodes.
void set_initial_and_terminal_nodes()
Updates the initial and terminal nodes based on graph_nodes_.
void finalize_nodes()
Sets the initial/terminal nodes.
Definition graph_node.h:322
std::vector< std::reference_wrapper< GraphNode > > trigger_nodes_
A subset of graph_nodes_ that are trigger nodes.
Definition graph_node.h:338
std::vector< std::reference_wrapper< GraphNode > > terminal_nodes_
A subset of graph_nodes_ that are terminal nodes.
Definition graph_node.h:345
std::vector< std::unique_ptr< GraphNode > > graph_nodes_
All nodes in the graph.
Definition graph_node.h:330
Represents a node in a DSP graph.
Definition graph_node.h:129
int init_refcount_
Initial incoming node count.
Definition graph_node.h:255
std::string print_node_to_str() const
For general debugging.
std::atomic< int > refcount_
Incoming node count.
Definition graph_node.h:235
nframes_t playback_latency_
The playback latency of the node, in samples.
Definition graph_node.h:243
auto & feeds() const
Read-only access to child nodes (outgoing connections).
Definition graph_node.h:191
void set_route_playback_latency(nframes_t dest_latency)
Sets the playback latency of the given node recursively.
auto & depends() const
Read-only access to parent nodes (incoming connections).
Definition graph_node.h:196
nframes_t capture_latency_
The capture latency of the node, in samples.
Definition graph_node.h:252
void process(EngineProcessTimeInfo time_nfo, nframes_t remaining_preroll_frames, const dsp::ITransport &transport) const
Processes the GraphNode.
void set_skip_processing(bool skip)
Sets whether processing should be skipped for this node.
Definition graph_node.h:184
nframes_t route_playback_latency_
The route's playback latency so far.
Definition graph_node.h:258
Interface for objects that can be processed in the DSP graph.
Definition graph_node.h:53
virtual nframes_t get_single_playback_latency() const
Returns the latency of only the given processable, without adding the previous/next latencies.
Definition graph_node.h:66
virtual void prepare_for_processing(const GraphNode *node, units::sample_rate_t sample_rate, nframes_t max_block_length)
Called to allocate resources required for processing.
Definition graph_node.h:79
virtual utils::Utf8String get_node_name() const =0
Returns a human friendly name of the node.
virtual void release_resources()
Called to release resources allocated by prepare_for_processing().
Definition graph_node.h:96
utils::Utf8String get_node_name() const override
Returns a human friendly name of the node.
Definition graph_node.h:104
Lightweight UTF-8 string wrapper with safe conversions.
Definition utf8_string.h:38
uint32_t nframes_t
Frame count.
Definition types.h:58
Common struct to pass around during processing to avoid repeating the data in function arguments.
Definition types.h:133