summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/resonance-audio/resonance_audio/geometrical_acoustics/proxy_room_estimator.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/resonance-audio/resonance_audio/geometrical_acoustics/proxy_room_estimator.h')
-rw-r--r--src/3rdparty/resonance-audio/resonance_audio/geometrical_acoustics/proxy_room_estimator.h156
1 files changed, 156 insertions, 0 deletions
diff --git a/src/3rdparty/resonance-audio/resonance_audio/geometrical_acoustics/proxy_room_estimator.h b/src/3rdparty/resonance-audio/resonance_audio/geometrical_acoustics/proxy_room_estimator.h
new file mode 100644
index 000000000..63aa58998
--- /dev/null
+++ b/src/3rdparty/resonance-audio/resonance_audio/geometrical_acoustics/proxy_room_estimator.h
@@ -0,0 +1,156 @@
+/*
+Copyright 2018 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS-IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#ifndef RESONANCE_AUDIO_GEOMETRICAL_ACOUSTICS_PROXY_ROOM_ESTIMATOR_H_
+#define RESONANCE_AUDIO_GEOMETRICAL_ACOUSTICS_PROXY_ROOM_ESTIMATOR_H_
+
+#include <array>
+#include <utility>
+#include <vector>
+
+#include "Eigen/Core"
+#include "api/resonance_audio_api.h"
+#include "base/constants_and_types.h"
+#include "base/misc_math.h"
+#include "geometrical_acoustics/path.h"
+#include "platforms/common/room_properties.h"
+
+namespace vraudio {
+
+// A class that estimates a "proxy room" from traced sound propagation paths.
+// A proxy room is used to model dynamic early reflections as if they are
+// reflected from a box-shaped room, even though the real scene geometry is
+// arbitrarily complex. This is to complement the pre-computed late reverb
+// effects, and it takes the same input (i.e., the ray tracing results) as the
+// reverb pre-computation. The proxy room is estimated from the first order
+// ray paths (i.e., those from the source to the first hit points), and the
+// estimation has two stages:
+// 1. Fitting the geometry (currently only as an axis-aligned cube).
+// 2. Fitting the surface materials on the six walls.
+class ProxyRoomEstimator {
+ public:
+ ProxyRoomEstimator() = default;
+
+ // ProxyRoomEstimator is neither copyable nor movable.
+ ProxyRoomEstimator(const ProxyRoomEstimator&) = delete;
+ ProxyRoomEstimator& operator=(const ProxyRoomEstimator&) = delete;
+
+ // Collects hit point data from traced ray paths, batch-by-batch.
+ //
+ // @param paths_batch A batch of ray paths.
+ void CollectHitPointData(const std::vector<Path>& paths_batch);
+
+ // Estimates a cube-shaped proxy room from collected hit points. Hit points
+ // are sorted according to their traveled distance. In order to make the
+ // estimation more robust, we discard "outlier" hit points, i.e., those whose
+ // traveled distances are too large or too small.
+ //
+ // @param outlier_portion What portion of the hit points are considered as
+ // outliers. For example, a value of 0.1 means that the hit points whose
+ // distances are in the top 10% and bottom 10% are considered as outliers
+ // and discarded. The value must be in the range of [0, 0.5].
+ // @param room_properties Room properties of the estimated axis-aligned cube-
+ // shaped room, each wall having an estimated surface material.
+ // @return True if the estimation is successful.
+ bool EstimateCubicProxyRoom(float outlier_portion,
+ RoomProperties* room_properties);
+
+ private:
+ class CoefficientsVector : public Eigen::Matrix<float, kNumReverbOctaveBands,
+ 1, Eigen::DontAlign> {
+ public:
+ // Inherits all constructors with 1-or-more arguments. Necessary because
+ // MSVC12 doesn't support inheriting constructors.
+ template <typename Arg1, typename... Args>
+ CoefficientsVector(const Arg1& arg1, Args&&... args)
+ : Matrix(arg1, std::forward<Args>(args)...) {}
+
+ // Constructs a zero vector.
+ CoefficientsVector() { setZero(); }
+ };
+
+ // A struct to contain data necessary for estimating a proxy room.
+ struct HitPointData {
+ // Origin of the ray that creates this hit point.
+ WorldPosition origin;
+
+ // Direction of the ray that creates this hit point.
+ WorldPosition direction;
+
+ // Ray parameter t corresponding to the hit point. If the ray escaped the
+ // scene and did not hit anything, then |t_far| takes the value of
+ // |AcousticRay::kInfinity|. Escaped rays are still useful in estimating
+ // surface materials, because they can be considered completely absorbed
+ // and should increase the effective absorption coefficients.
+ float t_far;
+
+ // Absorption coefficients of the surface of the hit point across the
+ // frequency bands.
+ std::array<float, kNumReverbOctaveBands> absorption_coefficients;
+ };
+
+ // Collects one hit point from one traced ray path.
+ //
+ // @param path Traced ray path.
+ // @return Collected hit point.
+ HitPointData CollectHitPointDataFromPath(const Path& path);
+
+ // Estimates the geometry of the cube.
+ //
+ // @param outlier_portion Portion of all hit points to be discarded. See
+ // EstimateCube() above.
+ // @param position Output center position of the estimated cube.
+ // @param dimensions Output dimensions of the estimated cube.
+ // @return True if the estimation is successful.
+ bool EstimateCubeGeometry(float outlier_portion, float* position,
+ float* dimensions, float* rotation);
+
+ // Groups hit points by which walls they lie on in an assumed axis-aligned
+ // room.
+ //
+ // @param room_position Center position of the assumed axis-aligned room.
+ // @param room_dimensions Dimensions of the assumed axis-aligned room.
+ // @return An array of six elements, each being a vector of hit points
+ // on one of the six walls.
+ std::array<std::vector<HitPointData>, kNumRoomSurfaces> GroupHitPointsByWalls(
+ const WorldPosition& room_position, const WorldPosition& room_dimensions);
+
+ // Compute the hit point positions and distances (measured along the normal
+ // direction of the walls that they hit) from hit points on walls.
+ //
+ // @param hit_points_on_walls Hit points on walls.
+ // @return A vector of {hit point position, distance} pairs.
+ std::vector<std::pair<WorldPosition, float>>
+ ComputeDistancesAndPositionsFromHitPoints(
+ const std::array<std::vector<HitPointData>, kNumRoomSurfaces>&
+ hit_points_on_walls);
+
+ // Estimates the surface materials on the six walls of the proxy room.
+ //
+ // @param room_position Center position of the estimated proxy room.
+ // @param room_dimensions Dimensions of the estimated proxy room.
+ // @param material_names Names of the estimated surface materials.
+ void EstimateSurfaceMaterials(const WorldPosition& room_position,
+ const WorldPosition& room_dimensions,
+ MaterialName* material_names);
+
+ // Collected hit points.
+ std::vector<HitPointData> hit_points_;
+};
+
+} // namespace vraudio
+
+#endif // RESONANCE_AUDIO_GEOMETRICAL_ACOUSTICS_PROXY_ROOM_ESTIMATOR_H_