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