Wayverb
waveguide.h
1 #pragma once
2 
3 #include "compensation_signal/compile_time.h"
4 
5 #include "core/cl/common.h"
6 #include "core/program_wrapper.h"
7 
8 #include "utilities/aligned/vector.h"
9 
10 #include <array>
11 
12 namespace wayverb {
13 namespace waveguide {
14 
16 public:
18  const core::compute_context& cc);
19 
20  auto get_compressed_waveguide_kernel() const {
21  return program_wrapper_.get_kernel<cl::Buffer, cl::Buffer>(
22  "compressed_waveguide");
23  }
24 
25  auto get_zero_buffer_kernel() const {
26  return program_wrapper_.get_kernel<cl::Buffer>("zero_buffer");
27  }
28 
29  template <cl_program_info T>
30  auto get_info() const {
31  return program_wrapper_.get_info<T>();
32  }
33 
34  cl::Device get_device() const { return program_wrapper_.get_device(); }
35 
36 private:
37  core::program_wrapper program_wrapper_;
38 };
39 
41 
43 public:
44  using compressed_waveguide_kernel =
45  decltype(std::declval<compressed_rectangular_waveguide_program>()
46  .get_compressed_waveguide_kernel());
47  using zero_buffer_kernel =
48  decltype(std::declval<compressed_rectangular_waveguide_program>()
49  .get_zero_buffer_kernel());
50 
52  size_t steps);
53 
54  template <typename It, typename T>
55  util::aligned::vector<float> run_hard_source(It begin,
56  It end,
57  const T& per_step) {
58  return run(begin,
59  end,
60  [](auto& queue, auto& buffer, float input) {
61  core::write_value(queue, buffer, 0, input);
62  },
63  per_step);
64  }
65 
66  template <typename It, typename T>
67  util::aligned::vector<float> run_soft_source(It begin,
68  It end,
69  const T& per_step) {
70  return run(begin,
71  end,
72  [](auto& queue, auto& buffer, float input) {
73  const auto c =
74  core::read_value<cl_float>(queue, buffer, 0);
75  core::write_value(queue, buffer, 0, c + input);
76  },
77  per_step);
78  }
79 
80 private:
81  template <typename It, typename T, typename U>
82  util::aligned::vector<float> run(It begin,
83  It end,
84  const T& writer,
85  const U& per_step) {
86  // init buffers
87  const auto buffer_size = tetrahedron(dimension_);
88  zero_buffer_kernel_(
89  cl::EnqueueArgs{queue_,
90  cl::NDRange{previous_.getInfo<CL_MEM_SIZE>() /
91  sizeof(cl_float)}},
92  previous_);
93  zero_buffer_kernel_(
94  cl::EnqueueArgs{queue_,
95  cl::NDRange{current_.getInfo<CL_MEM_SIZE>() /
96  sizeof(cl_float)}},
97  current_);
98 
99  util::aligned::vector<float> ret{};
100  ret.reserve(std::distance(begin, end));
101 
102  for (auto count = 0ul; count != dimension_ * 2; ++count) {
103  writer(queue_, current_, begin == end ? 0.0f : *begin++);
104 
105  // run the kernel
106  compressed_waveguide_kernel_(
107  cl::EnqueueArgs{queue_, cl::NDRange{buffer_size}},
108  previous_,
109  current_);
110 
111  // ping-pong the buffers
112  using std::swap;
113  swap(previous_, current_);
114 
115  // get output value
116  ret.emplace_back(core::read_value<cl_float>(queue_, current_, 0));
117 
118  per_step(count);
119  }
120 
121  return ret;
122  }
123 
124  cl::CommandQueue queue_;
125  compressed_waveguide_kernel compressed_waveguide_kernel_;
126  zero_buffer_kernel zero_buffer_kernel_;
127  size_t dimension_;
128 
129  cl::Buffer current_;
130  cl::Buffer previous_;
131 };
132 
133 } // namespace waveguide
134 } // namespace wayverb
Definition: program_wrapper.h:8
Definition: capsule_base.h:9
invariant: device is a valid device for the context
Definition: common.h:13