Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
graph_scheduler.h
1// SPDX-FileCopyrightText: © 2019-2021, 2024 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 * ---
25 */
26
27#pragma once
28
29#include "dsp/graph_node.h"
30#include "utils/mpmc_queue.h"
31#include "utils/rt_thread_id.h"
32
33#include <boost/unordered/concurrent_flat_set.hpp>
34#include <juce_wrapper.h>
35#include <moodycamel/lightweightsemaphore.h>
36
37namespace zrythm::dsp::graph
38{
39
40class GraphThread;
41
59{
60 friend class GraphThread;
61 using GraphThreadPtr = std::unique_ptr<GraphThread>;
62 static constexpr int MAX_GRAPH_THREADS = 128;
63
64public:
79 sample_rate_t sample_rate,
80 nframes_t max_block_length,
81 std::optional<juce::Thread::RealtimeOptions> realtime_options = std::nullopt,
82 std::optional<juce::AudioWorkgroup> thread_workgroup = std::nullopt);
84 Z_DISABLE_COPY_MOVE (GraphScheduler); // copy/move don't make sense here
85
100 GraphNodeCollection &&nodes,
101 sample_rate_t sample_rate,
102 nframes_t max_block_length);
103
112 void start_threads (std::optional<int> num_threads = std::nullopt);
113
118
119 auto &get_nodes () { return graph_nodes_; }
120
128 EngineProcessTimeInfo time_nfo,
129 nframes_t remaining_preroll_frames,
130 const dsp::ITransport &transport);
131
135 bool contains_thread (RTThreadId::IdType thread_id);
136
137 auto get_time_nfo () const { return time_nfo_; }
138 auto get_remaining_preroll_frames () const
139 {
140 return remaining_preroll_frames_;
141 }
142
150 {
151 assert (current_transport_.has_value ());
152 return current_transport_->get ();
153 }
154
155private:
159 [[gnu::hot]] void trigger_node (GraphNode &node);
160
165 void prepare_nodes_for_processing ();
166
171 void release_node_resources ();
172
173private:
174 boost::concurrent_flat_set<GraphThreadPtr> threads_;
175 GraphThreadPtr main_thread_;
176
180 EngineProcessTimeInfo time_nfo_;
181
185 std::optional<std::reference_wrapper<const dsp::ITransport>> current_transport_;
186
190 nframes_t remaining_preroll_frames_{};
191
193 moodycamel::LightweightSemaphore callback_start_sem_{ 0 };
194 moodycamel::LightweightSemaphore callback_done_sem_{ 0 };
195
197 std::atomic<int> idle_thread_cnt_ = 0;
198
200 // This is not a std::counting_semaphore due to issues on MSVC/Windows.
201 moodycamel::LightweightSemaphore trigger_sem_{ 0 };
202
204 MPMCQueue<GraphNode *> trigger_queue_;
205
209 GraphNodeCollection graph_nodes_;
210
212 std::atomic<int> terminal_refcnt_ = 0;
213
218 juce::Thread::RealtimeOptions realtime_thread_options_;
219
221 std::optional<juce::AudioWorkgroup> thread_workgroup_;
222
223 sample_rate_t sample_rate_;
224 nframes_t max_block_length_;
225};
226
227} // namespace zrythm::dsp::graph
Interface for transport.
Definition itransport.h:17
Manages the collection of graph nodes.
Definition graph_node.h:280
Represents a node in a DSP graph.
Definition graph_node.h:124
void rechain_from_node_collection(GraphNodeCollection &&nodes, sample_rate_t sample_rate, nframes_t max_block_length)
Steals the nodes from the given collection and prepares for processing.
bool contains_thread(RTThreadId::IdType thread_id)
Returns whether the given thread is one of the graph threads.
auto & get_transport_for_this_cycle() const
Returns the ITransport instance to be used in this cycle.
GraphScheduler(sample_rate_t sample_rate, nframes_t max_block_length, std::optional< juce::Thread::RealtimeOptions > realtime_options=std::nullopt, std::optional< juce::AudioWorkgroup > thread_workgroup=std::nullopt)
Construct a new Graph Scheduler.
void run_cycle(EngineProcessTimeInfo time_nfo, nframes_t remaining_preroll_frames, const dsp::ITransport &transport)
To be called repeatedly by a system audio callback thread.
void terminate_threads()
Tell all threads to terminate.
void start_threads(std::optional< int > num_threads=std::nullopt)
Starts the threads that will be processing the graph.
Processing graph thread.
uint32_t sample_rate_t
Sample rate.
Definition types.h:61
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:136