• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***
2   This file is part of PulseAudio.
3 
4   PulseAudio is free software; you can redistribute it and/or modify
5   it under the terms of the GNU Lesser General Public License as published
6   by the Free Software Foundation; either version 2.1 of the License,
7   or (at your option) any later version.
8 
9   PulseAudio is distributed in the hope that it will be useful, but
10   WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   General Public License for more details.
13 
14   You should have received a copy of the GNU Lesser General Public License
15   along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
16 ***/
17 
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21 
22 #include <check.h>
23 
24 #include <pulsecore/cpu-x86.h>
25 #include <pulsecore/cpu.h>
26 #include <pulsecore/random.h>
27 #include <pulsecore/macro.h>
28 #include <pulsecore/remap.h>
29 #include <pulse/xmalloc.h>
30 
31 #include "runtime-test-util.h"
32 
33 #define SAMPLES 1027
34 #define TIMES 1000
35 #define TIMES2 100
36 
run_remap_test_float(pa_remap_t * remap_func,pa_remap_t * remap_orig,int align,bool correct,bool perf)37 static void run_remap_test_float(
38         pa_remap_t *remap_func,
39         pa_remap_t *remap_orig,
40         int align,
41         bool correct,
42         bool perf) {
43 
44     PA_DECLARE_ALIGNED(8, float, out_buf_ref[SAMPLES*8]) = { 0.0f, };
45     PA_DECLARE_ALIGNED(8, float, out_buf[SAMPLES*8]) = { 0.0f, };
46     PA_DECLARE_ALIGNED(8, float, in_buf[SAMPLES*8]);
47     float *out, *out_ref;
48     float *in;
49     unsigned n_ic = remap_func->i_ss.channels;
50     unsigned n_oc = remap_func->o_ss.channels;
51     unsigned i, nsamples;
52 
53     pa_assert(n_ic >= 1 && n_ic <= 8);
54     pa_assert(n_oc >= 1 && n_oc <= 8);
55 
56     /* Force sample alignment as requested */
57     out = out_buf + (8 - align);
58     out_ref = out_buf_ref + (8 - align);
59     in = in_buf + (8 - align);
60     nsamples = SAMPLES - (8 - align);
61 
62     for (i = 0; i < nsamples * n_ic; i++)
63         in[i] = 2.1f * (rand()/(float) RAND_MAX - 0.5f);
64 
65     if (correct) {
66         remap_orig->do_remap(remap_orig, out_ref, in, nsamples);
67         remap_func->do_remap(remap_func, out, in, nsamples);
68 
69         for (i = 0; i < nsamples * n_oc; i++) {
70             if (fabsf(out[i] - out_ref[i]) > 0.0001f) {
71                 pa_log_debug("Correctness test failed: align=%d", align);
72                 pa_log_debug("%d: %.24f != %.24f", i,
73                     out[i], out_ref[i]);
74                 ck_abort();
75             }
76         }
77     }
78 
79     if (perf) {
80         pa_log_debug("Testing remap performance with %d sample alignment", align);
81 
82         PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) {
83             remap_func->do_remap(remap_func, out, in, nsamples);
84         } PA_RUNTIME_TEST_RUN_STOP
85 
86         PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) {
87             remap_orig->do_remap(remap_orig, out_ref, in, nsamples);
88         } PA_RUNTIME_TEST_RUN_STOP
89     }
90 }
91 
run_remap_test_s16(pa_remap_t * remap_func,pa_remap_t * remap_orig,int align,bool correct,bool perf)92 static void run_remap_test_s16(
93         pa_remap_t *remap_func,
94         pa_remap_t *remap_orig,
95         int align,
96         bool correct,
97         bool perf) {
98 
99     PA_DECLARE_ALIGNED(8, int16_t, out_buf_ref[SAMPLES*8]) = { 0 };
100     PA_DECLARE_ALIGNED(8, int16_t, out_buf[SAMPLES*8]) = { 0 };
101     PA_DECLARE_ALIGNED(8, int16_t, in_buf[SAMPLES*8]);
102     int16_t *out, *out_ref;
103     int16_t *in;
104     unsigned n_ic = remap_func->i_ss.channels;
105     unsigned n_oc = remap_func->o_ss.channels;
106     unsigned i, nsamples;
107 
108     pa_assert(n_ic >= 1 && n_ic <= 8);
109     pa_assert(n_oc >= 1 && n_oc <= 8);
110 
111     /* Force sample alignment as requested */
112     out = out_buf + (8 - align);
113     out_ref = out_buf_ref + (8 - align);
114     in = in_buf + (8 - align);
115     nsamples = SAMPLES - (8 - align);
116 
117     pa_random(in, nsamples * n_ic * sizeof(int16_t));
118 
119     if (correct) {
120         remap_orig->do_remap(remap_orig, out_ref, in, nsamples);
121         remap_func->do_remap(remap_func, out, in, nsamples);
122 
123         for (i = 0; i < nsamples * n_oc; i++) {
124             if (abs(out[i] - out_ref[i]) > 3) {
125                 pa_log_debug("Correctness test failed: align=%d", align);
126                 pa_log_debug("%d: %d != %d", i, out[i], out_ref[i]);
127                 ck_abort();
128             }
129         }
130     }
131 
132     if (perf) {
133         pa_log_debug("Testing remap performance with %d sample alignment", align);
134 
135         PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) {
136             remap_func->do_remap(remap_func, out, in, nsamples);
137         } PA_RUNTIME_TEST_RUN_STOP
138 
139         PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) {
140             remap_orig->do_remap(remap_orig, out_ref, in, nsamples);
141         } PA_RUNTIME_TEST_RUN_STOP
142     }
143 }
144 
145 
run_remap_test_s32(pa_remap_t * remap_func,pa_remap_t * remap_orig,int align,bool correct,bool perf)146 static void run_remap_test_s32(
147         pa_remap_t *remap_func,
148         pa_remap_t *remap_orig,
149         int align,
150         bool correct,
151         bool perf) {
152 
153     PA_DECLARE_ALIGNED(8, int32_t, out_buf_ref[SAMPLES*8]) = { 0 };
154     PA_DECLARE_ALIGNED(8, int32_t, out_buf[SAMPLES*8]) = { 0 };
155     PA_DECLARE_ALIGNED(8, int32_t, in_buf[SAMPLES*8]);
156     int32_t *out, *out_ref;
157     int32_t *in;
158     unsigned n_ic = remap_func->i_ss.channels;
159     unsigned n_oc = remap_func->o_ss.channels;
160     unsigned i, nsamples;
161 
162     pa_assert(n_ic >= 1 && n_ic <= 8);
163     pa_assert(n_oc >= 1 && n_oc <= 8);
164 
165     /* Force sample alignment as requested */
166     out = out_buf + (8 - align);
167     out_ref = out_buf_ref + (8 - align);
168     in = in_buf + (8 - align);
169     nsamples = SAMPLES - (8 - align);
170 
171     pa_random(in, nsamples * n_ic * sizeof(int32_t));
172 
173     if (correct) {
174         remap_orig->do_remap(remap_orig, out_ref, in, nsamples);
175         remap_func->do_remap(remap_func, out, in, nsamples);
176 
177         for (i = 0; i < nsamples * n_oc; i++) {
178             if (abs(out[i] - out_ref[i]) > 4) {
179                 pa_log_debug("Correctness test failed: align=%d", align);
180                 pa_log_debug("%d: %d != %d", i, out[i], out_ref[i]);
181                 ck_abort();
182             }
183         }
184     }
185 
186     if (perf) {
187         pa_log_debug("Testing remap performance with %d sample alignment", align);
188 
189         PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) {
190             remap_func->do_remap(remap_func, out, in, nsamples);
191         } PA_RUNTIME_TEST_RUN_STOP
192 
193         PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) {
194             remap_orig->do_remap(remap_orig, out_ref, in, nsamples);
195         } PA_RUNTIME_TEST_RUN_STOP
196     }
197 }
198 
setup_remap_channels(pa_remap_t * m,pa_sample_format_t f,unsigned in_channels,unsigned out_channels,bool rearrange)199 static void setup_remap_channels(
200     pa_remap_t *m,
201     pa_sample_format_t f,
202     unsigned in_channels,
203     unsigned out_channels,
204     bool rearrange) {
205 
206     unsigned i, o;
207 
208     m->format = f;
209     m->i_ss.channels = in_channels;
210     m->o_ss.channels = out_channels;
211 
212     if (rearrange) {
213         for (o = 0; o < out_channels; o++) {
214             for (i = 0; i < in_channels; i++) {
215                 m->map_table_f[o][i] = (o == i) ? 1.0f : 0.0f;
216                 m->map_table_i[o][i] = (o == i) ? 0x10000 : 0;
217             }
218         }
219     } else {
220         for (o = 0; o < out_channels; o++) {
221             for (i = 0; i < in_channels; i++) {
222                 m->map_table_f[o][i] = 1.0f / in_channels;
223                 m->map_table_i[o][i] = 0x10000 / in_channels;
224             }
225         }
226     }
227 }
228 
remap_test_channels(pa_remap_t * remap_func,pa_remap_t * remap_orig)229 static void remap_test_channels(
230     pa_remap_t *remap_func, pa_remap_t *remap_orig) {
231 
232     if (!remap_orig->do_remap) {
233         pa_log_warn("No reference remapping function, abort test");
234         return;
235     }
236 
237     if (!remap_func->do_remap || remap_func->do_remap == remap_orig->do_remap) {
238         pa_log_warn("No remapping function, abort test");
239         return;
240     }
241 
242     pa_assert(remap_func->format == remap_orig->format);
243 
244     switch (remap_func->format) {
245     case PA_SAMPLE_FLOAT32NE:
246         run_remap_test_float(remap_func, remap_orig, 0, true, false);
247         run_remap_test_float(remap_func, remap_orig, 1, true, false);
248         run_remap_test_float(remap_func, remap_orig, 2, true, false);
249         run_remap_test_float(remap_func, remap_orig, 3, true, true);
250         break;
251     case PA_SAMPLE_S32NE:
252         run_remap_test_s32(remap_func, remap_orig, 0, true, false);
253         run_remap_test_s32(remap_func, remap_orig, 1, true, false);
254         run_remap_test_s32(remap_func, remap_orig, 2, true, false);
255         run_remap_test_s32(remap_func, remap_orig, 3, true, true);
256         break;
257     case PA_SAMPLE_S16NE:
258         run_remap_test_s16(remap_func, remap_orig, 0, true, false);
259         run_remap_test_s16(remap_func, remap_orig, 1, true, false);
260         run_remap_test_s16(remap_func, remap_orig, 2, true, false);
261         run_remap_test_s16(remap_func, remap_orig, 3, true, true);
262         break;
263     default:
264         pa_assert_not_reached();
265     }
266 }
267 
remap_init_test_channels(pa_init_remap_func_t init_func,pa_init_remap_func_t orig_init_func,pa_sample_format_t f,unsigned in_channels,unsigned out_channels,bool rearrange)268 static void remap_init_test_channels(
269         pa_init_remap_func_t init_func,
270         pa_init_remap_func_t orig_init_func,
271         pa_sample_format_t f,
272         unsigned in_channels,
273         unsigned out_channels,
274         bool rearrange) {
275 
276     pa_remap_t remap_orig = {0}, remap_func = {0};
277 
278     setup_remap_channels(&remap_orig, f, in_channels, out_channels, rearrange);
279     orig_init_func(&remap_orig);
280 
281     setup_remap_channels(&remap_func, f, in_channels, out_channels, rearrange);
282     init_func(&remap_func);
283 
284     remap_test_channels(&remap_func, &remap_orig);
285 }
286 
remap_init2_test_channels(pa_sample_format_t f,unsigned in_channels,unsigned out_channels,bool rearrange)287 static void remap_init2_test_channels(
288         pa_sample_format_t f,
289         unsigned in_channels,
290         unsigned out_channels,
291         bool rearrange) {
292 
293     pa_cpu_info cpu_info = { PA_CPU_UNDEFINED, {}, false };
294     pa_remap_t remap_orig, remap_func = {0};
295 
296     cpu_info.force_generic_code = true;
297     pa_remap_func_init(&cpu_info);
298     setup_remap_channels(&remap_orig, f, in_channels, out_channels, rearrange);
299     pa_init_remap_func(&remap_orig);
300 
301     cpu_info.force_generic_code = false;
302     pa_remap_func_init(&cpu_info);
303     setup_remap_channels(&remap_func, f, in_channels, out_channels, rearrange);
304     pa_init_remap_func(&remap_func);
305 
306     remap_test_channels(&remap_func, &remap_orig);
307 
308     pa_xfree(remap_func.state);
309 }
310 
START_TEST(remap_special_test)311 START_TEST (remap_special_test) {
312     pa_log_debug("Checking special remap (float, mono->stereo)");
313     remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 1, 2, false);
314     pa_log_debug("Checking special remap (float, mono->4-channel)");
315     remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 1, 4, false);
316 
317     pa_log_debug("Checking special remap (s32, mono->stereo)");
318     remap_init2_test_channels(PA_SAMPLE_S32NE, 1, 2, false);
319     pa_log_debug("Checking special remap (s32, mono->4-channel)");
320     remap_init2_test_channels(PA_SAMPLE_S32NE, 1, 4, false);
321 
322     pa_log_debug("Checking special remap (s16, mono->stereo)");
323     remap_init2_test_channels(PA_SAMPLE_S16NE, 1, 2, false);
324     pa_log_debug("Checking special remap (s16, mono->4-channel)");
325     remap_init2_test_channels(PA_SAMPLE_S16NE, 1, 4, false);
326 
327     pa_log_debug("Checking special remap (float, stereo->mono)");
328     remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 2, 1, false);
329     pa_log_debug("Checking special remap (float, 4-channel->mono)");
330     remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 4, 1, false);
331 
332     pa_log_debug("Checking special remap (s32, stereo->mono)");
333     remap_init2_test_channels(PA_SAMPLE_S32NE, 2, 1, false);
334     pa_log_debug("Checking special remap (s32, 4-channel->mono)");
335     remap_init2_test_channels(PA_SAMPLE_S32NE, 4, 1, false);
336 
337     pa_log_debug("Checking special remap (s16, stereo->mono)");
338     remap_init2_test_channels(PA_SAMPLE_S16NE, 2, 1, false);
339     pa_log_debug("Checking special remap (s16, 4-channel->mono)");
340     remap_init2_test_channels(PA_SAMPLE_S16NE, 4, 1, false);
341 }
342 END_TEST
343 
START_TEST(rearrange_special_test)344 START_TEST (rearrange_special_test) {
345     pa_log_debug("Checking special remap (s16, stereo rearrange)");
346     remap_init2_test_channels(PA_SAMPLE_S16NE, 2, 2, true);
347     pa_log_debug("Checking special remap (s32, stereo rearrange)");
348     remap_init2_test_channels(PA_SAMPLE_S32NE, 2, 2, true);
349     pa_log_debug("Checking special remap (float, stereo rearrange)");
350     remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 2, 2, true);
351 
352     pa_log_debug("Checking special remap (s16, 4-channel rearrange)");
353     remap_init2_test_channels(PA_SAMPLE_S16NE, 4, 4, true);
354     pa_log_debug("Checking special remap (s32, 4-channel rearrange)");
355     remap_init2_test_channels(PA_SAMPLE_S32NE, 4, 4, true);
356     pa_log_debug("Checking special remap (float, 4-channel rearrange)");
357     remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 4, 4, true);
358 }
359 END_TEST
360 
361 #if defined (__i386__) || defined (__amd64__)
START_TEST(remap_mmx_test)362 START_TEST (remap_mmx_test) {
363     pa_cpu_x86_flag_t flags = 0;
364     pa_init_remap_func_t init_func, orig_init_func;
365 
366     pa_cpu_get_x86_flags(&flags);
367     if (!(flags & PA_CPU_X86_MMX)) {
368         pa_log_info("MMX not supported. Skipping");
369         return;
370     }
371 
372     pa_log_debug("Checking MMX remap (float, mono->stereo)");
373     orig_init_func = pa_get_init_remap_func();
374     pa_remap_func_init_mmx(flags);
375     init_func = pa_get_init_remap_func();
376     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 1, 2, false);
377 
378     pa_log_debug("Checking MMX remap (s32, mono->stereo)");
379     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S32NE, 1, 2, false);
380 
381     pa_log_debug("Checking MMX remap (s16, mono->stereo)");
382     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 1, 2, false);
383 }
384 END_TEST
385 
START_TEST(remap_sse2_test)386 START_TEST (remap_sse2_test) {
387     pa_cpu_x86_flag_t flags = 0;
388     pa_init_remap_func_t init_func, orig_init_func;
389 
390     pa_cpu_get_x86_flags(&flags);
391     if (!(flags & PA_CPU_X86_SSE2)) {
392         pa_log_info("SSE2 not supported. Skipping");
393         return;
394     }
395 
396     pa_log_debug("Checking SSE2 remap (float, mono->stereo)");
397     orig_init_func = pa_get_init_remap_func();
398     pa_remap_func_init_sse(flags);
399     init_func = pa_get_init_remap_func();
400     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 1, 2, false);
401 
402     pa_log_debug("Checking SSE2 remap (s32, mono->stereo)");
403     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S32NE, 1, 2, false);
404 
405     pa_log_debug("Checking SSE2 remap (s16, mono->stereo)");
406     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 1, 2, false);
407 }
408 END_TEST
409 #endif /* defined (__i386__) || defined (__amd64__) */
410 
411 #if defined (__arm__) && defined (__linux__) && defined (HAVE_NEON)
START_TEST(remap_neon_test)412 START_TEST (remap_neon_test) {
413     pa_cpu_arm_flag_t flags = 0;
414     pa_init_remap_func_t init_func, orig_init_func;
415 
416     pa_cpu_get_arm_flags(&flags);
417     if (!(flags & PA_CPU_ARM_NEON)) {
418         pa_log_info("NEON not supported. Skipping");
419         return;
420     }
421 
422     orig_init_func = pa_get_init_remap_func();
423     pa_remap_func_init_neon(flags);
424     init_func = pa_get_init_remap_func();
425 
426     pa_log_debug("Checking NEON remap (float, mono->stereo)");
427     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 1, 2, false);
428     pa_log_debug("Checking NEON remap (float, mono->4-channel)");
429     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 1, 4, false);
430 
431     pa_log_debug("Checking NEON remap (s32, mono->stereo)");
432     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S32NE, 1, 2, false);
433     pa_log_debug("Checking NEON remap (s32, mono->4-channel)");
434     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S32NE, 1, 4, false);
435 
436     pa_log_debug("Checking NEON remap (s16, mono->stereo)");
437     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 1, 2, false);
438     pa_log_debug("Checking NEON remap (s16, mono->4-channel)");
439     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 1, 4, false);
440 
441     pa_log_debug("Checking NEON remap (float, stereo->mono)");
442     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 2, 1, false);
443     pa_log_debug("Checking NEON remap (float, 4-channel->mono)");
444     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 4, 1, false);
445 
446     pa_log_debug("Checking NEON remap (s32, stereo->mono)");
447     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S32NE, 2, 1, false);
448     pa_log_debug("Checking NEON remap (s32, 4-channel->mono)");
449     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S32NE, 4, 1, false);
450 
451     pa_log_debug("Checking NEON remap (s16, stereo->mono)");
452     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 2, 1, false);
453     pa_log_debug("Checking NEON remap (s16, 4-channel->mono)");
454     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 4, 1, false);
455 
456     pa_log_debug("Checking NEON remap (float, 4-channel->4-channel)");
457     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 4, 4, false);
458     pa_log_debug("Checking NEON remap (s32, 4-channel->4-channel)");
459     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S32NE, 4, 4, false);
460     pa_log_debug("Checking NEON remap (s16, 4-channel->4-channel)");
461     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 4, 4, false);
462 }
463 END_TEST
464 
START_TEST(rearrange_neon_test)465 START_TEST (rearrange_neon_test) {
466     pa_cpu_arm_flag_t flags = 0;
467     pa_init_remap_func_t init_func, orig_init_func;
468 
469     pa_cpu_get_arm_flags(&flags);
470     if (!(flags & PA_CPU_ARM_NEON)) {
471         pa_log_info("NEON not supported. Skipping");
472         return;
473     }
474 
475     orig_init_func = pa_get_init_remap_func();
476     pa_remap_func_init_neon(flags);
477     init_func = pa_get_init_remap_func();
478 
479     pa_log_debug("Checking NEON remap (float, stereo rearrange)");
480     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 2, 2, true);
481     pa_log_debug("Checking NEON remap (s32, stereo rearrange)");
482     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S32NE, 2, 2, true);
483     pa_log_debug("Checking NEON remap (s16, stereo rearrange)");
484     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 2, 2, true);
485 
486     pa_log_debug("Checking NEON remap (float, 2-channel->4-channel rearrange)");
487     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 2, 4, true);
488     pa_log_debug("Checking NEON remap (s32, 2-channel->4-channel rearrange)");
489     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S32NE, 2, 4, true);
490     pa_log_debug("Checking NEON remap (s16, 2-channel->4-channel rearrange)");
491     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 2, 4, true);
492 
493     pa_log_debug("Checking NEON remap (float, 4-channel rearrange)");
494     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 4, 4, true);
495     pa_log_debug("Checking NEON remap (s32, 4-channel rearrange)");
496     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S32NE, 4, 4, true);
497     pa_log_debug("Checking NEON remap (s16, 4-channel rearrange)");
498     remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 4, 4, true);
499 }
500 END_TEST
501 #endif
502 
main(int argc,char * argv[])503 int main(int argc, char *argv[]) {
504     int failed = 0;
505     Suite *s;
506     TCase *tc;
507     SRunner *sr;
508 
509     if (!getenv("MAKE_CHECK"))
510         pa_log_set_level(PA_LOG_DEBUG);
511 
512     s = suite_create("CPU");
513 
514     tc = tcase_create("remap");
515     tcase_add_test(tc, remap_special_test);
516 #if defined (__i386__) || defined (__amd64__)
517     tcase_add_test(tc, remap_mmx_test);
518     tcase_add_test(tc, remap_sse2_test);
519 #endif
520 #if defined (__arm__) && defined (__linux__) && defined (HAVE_NEON)
521     tcase_add_test(tc, remap_neon_test);
522 #endif
523     tcase_set_timeout(tc, 120);
524     suite_add_tcase(s, tc);
525 
526     tc = tcase_create("rearrange");
527     tcase_add_test(tc, rearrange_special_test);
528 #if defined (__arm__) && defined (__linux__) && defined (HAVE_NEON)
529     tcase_add_test(tc, rearrange_neon_test);
530 #endif
531     tcase_set_timeout(tc, 120);
532     suite_add_tcase(s, tc);
533 
534     sr = srunner_create(s);
535     srunner_run_all(sr, CK_NORMAL);
536     failed = srunner_ntests_failed(sr);
537     srunner_free(sr);
538 
539     return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
540 }
541