Wayverb
schroeder.h
1 #pragma once
2 
3 #include "core/linear_regression.h"
4 
5 #include "utilities/aligned/vector.h"
6 #include "utilities/decibels.h"
7 #include "utilities/map_to_vector.h"
8 #include "utilities/string_builder.h"
9 
10 #include "glm/glm.hpp"
11 
12 #include <cmath>
13 
14 namespace wayverb {
15 namespace core {
16 
17 template <typename It>
18 auto squared_integrated(It begin, It end) {
19  using numeric = std::decay_t<decltype(*begin)>;
20  util::aligned::vector<numeric> ret;
21  numeric running_total{};
22  for (; begin != end; ++begin) {
23  using std::pow;
24  running_total += *begin * *begin;
25  ret.emplace_back(running_total);
26  }
27  return ret;
28 }
29 
30 struct reverb_time final {
33  double samples;
34 
38  double r;
39 };
40 
42 template <typename It>
43 reverb_time decay_time_from_points(
44  It begin, It end, float begin_db, float end_db, float min_db) {
45  const auto integrated = squared_integrated(
46  std::make_reverse_iterator(end), std::make_reverse_iterator(begin));
47 
48  size_t time{0};
49  const auto in_db_with_times = util::map_to_vector(
50  integrated.crbegin(), integrated.crend(), [&](auto i) {
51  return glm::vec2{time++,
52  util::decibels::p2db(i / integrated.back())};
53  });
54 
55  const auto comparator = [](auto i, auto j) { return i.y < j; };
56  const auto regression_end = std::lower_bound(in_db_with_times.crbegin(),
57  in_db_with_times.crend(),
58  begin_db,
59  comparator);
60  const auto regression_begin = std::lower_bound(in_db_with_times.crbegin(),
61  in_db_with_times.crend(),
62  end_db,
63  comparator);
64 
65  const auto regression =
66  simple_linear_regression(regression_begin, regression_end);
67 
68  // Find time between desired points on regression line.
69  const auto find_time = [&](auto level) {
70  return (level - regression.c) / regression.m;
71  };
72 
73  return {find_time(min_db), regression.r};
74 }
75 
76 template <typename It>
77 reverb_time rt20(It begin, It end) {
78  return decay_time_from_points(begin, end, -5, -25, -60);
79 }
80 
81 template <typename It>
82 reverb_time rt30(It begin, It end) {
83  return decay_time_from_points(begin, end, -5, -35, -60);
84 }
85 
86 template <typename It>
87 reverb_time edt(It begin, It end) {
88  return decay_time_from_points(begin, end, 0, -10, -60);
89 }
90 
91 } // namespace core
92 } // namespace wayverb
double samples
Definition: schroeder.h:33
Definition: traits.cpp:2
double r
Definition: schroeder.h:38
Definition: capsule_base.h:9
Definition: schroeder.h:30