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