3 #include "waveguide/bandpass_band.h" 4 #include "waveguide/calibration.h" 5 #include "waveguide/fitted_boundary.h" 6 #include "waveguide/postprocessor/directional_receiver.h" 7 #include "waveguide/preprocessor/hard_source.h" 8 #include "waveguide/simulation_parameters.h" 9 #include "waveguide/waveguide.h" 11 #include "core/callback_accumulator.h" 12 #include "core/environment.h" 13 #include "core/reverb_time.h" 15 #include "hrtf/multiband.h" 29 template <
typename Callback>
30 std::experimental::optional<band> canonical_impl(
31 const core::compute_context& cc,
33 double simulation_time,
34 const glm::vec3& source,
35 const glm::vec3& receiver,
36 const core::environment& environment,
37 const std::atomic_bool& keep_going,
38 Callback&& callback) {
39 const auto sample_rate = compute_sample_rate(mesh.get_descriptor(),
40 environment.speed_of_sound);
42 const auto compute_mesh_index = [&](
const auto& pt) {
43 const auto ret = compute_index(mesh.get_descriptor(), pt);
44 if (!waveguide::is_inside(
45 mesh.get_structure().get_condensed_nodes()[ret])) {
46 throw std::runtime_error{
47 "Source/receiver node position appears to be outside " 53 const auto ideal_steps = std::ceil(sample_rate * simulation_time);
55 const auto input = [&] {
56 auto raw = util::aligned::vector<float>(ideal_steps, 0.0f);
58 raw.front() = rectilinear_calibration_factor(
59 mesh.get_descriptor().spacing,
60 environment.acoustic_impedance);
65 auto output_accumulator =
66 core::callback_accumulator<postprocessor::directional_receiver>{
67 mesh.get_descriptor(),
69 get_ambient_density(environment),
70 compute_mesh_index(receiver)};
75 preprocessor::make_hard_source(
76 compute_mesh_index(source), begin(input), end(input)),
77 [&](
auto& queue,
const auto& buffer,
auto step) {
78 output_accumulator(queue, buffer, step);
79 callback(queue, buffer, step, ideal_steps);
83 if (steps != ideal_steps) {
84 return std::experimental::nullopt;
87 return band{std::move(output_accumulator.get_output()), sample_rate};
100 template <
typename PressureCallback>
101 std::experimental::optional<util::aligned::vector<bandpass_band>> canonical(
102 const core::compute_context& cc,
103 voxels_and_mesh voxelised,
104 const glm::vec3& source,
105 const glm::vec3& receiver,
106 const core::environment& environment,
107 const single_band_parameters& sim_params,
108 double simulation_time,
109 const std::atomic_bool& keep_going,
110 PressureCallback&& pressure_callback) {
111 if (
auto ret = detail::canonical_impl(cc,
118 pressure_callback)) {
119 return util::aligned::vector<bandpass_band>{bandpass_band{
120 std::move(*ret), util::make_range(0.0, sim_params.cutoff)}};
123 return std::experimental::nullopt;
128 inline auto set_flat_coefficients_for_band(voxels_and_mesh& voxels_and_mesh,
130 voxels_and_mesh.mesh.set_coefficients(util::map_to_vector(
131 begin(voxels_and_mesh.voxels.get_scene_data().get_surfaces()),
132 end(voxels_and_mesh.voxels.get_scene_data().get_surfaces()),
133 [&](
const auto& surface) {
134 return to_flat_coefficients(surface.absorption.s[band]);
140 template <
typename PressureCallback>
141 std::experimental::optional<util::aligned::vector<bandpass_band>> canonical(
142 const core::compute_context& cc,
143 voxels_and_mesh voxelised,
144 const glm::vec3& source,
145 const glm::vec3& receiver,
146 const core::environment& environment,
147 const multiple_band_constant_spacing_parameters& sim_params,
148 double simulation_time,
149 const std::atomic_bool& keep_going,
150 PressureCallback&& pressure_callback) {
151 const auto band_params = hrtf_data::hrtf_band_params_hz();
153 util::aligned::vector<bandpass_band> ret{};
156 for (
auto band = 0; band != sim_params.bands; ++band) {
157 set_flat_coefficients_for_band(voxelised, band);
159 if (
auto rendered_band = detail::canonical_impl(cc,
166 pressure_callback)) {
167 ret.emplace_back(bandpass_band{
168 std::move(*rendered_band),
169 util::make_range(band_params.edges[band],
170 band_params.edges[band + 1])});
172 return std::experimental::nullopt;
Definition: capsule_base.h:9