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