Skip to content

Commit 1719be8

Browse files
singalsukv2019i
authored andcommitted
Tools: Testbench: Add sof-ctl simulation to control scripts
With this change sof-ctl commands can be executed during sof-testbench4 simulation, e.g. sof-ctl -c name='Post Mixer Analog Playback IIR Eq bytes' \ -s tools/ctl/ipc4/eq_iir/loudness.txt No other than switches -c and -s are supported for simulated sof-ctl. The blob file must be in normal comma separated ASCII uint32_t numbers format with nothing else in it. With this change the SOF processing components can be tested extensively for their controls during simulated audio streaming. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent 3db28e4 commit 1719be8

File tree

4 files changed

+158
-2
lines changed

4 files changed

+158
-2
lines changed

tools/testbench/include/testbench/utils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#define TB_MAX_CTL_NAME_CHARS 128
2424
#define TB_MAX_VOLUME_SIZE 120
2525
#define TB_MAX_BYTES_DATA_SIZE 8192
26+
#define TB_MAX_BLOB_CONTENT_CHARS 32768
2627

2728
/* number of widgets types supported in testbench */
2829
#define TB_NUM_WIDGETS_SUPPORTED 16
@@ -159,6 +160,7 @@ int tb_pipeline_reset(struct ipc *ipc, struct pipeline *p);
159160
int tb_pipeline_start(struct ipc *ipc, struct pipeline *p);
160161
int tb_pipeline_stop(struct ipc *ipc, struct pipeline *p);
161162
int tb_read_controls(struct testbench_prm *tp, int64_t *sleep_ns);
163+
int tb_set_bytes_control(struct testbench_prm *tp, struct tb_ctl *ctl, uint32_t *data);
162164
int tb_set_enum_control(struct testbench_prm *tp, struct tb_ctl *ctl, char *control_params);
163165
int tb_set_reset_state(struct testbench_prm *tp);
164166
int tb_set_mixer_control(struct testbench_prm *tp, struct tb_ctl *ctl, char *control_params);

tools/testbench/utils.c

Lines changed: 144 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <sof/lib/notifier.h>
1010

1111
#include <ctype.h>
12+
#include <errno.h>
1213
#include <stdint.h>
1314
#include <stdio.h>
1415
#include <stdlib.h>
@@ -388,10 +389,141 @@ static int tb_parse_amixer(struct testbench_prm *tp, char *line)
388389
return ret;
389390
}
390391

392+
static int tb_parse_sofctl(struct testbench_prm *tp, char *line)
393+
{
394+
struct tb_ctl *ctl;
395+
uint32_t *blob_bin = NULL;
396+
char *blob_name = NULL;
397+
char *blob_str = NULL;
398+
char *control_name = NULL;
399+
char *end;
400+
char *find_ctl_name_str = "-c name=\"";
401+
char *find_end_str = "\" ";
402+
char *find_set_switch_str = "-s";
403+
char *name_str;
404+
char *rest;
405+
char *token;
406+
int copy_len;
407+
int find_len = strlen(find_ctl_name_str);
408+
int n = 0;
409+
int ret = 0;
410+
FILE *fh;
411+
412+
name_str = strstr(line, find_ctl_name_str);
413+
if (!name_str) {
414+
fprintf(stderr, "error: no control name in script line: %s\n", line);
415+
return -EINVAL;
416+
}
417+
418+
end = strstr(&name_str[find_len], find_end_str);
419+
if (!end) {
420+
fprintf(stderr, "error: no control name end quote in script line: %s\n", line);
421+
return -EINVAL;
422+
}
423+
424+
copy_len = end - name_str - find_len;
425+
control_name = strndup(name_str + find_len, copy_len);
426+
if (!control_name) {
427+
fprintf(stderr, "error: failed to duplicate control name.\n");
428+
return -errno;
429+
}
430+
431+
name_str = strstr(line, find_set_switch_str);
432+
if (!name_str) {
433+
fprintf(stderr, "error: no sof-ctl control set switch in command: %s.\n",
434+
line);
435+
ret = -EINVAL;
436+
goto err;
437+
}
438+
439+
name_str += strlen(find_set_switch_str) + 1;
440+
end = line + strlen(line);
441+
copy_len = end - name_str;
442+
blob_name = strndup(name_str, copy_len);
443+
if (!blob_name) {
444+
fprintf(stderr, "error: failed to duplicate blob name.\n");
445+
ret = -errno;
446+
goto err;
447+
}
448+
449+
ctl = tb_find_control_by_name(tp, control_name);
450+
if (!ctl) {
451+
fprintf(stderr, "error: control %s not found in topology.\n", control_name);
452+
ret = -EINVAL;
453+
goto err;
454+
}
455+
456+
if (ctl->type != SND_SOC_TPLG_TYPE_BYTES) {
457+
fprintf(stderr, "error: control %s type %d is not supported.\n",
458+
control_name, ctl->type);
459+
ret = -EINVAL;
460+
goto err;
461+
}
462+
463+
blob_str = malloc(TB_MAX_BLOB_CONTENT_CHARS);
464+
if (!blob_str) {
465+
fprintf(stderr, "error: failed to allocate memory for blob file content.\n");
466+
ret = -ENOMEM;
467+
goto err;
468+
}
469+
470+
blob_bin = malloc(TB_MAX_BYTES_DATA_SIZE);
471+
if (!blob_bin) {
472+
fprintf(stderr, "error: failed to allocate memory for blob data.\n");
473+
ret = -ENOMEM;
474+
goto err;
475+
}
476+
477+
printf("Info: Setting control name '%s' to blob '%s'\n", control_name, blob_name);
478+
fh = fopen(blob_name, "r");
479+
if (!fh) {
480+
fprintf(stderr, "error: could not open file.\n");
481+
ret = -errno;
482+
goto err;
483+
}
484+
485+
end = fgets(blob_str, TB_MAX_BLOB_CONTENT_CHARS, fh);
486+
fclose(fh);
487+
if (!end) {
488+
fprintf(stderr, "error: failed to read data from blob file.\n");
489+
ret = -ENODATA;
490+
goto err;
491+
}
492+
493+
rest = blob_str;
494+
while ((token = strtok_r(rest, ",", &rest))) {
495+
if (n == TB_MAX_BYTES_DATA_SIZE) {
496+
fprintf(stderr, "error: data read exceeds max control data size.\n");
497+
ret = -EINVAL;
498+
goto err;
499+
}
500+
501+
blob_bin[n] = atoi(token);
502+
n++;
503+
}
504+
505+
if (n < 2) {
506+
fprintf(stderr, "error: at least two values are required in the blob file.\n");
507+
ret = -EINVAL;
508+
goto err;
509+
}
510+
511+
/* Ignore TLV header from beginning. */
512+
ret = tb_set_bytes_control(tp, ctl, &blob_bin[2]);
513+
514+
err:
515+
free(blob_str);
516+
free(blob_bin);
517+
free(blob_name);
518+
free(control_name);
519+
return ret;
520+
}
521+
391522
int tb_read_controls(struct testbench_prm *tp, int64_t *sleep_ns)
392523
{
393524
char *sleep_cmd = "sleep ";
394525
char *amixer_cmd = "amixer ";
526+
char *sofctl_cmd = "sof-ctl ";
395527
char *raw_line;
396528
char *line;
397529
int ret = 0;
@@ -411,7 +543,7 @@ int tb_read_controls(struct testbench_prm *tp, int64_t *sleep_ns)
411543
if (line[0] == '#' || strlen(line) == 0)
412544
continue;
413545

414-
if (strncmp(line, sleep_cmd, sizeof(*sleep_cmd)) == 0) {
546+
if (strncmp(line, sleep_cmd, strlen(sleep_cmd)) == 0) {
415547
ret = tb_parse_sleep(line, sleep_ns);
416548
if (ret) {
417549
fprintf(stderr, "error: failed parse of sleep command.\n");
@@ -420,12 +552,22 @@ int tb_read_controls(struct testbench_prm *tp, int64_t *sleep_ns)
420552
break;
421553
}
422554

423-
if (strncmp(line, amixer_cmd, sizeof(*amixer_cmd)) == 0) {
555+
if (strncmp(line, amixer_cmd, strlen(amixer_cmd)) == 0) {
424556
ret = tb_parse_amixer(tp, line);
425557
if (ret) {
426558
fprintf(stderr, "error: failed parse of amixer command.\n");
427559
break;
428560
}
561+
continue;
562+
}
563+
564+
if (strncmp(line, sofctl_cmd, strlen(sofctl_cmd)) == 0) {
565+
ret = tb_parse_sofctl(tp, line);
566+
if (ret) {
567+
fprintf(stderr, "error: failed parse of sof-ctl command.\n");
568+
break;
569+
}
570+
continue;
429571
}
430572
}
431573

tools/testbench/utils_ipc3.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,4 +435,9 @@ int tb_set_mixer_control(struct testbench_prm *tp, struct tb_ctl *ctl, char *con
435435
return 0;
436436
}
437437

438+
int tb_set_bytes_control(struct testbench_prm *tp, struct tb_ctl *ctl, uint32_t *data)
439+
{
440+
return 0;
441+
}
442+
438443
#endif /* CONFIG_IPC_MAJOR_3 */

tools/testbench/utils_ipc4.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,4 +691,11 @@ int tb_set_mixer_control(struct testbench_prm *tp, struct tb_ctl *ctl, char *con
691691
return ret;
692692
}
693693

694+
int tb_set_bytes_control(struct testbench_prm *tp, struct tb_ctl *ctl, uint32_t *data)
695+
{
696+
return tb_send_bytes_data(&tp->ipc_tx, &tp->ipc_rx,
697+
ctl->module_id, ctl->instance_id,
698+
(struct sof_abi_hdr *)data);
699+
}
700+
694701
#endif /* CONFIG_IPC_MAJOR_4 */

0 commit comments

Comments
 (0)