Skip to content

Commit b826d6c

Browse files
singalsulgirdwood
authored andcommitted
Test: Cmocka: Add unit test for function drc_inv_fixed()
This patch adds unit test for the inverse function used in DRC component. The function is tested with all used Q-formats for input and output with 500 points in the positive int32_t range. Negative numbers are not tested since the DRC specific function inverse function does not need and implement it. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent ba07074 commit b826d6c

4 files changed

Lines changed: 164 additions & 0 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
CONFIG_METEORLAKE=y
2+
CONFIG_COMP_DRC=y

test/cmocka/src/audio/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,6 @@ endif()
2222
if(CONFIG_COMP_FIR)
2323
add_subdirectory(eq_fir)
2424
endif()
25+
if(CONFIG_COMP_DRC)
26+
add_subdirectory(drc)
27+
endif()
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# SPDX-License-Identifier: BSD-3-Clause
2+
3+
cmocka_test(drc_math_test
4+
drc_math_test.c
5+
${PROJECT_SOURCE_DIR}/src/audio/drc/drc_math_generic.c
6+
${PROJECT_SOURCE_DIR}/src/audio/drc/drc_math_hifi3.c
7+
${PROJECT_SOURCE_DIR}/src/math/numbers.c
8+
${PROJECT_SOURCE_DIR}/src/math/exp_fcn.c
9+
${PROJECT_SOURCE_DIR}/src/math/exp_fcn_hifi.c
10+
)
11+
12+
target_include_directories(drc_math_test PRIVATE ${PROJECT_SOURCE_DIR}/src/audio)
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
//
3+
// Copyright(c) 2024 Intel Corporation.
4+
5+
#include <math.h>
6+
#include <stdbool.h>
7+
#include <stdarg.h>
8+
#include <stddef.h>
9+
#include <setjmp.h>
10+
#include <stdint.h>
11+
#include <stdio.h>
12+
#include <cmocka.h>
13+
14+
#include <drc/drc_math.h>
15+
16+
#define TEST_POINTS 500
17+
18+
#define ABS_DELTA_TOLERANCE_T1 1.0e-9
19+
#define REL_DELTA_TOLERANCE_T1 1.4e-4
20+
#define ABS_DELTA_TOLERANCE_T2 7.4e-7
21+
#define REL_DELTA_TOLERANCE_T2 7.5e-6
22+
#define ABS_DELTA_TOLERANCE_T3 3.8e-4
23+
#define REL_DELTA_TOLERANCE_T3 1.9e-6
24+
25+
static int32_t drc_inv_ref(int32_t x, int32_t precision_x, int32_t precision_y)
26+
{
27+
double xf, yf, ys;
28+
29+
xf = (double)x / ((int64_t)1 << precision_x);
30+
yf = 1 / xf;
31+
ys = round(yf * ((int64_t)1 << precision_y));
32+
if (ys > INT32_MAX)
33+
ys = INT32_MAX;
34+
35+
if (ys < INT32_MIN)
36+
ys = INT32_MIN;
37+
38+
return (int32_t)ys;
39+
}
40+
41+
static void drc_math_inv_fixed_test_helper(int32_t x_start, int32_t x_end,
42+
int32_t x_step, int q_in, int q_out,
43+
double abs_delta_tolerance, double rel_delta_tolerance)
44+
{
45+
double fx, fy1, fy2;
46+
double abs_delta, rel_delta;
47+
int64_t x1;
48+
int32_t x, y1, y2;
49+
int32_t differences = 0;
50+
double abs_delta_max = 0;
51+
double rel_delta_max = 0;
52+
53+
printf("%s: Testing q_in = %d q_out = %d in = %d:%d:%d\n", __func__,
54+
q_in, q_out, x_start, x_step, x_end);
55+
56+
x1 = x_start;
57+
while (x1 <= x_end) {
58+
x = (int32_t)x1;
59+
y1 = drc_inv_ref(x, q_in, q_out);
60+
y2 = drc_inv_fixed(x, q_in, q_out);
61+
if (y1 != y2)
62+
differences++;
63+
64+
fx = (double)x / (1 << q_in);
65+
fy1 = (double)y1 / (1 << q_out);
66+
fy2 = (double)y2 / (1 << q_out);
67+
abs_delta = fabs(fy1 - fy2);
68+
rel_delta = abs_delta / fy1;
69+
if (rel_delta > rel_delta_max)
70+
rel_delta_max = rel_delta;
71+
72+
if (abs_delta > abs_delta_max)
73+
abs_delta_max = abs_delta;
74+
75+
if (rel_delta > rel_delta_tolerance) {
76+
printf("%s: Relative error %g exceeds limit %g, input %g output %g ref %g.\n",
77+
__func__, rel_delta, rel_delta_tolerance, fx, fy2, fy1);
78+
assert_true(false);
79+
}
80+
81+
if (abs_delta > abs_delta_tolerance) {
82+
printf("%s: Absolute error %g exceeds limit %g, input %g output %g ref %g.\n",
83+
__func__, abs_delta, abs_delta_tolerance, fx, fy2, fy1);
84+
assert_true(false);
85+
}
86+
87+
x1 += x_step;
88+
}
89+
90+
printf("%s: bit exact differences count = %d\n", __func__, differences);
91+
printf("%s: Absolute max error was %.6e.\n", __func__, abs_delta_max);
92+
printf("%s: Relative max error was %.6e.\n", __func__, rel_delta_max);
93+
}
94+
95+
static void test_function_drc_inv_fixed_q12_q30(void **state)
96+
{
97+
(void)state;
98+
99+
int32_t x_start = 1;
100+
int32_t x_end = INT32_MAX;
101+
int32_t x_step = (int32_t)(((int64_t)x_end - (int64_t)x_start) / (TEST_POINTS - 1));
102+
int q_in = 12;
103+
int q_out = 30;
104+
105+
drc_math_inv_fixed_test_helper(x_start, x_end, x_step, q_in, q_out,
106+
ABS_DELTA_TOLERANCE_T1, REL_DELTA_TOLERANCE_T1);
107+
}
108+
109+
static void test_function_drc_inv_fixed_q22_q26(void **state)
110+
{
111+
(void)state;
112+
113+
int32_t x_start = 1;
114+
int32_t x_end = INT32_MAX;
115+
int32_t x_step = (int32_t)(((int64_t)x_end - (int64_t)x_start) / TEST_POINTS);
116+
int q_in = 22;
117+
int q_out = 26;
118+
119+
drc_math_inv_fixed_test_helper(x_start, x_end, x_step, q_in, q_out,
120+
ABS_DELTA_TOLERANCE_T2, REL_DELTA_TOLERANCE_T2);
121+
}
122+
123+
static void test_function_drc_inv_fixed_q31_q20(void **state)
124+
{
125+
(void)state;
126+
127+
int32_t x_start = 1;
128+
int32_t x_end = INT32_MAX;
129+
int32_t x_step = (int32_t)(((int64_t)x_end - (int64_t)x_start) / TEST_POINTS);
130+
int q_in = 31;
131+
int q_out = 20;
132+
133+
drc_math_inv_fixed_test_helper(x_start, x_end, x_step, q_in, q_out,
134+
ABS_DELTA_TOLERANCE_T3, REL_DELTA_TOLERANCE_T3);
135+
}
136+
137+
int main(void)
138+
{
139+
const struct CMUnitTest tests[] = {
140+
cmocka_unit_test(test_function_drc_inv_fixed_q12_q30),
141+
cmocka_unit_test(test_function_drc_inv_fixed_q22_q26),
142+
cmocka_unit_test(test_function_drc_inv_fixed_q31_q20),
143+
};
144+
145+
cmocka_set_message_output(CM_OUTPUT_TAP);
146+
147+
return cmocka_run_group_tests(tests, NULL, NULL);
148+
}

0 commit comments

Comments
 (0)