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 "dsp/hardware_audio_interface.h"
9#include "utils/rt_thread_id.h"
10#include "utils/types.h"
11
12#include <juce_wrapper.h>
13
14namespace zrythm::dsp
15{
16
27class DspGraphDispatcher final
28{
29public:
30 using RunFunctionWithEngineLock = std::function<void (std::function<void ()>)>;
31
32 DspGraphDispatcher (
33 std::unique_ptr<graph::IGraphBuilder> graph_builder,
34 std::vector<graph::IProcessable *> terminal_processables,
35 const IHardwareAudioInterface &hw_interface,
36 RunFunctionWithEngineLock run_function_with_engine_lock,
38 std::optional<juce::AudioWorkgroup> workgroup = std::nullopt);
39
45 void recalc_graph (bool soft);
46
56 const dsp::ITransport &current_transport_state,
57 EngineProcessTimeInfo time_nfo,
58 nframes_t remaining_latency_preroll,
59 bool realtime_context,
60 const dsp::TempoMap &tempo_map) noexcept [[clang::nonblocking]];
61
67
72 [[nodiscard, gnu::hot]] bool is_processing_kickoff_thread () const
73 {
74 return process_kickoff_thread_.has_value ()
75 ? current_thread_id.get () == process_kickoff_thread_.value ()
76 : false;
77 }
78
82 [[nodiscard, gnu::hot]] bool is_processing_thread () const
83 {
84 /* this is called too often so use this optimization */
85 static thread_local bool have_result = false;
86 static thread_local bool is_processing_thread = false;
87
88 if (have_result) [[likely]]
89 {
91 }
92
93 if (!scheduler_) [[unlikely]]
94 {
95 have_result = false;
97 return false;
98 }
99
100 if (scheduler_->contains_thread (current_thread_id.get ()))
101 {
103 have_result = true;
104 return true;
105 }
106
107 have_result = true;
108 is_processing_thread = false;
109 return false;
110 }
111
119 {
120 return scheduler_->get_nodes ().trigger_nodes_;
121 }
122
123private:
139 void
140 preprocess_at_start_of_cycle (const EngineProcessTimeInfo &time_nfo) noexcept
141 [[clang::nonblocking]];
142
143private:
144 std::unique_ptr<graph::IGraphBuilder> graph_builder_;
145 const IHardwareAudioInterface &hw_interface_;
146 std::optional<juce::AudioWorkgroup> workgroup_;
147
152 RunFunctionWithEngineLock run_function_with_engine_lock_;
153
157 std::vector<graph::IProcessable *> terminal_processables_;
158
159 std::unique_ptr<graph::GraphScheduler> scheduler_;
160
162 nframes_t max_route_playback_latency_ = 0;
163
172 nframes_t global_offset_ = 0;
173
175 std::optional<unsigned int> process_kickoff_thread_;
176
178};
179
180}
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())...
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.
void start_cycle(const dsp::ITransport &current_transport_state, EngineProcessTimeInfo time_nfo, nframes_t remaining_latency_preroll, bool realtime_context, const dsp::TempoMap &tempo_map) noexcept
Starts a new cycle.
Abstraction for hardware audio interface.
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