Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
graph_dispatcher.h
1// SPDX-FileCopyrightText: © 2019-2021, 2024-2025 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include "dsp/graph_builder.h"
7#include "dsp/graph_scheduler.h"
8#include "utils/rt_thread_id.h"
9#include "utils/types.h"
10
11namespace zrythm::dsp
12{
13
24class DspGraphDispatcher final
25{
26public:
27 using RunFunctionWithEngineLock = std::function<void (std::function<void ()>)>;
28
29 DspGraphDispatcher (
30 std::unique_ptr<graph::IGraphBuilder> graph_builder,
31 std::vector<graph::IProcessable *> terminal_processables,
32 const juce::AudioDeviceManager &device_manager,
33 RunFunctionWithEngineLock run_function_with_engine_lock,
35
41 void recalc_graph (bool soft);
42
51 const dsp::ITransport &current_transport_state,
52 EngineProcessTimeInfo time_nfo,
53 nframes_t remaining_latency_preroll,
54 bool realtime_context) noexcept [[clang::nonblocking]];
55
61
66 [[nodiscard, gnu::hot]] bool is_processing_kickoff_thread () const
67 {
68 return process_kickoff_thread_.has_value ()
69 ? current_thread_id.get () == process_kickoff_thread_.value ()
70 : false;
71 }
72
76 [[nodiscard, gnu::hot]] bool is_processing_thread () const
77 {
78 /* this is called too often so use this optimization */
79 static thread_local bool have_result = false;
80 static thread_local bool is_processing_thread = false;
81
82 if (have_result) [[likely]]
83 {
85 }
86
87 if (!scheduler_) [[unlikely]]
88 {
89 have_result = false;
91 return false;
92 }
93
94 if (scheduler_->contains_thread (current_thread_id.get ()))
95 {
97 have_result = true;
98 return true;
99 }
100
101 have_result = true;
102 is_processing_thread = false;
103 return false;
104 }
105
113 {
114 return scheduler_->get_nodes ().trigger_nodes_;
115 }
116
117private:
133 void
134 preprocess_at_start_of_cycle (const EngineProcessTimeInfo &time_nfo) noexcept
135 [[clang::nonblocking]];
136
137private:
138 std::unique_ptr<graph::IGraphBuilder> graph_builder_;
139 const juce::AudioDeviceManager &device_manager_;
140
145 RunFunctionWithEngineLock run_function_with_engine_lock_;
146
150 std::vector<graph::IProcessable *> terminal_processables_;
151
152 std::unique_ptr<graph::GraphScheduler> scheduler_;
153
155 nframes_t max_route_playback_latency_ = 0;
156
165 nframes_t global_offset_ = 0;
166
168 std::optional<unsigned int> process_kickoff_thread_;
169
171};
172
173}
auto & current_trigger_nodes() const
Accessor for currently active trigger nodes.
bool is_processing_kickoff_thread() const
Returns whether this is the thread that kicks off processing (thread that calls router_start_cycle())...
void start_cycle(const dsp::ITransport &current_transport_state, EngineProcessTimeInfo time_nfo, nframes_t remaining_latency_preroll, bool realtime_context) noexcept
Starts a new cycle.
bool is_processing_thread() const
Returns if the current thread is a processing thread.
void recalc_graph(bool soft)
Recalculates the process acyclic directed graph.
nframes_t get_max_route_playback_latency()
Returns the max playback latency of the trigger nodes.
Interface for transport.
Definition itransport.h:17
std::function< void(std::function< void()>)> RunOnMainThreadFunc
Request for a function to run on the main thread (blocking).
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