153a5a1b3Sopenharmony_ci/***
253a5a1b3Sopenharmony_ci  This file is part of PulseAudio.
353a5a1b3Sopenharmony_ci
453a5a1b3Sopenharmony_ci  PulseAudio is free software; you can redistribute it and/or modify
553a5a1b3Sopenharmony_ci  it under the terms of the GNU Lesser General Public License as published
653a5a1b3Sopenharmony_ci  by the Free Software Foundation; either version 2.1 of the License,
753a5a1b3Sopenharmony_ci  or (at your option) any later version.
853a5a1b3Sopenharmony_ci
953a5a1b3Sopenharmony_ci  PulseAudio is distributed in the hope that it will be useful, but
1053a5a1b3Sopenharmony_ci  WITHOUT ANY WARRANTY; without even the implied warranty of
1153a5a1b3Sopenharmony_ci  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1253a5a1b3Sopenharmony_ci  General Public License for more details.
1353a5a1b3Sopenharmony_ci
1453a5a1b3Sopenharmony_ci  You should have received a copy of the GNU Lesser General Public License
1553a5a1b3Sopenharmony_ci  along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
1653a5a1b3Sopenharmony_ci***/
1753a5a1b3Sopenharmony_ci
1853a5a1b3Sopenharmony_ci#ifdef HAVE_CONFIG_H
1953a5a1b3Sopenharmony_ci#include <config.h>
2053a5a1b3Sopenharmony_ci#endif
2153a5a1b3Sopenharmony_ci
2253a5a1b3Sopenharmony_ci#include <check.h>
2353a5a1b3Sopenharmony_ci
2453a5a1b3Sopenharmony_ci#include <pulsecore/cpu-x86.h>
2553a5a1b3Sopenharmony_ci#include <pulsecore/cpu.h>
2653a5a1b3Sopenharmony_ci#include <pulsecore/random.h>
2753a5a1b3Sopenharmony_ci#include <pulsecore/macro.h>
2853a5a1b3Sopenharmony_ci#include <pulsecore/remap.h>
2953a5a1b3Sopenharmony_ci#include <pulse/xmalloc.h>
3053a5a1b3Sopenharmony_ci
3153a5a1b3Sopenharmony_ci#include "runtime-test-util.h"
3253a5a1b3Sopenharmony_ci
3353a5a1b3Sopenharmony_ci#define SAMPLES 1027
3453a5a1b3Sopenharmony_ci#define TIMES 1000
3553a5a1b3Sopenharmony_ci#define TIMES2 100
3653a5a1b3Sopenharmony_ci
3753a5a1b3Sopenharmony_cistatic void run_remap_test_float(
3853a5a1b3Sopenharmony_ci        pa_remap_t *remap_func,
3953a5a1b3Sopenharmony_ci        pa_remap_t *remap_orig,
4053a5a1b3Sopenharmony_ci        int align,
4153a5a1b3Sopenharmony_ci        bool correct,
4253a5a1b3Sopenharmony_ci        bool perf) {
4353a5a1b3Sopenharmony_ci
4453a5a1b3Sopenharmony_ci    PA_DECLARE_ALIGNED(8, float, out_buf_ref[SAMPLES*8]) = { 0.0f, };
4553a5a1b3Sopenharmony_ci    PA_DECLARE_ALIGNED(8, float, out_buf[SAMPLES*8]) = { 0.0f, };
4653a5a1b3Sopenharmony_ci    PA_DECLARE_ALIGNED(8, float, in_buf[SAMPLES*8]);
4753a5a1b3Sopenharmony_ci    float *out, *out_ref;
4853a5a1b3Sopenharmony_ci    float *in;
4953a5a1b3Sopenharmony_ci    unsigned n_ic = remap_func->i_ss.channels;
5053a5a1b3Sopenharmony_ci    unsigned n_oc = remap_func->o_ss.channels;
5153a5a1b3Sopenharmony_ci    unsigned i, nsamples;
5253a5a1b3Sopenharmony_ci
5353a5a1b3Sopenharmony_ci    pa_assert(n_ic >= 1 && n_ic <= 8);
5453a5a1b3Sopenharmony_ci    pa_assert(n_oc >= 1 && n_oc <= 8);
5553a5a1b3Sopenharmony_ci
5653a5a1b3Sopenharmony_ci    /* Force sample alignment as requested */
5753a5a1b3Sopenharmony_ci    out = out_buf + (8 - align);
5853a5a1b3Sopenharmony_ci    out_ref = out_buf_ref + (8 - align);
5953a5a1b3Sopenharmony_ci    in = in_buf + (8 - align);
6053a5a1b3Sopenharmony_ci    nsamples = SAMPLES - (8 - align);
6153a5a1b3Sopenharmony_ci
6253a5a1b3Sopenharmony_ci    for (i = 0; i < nsamples * n_ic; i++)
6353a5a1b3Sopenharmony_ci        in[i] = 2.1f * (rand()/(float) RAND_MAX - 0.5f);
6453a5a1b3Sopenharmony_ci
6553a5a1b3Sopenharmony_ci    if (correct) {
6653a5a1b3Sopenharmony_ci        remap_orig->do_remap(remap_orig, out_ref, in, nsamples);
6753a5a1b3Sopenharmony_ci        remap_func->do_remap(remap_func, out, in, nsamples);
6853a5a1b3Sopenharmony_ci
6953a5a1b3Sopenharmony_ci        for (i = 0; i < nsamples * n_oc; i++) {
7053a5a1b3Sopenharmony_ci            if (fabsf(out[i] - out_ref[i]) > 0.0001f) {
7153a5a1b3Sopenharmony_ci                pa_log_debug("Correctness test failed: align=%d", align);
7253a5a1b3Sopenharmony_ci                pa_log_debug("%d: %.24f != %.24f", i,
7353a5a1b3Sopenharmony_ci                    out[i], out_ref[i]);
7453a5a1b3Sopenharmony_ci                ck_abort();
7553a5a1b3Sopenharmony_ci            }
7653a5a1b3Sopenharmony_ci        }
7753a5a1b3Sopenharmony_ci    }
7853a5a1b3Sopenharmony_ci
7953a5a1b3Sopenharmony_ci    if (perf) {
8053a5a1b3Sopenharmony_ci        pa_log_debug("Testing remap performance with %d sample alignment", align);
8153a5a1b3Sopenharmony_ci
8253a5a1b3Sopenharmony_ci        PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) {
8353a5a1b3Sopenharmony_ci            remap_func->do_remap(remap_func, out, in, nsamples);
8453a5a1b3Sopenharmony_ci        } PA_RUNTIME_TEST_RUN_STOP
8553a5a1b3Sopenharmony_ci
8653a5a1b3Sopenharmony_ci        PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) {
8753a5a1b3Sopenharmony_ci            remap_orig->do_remap(remap_orig, out_ref, in, nsamples);
8853a5a1b3Sopenharmony_ci        } PA_RUNTIME_TEST_RUN_STOP
8953a5a1b3Sopenharmony_ci    }
9053a5a1b3Sopenharmony_ci}
9153a5a1b3Sopenharmony_ci
9253a5a1b3Sopenharmony_cistatic void run_remap_test_s16(
9353a5a1b3Sopenharmony_ci        pa_remap_t *remap_func,
9453a5a1b3Sopenharmony_ci        pa_remap_t *remap_orig,
9553a5a1b3Sopenharmony_ci        int align,
9653a5a1b3Sopenharmony_ci        bool correct,
9753a5a1b3Sopenharmony_ci        bool perf) {
9853a5a1b3Sopenharmony_ci
9953a5a1b3Sopenharmony_ci    PA_DECLARE_ALIGNED(8, int16_t, out_buf_ref[SAMPLES*8]) = { 0 };
10053a5a1b3Sopenharmony_ci    PA_DECLARE_ALIGNED(8, int16_t, out_buf[SAMPLES*8]) = { 0 };
10153a5a1b3Sopenharmony_ci    PA_DECLARE_ALIGNED(8, int16_t, in_buf[SAMPLES*8]);
10253a5a1b3Sopenharmony_ci    int16_t *out, *out_ref;
10353a5a1b3Sopenharmony_ci    int16_t *in;
10453a5a1b3Sopenharmony_ci    unsigned n_ic = remap_func->i_ss.channels;
10553a5a1b3Sopenharmony_ci    unsigned n_oc = remap_func->o_ss.channels;
10653a5a1b3Sopenharmony_ci    unsigned i, nsamples;
10753a5a1b3Sopenharmony_ci
10853a5a1b3Sopenharmony_ci    pa_assert(n_ic >= 1 && n_ic <= 8);
10953a5a1b3Sopenharmony_ci    pa_assert(n_oc >= 1 && n_oc <= 8);
11053a5a1b3Sopenharmony_ci
11153a5a1b3Sopenharmony_ci    /* Force sample alignment as requested */
11253a5a1b3Sopenharmony_ci    out = out_buf + (8 - align);
11353a5a1b3Sopenharmony_ci    out_ref = out_buf_ref + (8 - align);
11453a5a1b3Sopenharmony_ci    in = in_buf + (8 - align);
11553a5a1b3Sopenharmony_ci    nsamples = SAMPLES - (8 - align);
11653a5a1b3Sopenharmony_ci
11753a5a1b3Sopenharmony_ci    pa_random(in, nsamples * n_ic * sizeof(int16_t));
11853a5a1b3Sopenharmony_ci
11953a5a1b3Sopenharmony_ci    if (correct) {
12053a5a1b3Sopenharmony_ci        remap_orig->do_remap(remap_orig, out_ref, in, nsamples);
12153a5a1b3Sopenharmony_ci        remap_func->do_remap(remap_func, out, in, nsamples);
12253a5a1b3Sopenharmony_ci
12353a5a1b3Sopenharmony_ci        for (i = 0; i < nsamples * n_oc; i++) {
12453a5a1b3Sopenharmony_ci            if (abs(out[i] - out_ref[i]) > 3) {
12553a5a1b3Sopenharmony_ci                pa_log_debug("Correctness test failed: align=%d", align);
12653a5a1b3Sopenharmony_ci                pa_log_debug("%d: %d != %d", i, out[i], out_ref[i]);
12753a5a1b3Sopenharmony_ci                ck_abort();
12853a5a1b3Sopenharmony_ci            }
12953a5a1b3Sopenharmony_ci        }
13053a5a1b3Sopenharmony_ci    }
13153a5a1b3Sopenharmony_ci
13253a5a1b3Sopenharmony_ci    if (perf) {
13353a5a1b3Sopenharmony_ci        pa_log_debug("Testing remap performance with %d sample alignment", align);
13453a5a1b3Sopenharmony_ci
13553a5a1b3Sopenharmony_ci        PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) {
13653a5a1b3Sopenharmony_ci            remap_func->do_remap(remap_func, out, in, nsamples);
13753a5a1b3Sopenharmony_ci        } PA_RUNTIME_TEST_RUN_STOP
13853a5a1b3Sopenharmony_ci
13953a5a1b3Sopenharmony_ci        PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) {
14053a5a1b3Sopenharmony_ci            remap_orig->do_remap(remap_orig, out_ref, in, nsamples);
14153a5a1b3Sopenharmony_ci        } PA_RUNTIME_TEST_RUN_STOP
14253a5a1b3Sopenharmony_ci    }
14353a5a1b3Sopenharmony_ci}
14453a5a1b3Sopenharmony_ci
14553a5a1b3Sopenharmony_ci
14653a5a1b3Sopenharmony_cistatic void run_remap_test_s32(
14753a5a1b3Sopenharmony_ci        pa_remap_t *remap_func,
14853a5a1b3Sopenharmony_ci        pa_remap_t *remap_orig,
14953a5a1b3Sopenharmony_ci        int align,
15053a5a1b3Sopenharmony_ci        bool correct,
15153a5a1b3Sopenharmony_ci        bool perf) {
15253a5a1b3Sopenharmony_ci
15353a5a1b3Sopenharmony_ci    PA_DECLARE_ALIGNED(8, int32_t, out_buf_ref[SAMPLES*8]) = { 0 };
15453a5a1b3Sopenharmony_ci    PA_DECLARE_ALIGNED(8, int32_t, out_buf[SAMPLES*8]) = { 0 };
15553a5a1b3Sopenharmony_ci    PA_DECLARE_ALIGNED(8, int32_t, in_buf[SAMPLES*8]);
15653a5a1b3Sopenharmony_ci    int32_t *out, *out_ref;
15753a5a1b3Sopenharmony_ci    int32_t *in;
15853a5a1b3Sopenharmony_ci    unsigned n_ic = remap_func->i_ss.channels;
15953a5a1b3Sopenharmony_ci    unsigned n_oc = remap_func->o_ss.channels;
16053a5a1b3Sopenharmony_ci    unsigned i, nsamples;
16153a5a1b3Sopenharmony_ci
16253a5a1b3Sopenharmony_ci    pa_assert(n_ic >= 1 && n_ic <= 8);
16353a5a1b3Sopenharmony_ci    pa_assert(n_oc >= 1 && n_oc <= 8);
16453a5a1b3Sopenharmony_ci
16553a5a1b3Sopenharmony_ci    /* Force sample alignment as requested */
16653a5a1b3Sopenharmony_ci    out = out_buf + (8 - align);
16753a5a1b3Sopenharmony_ci    out_ref = out_buf_ref + (8 - align);
16853a5a1b3Sopenharmony_ci    in = in_buf + (8 - align);
16953a5a1b3Sopenharmony_ci    nsamples = SAMPLES - (8 - align);
17053a5a1b3Sopenharmony_ci
17153a5a1b3Sopenharmony_ci    pa_random(in, nsamples * n_ic * sizeof(int32_t));
17253a5a1b3Sopenharmony_ci
17353a5a1b3Sopenharmony_ci    if (correct) {
17453a5a1b3Sopenharmony_ci        remap_orig->do_remap(remap_orig, out_ref, in, nsamples);
17553a5a1b3Sopenharmony_ci        remap_func->do_remap(remap_func, out, in, nsamples);
17653a5a1b3Sopenharmony_ci
17753a5a1b3Sopenharmony_ci        for (i = 0; i < nsamples * n_oc; i++) {
17853a5a1b3Sopenharmony_ci            if (abs(out[i] - out_ref[i]) > 4) {
17953a5a1b3Sopenharmony_ci                pa_log_debug("Correctness test failed: align=%d", align);
18053a5a1b3Sopenharmony_ci                pa_log_debug("%d: %d != %d", i, out[i], out_ref[i]);
18153a5a1b3Sopenharmony_ci                ck_abort();
18253a5a1b3Sopenharmony_ci            }
18353a5a1b3Sopenharmony_ci        }
18453a5a1b3Sopenharmony_ci    }
18553a5a1b3Sopenharmony_ci
18653a5a1b3Sopenharmony_ci    if (perf) {
18753a5a1b3Sopenharmony_ci        pa_log_debug("Testing remap performance with %d sample alignment", align);
18853a5a1b3Sopenharmony_ci
18953a5a1b3Sopenharmony_ci        PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) {
19053a5a1b3Sopenharmony_ci            remap_func->do_remap(remap_func, out, in, nsamples);
19153a5a1b3Sopenharmony_ci        } PA_RUNTIME_TEST_RUN_STOP
19253a5a1b3Sopenharmony_ci
19353a5a1b3Sopenharmony_ci        PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) {
19453a5a1b3Sopenharmony_ci            remap_orig->do_remap(remap_orig, out_ref, in, nsamples);
19553a5a1b3Sopenharmony_ci        } PA_RUNTIME_TEST_RUN_STOP
19653a5a1b3Sopenharmony_ci    }
19753a5a1b3Sopenharmony_ci}
19853a5a1b3Sopenharmony_ci
19953a5a1b3Sopenharmony_cistatic void setup_remap_channels(
20053a5a1b3Sopenharmony_ci    pa_remap_t *m,
20153a5a1b3Sopenharmony_ci    pa_sample_format_t f,
20253a5a1b3Sopenharmony_ci    unsigned in_channels,
20353a5a1b3Sopenharmony_ci    unsigned out_channels,
20453a5a1b3Sopenharmony_ci    bool rearrange) {
20553a5a1b3Sopenharmony_ci
20653a5a1b3Sopenharmony_ci    unsigned i, o;
20753a5a1b3Sopenharmony_ci
20853a5a1b3Sopenharmony_ci    m->format = f;
20953a5a1b3Sopenharmony_ci    m->i_ss.channels = in_channels;
21053a5a1b3Sopenharmony_ci    m->o_ss.channels = out_channels;
21153a5a1b3Sopenharmony_ci
21253a5a1b3Sopenharmony_ci    if (rearrange) {
21353a5a1b3Sopenharmony_ci        for (o = 0; o < out_channels; o++) {
21453a5a1b3Sopenharmony_ci            for (i = 0; i < in_channels; i++) {
21553a5a1b3Sopenharmony_ci                m->map_table_f[o][i] = (o == i) ? 1.0f : 0.0f;
21653a5a1b3Sopenharmony_ci                m->map_table_i[o][i] = (o == i) ? 0x10000 : 0;
21753a5a1b3Sopenharmony_ci            }
21853a5a1b3Sopenharmony_ci        }
21953a5a1b3Sopenharmony_ci    } else {
22053a5a1b3Sopenharmony_ci        for (o = 0; o < out_channels; o++) {
22153a5a1b3Sopenharmony_ci            for (i = 0; i < in_channels; i++) {
22253a5a1b3Sopenharmony_ci                m->map_table_f[o][i] = 1.0f / in_channels;
22353a5a1b3Sopenharmony_ci                m->map_table_i[o][i] = 0x10000 / in_channels;
22453a5a1b3Sopenharmony_ci            }
22553a5a1b3Sopenharmony_ci        }
22653a5a1b3Sopenharmony_ci    }
22753a5a1b3Sopenharmony_ci}
22853a5a1b3Sopenharmony_ci
22953a5a1b3Sopenharmony_cistatic void remap_test_channels(
23053a5a1b3Sopenharmony_ci    pa_remap_t *remap_func, pa_remap_t *remap_orig) {
23153a5a1b3Sopenharmony_ci
23253a5a1b3Sopenharmony_ci    if (!remap_orig->do_remap) {
23353a5a1b3Sopenharmony_ci        pa_log_warn("No reference remapping function, abort test");
23453a5a1b3Sopenharmony_ci        return;
23553a5a1b3Sopenharmony_ci    }
23653a5a1b3Sopenharmony_ci
23753a5a1b3Sopenharmony_ci    if (!remap_func->do_remap || remap_func->do_remap == remap_orig->do_remap) {
23853a5a1b3Sopenharmony_ci        pa_log_warn("No remapping function, abort test");
23953a5a1b3Sopenharmony_ci        return;
24053a5a1b3Sopenharmony_ci    }
24153a5a1b3Sopenharmony_ci
24253a5a1b3Sopenharmony_ci    pa_assert(remap_func->format == remap_orig->format);
24353a5a1b3Sopenharmony_ci
24453a5a1b3Sopenharmony_ci    switch (remap_func->format) {
24553a5a1b3Sopenharmony_ci    case PA_SAMPLE_FLOAT32NE:
24653a5a1b3Sopenharmony_ci        run_remap_test_float(remap_func, remap_orig, 0, true, false);
24753a5a1b3Sopenharmony_ci        run_remap_test_float(remap_func, remap_orig, 1, true, false);
24853a5a1b3Sopenharmony_ci        run_remap_test_float(remap_func, remap_orig, 2, true, false);
24953a5a1b3Sopenharmony_ci        run_remap_test_float(remap_func, remap_orig, 3, true, true);
25053a5a1b3Sopenharmony_ci        break;
25153a5a1b3Sopenharmony_ci    case PA_SAMPLE_S32NE:
25253a5a1b3Sopenharmony_ci        run_remap_test_s32(remap_func, remap_orig, 0, true, false);
25353a5a1b3Sopenharmony_ci        run_remap_test_s32(remap_func, remap_orig, 1, true, false);
25453a5a1b3Sopenharmony_ci        run_remap_test_s32(remap_func, remap_orig, 2, true, false);
25553a5a1b3Sopenharmony_ci        run_remap_test_s32(remap_func, remap_orig, 3, true, true);
25653a5a1b3Sopenharmony_ci        break;
25753a5a1b3Sopenharmony_ci    case PA_SAMPLE_S16NE:
25853a5a1b3Sopenharmony_ci        run_remap_test_s16(remap_func, remap_orig, 0, true, false);
25953a5a1b3Sopenharmony_ci        run_remap_test_s16(remap_func, remap_orig, 1, true, false);
26053a5a1b3Sopenharmony_ci        run_remap_test_s16(remap_func, remap_orig, 2, true, false);
26153a5a1b3Sopenharmony_ci        run_remap_test_s16(remap_func, remap_orig, 3, true, true);
26253a5a1b3Sopenharmony_ci        break;
26353a5a1b3Sopenharmony_ci    default:
26453a5a1b3Sopenharmony_ci        pa_assert_not_reached();
26553a5a1b3Sopenharmony_ci    }
26653a5a1b3Sopenharmony_ci}
26753a5a1b3Sopenharmony_ci
26853a5a1b3Sopenharmony_cistatic void remap_init_test_channels(
26953a5a1b3Sopenharmony_ci        pa_init_remap_func_t init_func,
27053a5a1b3Sopenharmony_ci        pa_init_remap_func_t orig_init_func,
27153a5a1b3Sopenharmony_ci        pa_sample_format_t f,
27253a5a1b3Sopenharmony_ci        unsigned in_channels,
27353a5a1b3Sopenharmony_ci        unsigned out_channels,
27453a5a1b3Sopenharmony_ci        bool rearrange) {
27553a5a1b3Sopenharmony_ci
27653a5a1b3Sopenharmony_ci    pa_remap_t remap_orig = {0}, remap_func = {0};
27753a5a1b3Sopenharmony_ci
27853a5a1b3Sopenharmony_ci    setup_remap_channels(&remap_orig, f, in_channels, out_channels, rearrange);
27953a5a1b3Sopenharmony_ci    orig_init_func(&remap_orig);
28053a5a1b3Sopenharmony_ci
28153a5a1b3Sopenharmony_ci    setup_remap_channels(&remap_func, f, in_channels, out_channels, rearrange);
28253a5a1b3Sopenharmony_ci    init_func(&remap_func);
28353a5a1b3Sopenharmony_ci
28453a5a1b3Sopenharmony_ci    remap_test_channels(&remap_func, &remap_orig);
28553a5a1b3Sopenharmony_ci}
28653a5a1b3Sopenharmony_ci
28753a5a1b3Sopenharmony_cistatic void remap_init2_test_channels(
28853a5a1b3Sopenharmony_ci        pa_sample_format_t f,
28953a5a1b3Sopenharmony_ci        unsigned in_channels,
29053a5a1b3Sopenharmony_ci        unsigned out_channels,
29153a5a1b3Sopenharmony_ci        bool rearrange) {
29253a5a1b3Sopenharmony_ci
29353a5a1b3Sopenharmony_ci    pa_cpu_info cpu_info = { PA_CPU_UNDEFINED, {}, false };
29453a5a1b3Sopenharmony_ci    pa_remap_t remap_orig, remap_func = {0};
29553a5a1b3Sopenharmony_ci
29653a5a1b3Sopenharmony_ci    cpu_info.force_generic_code = true;
29753a5a1b3Sopenharmony_ci    pa_remap_func_init(&cpu_info);
29853a5a1b3Sopenharmony_ci    setup_remap_channels(&remap_orig, f, in_channels, out_channels, rearrange);
29953a5a1b3Sopenharmony_ci    pa_init_remap_func(&remap_orig);
30053a5a1b3Sopenharmony_ci
30153a5a1b3Sopenharmony_ci    cpu_info.force_generic_code = false;
30253a5a1b3Sopenharmony_ci    pa_remap_func_init(&cpu_info);
30353a5a1b3Sopenharmony_ci    setup_remap_channels(&remap_func, f, in_channels, out_channels, rearrange);
30453a5a1b3Sopenharmony_ci    pa_init_remap_func(&remap_func);
30553a5a1b3Sopenharmony_ci
30653a5a1b3Sopenharmony_ci    remap_test_channels(&remap_func, &remap_orig);
30753a5a1b3Sopenharmony_ci
30853a5a1b3Sopenharmony_ci    pa_xfree(remap_func.state);
30953a5a1b3Sopenharmony_ci}
31053a5a1b3Sopenharmony_ci
31153a5a1b3Sopenharmony_ciSTART_TEST (remap_special_test) {
31253a5a1b3Sopenharmony_ci    pa_log_debug("Checking special remap (float, mono->stereo)");
31353a5a1b3Sopenharmony_ci    remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 1, 2, false);
31453a5a1b3Sopenharmony_ci    pa_log_debug("Checking special remap (float, mono->4-channel)");
31553a5a1b3Sopenharmony_ci    remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 1, 4, false);
31653a5a1b3Sopenharmony_ci
31753a5a1b3Sopenharmony_ci    pa_log_debug("Checking special remap (s32, mono->stereo)");
31853a5a1b3Sopenharmony_ci    remap_init2_test_channels(PA_SAMPLE_S32NE, 1, 2, false);
31953a5a1b3Sopenharmony_ci    pa_log_debug("Checking special remap (s32, mono->4-channel)");
32053a5a1b3Sopenharmony_ci    remap_init2_test_channels(PA_SAMPLE_S32NE, 1, 4, false);
32153a5a1b3Sopenharmony_ci
32253a5a1b3Sopenharmony_ci    pa_log_debug("Checking special remap (s16, mono->stereo)");
32353a5a1b3Sopenharmony_ci    remap_init2_test_channels(PA_SAMPLE_S16NE, 1, 2, false);
32453a5a1b3Sopenharmony_ci    pa_log_debug("Checking special remap (s16, mono->4-channel)");
32553a5a1b3Sopenharmony_ci    remap_init2_test_channels(PA_SAMPLE_S16NE, 1, 4, false);
32653a5a1b3Sopenharmony_ci
32753a5a1b3Sopenharmony_ci    pa_log_debug("Checking special remap (float, stereo->mono)");
32853a5a1b3Sopenharmony_ci    remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 2, 1, false);
32953a5a1b3Sopenharmony_ci    pa_log_debug("Checking special remap (float, 4-channel->mono)");
33053a5a1b3Sopenharmony_ci    remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 4, 1, false);
33153a5a1b3Sopenharmony_ci
33253a5a1b3Sopenharmony_ci    pa_log_debug("Checking special remap (s32, stereo->mono)");
33353a5a1b3Sopenharmony_ci    remap_init2_test_channels(PA_SAMPLE_S32NE, 2, 1, false);
33453a5a1b3Sopenharmony_ci    pa_log_debug("Checking special remap (s32, 4-channel->mono)");
33553a5a1b3Sopenharmony_ci    remap_init2_test_channels(PA_SAMPLE_S32NE, 4, 1, false);
33653a5a1b3Sopenharmony_ci
33753a5a1b3Sopenharmony_ci    pa_log_debug("Checking special remap (s16, stereo->mono)");
33853a5a1b3Sopenharmony_ci    remap_init2_test_channels(PA_SAMPLE_S16NE, 2, 1, false);
33953a5a1b3Sopenharmony_ci    pa_log_debug("Checking special remap (s16, 4-channel->mono)");
34053a5a1b3Sopenharmony_ci    remap_init2_test_channels(PA_SAMPLE_S16NE, 4, 1, false);
34153a5a1b3Sopenharmony_ci}
34253a5a1b3Sopenharmony_ciEND_TEST
34353a5a1b3Sopenharmony_ci
34453a5a1b3Sopenharmony_ciSTART_TEST (rearrange_special_test) {
34553a5a1b3Sopenharmony_ci    pa_log_debug("Checking special remap (s16, stereo rearrange)");
34653a5a1b3Sopenharmony_ci    remap_init2_test_channels(PA_SAMPLE_S16NE, 2, 2, true);
34753a5a1b3Sopenharmony_ci    pa_log_debug("Checking special remap (s32, stereo rearrange)");
34853a5a1b3Sopenharmony_ci    remap_init2_test_channels(PA_SAMPLE_S32NE, 2, 2, true);
34953a5a1b3Sopenharmony_ci    pa_log_debug("Checking special remap (float, stereo rearrange)");
35053a5a1b3Sopenharmony_ci    remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 2, 2, true);
35153a5a1b3Sopenharmony_ci
35253a5a1b3Sopenharmony_ci    pa_log_debug("Checking special remap (s16, 4-channel rearrange)");
35353a5a1b3Sopenharmony_ci    remap_init2_test_channels(PA_SAMPLE_S16NE, 4, 4, true);
35453a5a1b3Sopenharmony_ci    pa_log_debug("Checking special remap (s32, 4-channel rearrange)");
35553a5a1b3Sopenharmony_ci    remap_init2_test_channels(PA_SAMPLE_S32NE, 4, 4, true);
35653a5a1b3Sopenharmony_ci    pa_log_debug("Checking special remap (float, 4-channel rearrange)");
35753a5a1b3Sopenharmony_ci    remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 4, 4, true);
35853a5a1b3Sopenharmony_ci}
35953a5a1b3Sopenharmony_ciEND_TEST
36053a5a1b3Sopenharmony_ci
36153a5a1b3Sopenharmony_ci#if (defined (__i386__) || defined (__amd64__)) && defined (HAVE_MMX)
36253a5a1b3Sopenharmony_ciSTART_TEST (remap_mmx_test) {
36353a5a1b3Sopenharmony_ci    pa_cpu_x86_flag_t flags = 0;
36453a5a1b3Sopenharmony_ci    pa_init_remap_func_t init_func, orig_init_func;
36553a5a1b3Sopenharmony_ci
36653a5a1b3Sopenharmony_ci    pa_cpu_get_x86_flags(&flags);
36753a5a1b3Sopenharmony_ci    if (!(flags & PA_CPU_X86_MMX)) {
36853a5a1b3Sopenharmony_ci        pa_log_info("MMX not supported. Skipping");
36953a5a1b3Sopenharmony_ci        return;
37053a5a1b3Sopenharmony_ci    }
37153a5a1b3Sopenharmony_ci
37253a5a1b3Sopenharmony_ci    pa_log_debug("Checking MMX remap (float, mono->stereo)");
37353a5a1b3Sopenharmony_ci    orig_init_func = pa_get_init_remap_func();
37453a5a1b3Sopenharmony_ci    pa_remap_func_init_mmx(flags);
37553a5a1b3Sopenharmony_ci    init_func = pa_get_init_remap_func();
37653a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 1, 2, false);
37753a5a1b3Sopenharmony_ci
37853a5a1b3Sopenharmony_ci    pa_log_debug("Checking MMX remap (s32, mono->stereo)");
37953a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S32NE, 1, 2, false);
38053a5a1b3Sopenharmony_ci
38153a5a1b3Sopenharmony_ci    pa_log_debug("Checking MMX remap (s16, mono->stereo)");
38253a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 1, 2, false);
38353a5a1b3Sopenharmony_ci}
38453a5a1b3Sopenharmony_ciEND_TEST
38553a5a1b3Sopenharmony_ci#endif /* (defined (__i386__) || defined (__amd64__)) && defined (HAVE_MMX) */
38653a5a1b3Sopenharmony_ci
38753a5a1b3Sopenharmony_ci#if (defined (__i386__) || defined (__amd64__)) && defined (HAVE_SSE)
38853a5a1b3Sopenharmony_ciSTART_TEST (remap_sse2_test) {
38953a5a1b3Sopenharmony_ci    pa_cpu_x86_flag_t flags = 0;
39053a5a1b3Sopenharmony_ci    pa_init_remap_func_t init_func, orig_init_func;
39153a5a1b3Sopenharmony_ci
39253a5a1b3Sopenharmony_ci    pa_cpu_get_x86_flags(&flags);
39353a5a1b3Sopenharmony_ci    if (!(flags & PA_CPU_X86_SSE2)) {
39453a5a1b3Sopenharmony_ci        pa_log_info("SSE2 not supported. Skipping");
39553a5a1b3Sopenharmony_ci        return;
39653a5a1b3Sopenharmony_ci    }
39753a5a1b3Sopenharmony_ci
39853a5a1b3Sopenharmony_ci    pa_log_debug("Checking SSE2 remap (float, mono->stereo)");
39953a5a1b3Sopenharmony_ci    orig_init_func = pa_get_init_remap_func();
40053a5a1b3Sopenharmony_ci    pa_remap_func_init_sse(flags);
40153a5a1b3Sopenharmony_ci    init_func = pa_get_init_remap_func();
40253a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 1, 2, false);
40353a5a1b3Sopenharmony_ci
40453a5a1b3Sopenharmony_ci    pa_log_debug("Checking SSE2 remap (s32, mono->stereo)");
40553a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S32NE, 1, 2, false);
40653a5a1b3Sopenharmony_ci
40753a5a1b3Sopenharmony_ci    pa_log_debug("Checking SSE2 remap (s16, mono->stereo)");
40853a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 1, 2, false);
40953a5a1b3Sopenharmony_ci}
41053a5a1b3Sopenharmony_ciEND_TEST
41153a5a1b3Sopenharmony_ci#endif /* (defined (__i386__) || defined (__amd64__)) && defined (HAVE_SSE) */
41253a5a1b3Sopenharmony_ci
41353a5a1b3Sopenharmony_ci#if defined (__arm__) && defined (__linux__) && defined (HAVE_NEON)
41453a5a1b3Sopenharmony_ciSTART_TEST (remap_neon_test) {
41553a5a1b3Sopenharmony_ci    pa_cpu_arm_flag_t flags = 0;
41653a5a1b3Sopenharmony_ci    pa_init_remap_func_t init_func, orig_init_func;
41753a5a1b3Sopenharmony_ci
41853a5a1b3Sopenharmony_ci    pa_cpu_get_arm_flags(&flags);
41953a5a1b3Sopenharmony_ci    if (!(flags & PA_CPU_ARM_NEON)) {
42053a5a1b3Sopenharmony_ci        pa_log_info("NEON not supported. Skipping");
42153a5a1b3Sopenharmony_ci        return;
42253a5a1b3Sopenharmony_ci    }
42353a5a1b3Sopenharmony_ci
42453a5a1b3Sopenharmony_ci    orig_init_func = pa_get_init_remap_func();
42553a5a1b3Sopenharmony_ci    pa_remap_func_init_neon(flags);
42653a5a1b3Sopenharmony_ci    init_func = pa_get_init_remap_func();
42753a5a1b3Sopenharmony_ci
42853a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (float, mono->stereo)");
42953a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 1, 2, false);
43053a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (float, mono->4-channel)");
43153a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 1, 4, false);
43253a5a1b3Sopenharmony_ci
43353a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (s32, mono->stereo)");
43453a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S32NE, 1, 2, false);
43553a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (s32, mono->4-channel)");
43653a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S32NE, 1, 4, false);
43753a5a1b3Sopenharmony_ci
43853a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (s16, mono->stereo)");
43953a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 1, 2, false);
44053a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (s16, mono->4-channel)");
44153a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 1, 4, false);
44253a5a1b3Sopenharmony_ci
44353a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (float, stereo->mono)");
44453a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 2, 1, false);
44553a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (float, 4-channel->mono)");
44653a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 4, 1, false);
44753a5a1b3Sopenharmony_ci
44853a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (s32, stereo->mono)");
44953a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S32NE, 2, 1, false);
45053a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (s32, 4-channel->mono)");
45153a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S32NE, 4, 1, false);
45253a5a1b3Sopenharmony_ci
45353a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (s16, stereo->mono)");
45453a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 2, 1, false);
45553a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (s16, 4-channel->mono)");
45653a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 4, 1, false);
45753a5a1b3Sopenharmony_ci
45853a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (float, 4-channel->4-channel)");
45953a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 4, 4, false);
46053a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (s32, 4-channel->4-channel)");
46153a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S32NE, 4, 4, false);
46253a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (s16, 4-channel->4-channel)");
46353a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 4, 4, false);
46453a5a1b3Sopenharmony_ci}
46553a5a1b3Sopenharmony_ciEND_TEST
46653a5a1b3Sopenharmony_ci
46753a5a1b3Sopenharmony_ciSTART_TEST (rearrange_neon_test) {
46853a5a1b3Sopenharmony_ci    pa_cpu_arm_flag_t flags = 0;
46953a5a1b3Sopenharmony_ci    pa_init_remap_func_t init_func, orig_init_func;
47053a5a1b3Sopenharmony_ci
47153a5a1b3Sopenharmony_ci    pa_cpu_get_arm_flags(&flags);
47253a5a1b3Sopenharmony_ci    if (!(flags & PA_CPU_ARM_NEON)) {
47353a5a1b3Sopenharmony_ci        pa_log_info("NEON not supported. Skipping");
47453a5a1b3Sopenharmony_ci        return;
47553a5a1b3Sopenharmony_ci    }
47653a5a1b3Sopenharmony_ci
47753a5a1b3Sopenharmony_ci    orig_init_func = pa_get_init_remap_func();
47853a5a1b3Sopenharmony_ci    pa_remap_func_init_neon(flags);
47953a5a1b3Sopenharmony_ci    init_func = pa_get_init_remap_func();
48053a5a1b3Sopenharmony_ci
48153a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (float, stereo rearrange)");
48253a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 2, 2, true);
48353a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (s32, stereo rearrange)");
48453a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S32NE, 2, 2, true);
48553a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (s16, stereo rearrange)");
48653a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 2, 2, true);
48753a5a1b3Sopenharmony_ci
48853a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (float, 2-channel->4-channel rearrange)");
48953a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 2, 4, true);
49053a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (s32, 2-channel->4-channel rearrange)");
49153a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S32NE, 2, 4, true);
49253a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (s16, 2-channel->4-channel rearrange)");
49353a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 2, 4, true);
49453a5a1b3Sopenharmony_ci
49553a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (float, 4-channel rearrange)");
49653a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 4, 4, true);
49753a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (s32, 4-channel rearrange)");
49853a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S32NE, 4, 4, true);
49953a5a1b3Sopenharmony_ci    pa_log_debug("Checking NEON remap (s16, 4-channel rearrange)");
50053a5a1b3Sopenharmony_ci    remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 4, 4, true);
50153a5a1b3Sopenharmony_ci}
50253a5a1b3Sopenharmony_ciEND_TEST
50353a5a1b3Sopenharmony_ci#endif
50453a5a1b3Sopenharmony_ci
50553a5a1b3Sopenharmony_ciint main(int argc, char *argv[]) {
50653a5a1b3Sopenharmony_ci    int failed = 0;
50753a5a1b3Sopenharmony_ci    Suite *s;
50853a5a1b3Sopenharmony_ci    TCase *tc;
50953a5a1b3Sopenharmony_ci    SRunner *sr;
51053a5a1b3Sopenharmony_ci
51153a5a1b3Sopenharmony_ci    if (!getenv("MAKE_CHECK"))
51253a5a1b3Sopenharmony_ci        pa_log_set_level(PA_LOG_DEBUG);
51353a5a1b3Sopenharmony_ci
51453a5a1b3Sopenharmony_ci    s = suite_create("CPU");
51553a5a1b3Sopenharmony_ci
51653a5a1b3Sopenharmony_ci    tc = tcase_create("remap");
51753a5a1b3Sopenharmony_ci    tcase_add_test(tc, remap_special_test);
51853a5a1b3Sopenharmony_ci#if (defined (__i386__) || defined (__amd64__)) && defined (HAVE_MMX)
51953a5a1b3Sopenharmony_ci    tcase_add_test(tc, remap_mmx_test);
52053a5a1b3Sopenharmony_ci#endif
52153a5a1b3Sopenharmony_ci#if (defined (__i386__) || defined (__amd64__)) && defined (HAVE_SSE)
52253a5a1b3Sopenharmony_ci    tcase_add_test(tc, remap_sse2_test);
52353a5a1b3Sopenharmony_ci#endif
52453a5a1b3Sopenharmony_ci#if defined (__arm__) && defined (__linux__) && defined (HAVE_NEON)
52553a5a1b3Sopenharmony_ci    tcase_add_test(tc, remap_neon_test);
52653a5a1b3Sopenharmony_ci#endif
52753a5a1b3Sopenharmony_ci    tcase_set_timeout(tc, 120);
52853a5a1b3Sopenharmony_ci    suite_add_tcase(s, tc);
52953a5a1b3Sopenharmony_ci
53053a5a1b3Sopenharmony_ci    tc = tcase_create("rearrange");
53153a5a1b3Sopenharmony_ci    tcase_add_test(tc, rearrange_special_test);
53253a5a1b3Sopenharmony_ci#if defined (__arm__) && defined (__linux__) && defined (HAVE_NEON)
53353a5a1b3Sopenharmony_ci    tcase_add_test(tc, rearrange_neon_test);
53453a5a1b3Sopenharmony_ci#endif
53553a5a1b3Sopenharmony_ci    tcase_set_timeout(tc, 120);
53653a5a1b3Sopenharmony_ci    suite_add_tcase(s, tc);
53753a5a1b3Sopenharmony_ci
53853a5a1b3Sopenharmony_ci    sr = srunner_create(s);
53953a5a1b3Sopenharmony_ci    srunner_run_all(sr, CK_NORMAL);
54053a5a1b3Sopenharmony_ci    failed = srunner_ntests_failed(sr);
54153a5a1b3Sopenharmony_ci    srunner_free(sr);
54253a5a1b3Sopenharmony_ci
54353a5a1b3Sopenharmony_ci    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
54453a5a1b3Sopenharmony_ci}
545