RavEngine
Loading...
Searching...
No Matches
graph_manager.h
1/*
2Copyright 2018 Google Inc. All Rights Reserved.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS-IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17#ifndef RESONANCE_AUDIO_GRAPH_GRAPH_MANAGER_H_
18#define RESONANCE_AUDIO_GRAPH_GRAPH_MANAGER_H_
19
20#include <memory>
21#include <string>
22#include <unordered_map>
23
24#include "ambisonics/ambisonic_lookup_table.h"
25#include "base/audio_buffer.h"
26#include "base/constants_and_types.h"
27#include "config/global_config.h"
28#include "dsp/fft_manager.h"
29#include "dsp/resampler.h"
30#include "graph/ambisonic_binaural_decoder_node.h"
31#include "graph/ambisonic_mixing_encoder_node.h"
32#include "graph/buffered_source_node.h"
33#include "graph/gain_mixer_node.h"
34#include "graph/mixer_node.h"
35#include "graph/reflections_node.h"
36#include "graph/reverb_node.h"
37#include "graph/stereo_mixing_panner_node.h"
38#include "graph/system_settings.h"
39#include "node/sink_node.h"
40
41namespace vraudio {
42
43// The GraphManager class manages the construction and lifetime of the audio
44// processing graph. It owns the output node that connects the audio processing
45// graph to the audio hardware.
47 public:
48 // Initializes GraphManager class.
49 //
50 // @param system_settings Global system configuration.
51 explicit GraphManager(const SystemSettings& system_settings);
52
53 // Returns the sink node the audio graph is connected to.
54 //
55 // @return Shared pointer of the sink node.
56 std::shared_ptr<SinkNode> GetSinkNode();
57
58 // Triggers processing of the audio graph for all the connected nodes.
59 void Process();
60
61 // Returns a mutable pointer to the |AudioBuffer| of an audio source with
62 // given |source_id|. Calls to this method must be synchronized with the audio
63 // graph processing.
64 //
65 // @param source_id Source id.
66 // @return Mutable audio buffer pointer. Nullptr if source_id not found.
67 AudioBuffer* GetMutableAudioBuffer(SourceId source_id);
68
69 // Creates an ambisonic panner source with given |sound_object_source_id|.
70 //
71 // Processing graph:
72 //
73 // +-------------------+
74 // | |
75 // +------------+ SoundObjectSource +----------+
76 // | | | |
77 // | +---------+---------+ |
78 // | |
79 // +-----------v-----------+ +---------v----------+
80 // | | | |
81 // | AmbisonicMixingPanner | | StereoMixingPanner |
82 // | | | |
83 // +-----------+-----------+ +---------+----------+
84 // | |
85 // +-----------v-----------+ +---------v----------+
86 // | | | |
87 // | AmbisonicMixer | | StereoMixer |
88 // | | | |
89 // +-----------+-----------+ +--------------------+
90 //
91 //
92 // @param sound_object_source_id Id of sound object source.
93 // @param enable_hrtf Flag to enable HRTF-based spatialization.
94 void CreateAmbisonicPannerSource(SourceId sound_object_source_id,
95 bool enable_hrtf);
96
97 // Creates a new stereo non-spatialized source with given |stereo_source_id|.
98 //
99 // Processing graph:
100 //
101 // +--------------+
102 // | |
103 // | StereoSource |
104 // | |
105 // +-------+------+
106 // |
107 // +-------v------+
108 // | |
109 // | Gain |
110 // | |
111 // +-------+------+
112 // |
113 // +-------V------+
114 // | |
115 // | StereoMixer |
116 // | |
117 // +--------------+
118 //
119 // @param stereo_source_id Id of new stereo source.
120 void CreateStereoSource(SourceId stereo_source_id);
121
122 // Destroys source with given |source_id|. Note that this call only sets a
123 // flag to indicate that this source can be removed. The actual disconnect
124 // happens from the audio processing thread the next time the processing graph
125 // is triggered.
126 //
127 // @param source_id Id of source to be destroyed.
128 void DestroySource(SourceId source_id);
129
130 // Creates a new ambisonic source subgraph with given |ambisonic_source_id|.
131 // Note: Ambisonic source subgraph is only created if the rendering mode is
132 // HRTF.
133 //
134 // Processing graph (all the graphs created using http://asciiflow.com/):
135 //
136 // +-----------------+
137 // | |
138 // +-------+ AmbisonicSource +-------+
139 // | | | |
140 // | +-----------------+ |
141 // | |
142 // +----v---+ +----------v---------+
143 // | | | |
144 // | Gain | +--+ MonoFromSoundfield +--+
145 // | | | | | |
146 // +----+---+ | +--------------------+ |
147 // | | |
148 // | | |
149 // +--------v-------+ +--------v---------+ +------v------+
150 // | | | | | |
151 // | Foa/HoaRotator | | ReflectionsMixer | | ReverbMixer |
152 // | | | | | |
153 // +--------+-------+ +--------+---------+ +------+------+
154 // |
155 // +--------v-------+
156 // | |
157 // | AmbisonicMixer |
158 // | |
159 // +--------+-------+
160 //
161 // @param ambisonic_source_id Id of new ambisonic source.
162 // @param num_channels Number of input channels of ambisonic source node.
163 void CreateAmbisonicSource(SourceId ambisonic_source_id, size_t num_channels);
164
165 // Creates a new sound object source with given |sound_object_source_id|.
166 //
167 // Processing graph:
168 //
169 // +-------------------+
170 // | |
171 // +-------------+ SoundObjectSource +----------+
172 // | | | |
173 // | +---------+---------+ |
174 // | | |
175 // +----------v-----------+ +---------v---------+ +--------v--------+
176 // | | | | | |
177 // | ReflectionsGainMixer | | DirectAttenuation | | ReverbGainMixer |
178 // | | | | | |
179 // +----------+-----------+ +---------+---------+ +--------+--------+
180 // |
181 // +---------v---------+
182 // HRTF | | Stereo Panning
183 // +------------+ Occlusion +----------+
184 // | | | |
185 // | +---------+---------+ |
186 // | | |
187 // +-----------v-----------+ +--------v--------+ +---------v----------+
188 // | | | | | |
189 // | AmbisonicMixingPanner | | NearFieldEffect | | StereoMixingPanner |
190 // | | | | | |
191 // +-----------+-----------+ +--------+--------+ +---------+----------+
192 // | | |
193 // +-----------v-----------+ +--------v--------+ |
194 // | | | | |
195 // | AmbisonicMixer | | StereoMixer <-----------+
196 // | | | |
197 // +-----------+-----------+ +-----------------+
198 //
199 //
200 // @param sound_object_source_id Id of sound object source.
201 // @param ambisonic_order Ambisonic order to encode the sound object source.
202 // @param enable_hrtf Flag to enable HRTF-based rendering.
203 // @param enable_direct_rendering Flag to enable direct source rendering.
204 void CreateSoundObjectSource(SourceId sound_object_source_id,
205 int ambisonic_order, bool enable_hrtf,
206 bool enable_direct_rendering);
207
208 // Mutes on/off the room effects mixers.
209 //
210 // @param Whether to enable room effects.
211 void EnableRoomEffects(bool enable);
212
213 // Returns the last processed output audio buffer of the ambisonic mix with
214 // the highest possible ambisonic channel configuration. Note that, this
215 // method will *not* trigger the processing of the audio graph.
216 // |GraphManager::Process| must be called prior to this method call to ensure
217 // that the output buffer is up-to-date.
218 //
219 // @return Output audio buffer of the ambisonic mix, or nullptr if no output.
220 const AudioBuffer* GetAmbisonicBuffer() const;
221
222 // Returns the last processed output audio buffer of the stereo (binaural)
223 // mix. Note that, this method will *not* trigger the processing of the audio
224 // graph. |GraphManager::Process| must be called prior to this method call to
225 // ensure that the output buffer is up-to-date.
226 //
227 // @return Output audio buffer of the stereo mix, or nullptr if no output.
228 const AudioBuffer* GetStereoBuffer() const;
229
230 // Returns the maximum allowed number of ambisonic channels.
231 //
232 // @return Number of channels based on Ambisonic order in the global config.
233 size_t GetNumMaxAmbisonicChannels() const;
234
235 // Returns whether the room effects graph is enabled.
236 //
237 // @return True if room effects are enabled.
238 bool GetRoomEffectsEnabled() const;
239
240 // Updates the room reflections with the current properties for room effects
241 // processing.
242 void UpdateRoomReflections();
243
244 // Updates the room reverb.
245 void UpdateRoomReverb();
246
247 private:
248 // Initializes the Ambisonic renderer subgraph for the speficied Ambisonic
249 // order and connects it to the |StereoMixerNode|.
250 //
251 // Processing graph:
252 //
253 // +------------------+
254 // | |
255 // | AmbisonicMixer |
256 // | |
257 // +--------+---------+
258 // |
259 // |
260 // +------------v-------------+
261 // | |
262 // | AmbisonicBinauralDecoder |
263 // | |
264 // +------------+-------------+
265 // |
266 // |
267 // +-----------v------------+
268 // | |
269 // | StereoMixer |
270 // | |
271 // +------------------------+
272 //
273 // @param ambisonic_order Ambisonic order.
274 // @param sh_hrir_filename Filename to load the HRIR data from.
275 void InitializeAmbisonicRendererGraph(int ambisonic_order,
276 const std::string& sh_hrir_filename);
277
278 // Helper method to lookup a source node with given |source_id|.
279 //
280 // @param source_id Source id.
281 // @returns Shared pointer to source node instance, nullptr if not found.
282 std::shared_ptr<BufferedSourceNode> LookupSourceNode(SourceId source_id);
283
284 // Creates an audio subgraph that renders early reflections based on a room
285 // model on a single mix.
286 //
287 // Processing graph:
288 //
289 // +---------------------------+
290 // | |
291 // | ReflectionsGainMixer |
292 // | |
293 // +-------------+-------------+
294 // |
295 // +----------v----------+
296 // | |
297 // | Reflections |
298 // | |
299 // +----------+----------+
300 // |
301 // +----------v----------+
302 // | |
303 // | AmbisonicMixer |
304 // | |
305 // +----------+----------+
306 //
307 void InitializeReflectionsGraph();
308
309 // Creates an audio subgraph that renders a reverb from a mono mix of all the
310 // sound objects based on a room model.
311 //
312 // Processing graph:
313 //
314 // +-----------------+
315 // | |
316 // | ReverbGainMixer |
317 // | |
318 // +--------+--------+
319 // |
320 // +--------v--------+
321 // | |
322 // | Reverb |
323 // | |
324 // +--------+--------+
325 // |
326 // +--------v--------+
327 // | |
328 // | StereoMixer |
329 // | |
330 // +-----------------+
331 //
332 void InitializeReverbGraph();
333
334 // Flag indicating if room effects are enabled.
335 bool room_effects_enabled_;
336
337 // Mono mixer to accumulate all reverb sources.
338 std::shared_ptr<GainMixerNode> reverb_gain_mixer_node_;
339
340 // Reflections node.
341 std::shared_ptr<ReflectionsNode> reflections_node_;
342
343 // Mono mixer node to accumulate the early reflection sources.
344 std::shared_ptr<GainMixerNode> reflections_gain_mixer_node_;
345
346 // Reverb node.
347 std::shared_ptr<ReverbNode> reverb_node_;
348
349 // Ambisonic output mixer to accumulate incoming ambisonic inputs into a
350 // single ambisonic output buffer.
351 std::unique_ptr<Mixer> ambisonic_output_mixer_;
352
353 // Global config passed in during construction.
354 const GraphManagerConfig config_;
355
356 // Manages system wide settings.
357 const SystemSettings& system_settings_;
358
359 // Provides Ambisonic encoding coefficients.
360 std::unique_ptr<AmbisonicLookupTable> lookup_table_;
361
362 // |FftManager| to be used in nodes that require FFT transformations.
363 FftManager fft_manager_;
364
365 // |Resampler| to be used to convert HRIRs to the system sample rate.
366 Resampler resampler_;
367
368 // Ambisonic mixer nodes per each ambisonic order to accumulate the
369 // ambisonic sources for the corresponding binaural Ambisonic decoders.
370 std::unordered_map<int, std::shared_ptr<MixerNode>> ambisonic_mixer_nodes_;
371
372 // Stereo mixer to combine all the stereo and binaural output.
373 std::shared_ptr<MixerNode> stereo_mixer_node_;
374
375 // Ambisonic mixing encoder node to apply encoding coefficients and accumulate
376 // the Ambisonic buffers.
377 std::unordered_map<int, std::shared_ptr<AmbisonicMixingEncoderNode>>
378 ambisonic_mixing_encoder_nodes_;
379
380 // Stereo mixing panner node to apply stereo panning gains and accumulate the
381 // buffers.
382 std::shared_ptr<StereoMixingPannerNode> stereo_mixing_panner_node_;
383
384 // Output node that enables audio playback of a single audio stream.
385 std::shared_ptr<SinkNode> output_node_;
386
387 // Holds all registered source nodes (independently of their type) and
388 // allows look up by id.
389 std::unordered_map<SourceId, std::shared_ptr<BufferedSourceNode>>
390 source_nodes_;
391};
392
393} // namespace vraudio
394
395#endif // RESONANCE_AUDIO_GRAPH_GRAPH_MANAGER_H_
Definition audio_buffer.h:78
Definition fft_manager.h:28
Definition graph_manager.h:46
Definition resampler.h:25
Definition system_settings.h:30
Definition graph_manager_config.h:27