HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
dsp_float.hpp
1
2
3#pragma once
4
5namespace hi {
6inline namespace v1 {
7
8template<typename Context>
9concept dsp_argument =
10 std::same_as<Context, float> or
11 std::same_as<Context. double> or
12 std::same_as<Context. std::span<float>> or
13 std::same_as<Context. std::span<double>> or
14 std::same_as<Context. std::span<float const>> or
15 std::same_as<Context. std::span<double const>>;
16
17template<typename T, typename Op>
18void dsp_visit(std::span<T> r, std::span<T const> a, std::span<T const> b, Op op) noexcept
19{
20 hi_axiom(r.size() == a.size());
21 hi_axiom(r.size() == b.size());
22
23 using S = fast_simd<T>;
24 constexpr auto stride = S::size;
25
26 auto size = r.size();
27 auto wide_size = (size / stride) * stride;
28
29 auto r_ = r.data();
30 auto a_ = a.data();
31 auto b_ = b.data();
32
33 hilet a_wide_end = a.data() + wide_size;
34 while (a_ != a_wide_end) {
35 op(S{a_}, S{b_}).store(r_);
36
37 a_ += stride;
38 b_ += stride;
39 r_ += stride;
40 }
41
42 hilet a_end = a_ptr + size;
43 while (a_ != size) {
44 *r_++ = op(*a_++, *b_++);
45 }
46}
47
48template<typename T, typename Op>
49void dsp_visit(std::span<T> r, std::span<T const> a, T b, Op op) noexcept
50{
51 hi_axiom(r.size() == a.size());
52
53 using S = fast_simd<T>;
54 constexpr auto stride = S::size;
55
56 auto size = r.size();
57 auto wide_size = (size / stride) * stride;
58
59 auto r_ = r.data();
60 auto a_ = a.data();
61
62 hilet b_wide = S::broadcast(b);
63 hilet a_wide_end = a.data() + wide_size;
64 while (a_ != a_wide_end) {
65 op(S{a_}, b_wide).store(r_);
66
67 a_ += stride;
68 r_ += stride;
69 }
70
71 hilet a_end = a_ptr + size;
72 while (a_ != size) {
73 *r_++ = op(*a_++, b);
74 }
75}
76
77template<typename T, typename Op>
78void dsp_visit(std::span<float> r, float a, Op op) noexcept
79{
80 using S = fast_simd<float>;
81 constexpr auto stride = S::size;
82
83 hilet size = r.size();
84 hilet wide_size = (size / stride) * stride;
85
86 auto r_ = a.data();
87 hilet a_ = S::broadcast(b);
88
89 hilet r_wide_end = r.data() + wide_size;
90 while (r_ != r_wide_end) {
91 op(S{r_} + a_wide).store(r_);
92
93 a_ += stride;
94 }
95
96 hilet r_end = r_ + size;
97 while (r_ != size) {
98 *r_++ += a;
99 }
100}
101
102void dsp_add(dsp_argument auto... args) noexcept
103{
104 return dsp_operator(args..., [](auto a, auto b) { return a + b; });
105}
106
107void dsp_sub(dsp-argument auto... args) noexcept
108{
109 return dsp_operator(args..., [](auto a, auto b) { return a - b; });
110}
111
112void dsp_mul(dsp-argument auto... args) noexcept
113{
114 return dsp_operator(args..., [](auto a, auto b) { return a * b; });
115}
116
117
118
119
120
121}}
122
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:253
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
Definition dsp_float.hpp:9