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 "dsp/tempo_map.h"
33#include "utils/utf8_string.h"
34
35#include <QObject>
36
37namespace zrythm::dsp::graph
38{
39class GraphNode;
40
54{
55public:
56 virtual ~IProcessable () { release_resources (); }
57
61 virtual utils::Utf8String get_node_name () const = 0;
62
67 [[gnu::hot]] virtual nframes_t get_single_playback_latency () const
68 {
69 return 0;
70 }
71
81 const GraphNode * node,
82 units::sample_rate_t sample_rate,
83 nframes_t max_block_length)
84 {
85 }
86
87 [[gnu::hot]] virtual void process_block (
88 EngineProcessTimeInfo time_nfo,
89 const dsp::ITransport &transport,
90 const dsp::TempoMap &tempo_map) noexcept [[clang::nonblocking]] { };
91
98 virtual void release_resources () { }
99};
100
101class InitialProcessor final : public QObject, public IProcessable
102{
103 Q_OBJECT
104
105public:
107 {
108 return u8"Initial Processor";
109 }
110};
111
130class GraphNode
131{
132public:
133 using NodeId = int;
134
135 GraphNode (NodeId id, IProcessable &processable);
136 Z_DISABLE_COPY_MOVE (GraphNode)
137 ~GraphNode () noexcept = default;
138
140 std::string print_node_to_str () const;
141
142 void print_node () const;
143
144 // For debugging purposes.
145 NodeId get_id () const { return node_id_; }
146
157 [[gnu::hot]] void process (
158 EngineProcessTimeInfo time_nfo,
159 nframes_t remaining_preroll_frames,
160 const dsp::ITransport &transport,
161 const dsp::TempoMap &tempo_map) const;
162
163 nframes_t get_single_playback_latency () const
164 {
165 return processable_.get_single_playback_latency ();
166 }
167
176
177 void connect_to (GraphNode &target);
178
187 void set_skip_processing (bool skip) { bypass_ = skip; }
188
189 IProcessable &get_processable () { return processable_; }
190
194 auto &feeds () const { return childnodes_; }
195
199 auto &depends () const { return parentnodes_; }
200
201 bool remove_feed (const GraphNode &feed);
202 bool remove_depend (const GraphNode &depend);
203
204private:
205 void add_feeds (GraphNode &dest);
206 void add_depends (GraphNode &src);
207
218 [[gnu::hot]] void compensate_latency (
219 EngineProcessTimeInfo &time_nfo,
220 nframes_t remaining_preroll_frames,
221 const dsp::ITransport &transport,
222 const dsp::TempoMap &tempo_map) const;
223
233 [[gnu::hot]] void process_chunks_after_splitting_at_loop_points (
234 EngineProcessTimeInfo &time_nfo,
235 const dsp::ITransport &transport,
236 const dsp::TempoMap &tempo_map) const;
237
238public:
240 std::atomic<int> refcount_ = 0;
241
249
250 // TODO
258
261
264
265 /* For debugging. These are set by
266 * GraphNodeCollection.set_initial_and_terminal_nodes(). */
267 bool terminal_ = false;
268 bool initial_ = false;
269
270private:
271 NodeId node_id_ = 0;
272
279 std::vector<std::reference_wrapper<GraphNode>> parentnodes_;
280
286 std::vector<std::reference_wrapper<GraphNode>> childnodes_;
287
288 IProcessable &processable_;
289
293 bool bypass_ = false;
294};
295
303{
304public:
311
316
321
328
329 GraphNode * find_node_for_processable (const IProcessable &processable) const;
330
331public:
335 std::vector<std::unique_ptr<GraphNode>> graph_nodes_;
336
343 std::vector<std::reference_wrapper<GraphNode>> trigger_nodes_;
344
350 std::vector<std::reference_wrapper<GraphNode>> terminal_nodes_;
351
352 std::unique_ptr<InitialProcessor> initial_processor_;
353};
354
355} // namespace zrythm::dsp::graph
Interface for transport.
Definition itransport.h:17
Manages the collection of graph nodes.
Definition graph_node.h:303
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:327
std::vector< std::reference_wrapper< GraphNode > > trigger_nodes_
A subset of graph_nodes_ that are trigger nodes.
Definition graph_node.h:343
std::vector< std::reference_wrapper< GraphNode > > terminal_nodes_
A subset of graph_nodes_ that are terminal nodes.
Definition graph_node.h:350
std::vector< std::unique_ptr< GraphNode > > graph_nodes_
All nodes in the graph.
Definition graph_node.h:335
Represents a node in a DSP graph.
Definition graph_node.h:131
int init_refcount_
Initial incoming node count.
Definition graph_node.h:260
std::string print_node_to_str() const
For general debugging.
std::atomic< int > refcount_
Incoming node count.
Definition graph_node.h:240
nframes_t playback_latency_
The playback latency of the node, in samples.
Definition graph_node.h:248
auto & feeds() const
Read-only access to child nodes (outgoing connections).
Definition graph_node.h:194
void set_route_playback_latency(nframes_t dest_latency)
Sets the playback latency of the given node recursively.
void process(EngineProcessTimeInfo time_nfo, nframes_t remaining_preroll_frames, const dsp::ITransport &transport, const dsp::TempoMap &tempo_map) const
Processes the GraphNode.
auto & depends() const
Read-only access to parent nodes (incoming connections).
Definition graph_node.h:199
nframes_t capture_latency_
The capture latency of the node, in samples.
Definition graph_node.h:257
void set_skip_processing(bool skip)
Sets whether processing should be skipped for this node.
Definition graph_node.h:187
nframes_t route_playback_latency_
The route's playback latency so far.
Definition graph_node.h:263
Interface for objects that can be processed in the DSP graph.
Definition graph_node.h:54
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:67
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:80
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:98
utils::Utf8String get_node_name() const override
Returns a human friendly name of the node.
Definition graph_node.h:106
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