Skip to content

Commit dfe49a3

Browse files
committed
test: audio: add unit test for mixin_mixout
Add the ztest framework test cases for the mixin_mixout module, validating component instantiation and evaluation configuration structs bindings. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
1 parent 709eb88 commit dfe49a3

1 file changed

Lines changed: 263 additions & 0 deletions

File tree

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
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+
19+
extern void sys_comp_module_mixin_interface_init(void);
20+
extern void sys_comp_module_mixout_interface_init(void);
21+
22+
static void *setup(void)
23+
{
24+
struct sof *sof = sof_get();
25+
26+
sys_comp_init(sof);
27+
28+
if (!sof->ipc) {
29+
sof->ipc = rzalloc(SOF_MEM_FLAG_COHERENT, sizeof(*sof->ipc));
30+
sof->ipc->comp_data = rzalloc(SOF_MEM_FLAG_COHERENT, 4096);
31+
k_spinlock_init(&sof->ipc->lock);
32+
list_init(&sof->ipc->msg_list);
33+
list_init(&sof->ipc->comp_list);
34+
}
35+
36+
sys_comp_module_mixin_interface_init();
37+
sys_comp_module_mixout_interface_init();
38+
return NULL;
39+
}
40+
41+
/* UUIDs extracted from native registries */
42+
SOF_DEFINE_UUID("mixin_test", mixin_test_uuid, 0x39656eb2, 0x3b71, 0x4049,
43+
0x8d, 0x3f, 0xf9, 0x2c, 0xd5, 0xc4, 0x3c, 0x09);
44+
45+
SOF_DEFINE_UUID("mixout_test", mixout_test_uuid, 0x3c56505a, 0x24d7, 0x418f,
46+
0xbd, 0xdc, 0xc1, 0xf5, 0xa3, 0xac, 0x2a, 0xe0);
47+
48+
struct custom_ipc4_config_mix {
49+
struct ipc4_base_module_cfg base;
50+
} __attribute__((packed, aligned(4)));
51+
52+
/* Test MIXIN initialization */
53+
ZTEST(audio_mixin_mixout, test_mixin_init)
54+
{
55+
struct comp_dev *comp;
56+
struct comp_ipc_config ipc_config;
57+
struct ipc_config_process spec;
58+
struct custom_ipc4_config_mix mixin_init_data;
59+
60+
memset(&mixin_init_data, 0, sizeof(mixin_init_data));
61+
memset(&mixin_init_data.base.audio_fmt, 0, sizeof(mixin_init_data.base.audio_fmt));
62+
mixin_init_data.base.audio_fmt.channels_count = 2;
63+
mixin_init_data.base.audio_fmt.sampling_frequency = 48000;
64+
mixin_init_data.base.audio_fmt.depth = 32;
65+
mixin_init_data.base.audio_fmt.valid_bit_depth = 32;
66+
mixin_init_data.base.audio_fmt.interleaving_style = IPC4_CHANNELS_INTERLEAVED;
67+
68+
/* Setup basic IPC configuration */
69+
memset(&ipc_config, 0, sizeof(ipc_config));
70+
ipc_config.id = 1;
71+
ipc_config.pipeline_id = 1;
72+
ipc_config.core = 0;
73+
74+
memset(&spec, 0, sizeof(spec));
75+
spec.size = sizeof(mixin_init_data);
76+
spec.data = (unsigned char *)&mixin_init_data;
77+
78+
struct list_item *clist;
79+
const struct comp_driver *drv = NULL;
80+
81+
/* Find driver by UUID */
82+
list_for_item(clist, &comp_drivers_get()->list) {
83+
struct comp_driver_info *info = container_of(clist, struct comp_driver_info, list);
84+
if (!info->drv->uid) continue;
85+
if (!memcmp(info->drv->uid, &mixin_test_uuid, sizeof(struct sof_uuid))) {
86+
drv = info->drv;
87+
break;
88+
}
89+
}
90+
zassert_not_null(drv, "Driver for MIXIN not found");
91+
92+
/* Initialize component via ops */
93+
comp = drv->ops.create(drv, &ipc_config, &spec);
94+
zassert_not_null(comp, "MIXIN allocation failed");
95+
96+
/* Verify component state */
97+
zassert_equal(comp->state, COMP_STATE_READY, "Component is not in READY state");
98+
zassert_equal(comp->ipc_config.id, 1, "IPC ID mismatch");
99+
100+
/* Free the component */
101+
drv->ops.free(comp);
102+
}
103+
104+
/* Test MIXOUT initialization */
105+
ZTEST(audio_mixin_mixout, test_mixout_init)
106+
{
107+
struct comp_dev *comp;
108+
struct comp_ipc_config ipc_config;
109+
struct ipc_config_process spec;
110+
struct custom_ipc4_config_mix mixout_init_data;
111+
112+
memset(&mixout_init_data, 0, sizeof(mixout_init_data));
113+
memset(&mixout_init_data.base.audio_fmt, 0, sizeof(mixout_init_data.base.audio_fmt));
114+
mixout_init_data.base.audio_fmt.channels_count = 2;
115+
mixout_init_data.base.audio_fmt.sampling_frequency = 48000;
116+
mixout_init_data.base.audio_fmt.depth = 32;
117+
mixout_init_data.base.audio_fmt.valid_bit_depth = 32;
118+
mixout_init_data.base.audio_fmt.interleaving_style = IPC4_CHANNELS_INTERLEAVED;
119+
120+
/* Setup basic IPC configuration */
121+
memset(&ipc_config, 0, sizeof(ipc_config));
122+
ipc_config.id = 2;
123+
ipc_config.pipeline_id = 1;
124+
ipc_config.core = 0;
125+
126+
memset(&spec, 0, sizeof(spec));
127+
spec.size = sizeof(mixout_init_data);
128+
spec.data = (unsigned char *)&mixout_init_data;
129+
130+
struct list_item *clist;
131+
const struct comp_driver *drv = NULL;
132+
133+
/* Find driver by UUID */
134+
list_for_item(clist, &comp_drivers_get()->list) {
135+
struct comp_driver_info *info = container_of(clist, struct comp_driver_info, list);
136+
if (!info->drv->uid) continue;
137+
if (!memcmp(info->drv->uid, &mixout_test_uuid, sizeof(struct sof_uuid))) {
138+
drv = info->drv;
139+
break;
140+
}
141+
}
142+
zassert_not_null(drv, "Driver for MIXOUT not found");
143+
144+
/* Initialize component via ops */
145+
comp = drv->ops.create(drv, &ipc_config, &spec);
146+
zassert_not_null(comp, "MIXOUT allocation failed");
147+
148+
drv->ops.free(comp);
149+
}
150+
151+
/* Test MIXIN parameters parsing */
152+
ZTEST(audio_mixin_mixout, test_mixin_params)
153+
{
154+
struct comp_dev *comp;
155+
struct comp_ipc_config ipc_config;
156+
struct ipc_config_process spec;
157+
struct sof_ipc_stream_params params;
158+
struct custom_ipc4_config_mix mixin_init_data;
159+
int ret;
160+
161+
memset(&mixin_init_data, 0, sizeof(mixin_init_data));
162+
memset(&mixin_init_data.base.audio_fmt, 0, sizeof(mixin_init_data.base.audio_fmt));
163+
mixin_init_data.base.audio_fmt.channels_count = 2;
164+
mixin_init_data.base.audio_fmt.sampling_frequency = 48000;
165+
mixin_init_data.base.audio_fmt.depth = 32;
166+
mixin_init_data.base.audio_fmt.valid_bit_depth = 32;
167+
mixin_init_data.base.audio_fmt.interleaving_style = IPC4_CHANNELS_INTERLEAVED;
168+
169+
memset(&ipc_config, 0, sizeof(ipc_config));
170+
ipc_config.id = 1;
171+
ipc_config.pipeline_id = 1;
172+
173+
memset(&spec, 0, sizeof(spec));
174+
spec.size = sizeof(mixin_init_data);
175+
spec.data = (unsigned char *)&mixin_init_data;
176+
177+
struct list_item *clist;
178+
const struct comp_driver *drv = NULL;
179+
180+
list_for_item(clist, &comp_drivers_get()->list) {
181+
struct comp_driver_info *info = container_of(clist, struct comp_driver_info, list);
182+
if (!info->drv->uid) continue;
183+
if (!memcmp(info->drv->uid, &mixin_test_uuid, sizeof(struct sof_uuid))) {
184+
drv = info->drv;
185+
break;
186+
}
187+
}
188+
zassert_not_null(drv, "Driver for MIXIN not found");
189+
comp = drv->ops.create(drv, &ipc_config, &spec);
190+
191+
memset(&params, 0, sizeof(params));
192+
params.channels = 2;
193+
params.rate = 48000;
194+
params.sample_container_bytes = 4;
195+
params.sample_valid_bytes = 4;
196+
params.buffer_fmt = SOF_IPC_BUFFER_INTERLEAVED;
197+
198+
/* Configure parameters */
199+
if (drv->ops.params) {
200+
ret = drv->ops.params(comp, &params);
201+
zassert_true(ret >= 0, "MIXIN parameter setup failed");
202+
}
203+
204+
drv->ops.free(comp);
205+
}
206+
207+
/* Test MIXOUT parameters parsing */
208+
ZTEST(audio_mixin_mixout, test_mixout_params)
209+
{
210+
struct comp_dev *comp;
211+
struct comp_ipc_config ipc_config;
212+
struct ipc_config_process spec;
213+
struct sof_ipc_stream_params params;
214+
struct custom_ipc4_config_mix mixout_init_data;
215+
int ret;
216+
217+
memset(&mixout_init_data, 0, sizeof(mixout_init_data));
218+
memset(&mixout_init_data.base.audio_fmt, 0, sizeof(mixout_init_data.base.audio_fmt));
219+
mixout_init_data.base.audio_fmt.channels_count = 2;
220+
mixout_init_data.base.audio_fmt.sampling_frequency = 48000;
221+
mixout_init_data.base.audio_fmt.depth = 32;
222+
mixout_init_data.base.audio_fmt.valid_bit_depth = 32;
223+
mixout_init_data.base.audio_fmt.interleaving_style = IPC4_CHANNELS_INTERLEAVED;
224+
225+
memset(&ipc_config, 0, sizeof(ipc_config));
226+
ipc_config.id = 2;
227+
ipc_config.pipeline_id = 1;
228+
229+
memset(&spec, 0, sizeof(spec));
230+
spec.size = sizeof(mixout_init_data);
231+
spec.data = (unsigned char *)&mixout_init_data;
232+
233+
struct list_item *clist;
234+
const struct comp_driver *drv = NULL;
235+
236+
list_for_item(clist, &comp_drivers_get()->list) {
237+
struct comp_driver_info *info = container_of(clist, struct comp_driver_info, list);
238+
if (!info->drv->uid) continue;
239+
if (!memcmp(info->drv->uid, &mixout_test_uuid, sizeof(struct sof_uuid))) {
240+
drv = info->drv;
241+
break;
242+
}
243+
}
244+
zassert_not_null(drv, "Driver for MIXOUT not found");
245+
comp = drv->ops.create(drv, &ipc_config, &spec);
246+
247+
memset(&params, 0, sizeof(params));
248+
params.channels = 2;
249+
params.rate = 48000;
250+
params.sample_container_bytes = 4;
251+
params.sample_valid_bytes = 4;
252+
params.buffer_fmt = SOF_IPC_BUFFER_INTERLEAVED;
253+
254+
/* Configure parameters */
255+
if (drv->ops.params) {
256+
ret = drv->ops.params(comp, &params);
257+
zassert_true(ret >= 0, "MIXOUT parameter setup failed");
258+
}
259+
260+
drv->ops.free(comp);
261+
}
262+
263+
ZTEST_SUITE(audio_mixin_mixout, NULL, setup, NULL, NULL, NULL);

0 commit comments

Comments
 (0)