5 #include "utilities/aligned/vector.h" 6 #include "utilities/mapping_iterator_adapter.h" 14 constexpr
auto time(
const T& t) {
19 constexpr
auto volume(
const T& t) {
30 constexpr
auto make_item_with_time(T item,
double time) {
36 return volume(t.item);
40 double speed_of_sound;
43 auto operator()(
const T& i)
const {
44 return make_item_with_time(i, i.distance / speed_of_sound);
50 constexpr
auto operator()(
const T& t)
const {
55 template <
typename T,
typename Alloc>
56 void resize_if_necessary(std::vector<T, Alloc>& t,
size_t new_size) {
57 if (t.size() < new_size) {
62 template <
typename Ret,
typename It,
typename T>
63 void incremental_histogram(
64 Ret& ret, It b, It e,
double sample_rate,
const T& callback) {
65 if (std::distance(b, e)) {
66 const auto make_time_iterator = [](
auto it) {
67 return util::make_mapping_iterator_adapter(std::move(it),
70 const auto max_time_in_input =
71 *std::max_element(make_time_iterator(b), make_time_iterator(e));
73 resize_if_necessary(ret,
74 std::floor(max_time_in_input * sample_rate) + 1);
77 callback(*b, sample_rate, ret);
82 template <
typename It,
typename T>
83 auto histogram(It b, It e,
double sample_rate,
const T& callback) {
84 using value_type = decltype(volume(*b));
85 util::aligned::vector<value_type> ret{};
86 incremental_histogram(ret, b, e, sample_rate, callback);
90 template <
typename T,
typename U,
typename Alloc>
91 void dirac_sum(
const T& item,
double sample_rate, std::vector<U, Alloc>& ret) {
92 ret[time(item) * sample_rate] += volume(item);
96 template <
typename T,
typename Ret>
97 void operator()(
const T& item,
double sample_rate, Ret& ret)
const {
98 dirac_sum(item, sample_rate, ret);
104 template <
typename T,
typename Ret>
105 void operator()(
const T& item,
double sample_rate, Ret& ret)
const {
106 constexpr
auto width = 400;
108 const auto item_time = time(item);
109 const auto centre_sample = item_time * sample_rate;
111 const ptrdiff_t ideal_begin = std::floor(centre_sample - width / 2);
112 const ptrdiff_t ideal_end = std::ceil(centre_sample + width / 2);
113 ret.resize(std::max(ret.size(),
static_cast<size_t>(ideal_end)));
115 const auto begin_samp =
116 std::max(static_cast<ptrdiff_t>(0), ideal_begin);
117 const auto end_samp =
118 std::min(static_cast<ptrdiff_t>(ret.size()), ideal_end);
120 for (
auto it = ret.begin() + begin_samp,
121 end_it = ret.begin() + end_samp;
124 const auto this_sample = std::distance(ret.begin(), it);
125 const auto relative_sample = this_sample - centre_sample;
126 const auto envelope =
127 0.5 * (1 + std::cos(2 * M_PI * relative_sample / width));
128 const auto filt = core::sinc(relative_sample);
129 *it += volume(item) * envelope * filt;
138 template <
typename T>
139 auto make_histogram_iterator(T t,
double speed_of_sound) {
140 if (speed_of_sound < 300 || 400 <= speed_of_sound) {
141 throw std::runtime_error{
"Speed_of_sound outside expected range."};
143 return util::make_mapping_iterator_adapter(
Definition: histogram.h:39
See fu2015 2.2.2 'Discrete form of the impulse response'.
Definition: histogram.h:103
Definition: histogram.h:95
Definition: histogram.h:24
Definition: pressure.h:22
Definition: capsule_base.h:9
Definition: histogram.h:48