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#include "graph/reflections_node.h"
18
19#include "base/constants_and_types.h"
20#include "base/logging.h"
21#include "base/misc_math.h"
22
23
24namespace vraudio {
25
26ReflectionsNode::ReflectionsNode(const SystemSettings& system_settings)
27 : system_settings_(system_settings),
28 reflections_processor_(system_settings_.GetSampleRateHz(),
29 system_settings_.GetFramesPerBuffer()),
30 num_frames_processed_on_empty_input_(
31 system_settings_.GetFramesPerBuffer()),
32 output_buffer_(kNumFirstOrderAmbisonicChannels,
33 system_settings_.GetFramesPerBuffer()),
34 silence_mono_buffer_(kNumMonoChannels,
35 system_settings_.GetFramesPerBuffer()) {
36 silence_mono_buffer_.Clear();
37 EnableProcessOnEmptyInput(enable: true);
38}
39
40void ReflectionsNode::Update() {
41
42 const auto& current_reflection_properties = reflection_properties_;
43 const auto& new_reflection_properties =
44 system_settings_.GetReflectionProperties();
45 const bool room_position_changed =
46 !EqualSafe(lhs_begin: std::begin(arr: current_reflection_properties.room_position),
47 lhs_end: std::end(arr: current_reflection_properties.room_position),
48 rhs_begin: std::begin(arr: new_reflection_properties.room_position),
49 rhs_end: std::end(arr: new_reflection_properties.room_position));
50 const bool room_rotation_changed =
51 !EqualSafe(lhs_begin: std::begin(arr: current_reflection_properties.room_rotation),
52 lhs_end: std::end(arr: current_reflection_properties.room_rotation),
53 rhs_begin: std::begin(arr: new_reflection_properties.room_rotation),
54 rhs_end: std::end(arr: new_reflection_properties.room_rotation));
55 const bool room_dimensions_changed =
56 !EqualSafe(lhs_begin: std::begin(arr: current_reflection_properties.room_dimensions),
57 lhs_end: std::end(arr: current_reflection_properties.room_dimensions),
58 rhs_begin: std::begin(arr: new_reflection_properties.room_dimensions),
59 rhs_end: std::end(arr: new_reflection_properties.room_dimensions));
60 const bool cutoff_frequency_changed =
61 current_reflection_properties.cutoff_frequency !=
62 new_reflection_properties.cutoff_frequency;
63 const bool coefficients_changed =
64 !EqualSafe(lhs_begin: std::begin(arr: current_reflection_properties.coefficients),
65 lhs_end: std::end(arr: current_reflection_properties.coefficients),
66 rhs_begin: std::begin(arr: new_reflection_properties.coefficients),
67 rhs_end: std::end(arr: new_reflection_properties.coefficients));
68 const auto& current_listener_position = listener_position_;
69 const auto& new_listener_position = system_settings_.GetHeadPosition();
70 const bool listener_position_changed =
71 current_listener_position != new_listener_position;
72 if (room_position_changed || room_rotation_changed ||
73 room_dimensions_changed || cutoff_frequency_changed ||
74 coefficients_changed || listener_position_changed) {
75 // Update reflections processor if necessary.
76 reflection_properties_ = new_reflection_properties;
77 listener_position_ = new_listener_position;
78 reflections_processor_.Update(reflection_properties: reflection_properties_, listener_position: listener_position_);
79 }
80}
81
82const AudioBuffer* ReflectionsNode::AudioProcess(const NodeInput& input) {
83
84 const AudioBuffer* input_buffer = input.GetSingleInput();
85 const size_t num_frames = system_settings_.GetFramesPerBuffer();
86 if (input_buffer == nullptr) {
87 // If we have no input, generate a silent input buffer until the node states
88 // are cleared.
89 if (num_frames_processed_on_empty_input_ <
90 reflections_processor_.num_frames_to_process_on_empty_input()) {
91 num_frames_processed_on_empty_input_ += num_frames;
92 input_buffer = &silence_mono_buffer_;
93 } else {
94 // Skip processing entirely when the states are fully cleared.
95 return nullptr;
96 }
97 } else {
98 num_frames_processed_on_empty_input_ = 0;
99 DCHECK_EQ(input_buffer->num_channels(), kNumMonoChannels);
100 }
101 output_buffer_.Clear();
102 reflections_processor_.Process(input: *input_buffer, output: &output_buffer_);
103
104 // Rotate the reflections with respect to listener's orientation.
105 const WorldRotation inverse_head_rotation =
106 system_settings_.GetHeadRotation().conjugate();
107 foa_rotator_.Process(target_rotation: inverse_head_rotation, input: output_buffer_, output: &output_buffer_);
108
109 // Copy buffer parameters.
110 return &output_buffer_;
111}
112
113} // namespace vraudio
114

source code of qtmultimedia/src/3rdparty/resonance-audio/resonance_audio/graph/reflections_node.cc