Skip to content

Commit 6277f54

Browse files
committed
Core (Math): Wrap SIMD routines in C++.
1 parent 31e7eaa commit 6277f54

File tree

4 files changed

+229
-114
lines changed

4 files changed

+229
-114
lines changed

libvisual/libvisual/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ SET(libvisual_SOURCES
6262
lv_param_validators.c
6363
lv_cpu.c
6464
lv_error.c
65-
lv_math.c
6665
lv_gl.c
6766
lv_alpha_blend.c
6867
lv_util.c
@@ -76,6 +75,7 @@ SET(libvisual_SOURCES
7675
lv_fourier.cpp
7776
lv_input.cpp
7877
lv_libvisual.cpp
78+
lv_math.cpp
7979
lv_morph.cpp
8080
lv_param.cpp
8181
lv_plugin.cpp

libvisual/libvisual/lv_math.c

Lines changed: 0 additions & 109 deletions
This file was deleted.

libvisual/libvisual/lv_math.cpp

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
/* Libvisual - The audio visualisation framework.
2+
*
3+
* Copyright (C) 2012 Libvisual team
4+
* 2004-2006 Dennis Smit
5+
*
6+
* Authors: Chong Kai Xiong <[email protected]>
7+
* Dennis Smit <[email protected]>
8+
*
9+
* This program is free software; you can redistribute it and/or modify
10+
* it under the terms of the GNU Lesser General Public License as
11+
* published by the Free Software Foundation; either version 2.1
12+
* of the License, or (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU Lesser General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Lesser General Public License
20+
* along with this program; if not, write to the Free Software
21+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22+
*/
23+
24+
#include "config.h"
25+
#include "lv_math.h"
26+
#include "lv_common.h"
27+
#include "lv_math_orc.h"
28+
#include <algorithm>
29+
#include <cassert>
30+
#include <cmath>
31+
32+
// NOTE: The ORC SIMD routines use uint32_t instead of int32_t for some reason. We are forced
33+
// to perform signed to unsigned casts for routines accepting 32-bit integer vectors.
34+
35+
namespace LV::Math {
36+
37+
void simd_add (std::span<float> dst, std::span<float const> src, float adder)
38+
{
39+
assert (dst.data () != src.data ());
40+
41+
auto count {static_cast<int> (std::min (dst.size (), src.size ()))};
42+
::simd_add_floats_float (dst.data (), src.data (), adder, count);
43+
}
44+
45+
void simd_mul (std::span<float> dst, std::span<float const> src, float k)
46+
{
47+
assert (dst.data () != src.data ());
48+
49+
auto count {static_cast<int> (std::min (dst.size (), src.size ()))};
50+
::simd_mul_floats_float (dst.data (), src.data (), k, count);
51+
}
52+
53+
void simd_mul (std::span<float> dst, std::span<float const> src1, std::span<float const> src2)
54+
{
55+
assert (dst.data () != src1.data ());
56+
assert (src1.data () != src2.data ());
57+
58+
auto count {static_cast<int> (std::min (dst.size (), std::min (src1.size (), src2.size ())))};
59+
::simd_mul_floats_floats (dst.data (), src1.data (), src2.data (), count);
60+
}
61+
62+
void simd_convert (std::span<int32_t> ints, std::span<float const> flts)
63+
{
64+
auto count {static_cast<int> (std::min (ints.size (), flts.size ()))};
65+
::simd_floats_to_int32s (reinterpret_cast<std::uint32_t*> (ints.data ()), flts.data (), count);
66+
}
67+
68+
void simd_convert (std::span<float> flts, std::span<std::int32_t const> ints)
69+
{
70+
auto count {static_cast<int> (std::min (flts.size (), ints.size ()))};
71+
::simd_int32s_to_floats (flts.data (), reinterpret_cast<std::uint32_t const*> (ints.data ()), count);
72+
}
73+
74+
void simd_mul (std::span<std::int32_t> ints, std::span<float const> flts, float k)
75+
{
76+
auto count {static_cast<int> (std::min (ints.size (), flts.size ()))};
77+
::simd_floats_to_int32s_mul_float (reinterpret_cast<std::uint32_t*> (ints.data ()), flts.data (), k, count);
78+
}
79+
80+
void simd_mul (std::span<float> flts, std::span<std::int32_t const> ints, float k)
81+
{
82+
auto count {static_cast<int> (std::min (flts.size (), ints.size ()))};
83+
::simd_int32s_to_floats_mul_float (flts.data (), reinterpret_cast<std::uint32_t const*> (ints.data ()), k, count);
84+
}
85+
86+
void simd_convert_denorm (std::span<std::int32_t> ints, std::span<float const> flts, float k)
87+
{
88+
auto count {static_cast<int> (std::min (ints.size (), flts.size ()))};
89+
::simd_denorm_floats_to_int32s (reinterpret_cast<std::uint32_t*> (ints.data ()), flts.data (), k, count);
90+
}
91+
92+
void simd_convert_denorm_neg (std::span<std::int32_t> ints, std::span<float const> flts, float k)
93+
{
94+
auto count {static_cast<int> (std::min (ints.size (), flts.size ()))};
95+
::simd_denorm_neg_floats_to_int32s (reinterpret_cast<std::uint32_t*> (ints.data ()), flts.data (), k, count);
96+
}
97+
98+
void simd_sqrt (std::span<float> dst, std::span<float const> src)
99+
{
100+
assert (dst.data () != src.data ());
101+
102+
auto count {static_cast<int> (std::min (dst.size (), src.size ()))};
103+
::simd_sqrt_floats (dst.data (), src.data (), count);
104+
}
105+
106+
void simd_complex_norm (std::span<float> dst, std::span<float const> real, std::span<float const> imag)
107+
{
108+
assert (real.data () != dst.data ());
109+
assert (real.size () == imag.size ());
110+
111+
auto count {static_cast<int> (std::min (dst.size (), real.size()))};
112+
::simd_complex_norm (dst.data (), real.data (), imag.data (), count);
113+
}
114+
115+
void simd_complex_scaled_norm (std::span<float> dst, std::span<float const> real, std::span<float const> imag, float k)
116+
{
117+
assert (real.data () != dst.data ());
118+
assert (real.data () != imag.data ());
119+
assert (real.size () == imag.size ());
120+
121+
auto size {static_cast<int> (std::min (dst.size (), real.size ()))};
122+
::simd_complex_scaled_norm (dst.data (), real.data (), imag.data (), k, size);
123+
}
124+
125+
} // LV::Math namespace
126+
127+
int visual_math_is_power_of_2 (int n)
128+
{
129+
return (n > 0) && !(n & (n - 1));
130+
}
131+
132+
unsigned int visual_math_round_power_of_2 (unsigned int n)
133+
{
134+
n--;
135+
n |= n >> 1;
136+
n |= n >> 2;
137+
n |= n >> 4;
138+
n |= n >> 8;
139+
n |= n >> 16;
140+
#if SIZEOF_INT > 4
141+
n |= n >> 32;
142+
#endif
143+
n++;
144+
145+
return n;
146+
}
147+
148+
void visual_math_simd_mul_floats_float (float *LV_RESTRICT dest, const float *LV_RESTRICT src, float k, visual_size_t count)
149+
{
150+
simd_mul_floats_float (dest, src, k, (int) count);
151+
}
152+
153+
void visual_math_simd_add_floats_float (float *LV_RESTRICT dest, const float *LV_RESTRICT src, float adder, visual_size_t count)
154+
{
155+
simd_add_floats_float (dest, src, adder, (int) count);
156+
}
157+
158+
void visual_math_simd_mul_floats_floats (float *LV_RESTRICT dest, const float *LV_RESTRICT src1, const float *LV_RESTRICT src2, visual_size_t count)
159+
{
160+
simd_mul_floats_floats (dest, src1, src2, (int) count);
161+
}
162+
163+
void visual_math_simd_floats_to_int32s (int32_t *LV_RESTRICT ints, const float *LV_RESTRICT flts, visual_size_t count)
164+
{
165+
simd_floats_to_int32s ((uint32_t *LV_RESTRICT) ints, flts, (int) count);
166+
}
167+
168+
void visual_math_simd_int32s_to_floats (float *LV_RESTRICT flts, const int32_t *LV_RESTRICT ints, visual_size_t count)
169+
{
170+
simd_int32s_to_floats (flts, (const uint32_t *LV_RESTRICT) ints, (int) count);
171+
}
172+
173+
void visual_math_simd_floats_to_int32s_mul_float (int32_t *LV_RESTRICT ints, const float *LV_RESTRICT flts, float k, visual_size_t count)
174+
{
175+
simd_floats_to_int32s_mul_float ((uint32_t *LV_RESTRICT) ints, flts, k, (int) count);
176+
}
177+
178+
void visual_math_simd_int32s_to_floats_mul_float (float *LV_RESTRICT flts, const int32_t *LV_RESTRICT ints, float k, visual_size_t count)
179+
{
180+
simd_int32s_to_floats_mul_float (flts, (const uint32_t *LV_RESTRICT) ints, k, (int) count);
181+
}
182+
183+
void visual_math_simd_denorm_floats_to_int32s (int32_t *LV_RESTRICT ints, const float *LV_RESTRICT flts, float k, visual_size_t count)
184+
{
185+
simd_denorm_floats_to_int32s ((uint32_t *LV_RESTRICT) ints, flts, k, (int) count);
186+
}
187+
188+
void visual_math_simd_denorm_neg_floats_to_int32s (int32_t *LV_RESTRICT ints, const float *LV_RESTRICT flts, float k, visual_size_t count)
189+
{
190+
simd_denorm_neg_floats_to_int32s ((uint32_t *LV_RESTRICT) ints, flts, k, (int) count);
191+
}
192+
193+
void visual_math_simd_sqrt_floats (float *LV_RESTRICT dest, const float *LV_RESTRICT src, visual_size_t count)
194+
{
195+
simd_sqrt_floats (dest, src, (int) count);
196+
}
197+
198+
void visual_math_simd_complex_norm (float *LV_RESTRICT dest, const float *LV_RESTRICT real, const float *LV_RESTRICT imag, visual_size_t count)
199+
{
200+
simd_complex_norm (dest, real, imag, (int) count);
201+
}
202+
203+
void visual_math_simd_complex_scaled_norm (float *LV_RESTRICT dest, const float *LV_RESTRICT real, const float *LV_RESTRICT imag, float k, visual_size_t count)
204+
{
205+
simd_complex_scaled_norm (dest, real, imag, k, (int) count);
206+
}

libvisual/libvisual/lv_math.h

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,31 @@
3030

3131
#ifdef __cplusplus
3232

33-
#include <algorithm>
33+
#include <concepts>
34+
#include <cstdint>
35+
#include <span>
3436

35-
namespace LV {
37+
namespace LV::Math {
3638

37-
// empty at the moment
39+
LV_API void simd_add (std::span<float> dst, std::span<float const> src, float adder);
3840

39-
} // LV namespce
41+
LV_API void simd_mul (std::span<float> dst, std::span<float const> src1, std::span<float const> src2);
42+
LV_API void simd_mul (std::span<float> dst, std::span<float const> src, float k);
43+
LV_API void simd_mul (std::span<std::int32_t> ints, std::span<float const> flts, float k);
44+
LV_API void simd_mul (std::span<float> flts, std::span<std::int32_t const> ints, float k);
45+
46+
LV_API void simd_convert (std::span<int32_t> ints, std::span<float const> flts);
47+
LV_API void simd_convert (std::span<float> flts, std::span<std::int32_t const> ints);
48+
49+
LV_API void simd_convert_denorm (std::span<std::int32_t> ints, std::span<float const> flts, float k);
50+
LV_API void simd_convert_denorm_neg (std::span<std::int32_t> ints, std::span<float const> flts, float k);
51+
52+
LV_API void simd_sqrt (std::span<float> dst, std::span<float const> src);
53+
54+
LV_API void simd_complex_norm (std::span<float> dst, std::span<float const> real, std::span<float const> imag);
55+
LV_API void simd_complex_scaled_norm (std::span<float> dst, std::span<float const> real, std::span<float const> imag, float k);
56+
57+
} // LV::Math namespce
4058

4159
#endif /* __cplusplus */
4260

0 commit comments

Comments
 (0)