1 /* 2 * Copyright (C) 2019-2021 Alexandros Theodotou <alex at zrythm dot org> 3 * 4 * This file is part of Zrythm 5 * 6 * Zrythm is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU Affero General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * Zrythm is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU Affero General Public License for more details. 15 * 16 * You should have received a copy of the GNU Affero General Public License 17 * along with Zrythm. If not, see <https://www.gnu.org/licenses/>. 18 * 19 * This file incorporates work covered by the following copyright and 20 * permission notice: 21 * 22 * Copyright (C) 2017, 2019 Robin Gareus <robin@gareus.org> 23 * 24 * This program is free software: you can redistribute it and/or modify 25 * it under the terms of the GNU General Public License as published by 26 * the Free Software Foundation, either version 2 of the License, or 27 * (at your option) any later version. 28 * 29 * This program is distributed in the hope that it will be useful, 30 * but WITHOUT ANY WARRANTY; without even the implied warranty of 31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 32 * GNU General Public License for more details. 33 * 34 * You should have received a copy of the GNU General Public License 35 * along with this program. If not, see <https://www.gnu.org/licenses/>. 36 */ 37 38 /** 39 * \file 40 * 41 * Routing graph. 42 */ 43 44 #ifndef __AUDIO_GRAPH_H__ 45 #define __AUDIO_GRAPH_H__ 46 47 #include <pthread.h> 48 49 #include "audio/graph_node.h" 50 #include "utils/types.h" 51 52 #include "zix/sem.h" 53 54 typedef struct GraphNode GraphNode; 55 typedef struct Graph Graph; 56 typedef struct MPMCQueue MPMCQueue; 57 typedef struct Port Port; 58 typedef struct Fader Fader; 59 typedef struct Track Track; 60 typedef struct SampleProcessor SampleProcessor; 61 typedef struct Plugin Plugin; 62 typedef struct Position Position; 63 typedef struct GraphThread GraphThread; 64 typedef struct Router Router; 65 typedef struct ModulatorMacroProcessor 66 ModulatorMacroProcessor; 67 68 /** 69 * @addtogroup audio 70 * 71 * @{ 72 */ 73 74 #define mpmc_queue_push_back_node(q,x) \ 75 mpmc_queue_push_back (q, (void *) x) 76 77 #define mpmc_queue_dequeue_node(q,x) \ 78 mpmc_queue_dequeue (q, (void *) x) 79 80 #define MAX_GRAPH_THREADS 128 81 82 /** 83 * Graph. 84 */ 85 typedef struct Graph 86 { 87 /** Pointer back to router for convenience. */ 88 Router * router; 89 90 /** Flag to indicate if graph is currently getting 91 * destroyed. */ 92 int destroying; 93 94 /** List of all graph nodes (only used for memory 95 * management) */ 96 /** key = internal pointer, value = graph node. */ 97 GHashTable * graph_nodes; 98 99 /* --- caches for current graph --- */ 100 GraphNode * bpm_node; 101 GraphNode * beats_per_bar_node; 102 GraphNode * beat_unit_node; 103 104 /** Nodes without incoming edges. 105 * These run concurrently at the start of each 106 * cycle to kick off processing */ 107 GraphNode ** init_trigger_list; 108 size_t n_init_triggers; 109 110 /* Terminal node reference count. */ 111 /** Number of graph nodes without an outgoing 112 * edge. */ 113 gint n_terminal_nodes; 114 GraphNode ** terminal_nodes; 115 116 /** Remaining unprocessed terminal nodes in this 117 * cycle. */ 118 volatile gint terminal_refcnt; 119 120 /** Synchronization with main process callback. */ 121 ZixSem callback_start; 122 ZixSem callback_done; 123 124 /** Wake up graph node process threads. */ 125 ZixSem trigger; 126 127 /** Queue containing nodes that can be 128 * processed. */ 129 MPMCQueue * trigger_queue; 130 131 /** Number of entries in trigger queue. */ 132 volatile guint trigger_queue_size; 133 134 /** flag to exit, terminate all process-threads */ 135 volatile gint terminate; 136 137 /** Number of threads waiting for work. */ 138 volatile guint idle_thread_cnt; 139 140 /** Chain used to setup in the background. 141 * This is applied and cleared by graph_rechain() 142 */ 143 /** key = internal pointer, value = graph node. */ 144 GHashTable * setup_graph_nodes; 145 146 GraphNode ** setup_init_trigger_list; 147 size_t num_setup_init_triggers; 148 149 /** Used only when constructing the graph so we 150 * can traverse the graph backwards to calculate 151 * the playback latencies. */ 152 GraphNode ** setup_terminal_nodes; 153 size_t num_setup_terminal_nodes; 154 155 /** Dummy member to make lookups work. */ 156 int initial_processor; 157 158 /* ------------------------------------ */ 159 160 GraphThread * threads[MAX_GRAPH_THREADS]; 161 GraphThread * main_thread; 162 gint num_threads; 163 164 /** 165 * An array of pointers to ports that are exposed 166 * to the backend and are outputs. 167 * 168 * Used to clear their buffers when returning 169 * early from the processing cycle. 170 */ 171 GPtrArray * external_out_ports; 172 173 } Graph; 174 175 void 176 graph_print ( 177 Graph * graph); 178 179 void 180 graph_destroy ( 181 Graph * graph); 182 183 GraphNode * 184 graph_find_node_from_port ( 185 const Graph * self, 186 const Port * port); 187 188 GraphNode * 189 graph_find_node_from_plugin ( 190 const Graph * self, 191 const Plugin * pl); 192 193 GraphNode * 194 graph_find_node_from_track ( 195 const Graph * self, 196 const Track * track, 197 bool use_setup_nodes); 198 199 GraphNode * 200 graph_find_node_from_fader ( 201 const Graph * self, 202 const Fader * fader); 203 204 GraphNode * 205 graph_find_node_from_prefader ( 206 const Graph * self, 207 const Fader * prefader); 208 209 GraphNode * 210 graph_find_node_from_sample_processor ( 211 const Graph * self, 212 const SampleProcessor * sample_processor); 213 214 GraphNode * 215 graph_find_node_from_monitor_fader ( 216 const Graph * self, 217 const Fader * fader); 218 219 GraphNode * 220 graph_find_node_from_modulator_macro_processor ( 221 const Graph * self, 222 const ModulatorMacroProcessor * processor); 223 224 GraphNode * 225 graph_find_node_from_channel_send ( 226 const Graph * self, 227 const ChannelSend * send); 228 229 GraphNode * 230 graph_find_initial_processor_node ( 231 const Graph * self); 232 233 GraphNode * 234 graph_find_hw_processor_node ( 235 const Graph * self, 236 const HardwareProcessor * processor); 237 238 /** 239 * Creates a new node, adds it to the graph and 240 * returns it. 241 */ 242 NONNULL 243 GraphNode * 244 graph_create_node ( 245 Graph * self, 246 GraphNodeType type, 247 void * data); 248 249 /** 250 * Returns the max playback latency of the trigger 251 * nodes. 252 */ 253 nframes_t 254 graph_get_max_route_playback_latency ( 255 Graph * graph, 256 bool use_setup_nodes); 257 258 /* called from a terminal node (from the Graph 259 * worked-thread) to indicate it has completed 260 * processing. 261 * 262 * The thread of the last terminal node that 263 * reaches here will inform the main-thread, wait, 264 * and kick off the next process cycle. 265 */ 266 HOT 267 void 268 graph_on_reached_terminal_node ( 269 Graph * self); 270 271 void 272 graph_update_latencies ( 273 Graph * self, 274 bool use_setup_nodes); 275 276 /* 277 * Adds the graph nodes and connections, then 278 * rechains. 279 * 280 * @param drop_unnecessary_ports Drops any ports 281 * that don't connect anywhere. 282 * @param rechain Whether to rechain or not. If 283 * we are just validating this should be 0. 284 */ 285 void 286 graph_setup ( 287 Graph * self, 288 const int drop_unnecessary_ports, 289 const int rechain); 290 291 /** 292 * Adds a new connection for the given 293 * src and dest ports and validates the graph. 294 * 295 * This is a low level function. Better used via 296 * ports_can_be_connected(). 297 * 298 * @note The graph should be created before this 299 * call with graph_new() and free'd after this 300 * call with graph_free(). 301 * 302 * @return True if ok, false if invalid. 303 */ 304 bool 305 graph_validate_with_connection ( 306 Graph * self, 307 const Port * src, 308 const Port * dest); 309 310 /** 311 * Starts as many threads as there are cores. 312 * 313 * @return 1 if graph started, 0 otherwise. 314 */ 315 int 316 graph_start ( 317 Graph * graph); 318 319 /** 320 * Returns a new graph. 321 */ 322 Graph * 323 graph_new ( 324 Router * router); 325 326 /** 327 * Tell all threads to terminate. 328 */ 329 void 330 graph_terminate ( 331 Graph * self); 332 333 /** 334 * Frees the graph and its members. 335 */ 336 void 337 graph_free ( 338 Graph * self); 339 340 /** 341 * @} 342 */ 343 344 #endif 345