[pulseaudio-discuss] [PATCH 09/10] cpu-test: Add test cases for remap, remap_neon
Peter Meerwald
pmeerw at pmeerw.net
Fri Mar 29 08:56:50 PDT 2013
From: Peter Meerwald <p.meerwald at bct-electronic.com>
add 4-channel remapping tests
Signed-off-by: Peter Meerwald <p.meerwald at bct-electronic.com>
---
src/tests/cpu-test.c | 304 ++++++++++++++++++++++++++++++++++++++------------
1 file changed, 231 insertions(+), 73 deletions(-)
diff --git a/src/tests/cpu-test.c b/src/tests/cpu-test.c
index 3aa73f2..ea18eef 100644
--- a/src/tests/cpu-test.c
+++ b/src/tests/cpu-test.c
@@ -273,7 +273,7 @@ static void run_conv_test_float_to_s16(
PA_DECLARE_ALIGNED(8, int16_t, s[SAMPLES]) = { 0 };
PA_DECLARE_ALIGNED(8, int16_t, s_ref[SAMPLES]) = { 0 };
- PA_DECLARE_ALIGNED(8, float, f[SAMPLES]);
+ PA_DECLARE_ALIGNED(8, float, f[SAMPLES]) = { 0 };
int16_t *samples, *samples_ref;
float *floats;
int i, nsamples;
@@ -326,7 +326,7 @@ static void run_conv_test_s16_to_float(
PA_DECLARE_ALIGNED(8, float, f[SAMPLES]) = { 0 };
PA_DECLARE_ALIGNED(8, float, f_ref[SAMPLES]) = { 0 };
- PA_DECLARE_ALIGNED(8, int16_t, s[SAMPLES]);
+ PA_DECLARE_ALIGNED(8, int16_t, s[SAMPLES]) = { 0 };
float *floats, *floats_ref;
int16_t *samples;
int i, nsamples;
@@ -476,38 +476,38 @@ END_TEST
#define TIMES 1000
#define TIMES2 100
-static void run_remap_test_mono_stereo_float(
+static void run_remap_test_mono_channels_float(
pa_remap_t *remap,
- pa_do_remap_func_t func,
- pa_do_remap_func_t orig_func,
- int align,
- pa_bool_t correct,
- pa_bool_t perf) {
+ pa_do_remap_func_t func, pa_do_remap_func_t orig_func,
+ int channels,
+ int align, pa_bool_t correct, pa_bool_t perf) {
- PA_DECLARE_ALIGNED(8, float, s_ref[SAMPLES*2]) = { 0 };
- PA_DECLARE_ALIGNED(8, float, s[SAMPLES*2]) = { 0 };
- PA_DECLARE_ALIGNED(8, float, m[SAMPLES]);
- float *stereo, *stereo_ref;
+ PA_DECLARE_ALIGNED(8, float, out_ref[SAMPLES*8]) = { 0 };
+ PA_DECLARE_ALIGNED(8, float, out[SAMPLES*8]) = { 0 };
+ PA_DECLARE_ALIGNED(8, float, in[SAMPLES]) = { 0 };
+ float *ch, *ch_ref;
float *mono;
int i, nsamples;
+ assert(channels == 2 || channels == 4 || channels == 8);
+
/* Force sample alignment as requested */
- stereo = s + (8 - align);
- stereo_ref = s_ref + (8 - align);
- mono = m + (8 - align);
+ ch = out + (8 - align);
+ ch_ref = out_ref + (8 - align);
+ mono = in + (8 - align);
nsamples = SAMPLES - (8 - align);
for (i = 0; i < nsamples; i++)
mono[i] = 2.1f * (rand()/(float) RAND_MAX - 0.5f);
if (correct) {
- orig_func(remap, stereo_ref, mono, nsamples);
- func(remap, stereo, mono, nsamples);
+ orig_func(remap, ch_ref, mono, nsamples);
+ func(remap, ch, mono, nsamples);
- for (i = 0; i < nsamples * 2; i++) {
- if (fabsf(stereo[i] - stereo_ref[i]) > 0.0001) {
+ for (i = 0; i < nsamples * channels; i++) {
+ if (fabsf(ch[i] - ch_ref[i]) > 0.0001) {
pa_log_debug("Correctness test failed: align=%d", align);
- pa_log_debug("%d: %.24f != %.24f (%.24f)\n", i, stereo[i], stereo_ref[i], mono[i]);
+ pa_log_debug("%d: %.24f != %.24f (%.24f)\n", i, ch[i], ch_ref[i], mono[i]);
fail();
}
}
@@ -517,46 +517,46 @@ static void run_remap_test_mono_stereo_float(
pa_log_debug("Testing remap performance with %d sample alignment", align);
PA_CPU_TEST_RUN_START("func", TIMES, TIMES2) {
- func(remap, stereo, mono, nsamples);
+ func(remap, ch, mono, nsamples);
} PA_CPU_TEST_RUN_STOP
PA_CPU_TEST_RUN_START("orig", TIMES, TIMES2) {
- orig_func(remap, stereo_ref, mono, nsamples);
+ orig_func(remap, ch_ref, mono, nsamples);
} PA_CPU_TEST_RUN_STOP
}
}
-static void run_remap_test_mono_stereo_s16(
+static void run_remap_test_mono_channels_s16(
pa_remap_t *remap,
- pa_do_remap_func_t func,
- pa_do_remap_func_t orig_func,
- int align,
- pa_bool_t correct,
- pa_bool_t perf) {
+ pa_do_remap_func_t func, pa_do_remap_func_t orig_func,
+ int channels,
+ int align, pa_bool_t correct, pa_bool_t perf) {
- PA_DECLARE_ALIGNED(8, int16_t, s_ref[SAMPLES*2]) = { 0 };
- PA_DECLARE_ALIGNED(8, int16_t, s[SAMPLES*2]) = { 0 };
- PA_DECLARE_ALIGNED(8, int16_t, m[SAMPLES]);
- int16_t *stereo, *stereo_ref;
+ PA_DECLARE_ALIGNED(8, int16_t, out_ref[SAMPLES*8]) = { 0 };
+ PA_DECLARE_ALIGNED(8, int16_t, out[SAMPLES*8]) = { 0 };
+ PA_DECLARE_ALIGNED(8, int16_t, in[SAMPLES]) = { 0 };
+ int16_t *ch, *ch_ref;
int16_t *mono;
int i, nsamples;
+ assert(channels == 2 || channels == 4 || channels == 8);
+
/* Force sample alignment as requested */
- stereo = s + (8 - align);
- stereo_ref = s_ref + (8 - align);
- mono = m + (8 - align);
+ ch = out + (8 - align);
+ ch_ref = out_ref + (8 - align);
+ mono = in + (8 - align);
nsamples = SAMPLES - (8 - align);
pa_random(mono, nsamples * sizeof(int16_t));
if (correct) {
- orig_func(remap, stereo_ref, mono, nsamples);
- func(remap, stereo, mono, nsamples);
+ orig_func(remap, ch_ref, mono, nsamples);
+ func(remap, ch, mono, nsamples);
- for (i = 0; i < nsamples * 2; i++) {
- if (abs(stereo[i] - stereo_ref[i]) > 1) {
+ for (i = 0; i < nsamples * channels; i++) {
+ if (abs(ch[i] - ch_ref[i]) > 1) {
pa_log_debug("Correctness test failed: align=%d", align);
- pa_log_debug("%d: %d != %d (%d)\n", i, stereo[i], stereo_ref[i], mono[i]);
+ pa_log_debug("%d: %d != %d (%d)\n", i, ch[i], ch_ref[i], mono[i]);
fail();
}
}
@@ -566,34 +566,35 @@ static void run_remap_test_mono_stereo_s16(
pa_log_debug("Testing remap performance with %d sample alignment", align);
PA_CPU_TEST_RUN_START("func", TIMES, TIMES2) {
- func(remap, stereo, mono, nsamples);
+ func(remap, ch, mono, nsamples);
} PA_CPU_TEST_RUN_STOP
PA_CPU_TEST_RUN_START("orig", TIMES, TIMES2) {
- orig_func(remap, stereo_ref, mono, nsamples);
+ orig_func(remap, ch_ref, mono, nsamples);
} PA_CPU_TEST_RUN_STOP
}
}
-static void remap_test_mono_stereo_float(
- pa_init_remap_func_t init_func,
- pa_init_remap_func_t orig_init_func) {
+static void remap_test_mono_channels(
+ pa_init_remap_func_t init_func, pa_init_remap_func_t orig_init_func,
+ pa_sample_format_t format, int channels) {
pa_sample_format_t sf;
pa_remap_t remap;
pa_sample_spec iss, oss;
pa_do_remap_func_t orig_func, func;
+ int i;
- iss.format = oss.format = sf = PA_SAMPLE_FLOAT32NE;
+ iss.format = oss.format = sf = format;
iss.channels = 1;
- oss.channels = 2;
+ oss.channels = channels;
remap.format = &sf;
remap.i_ss = &iss;
remap.o_ss = &oss;
- remap.map_table_f[0][0] = 1.0;
- remap.map_table_f[1][0] = 1.0;
- remap.map_table_i[0][0] = 0x10000;
- remap.map_table_i[1][0] = 0x10000;
+ for (i = 0; i < channels; i++) {
+ remap.map_table_f[i][0] = 1.0f;
+ remap.map_table_i[i][0] = PA_VOLUME_NORM;
+ }
orig_init_func(&remap);
orig_func = remap.do_remap;
if (!orig_func) {
@@ -608,31 +609,136 @@ static void remap_test_mono_stereo_float(
return;
}
- run_remap_test_mono_stereo_float(&remap, func, orig_func, 0, TRUE, FALSE);
- run_remap_test_mono_stereo_float(&remap, func, orig_func, 1, TRUE, FALSE);
- run_remap_test_mono_stereo_float(&remap, func, orig_func, 2, TRUE, FALSE);
- run_remap_test_mono_stereo_float(&remap, func, orig_func, 3, TRUE, TRUE);
+ if (format == PA_SAMPLE_FLOAT32NE) {
+ run_remap_test_mono_channels_float(&remap, func, orig_func, channels, 0, TRUE, FALSE);
+ run_remap_test_mono_channels_float(&remap, func, orig_func, channels, 1, TRUE, FALSE);
+ run_remap_test_mono_channels_float(&remap, func, orig_func, channels, 2, TRUE, FALSE);
+ run_remap_test_mono_channels_float(&remap, func, orig_func, channels, 3, TRUE, TRUE);
+ } else if (format == PA_SAMPLE_S16NE) {
+ run_remap_test_mono_channels_s16(&remap, func, orig_func, channels, 0, TRUE, FALSE);
+ run_remap_test_mono_channels_s16(&remap, func, orig_func, channels, 1, TRUE, FALSE);
+ run_remap_test_mono_channels_s16(&remap, func, orig_func, channels, 2, TRUE, FALSE);
+ run_remap_test_mono_channels_s16(&remap, func, orig_func, channels, 3, TRUE, TRUE);
+ } else pa_assert_not_reached();
}
-static void remap_test_mono_stereo_s16(
- pa_init_remap_func_t init_func,
- pa_init_remap_func_t orig_init_func) {
+static void run_remap_test_channels_mono_float(
+ pa_remap_t *remap,
+ pa_do_remap_func_t func, pa_do_remap_func_t orig_func,
+ int channels, int align, pa_bool_t correct, pa_bool_t perf) {
+
+ PA_DECLARE_ALIGNED(8, float, in[SAMPLES*8]) = { 0 };
+ PA_DECLARE_ALIGNED(8, float, out[SAMPLES]) = { 0 };
+ PA_DECLARE_ALIGNED(8, float, out_ref[SAMPLES]) = { 0 };
+ float *ch;
+ float *mono, *mono_ref;
+ int i, nsamples;
+
+ assert(channels == 2 || channels == 4 || channels == 8);
+
+ /* Force sample alignment as requested */
+ ch = in + (8 - align);
+ mono_ref = out_ref + (8 - align);
+ mono = out + (8 - align);
+ nsamples = SAMPLES - (8 - align);
+
+ for (i = 0; i < nsamples * channels; i++)
+ ch[i] = 2.1f * (rand()/(float) RAND_MAX - 0.5f);
+
+ if (correct) {
+ orig_func(remap, mono_ref, ch, nsamples);
+ func(remap, mono, ch, nsamples);
+
+ for (i = 0; i < nsamples; i++) {
+ if (fabsf(mono[i] - mono_ref[i]) > 0.0001) {
+ pa_log_debug("Correctness test failed: align=%d", align);
+ pa_log_debug("%d: %.24f != %.24f\n", i, mono[i], mono_ref[i]);
+ fail();
+ }
+ }
+ }
+
+ if (perf) {
+ pa_log_debug("Testing remap performance with %d sample alignment", align);
+
+ PA_CPU_TEST_RUN_START("func", TIMES, TIMES2) {
+ func(remap, mono, ch, nsamples);
+ } PA_CPU_TEST_RUN_STOP
+
+ PA_CPU_TEST_RUN_START("orig", TIMES, TIMES2) {
+ orig_func(remap, mono_ref, ch, nsamples);
+ } PA_CPU_TEST_RUN_STOP
+ }
+}
+
+static void run_remap_test_channels_mono_s16(
+ pa_remap_t *remap,
+ pa_do_remap_func_t func, pa_do_remap_func_t orig_func,
+ int channels, int align, pa_bool_t correct, pa_bool_t perf) {
+
+ PA_DECLARE_ALIGNED(8, int16_t, in[SAMPLES*8]) = { 0 };
+ PA_DECLARE_ALIGNED(8, int16_t, out[SAMPLES]) = { 0 };
+ PA_DECLARE_ALIGNED(8, int16_t, out_ref[SAMPLES]) = { 0 };
+ int16_t *ch;
+ int16_t *mono, *mono_ref;
+ int i, nsamples;
+
+ assert(channels == 2 || channels == 4 || channels == 8);
+
+ /* Force sample alignment as requested */
+ ch = in + (8 - align);
+ mono_ref = out_ref + (8 - align);
+ mono = out + (8 - align);
+ nsamples = SAMPLES - (8 - align);
+
+ pa_random(ch, nsamples * channels * sizeof(int16_t));
+
+ if (correct) {
+ orig_func(remap, mono_ref, ch, nsamples);
+ func(remap, mono, ch, nsamples);
+
+ for (i = 0; i < nsamples; i++) {
+ if (abs(mono[i] - mono_ref[i]) > 1) {
+ pa_log_debug("Correctness test failed: align=%d", align);
+ pa_log_debug("%d: %hx != %hx\n", i, mono[i], mono_ref[i]);
+ fail();
+ }
+ }
+ }
+
+ if (perf) {
+ pa_log_debug("Testing remap performance with %d sample alignment", align);
+
+ PA_CPU_TEST_RUN_START("func", TIMES, TIMES2) {
+ func(remap, mono, ch, nsamples);
+ } PA_CPU_TEST_RUN_STOP
+
+ PA_CPU_TEST_RUN_START("orig", TIMES, TIMES2) {
+ orig_func(remap, mono_ref, ch, nsamples);
+ } PA_CPU_TEST_RUN_STOP
+ }
+}
+
+static void remap_test_channels_mono(
+ pa_init_remap_func_t init_func, pa_init_remap_func_t orig_init_func,
+ pa_sample_format_t format, int channels) {
pa_sample_format_t sf;
pa_remap_t remap;
pa_sample_spec iss, oss;
pa_do_remap_func_t orig_func, func;
+ int i;
- iss.format = oss.format = sf = PA_SAMPLE_S16NE;
- iss.channels = 1;
- oss.channels = 2;
+ iss.format = oss.format = sf = format;
+ iss.channels = channels;
+ oss.channels = 1;
remap.format = &sf;
remap.i_ss = &iss;
remap.o_ss = &oss;
- remap.map_table_f[0][0] = 1.0;
- remap.map_table_f[1][0] = 1.0;
- remap.map_table_i[0][0] = 0x10000;
- remap.map_table_i[1][0] = 0x10000;
+ for (i = 0; i < channels; i++) {
+ remap.map_table_f[0][i] = 1.0f / channels;
+ remap.map_table_i[0][i] = PA_VOLUME_NORM / channels;
+ }
orig_init_func(&remap);
orig_func = remap.do_remap;
if (!orig_func) {
@@ -647,10 +753,17 @@ static void remap_test_mono_stereo_s16(
return;
}
- run_remap_test_mono_stereo_s16(&remap, func, orig_func, 0, TRUE, FALSE);
- run_remap_test_mono_stereo_s16(&remap, func, orig_func, 1, TRUE, FALSE);
- run_remap_test_mono_stereo_s16(&remap, func, orig_func, 2, TRUE, FALSE);
- run_remap_test_mono_stereo_s16(&remap, func, orig_func, 3, TRUE, TRUE);
+ if (format == PA_SAMPLE_FLOAT32NE) {
+ run_remap_test_channels_mono_float(&remap, func, orig_func, channels, 0, TRUE, FALSE);
+ run_remap_test_channels_mono_float(&remap, func, orig_func, channels, 1, TRUE, FALSE);
+ run_remap_test_channels_mono_float(&remap, func, orig_func, channels, 2, TRUE, FALSE);
+ run_remap_test_channels_mono_float(&remap, func, orig_func, channels, 3, TRUE, TRUE);
+ } else if (format == PA_SAMPLE_S16NE) {
+ run_remap_test_channels_mono_s16(&remap, func, orig_func, channels, 0, TRUE, FALSE);
+ run_remap_test_channels_mono_s16(&remap, func, orig_func, channels, 1, TRUE, FALSE);
+ run_remap_test_channels_mono_s16(&remap, func, orig_func, channels, 2, TRUE, FALSE);
+ run_remap_test_channels_mono_s16(&remap, func, orig_func, channels, 3, TRUE, TRUE);
+ } else pa_assert_not_reached();
}
#if defined (__i386__) || defined (__amd64__)
@@ -668,10 +781,10 @@ START_TEST (remap_mmx_test) {
orig_init_func = pa_get_init_remap_func();
pa_remap_func_init_mmx(flags);
init_func = pa_get_init_remap_func();
- remap_test_mono_stereo_float(init_func, orig_init_func);
+ remap_test_mono_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 2);
pa_log_debug("Checking MMX remap (s16, mono->stereo)");
- remap_test_mono_stereo_s16(init_func, orig_init_func);
+ remap_test_mono_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 2);
}
END_TEST
@@ -689,14 +802,54 @@ START_TEST (remap_sse2_test) {
orig_init_func = pa_get_init_remap_func();
pa_remap_func_init_sse(flags);
init_func = pa_get_init_remap_func();
- remap_test_mono_stereo_float(init_func, orig_init_func);
+ remap_test_mono_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 2);
pa_log_debug("Checking SSE2 remap (s16, mono->stereo)");
- remap_test_mono_stereo_s16(init_func, orig_init_func);
+ remap_test_mono_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 2);
}
END_TEST
#endif /* defined (__i386__) || defined (__amd64__) */
+#if defined (__arm__) && defined (__linux__)
+#ifdef HAVE_NEON
+START_TEST (remap_neon_test) {
+ pa_cpu_arm_flag_t flags = 0;
+ pa_init_remap_func_t init_func, orig_init_func;
+
+ pa_cpu_get_arm_flags(&flags);
+ if (!(flags & PA_CPU_ARM_NEON)) {
+ pa_log_info("NEON not supported. Skipping");
+ return;
+ }
+
+ pa_log_debug("Checking NEON remap (float, mono->stereo)");
+ orig_init_func = pa_get_init_remap_func();
+ pa_remap_func_init_neon(flags);
+ init_func = pa_get_init_remap_func();
+ remap_test_mono_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 2);
+
+ pa_log_debug("Checking NEON remap (float, mono->ch4)");
+ remap_test_mono_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 4);
+
+ pa_log_debug("Checking NEON remap (s16, mono->stereo)");
+ remap_test_mono_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 2);
+ pa_log_debug("Checking NEON remap (s16, mono->ch4)");
+ remap_test_mono_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 4);
+
+ pa_log_debug("Checking NEON remap (float, stereo->mono)");
+ remap_test_channels_mono(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 2);
+ pa_log_debug("Checking NEON remap (float, ch4->mono)");
+ remap_test_channels_mono(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 4);
+
+ pa_log_debug("Checking NEON remap (s16, stereo->mono)");
+ remap_test_channels_mono(init_func, orig_init_func, PA_SAMPLE_S16NE, 2);
+ pa_log_debug("Checking NEON remap (s16, ch4->mono)");
+ remap_test_channels_mono(init_func, orig_init_func, PA_SAMPLE_S16NE, 4);
+}
+END_TEST
+#endif
+#endif
+
#undef SAMPLES
#undef TIMES
#undef TIMES2
@@ -896,6 +1049,11 @@ int main(int argc, char *argv[]) {
tcase_add_test(tc, remap_mmx_test);
tcase_add_test(tc, remap_sse2_test);
#endif
+#if defined (__arm__) && defined (__linux__)
+#if HAVE_NEON
+ tcase_add_test(tc, remap_neon_test);
+#endif
+#endif
tcase_set_timeout(tc, 120);
suite_add_tcase(s, tc);
/* Mix tests */
--
1.7.9.5
More information about the pulseaudio-discuss
mailing list