1 /*
2 * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/>
3 * (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com>
4 *
5 * This file is part of lsp-plugins
6 * Created on: 21 авг. 2018 г.
7 *
8 * lsp-plugins is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * any later version.
12 *
13 * lsp-plugins is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with lsp-plugins. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22 #include <dsp/dsp.h>
23 #include <test/utest.h>
24 #include <test/FloatBuffer.h>
25
26 namespace native
27 {
28 void lanczos_resample_2x2(float *dst, const float *src, size_t count);
29 void lanczos_resample_2x3(float *dst, const float *src, size_t count);
30 void lanczos_resample_2x4(float *dst, const float *src, size_t count);
31 void lanczos_resample_3x2(float *dst, const float *src, size_t count);
32 void lanczos_resample_3x3(float *dst, const float *src, size_t count);
33 void lanczos_resample_3x4(float *dst, const float *src, size_t count);
34 void lanczos_resample_4x2(float *dst, const float *src, size_t count);
35 void lanczos_resample_4x3(float *dst, const float *src, size_t count);
36 void lanczos_resample_4x4(float *dst, const float *src, size_t count);
37 void lanczos_resample_6x2(float *dst, const float *src, size_t count);
38 void lanczos_resample_6x3(float *dst, const float *src, size_t count);
39 void lanczos_resample_6x4(float *dst, const float *src, size_t count);
40 void lanczos_resample_8x2(float *dst, const float *src, size_t count);
41 void lanczos_resample_8x3(float *dst, const float *src, size_t count);
42 void lanczos_resample_8x4(float *dst, const float *src, size_t count);
43 }
44
45 IF_ARCH_X86(
46 namespace sse
47 {
48 void lanczos_resample_2x2(float *dst, const float *src, size_t count);
49 void lanczos_resample_2x3(float *dst, const float *src, size_t count);
50 void lanczos_resample_2x4(float *dst, const float *src, size_t count);
51 void lanczos_resample_3x2(float *dst, const float *src, size_t count);
52 void lanczos_resample_3x3(float *dst, const float *src, size_t count);
53 void lanczos_resample_3x4(float *dst, const float *src, size_t count);
54 void lanczos_resample_4x2(float *dst, const float *src, size_t count);
55 void lanczos_resample_4x3(float *dst, const float *src, size_t count);
56 void lanczos_resample_4x4(float *dst, const float *src, size_t count);
57 void lanczos_resample_6x2(float *dst, const float *src, size_t count);
58 void lanczos_resample_6x3(float *dst, const float *src, size_t count);
59 void lanczos_resample_6x4(float *dst, const float *src, size_t count);
60 void lanczos_resample_8x2(float *dst, const float *src, size_t count);
61 void lanczos_resample_8x3(float *dst, const float *src, size_t count);
62 void lanczos_resample_8x4(float *dst, const float *src, size_t count);
63 }
64
65 namespace avx
66 {
67 void lanczos_resample_2x2(float *dst, const float *src, size_t count);
68 void lanczos_resample_2x3(float *dst, const float *src, size_t count);
69 void lanczos_resample_2x4(float *dst, const float *src, size_t count);
70 void lanczos_resample_3x2(float *dst, const float *src, size_t count);
71 void lanczos_resample_3x3(float *dst, const float *src, size_t count);
72 void lanczos_resample_3x4(float *dst, const float *src, size_t count);
73 void lanczos_resample_4x2(float *dst, const float *src, size_t count);
74 void lanczos_resample_4x3(float *dst, const float *src, size_t count);
75 void lanczos_resample_4x4(float *dst, const float *src, size_t count);
76 void lanczos_resample_6x2(float *dst, const float *src, size_t count);
77 void lanczos_resample_6x3(float *dst, const float *src, size_t count);
78 void lanczos_resample_6x4(float *dst, const float *src, size_t count);
79 void lanczos_resample_8x2(float *dst, const float *src, size_t count);
80 void lanczos_resample_8x3(float *dst, const float *src, size_t count);
81 void lanczos_resample_8x4(float *dst, const float *src, size_t count);
82 }
83 )
84
IF_ARCH_ARM(namespace neon_d32{ void lanczos_resample_2x2(float *dst, const float *src, size_t count); void lanczos_resample_2x3(float *dst, const float *src, size_t count); void lanczos_resample_2x4(float *dst, const float *src, size_t count); void lanczos_resample_3x2(float *dst, const float *src, size_t count); void lanczos_resample_3x3(float *dst, const float *src, size_t count); void lanczos_resample_3x4(float *dst, const float *src, size_t count); void lanczos_resample_4x2(float *dst, const float *src, size_t count); void lanczos_resample_4x3(float *dst, const float *src, size_t count); void lanczos_resample_4x4(float *dst, const float *src, size_t count); void lanczos_resample_6x2(float *dst, const float *src, size_t count); void lanczos_resample_6x3(float *dst, const float *src, size_t count); void lanczos_resample_6x4(float *dst, const float *src, size_t count); void lanczos_resample_8x2(float *dst, const float *src, size_t count); void lanczos_resample_8x3(float *dst, const float *src, size_t count); void lanczos_resample_8x4(float *dst, const float *src, size_t count); } )85 IF_ARCH_ARM(
86 namespace neon_d32
87 {
88 void lanczos_resample_2x2(float *dst, const float *src, size_t count);
89 void lanczos_resample_2x3(float *dst, const float *src, size_t count);
90 void lanczos_resample_2x4(float *dst, const float *src, size_t count);
91 void lanczos_resample_3x2(float *dst, const float *src, size_t count);
92 void lanczos_resample_3x3(float *dst, const float *src, size_t count);
93 void lanczos_resample_3x4(float *dst, const float *src, size_t count);
94 void lanczos_resample_4x2(float *dst, const float *src, size_t count);
95 void lanczos_resample_4x3(float *dst, const float *src, size_t count);
96 void lanczos_resample_4x4(float *dst, const float *src, size_t count);
97 void lanczos_resample_6x2(float *dst, const float *src, size_t count);
98 void lanczos_resample_6x3(float *dst, const float *src, size_t count);
99 void lanczos_resample_6x4(float *dst, const float *src, size_t count);
100 void lanczos_resample_8x2(float *dst, const float *src, size_t count);
101 void lanczos_resample_8x3(float *dst, const float *src, size_t count);
102 void lanczos_resample_8x4(float *dst, const float *src, size_t count);
103 }
104 )
105
106 IF_ARCH_AARCH64(
107 namespace asimd
108 {
109 void lanczos_resample_2x2(float *dst, const float *src, size_t count);
110 void lanczos_resample_2x3(float *dst, const float *src, size_t count);
111 void lanczos_resample_2x4(float *dst, const float *src, size_t count);
112 void lanczos_resample_3x2(float *dst, const float *src, size_t count);
113 void lanczos_resample_3x3(float *dst, const float *src, size_t count);
114 void lanczos_resample_3x4(float *dst, const float *src, size_t count);
115 void lanczos_resample_4x2(float *dst, const float *src, size_t count);
116 void lanczos_resample_4x3(float *dst, const float *src, size_t count);
117 void lanczos_resample_4x4(float *dst, const float *src, size_t count);
118 void lanczos_resample_6x2(float *dst, const float *src, size_t count);
119 void lanczos_resample_6x3(float *dst, const float *src, size_t count);
120 void lanczos_resample_6x4(float *dst, const float *src, size_t count);
121 void lanczos_resample_8x2(float *dst, const float *src, size_t count);
122 void lanczos_resample_8x3(float *dst, const float *src, size_t count);
123 void lanczos_resample_8x4(float *dst, const float *src, size_t count);
124 }
125 )
126
127 UTEST_BEGIN("dsp.resampling", oversampling)
128
129 void call(size_t times, const char *text, size_t align,
130 resampling_function_t func1,
131 resampling_function_t func2
132 )
133 {
134 if (!UTEST_SUPPORTED(func1))
135 return;
136 if (!UTEST_SUPPORTED(func2))
137 return;
138
139 UTEST_FOREACH(count, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31,
140 32, 63, 64, 127, 100, 999)
141 {
142 for (size_t mask=0; mask <= 0x03; ++mask)
143 {
144 printf("Testing %s resampling for %d -> %d samples, mask=0x%x...\n", text, int(count), int(count * times), int(mask));
145
146 FloatBuffer src(count, align, mask & 0x01);
147 FloatBuffer dst1(count*times + RESAMPLING_RESERVED_SAMPLES, align, mask & 0x02);
148 dst1.randomize_sign();
149 dst1.fill_zero();
150 FloatBuffer dst2(dst1);
151
152 // Call functions
153 func1(dst1, src, count);
154 func2(dst2, src, count);
155
156 if (src.corrupted())
157 UTEST_FAIL_MSG("Source buffer corrupted");
158 if (dst1.corrupted())
159 UTEST_FAIL_MSG("Destination buffer 1 corrupted");
160 if (dst2.corrupted())
161 UTEST_FAIL_MSG("Destination buffer 2 corrupted");
162
163 // Compare buffers
164 if (!dst1.equals_absolute(dst2))
165 {
166 src.dump("src1");
167 dst1.dump("dst1");
168 dst2.dump("dst2");
169 UTEST_FAIL_MSG("Output of functions for test '%s' differs", text);
170 }
171 }
172 }
173 }
174
175 UTEST_MAIN
176 {
177 #define CALL(native, func, align, order) \
178 call(order, #func, align, native, func)
179
180 // Do tests
181 IF_ARCH_X86(CALL(native::lanczos_resample_2x2, sse::lanczos_resample_2x2, 16, 2));
182 IF_ARCH_X86(CALL(native::lanczos_resample_2x3, sse::lanczos_resample_2x3, 16, 2));
183 IF_ARCH_X86(CALL(native::lanczos_resample_2x4, sse::lanczos_resample_2x4, 16, 2));
184 IF_ARCH_X86(CALL(native::lanczos_resample_3x2, sse::lanczos_resample_3x2, 16, 3));
185 IF_ARCH_X86(CALL(native::lanczos_resample_3x3, sse::lanczos_resample_3x3, 16, 3));
186 IF_ARCH_X86(CALL(native::lanczos_resample_3x4, sse::lanczos_resample_3x4, 16, 3));
187 IF_ARCH_X86(CALL(native::lanczos_resample_4x2, sse::lanczos_resample_4x2, 16, 4));
188 IF_ARCH_X86(CALL(native::lanczos_resample_4x3, sse::lanczos_resample_4x3, 16, 4));
189 IF_ARCH_X86(CALL(native::lanczos_resample_4x4, sse::lanczos_resample_4x4, 16, 4));
190 IF_ARCH_X86(CALL(native::lanczos_resample_6x2, sse::lanczos_resample_6x2, 16, 6));
191 IF_ARCH_X86(CALL(native::lanczos_resample_6x3, sse::lanczos_resample_6x3, 16, 6));
192 IF_ARCH_X86(CALL(native::lanczos_resample_6x4, sse::lanczos_resample_6x4, 16, 6));
193 IF_ARCH_X86(CALL(native::lanczos_resample_8x2, sse::lanczos_resample_8x2, 16, 8));
194 IF_ARCH_X86(CALL(native::lanczos_resample_8x3, sse::lanczos_resample_8x3, 16, 8));
195 IF_ARCH_X86(CALL(native::lanczos_resample_8x4, sse::lanczos_resample_8x4, 16, 8));
196
197 IF_ARCH_X86(CALL(native::lanczos_resample_2x2, avx::lanczos_resample_2x2, 32, 2));
198 IF_ARCH_X86(CALL(native::lanczos_resample_2x3, avx::lanczos_resample_2x3, 32, 2));
199 IF_ARCH_X86(CALL(native::lanczos_resample_2x4, avx::lanczos_resample_2x4, 32, 2));
200 IF_ARCH_X86(CALL(native::lanczos_resample_3x2, avx::lanczos_resample_3x2, 32, 3));
201 IF_ARCH_X86(CALL(native::lanczos_resample_3x3, avx::lanczos_resample_3x3, 32, 3));
202 IF_ARCH_X86(CALL(native::lanczos_resample_3x4, avx::lanczos_resample_3x4, 32, 3));
203 IF_ARCH_X86(CALL(native::lanczos_resample_4x2, avx::lanczos_resample_4x2, 32, 4));
204 IF_ARCH_X86(CALL(native::lanczos_resample_4x3, avx::lanczos_resample_4x3, 32, 4));
205 IF_ARCH_X86(CALL(native::lanczos_resample_4x4, avx::lanczos_resample_4x4, 32, 4));
206 IF_ARCH_X86(CALL(native::lanczos_resample_6x2, avx::lanczos_resample_6x2, 32, 6));
207 IF_ARCH_X86(CALL(native::lanczos_resample_6x3, avx::lanczos_resample_6x3, 32, 6));
208 IF_ARCH_X86(CALL(native::lanczos_resample_6x4, avx::lanczos_resample_6x4, 32, 6));
209 IF_ARCH_X86(CALL(native::lanczos_resample_8x2, avx::lanczos_resample_8x2, 32, 8));
210 IF_ARCH_X86(CALL(native::lanczos_resample_8x3, avx::lanczos_resample_8x3, 32, 8));
211 IF_ARCH_X86(CALL(native::lanczos_resample_8x4, avx::lanczos_resample_8x4, 32, 8));
212
213 IF_ARCH_ARM(CALL(native::lanczos_resample_2x2, neon_d32::lanczos_resample_2x2, 16, 2));
214 IF_ARCH_ARM(CALL(native::lanczos_resample_2x3, neon_d32::lanczos_resample_2x3, 16, 2));
215 IF_ARCH_ARM(CALL(native::lanczos_resample_2x4, neon_d32::lanczos_resample_2x4, 16, 2));
216 IF_ARCH_ARM(CALL(native::lanczos_resample_3x2, neon_d32::lanczos_resample_3x2, 16, 3));
217 IF_ARCH_ARM(CALL(native::lanczos_resample_3x3, neon_d32::lanczos_resample_3x3, 16, 3));
218 IF_ARCH_ARM(CALL(native::lanczos_resample_3x4, neon_d32::lanczos_resample_3x4, 16, 3));
219 IF_ARCH_ARM(CALL(native::lanczos_resample_4x2, neon_d32::lanczos_resample_4x2, 16, 4));
220 IF_ARCH_ARM(CALL(native::lanczos_resample_4x3, neon_d32::lanczos_resample_4x3, 16, 4));
221 IF_ARCH_ARM(CALL(native::lanczos_resample_4x4, neon_d32::lanczos_resample_4x4, 16, 4));
222 IF_ARCH_ARM(CALL(native::lanczos_resample_6x2, neon_d32::lanczos_resample_6x2, 16, 6));
223 IF_ARCH_ARM(CALL(native::lanczos_resample_6x3, neon_d32::lanczos_resample_6x3, 16, 6));
224 IF_ARCH_ARM(CALL(native::lanczos_resample_6x4, neon_d32::lanczos_resample_6x4, 16, 6));
225 IF_ARCH_ARM(CALL(native::lanczos_resample_8x2, neon_d32::lanczos_resample_8x2, 16, 8));
226 IF_ARCH_ARM(CALL(native::lanczos_resample_8x3, neon_d32::lanczos_resample_8x3, 16, 8));
227 IF_ARCH_ARM(CALL(native::lanczos_resample_8x4, neon_d32::lanczos_resample_8x4, 16, 8));
228
229 IF_ARCH_AARCH64(CALL(native::lanczos_resample_2x2, asimd::lanczos_resample_2x2, 16, 2));
230 IF_ARCH_AARCH64(CALL(native::lanczos_resample_2x3, asimd::lanczos_resample_2x3, 16, 2));
231 IF_ARCH_AARCH64(CALL(native::lanczos_resample_2x4, asimd::lanczos_resample_2x4, 16, 2));
232 IF_ARCH_AARCH64(CALL(native::lanczos_resample_3x2, asimd::lanczos_resample_3x2, 16, 3));
233 IF_ARCH_AARCH64(CALL(native::lanczos_resample_3x3, asimd::lanczos_resample_3x3, 16, 3));
234 IF_ARCH_AARCH64(CALL(native::lanczos_resample_3x4, asimd::lanczos_resample_3x4, 16, 3));
235 IF_ARCH_AARCH64(CALL(native::lanczos_resample_4x2, asimd::lanczos_resample_4x2, 16, 4));
236 IF_ARCH_AARCH64(CALL(native::lanczos_resample_4x3, asimd::lanczos_resample_4x3, 16, 4));
237 IF_ARCH_AARCH64(CALL(native::lanczos_resample_4x4, asimd::lanczos_resample_4x4, 16, 4));
238 IF_ARCH_AARCH64(CALL(native::lanczos_resample_6x2, asimd::lanczos_resample_6x2, 16, 6));
239 IF_ARCH_AARCH64(CALL(native::lanczos_resample_6x3, asimd::lanczos_resample_6x3, 16, 6));
240 IF_ARCH_AARCH64(CALL(native::lanczos_resample_6x4, asimd::lanczos_resample_6x4, 16, 6));
241 IF_ARCH_AARCH64(CALL(native::lanczos_resample_8x2, asimd::lanczos_resample_8x2, 16, 8));
242 IF_ARCH_AARCH64(CALL(native::lanczos_resample_8x3, asimd::lanczos_resample_8x3, 16, 8));
243 IF_ARCH_AARCH64(CALL(native::lanczos_resample_8x4, asimd::lanczos_resample_8x4, 16, 8));
244 }
245 UTEST_END;
246