62 float cosine_interpolation(
float y0,
float y1,
float x) {
63 const auto phase = (1 - std::cos(x * M_PI)) * 0.5;
64 return y0 * (1 - phase) + y1 * phase;
72 template <
size_t num_bands>
75 using cplx = std::complex<real>;
78 using bins = std::array<T, num_bands>;
80 template <
typename T,
typename Func>
81 static constexpr
auto map_bins(
const bins<T>& x, Func func) {
82 using ret_t = decltype(func(x.front()));
87 begin(x), end(x), begin(ret), [&](
auto i) {
return func(i); });
91 static auto absorption_to_reflection_factor(real x) {
92 return std::sqrt(1 - x);
95 static auto absorption_to_reflection_factor(
const bins<real>& x) {
97 x, [](
auto i) {
return absorption_to_reflection_factor(i); });
100 static real compute_phase(real frequency, real time) {
101 return 2 * M_PI * frequency * time;
104 static auto compute_phase(
const bins<real>& per_band_frequencies,
106 return map_bins(per_band_frequencies,
107 [&](
auto i) {
return compute_phase(i, time); });
110 static auto compute_unit_phase_spectrum(
111 const bins<real>& per_band_frequencies, real time) {
112 const auto phases = compute_phase(per_band_frequencies, time);
113 return map_bins(phases, [](
auto i) {
return std::exp(cplx{0, -i}); });
116 template <
size_t output_bins>
117 static std::array<real, output_bins> cosine_smoothing(
118 const bins<real>& per_band_amplitudes,
119 const bins<real>& per_band_frequencies,
121 const auto extend = [](
auto min,
auto arr,
auto max) {
122 std::array<real, num_bands + 2> extended;
123 extended.front() = min;
124 extended.back() = max;
125 std::copy(arr.begin(), arr.end(), extended.begin() + 1);
129 const auto extended_amplitudes = extend(0, per_band_amplitudes, 0);
130 const auto extended_frequencies =
131 extend(0, per_band_frequencies, sample_rate / 2);
133 std::array<real, output_bins> ret;
135 for (
auto i = 0u; i != ret.size(); ++i) {
136 const auto bin_frequency = (i * sample_rate) / (2 * ret.size());
137 while (extended_frequencies[this_band] < bin_frequency) {
141 const auto lower = extended_frequencies[this_band - 1];
142 const auto upper = extended_frequencies[this_band];
143 const auto x = (bin_frequency - lower) / (upper - lower);
144 ret[i] = cosine_interpolation(extended_amplitudes[this_band - 1],
145 extended_amplitudes[this_band],
152 template <
typename It>
158 real amplitude_adjustment,
160 const bins<real>& per_band_frequencies) {
162 const auto time = distance / speed_of_sound;
164 auto spectrum = compute_unit_phase_spectrum(per_band_frequencies, time);
167 const auto amplitude = amplitude_adjustment / distance;
168 for (
auto& i : spectrum) {
174 for (; begin != end; ++begin) {
Definition: pressure.h:22
static auto compute_pressure_spectrum(It begin, It end, real distance, real speed_of_sound, real amplitude_adjustment, const bins< real > &per_band_frequencies)
iterator over absorption coefficients
Definition: pressure.h:153
Definition: pressure.h:73