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.
46class GraphManager {
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 last processed buffer containing the reverb data for the room.
231 // The buffer contains stereo data.
232 // Note that, this method will *not* trigger the processing of the audio
233 // graph. |GraphManager::Process| must be called prior to this method call to
234 // ensure that the buffer is up-to-date.
235 //
236 // @return Room reverb audio buffer, or nullptr if no output.
237 const AudioBuffer* GetReverbBuffer() const;
238
239 // Returns the maximum allowed number of ambisonic channels.
240 //
241 // @return Number of channels based on Ambisonic order in the global config.
242 size_t GetNumMaxAmbisonicChannels() const;
243
244 // Returns whether the room effects graph is enabled.
245 //
246 // @return True if room effects are enabled.
247 bool GetRoomEffectsEnabled() const;
248
249 // Updates the room reflections with the current properties for room effects
250 // processing.
251 void UpdateRoomReflections();
252
253 // Updates the room reverb.
254 void UpdateRoomReverb();
255
256 private:
257 // Initializes the Ambisonic renderer subgraph for the speficied Ambisonic
258 // order and connects it to the |StereoMixerNode|.
259 //
260 // Processing graph:
261 //
262 // +------------------+
263 // | |
264 // | AmbisonicMixer |
265 // | |
266 // +--------+---------+
267 // |
268 // |
269 // +------------v-------------+
270 // | |
271 // | AmbisonicBinauralDecoder |
272 // | |
273 // +------------+-------------+
274 // |
275 // |
276 // +-----------v------------+
277 // | |
278 // | StereoMixer |
279 // | |
280 // +------------------------+
281 //
282 // @param ambisonic_order Ambisonic order.
283 // @param sh_hrir_filename Filename to load the HRIR data from.
284 void InitializeAmbisonicRendererGraph(int ambisonic_order,
285 const std::string& sh_hrir_filename);
286
287 // Helper method to lookup a source node with given |source_id|.
288 //
289 // @param source_id Source id.
290 // @returns Shared pointer to source node instance, nullptr if not found.
291 std::shared_ptr<BufferedSourceNode> LookupSourceNode(SourceId source_id);
292
293 // Creates an audio subgraph that renders early reflections based on a room
294 // model on a single mix.
295 //
296 // Processing graph:
297 //
298 // +---------------------------+
299 // | |
300 // | ReflectionsGainMixer |
301 // | |
302 // +-------------+-------------+
303 // |
304 // +----------v----------+
305 // | |
306 // | Reflections |
307 // | |
308 // +----------+----------+
309 // |
310 // +----------v----------+
311 // | |
312 // | AmbisonicMixer |
313 // | |
314 // +----------+----------+
315 //
316 void InitializeReflectionsGraph();
317
318 // Creates an audio subgraph that renders a reverb from a mono mix of all the
319 // sound objects based on a room model.
320 //
321 // Processing graph:
322 //
323 // +-----------------+
324 // | |
325 // | ReverbGainMixer |
326 // | |
327 // +--------+--------+
328 // |
329 // +--------v--------+
330 // | |
331 // | Reverb |
332 // | |
333 // +--------+--------+
334 // |
335 // +--------v--------+
336 // | |
337 // | StereoMixer |
338 // | |
339 // +-----------------+
340 //
341 void InitializeReverbGraph();
342
343 // Flag indicating if room effects are enabled.
344 bool room_effects_enabled_;
345
346 // Mono mixer to accumulate all reverb sources.
347 std::shared_ptr<GainMixerNode> reverb_gain_mixer_node_;
348
349 // Reflections node.
350 std::shared_ptr<ReflectionsNode> reflections_node_;
351
352 // Mono mixer node to accumulate the early reflection sources.
353 std::shared_ptr<GainMixerNode> reflections_gain_mixer_node_;
354
355 // Reverb node.
356 std::shared_ptr<ReverbNode> reverb_node_;
357
358 // Ambisonic output mixer to accumulate incoming ambisonic inputs into a
359 // single ambisonic output buffer.
360 std::unique_ptr<Mixer> ambisonic_output_mixer_;
361
362 // Global config passed in during construction.
363 const GraphManagerConfig config_;
364
365 // Manages system wide settings.
366 const SystemSettings& system_settings_;
367
368 // Provides Ambisonic encoding coefficients.
369 std::unique_ptr<AmbisonicLookupTable> lookup_table_;
370
371 // |FftManager| to be used in nodes that require FFT transformations.
372 FftManager fft_manager_;
373
374 // |Resampler| to be used to convert HRIRs to the system sample rate.
375 Resampler resampler_;
376
377 // Ambisonic mixer nodes per each ambisonic order to accumulate the
378 // ambisonic sources for the corresponding binaural Ambisonic decoders.
379 std::unordered_map<int, std::shared_ptr<MixerNode>> ambisonic_mixer_nodes_;
380
381 // Stereo mixer to combine all the stereo and binaural output.
382 std::shared_ptr<MixerNode> stereo_mixer_node_;
383
384 // Ambisonic mixing encoder node to apply encoding coefficients and accumulate
385 // the Ambisonic buffers.
386 std::unordered_map<int, std::shared_ptr<AmbisonicMixingEncoderNode>>
387 ambisonic_mixing_encoder_nodes_;
388
389 // Stereo mixing panner node to apply stereo panning gains and accumulate the
390 // buffers.
391 std::shared_ptr<StereoMixingPannerNode> stereo_mixing_panner_node_;
392
393 // Output node that enables audio playback of a single audio stream.
394 std::shared_ptr<SinkNode> output_node_;
395
396 // Holds all registered source nodes (independently of their type) and
397 // allows look up by id.
398 std::unordered_map<SourceId, std::shared_ptr<BufferedSourceNode>>
399 source_nodes_;
400};
401
402} // namespace vraudio
403
404#endif // RESONANCE_AUDIO_GRAPH_GRAPH_MANAGER_H_
405

source code of qtmultimedia/src/3rdparty/resonance-audio/resonance_audio/graph/graph_manager.h