RavEngine
Loading...
Searching...
No Matches
acoustic_source.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_GEOMETRICAL_ACOUSTICS_ACOUSTIC_SOURCE_H_
18#define RESONANCE_AUDIO_GEOMETRICAL_ACOUSTICS_ACOUSTIC_SOURCE_H_
19
20#include <array>
21#include <functional>
22#include <utility>
23#include <vector>
24
25#include "Eigen/Core"
26#include "base/constants_and_types.h"
27#include "geometrical_acoustics/acoustic_ray.h"
28#include "geometrical_acoustics/sampling.h"
29
30namespace vraudio {
31
32// A class modeling a sound source. Currently we only support point source
33// that emits rays uniformly in all directions.
35 public:
36 // Constructor.
37 //
38 // @param position Source position.
39 // @param energies Source energies. This will be the initial energies for
40 // all frequency bands shared by all rays generated from this source.
41 // @param random_number_generator Random number generator used to sample
42 // ray directions. It should implement operator() that returns a
43 // random value in [0.0, 1.0).
44 AcousticSource(const Eigen::Vector3f& position,
45 const std::array<float, kNumReverbOctaveBands>& energies,
46 std::function<float()> random_number_generator)
47 : position_(position),
48 energies_(energies),
49 random_number_generator_(std::move(random_number_generator)) {}
50
51 // Generates one ray.
52 //
53 // @return AcousticRay starting from this source.
54 AcousticRay GenerateRay() const {
55 const Eigen::Vector3f& direction = UniformSampleSphere(
56 random_number_generator_(), random_number_generator_());
57 return AcousticRay(position_.data(), direction.data(), 0.0f,
58 AcousticRay::kInfinity, energies_,
59 AcousticRay::RayType::kSpecular, 0.0f);
60 }
61
62 // Generates a vector of rays at once, using stratified sampling. The rays
63 // generated this way are more "evenly spaced", with fewer holes and clusters.
64 //
65 // One caveat: only the whole set of the returned rays is uniformly
66 // distributed (the expected number of rays found in a finite solid angle
67 // is the same in any direction), while any subset with fewer than
68 // |num_rays| rays is not.
69 //
70 // In contrast, the GenerateRay() above guarantees any subset is a uniformly
71 // distributed set of rays. This is why the function is designed to return
72 // a vector of rays, which are meant to be used as a whole and not partially.
73 //
74 // @param num_rays Number of rays; must be equal to |sqrt_num_rays|^2.
75 // @param sqrt_num_rays The square root of number of rays to emit.
76 // @return A vector of |sqrt_num_rays|^2 AcousticRays starting from this
77 // source.
78 std::vector<AcousticRay> GenerateStratifiedRays(size_t num_rays,
79 size_t sqrt_num_rays) const {
80 // To save computation time, it is the caller's responsibility to make sure
81 // that |num_rays| is equal to |sqrt_num_rays|^2.
82 DCHECK_EQ(sqrt_num_rays * sqrt_num_rays, num_rays);
83
84 std::vector<AcousticRay> rays;
85 rays.reserve(num_rays);
86 for (size_t ray_index = 0; ray_index < num_rays; ++ray_index) {
87 const Eigen::Vector3f& direction = StratifiedSampleSphere(
88 random_number_generator_(), random_number_generator_(), sqrt_num_rays,
89 ray_index);
90 rays.push_back(AcousticRay(position_.data(), direction.data(),
91 0.0f /* t_near */, AcousticRay::kInfinity,
92 energies_, AcousticRay::RayType::kSpecular,
93 0.0f /* prior_distance */));
94 }
95 return rays;
96 }
97
98 private:
99 // The position of this point source.
100 const Eigen::Vector3f position_;
101
102 // The energy of this source.
103 const std::array<float, kNumReverbOctaveBands> energies_;
104
105 // Randon number generator for sampling ray directions.
106 std::function<float()> random_number_generator_;
107};
108
109} // namespace vraudio
110
111#endif // RESONANCE_AUDIO_GEOMETRICAL_ACOUSTICS_ACOUSTIC_SOURCE_H_
Definition acoustic_source.h:34