Skip to content

Commit b33fc23

Browse files
committed
tests: audio: Add unit test for eq_fir
Add ZTest unit test validating module creation, configuration, prepare, copy, and teardown lifecycle for the eq_fir component. Includes passthrough configuration blob for 2-channel operation. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
1 parent d956015 commit b33fc23

2 files changed

Lines changed: 194 additions & 0 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/* SPDX-License-Identifier: BSD-3-Clause
2+
*
3+
* Copyright(c) 2026 Intel Corporation.
4+
*
5+
* EQ FIR passthrough config for 2 channels
6+
* Auto-generated by gen_ztest_blobs.m - do not edit.
7+
*/
8+
9+
#ifndef ZTEST_BLOB_EQ_FIR_BLOB_H
10+
#define ZTEST_BLOB_EQ_FIR_BLOB_H
11+
12+
#include <stdint.h>
13+
14+
static const uint32_t eq_fir_blob[22] = {
15+
0x34464f53, 0x00000000, 0x00000038, 0x0301d001,
16+
0x00000000, 0x00000000, 0x00000000, 0x00000000,
17+
0x00000038, 0x00010002, 0x00000000, 0x00000000,
18+
0x00000000, 0x00000000, 0x00000000, 0xffff0004,
19+
0x00000000, 0x00000000, 0x00000000, 0x00000000,
20+
0x00004000, 0x00000000
21+
};
22+
23+
#endif /* ZTEST_BLOB_EQ_FIR_BLOB_H */

zephyr/test/audio/test_eq_fir.c

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
/*
3+
* Copyright(c) 2026 Intel Corporation.
4+
*/
5+
6+
#include <zephyr/kernel.h>
7+
#include <zephyr/ztest.h>
8+
#include <string.h>
9+
#include <rtos/sof.h>
10+
#include <sof/list.h>
11+
#include <sof/audio/component.h>
12+
#include <sof/audio/component_ext.h>
13+
#include <sof/audio/pipeline.h>
14+
#include <sof/ipc/topology.h>
15+
#include <ipc4/base-config.h>
16+
17+
#include <rtos/alloc.h>
18+
#include <user/eq.h>
19+
#include <user/fir.h>
20+
#include "test_audio_helper.h"
21+
22+
extern void sys_comp_module_eq_fir_interface_init(void);
23+
24+
static void *setup(void)
25+
{
26+
struct sof *sof = sof_get();
27+
28+
sys_comp_init(sof);
29+
30+
if (!sof->ipc) {
31+
sof->ipc = rzalloc(SOF_MEM_FLAG_COHERENT, sizeof(*sof->ipc));
32+
sof->ipc->comp_data = rzalloc(SOF_MEM_FLAG_COHERENT, 4096);
33+
k_spinlock_init(&sof->ipc->lock);
34+
list_init(&sof->ipc->msg_list);
35+
list_init(&sof->ipc->comp_list);
36+
}
37+
38+
sys_comp_module_eq_fir_interface_init();
39+
return NULL;
40+
}
41+
42+
/* EQ_FIR_UUID */
43+
SOF_DEFINE_UUID("eq_fir_test", eq_fir_test_uuid, 0x43a90ce7, 0xf3a5, 0x41df,
44+
0xac, 0x06, 0xba, 0x98, 0x65, 0x1a, 0xe6, 0xa3);
45+
46+
struct custom_ipc4_config_eq_fir {
47+
struct ipc4_base_module_cfg base;
48+
} __attribute__((packed, aligned(4)));
49+
50+
/* Test EQ_FIR initialization */
51+
static struct comp_dev *test_eq_fir_create(void)
52+
{
53+
struct comp_dev *comp;
54+
struct comp_ipc_config ipc_config;
55+
struct ipc_config_process spec;
56+
struct custom_ipc4_config_eq_fir init_data;
57+
58+
memset(&init_data, 0, sizeof(init_data));
59+
memset(&init_data.base.audio_fmt, 0, sizeof(init_data.base.audio_fmt));
60+
init_data.base.audio_fmt.channels_count = 2;
61+
init_data.base.audio_fmt.sampling_frequency = 48000;
62+
init_data.base.audio_fmt.depth = 32;
63+
init_data.base.audio_fmt.valid_bit_depth = 32;
64+
init_data.base.audio_fmt.interleaving_style = IPC4_CHANNELS_INTERLEAVED;
65+
66+
/* Setup basic IPC configuration */
67+
memset(&ipc_config, 0, sizeof(ipc_config));
68+
ipc_config.id = 1;
69+
ipc_config.pipeline_id = 1;
70+
ipc_config.core = 0;
71+
72+
memset(&spec, 0, sizeof(spec));
73+
spec.size = sizeof(init_data);
74+
spec.data = (unsigned char *)&init_data;
75+
76+
struct list_item *clist;
77+
const struct comp_driver *drv = NULL;
78+
79+
/* Find EQ_FIR driver by UUID */
80+
list_for_item(clist, &comp_drivers_get()->list) {
81+
struct comp_driver_info *info = container_of(clist, struct comp_driver_info, list);
82+
if (!info->drv->uid) continue;
83+
if (!memcmp(info->drv->uid, &eq_fir_test_uuid, sizeof(struct sof_uuid))) {
84+
drv = info->drv;
85+
break;
86+
}
87+
}
88+
zassert_not_null(drv, "Driver for EQ_FIR not found");
89+
90+
/* Initialize EQ_FIR component via ops */
91+
comp = drv->ops.create(drv, &ipc_config, &spec);
92+
zassert_not_null(comp, "Component allocation failed");
93+
94+
return comp;
95+
}
96+
97+
ZTEST(audio_eq_fir, test_eq_fir_init)
98+
{
99+
struct comp_dev *comp = test_eq_fir_create();
100+
101+
/* Verify component state */
102+
zassert_equal(comp->state, COMP_STATE_READY, "Component is not in READY state");
103+
zassert_equal(comp->ipc_config.id, 1, "IPC ID mismatch");
104+
105+
/* Free the component */
106+
comp->drv->ops.free(comp);
107+
}
108+
109+
/* Use generated passthrough config blob */
110+
#include "blobs/eq_fir_passthrough_2ch.h"
111+
112+
ZTEST(audio_eq_fir, test_eq_fir_config)
113+
{
114+
struct comp_dev *comp = test_eq_fir_create();
115+
116+
/* Apply generated config blob before processing (skip 32-byte ABI header) */
117+
if (comp->drv->ops.set_large_config) {
118+
int ret = comp->drv->ops.set_large_config(comp, 1, true, true,
119+
sizeof(eq_fir_blob) - 32, (uint8_t *)eq_fir_blob + 32);
120+
zassert_equal(ret, 0, "set_large_config failed");
121+
}
122+
123+
comp->drv->ops.free(comp);
124+
}
125+
126+
ZTEST(audio_eq_fir, test_eq_fir_process)
127+
{
128+
struct comp_dev *comp = test_eq_fir_create();
129+
130+
/* Apply generated config blob before processing (skip 32-byte ABI header) */
131+
if (comp->drv->ops.set_large_config) {
132+
int ret = comp->drv->ops.set_large_config(comp, 1, true, true,
133+
sizeof(eq_fir_blob) - 32, (uint8_t *)eq_fir_blob + 32);
134+
zassert_true(ret >= 0, "set_large_config failed: %d", ret);
135+
}
136+
137+
struct sof_ipc_stream_params params = {0};
138+
params.buffer_fmt = SOF_IPC_BUFFER_INTERLEAVED;
139+
params.channels = 2;
140+
params.rate = 48000;
141+
params.sample_container_bytes = 4;
142+
params.sample_valid_bytes = 4;
143+
144+
test_audio_helper_setup_buffers(comp, 4096, &params);
145+
test_audio_helper_process(comp);
146+
test_audio_helper_free_buffers(comp);
147+
148+
comp->drv->ops.free(comp);
149+
}
150+
151+
ZTEST(audio_eq_fir, test_eq_fir_params)
152+
{
153+
struct comp_dev *comp = test_eq_fir_create();
154+
struct sof_ipc_stream_params params;
155+
int ret;
156+
157+
memset(&params, 0, sizeof(params));
158+
params.channels = 2;
159+
params.rate = 48000;
160+
params.sample_container_bytes = 4;
161+
params.sample_valid_bytes = 4;
162+
params.buffer_fmt = SOF_IPC_BUFFER_INTERLEAVED;
163+
164+
/* Configure parameters */
165+
ret = comp->drv->ops.params(comp, &params);
166+
zassert_true(ret >= 0, "EQ_FIR parameter setup failed");
167+
168+
comp->drv->ops.free(comp);
169+
}
170+
171+
ZTEST_SUITE(audio_eq_fir, NULL, setup, NULL, NULL, NULL);

0 commit comments

Comments
 (0)