diff --git a/src/include/kernel/tokens.h b/src/include/kernel/tokens.h index 622744318..26b1fd7ad 100644 --- a/src/include/kernel/tokens.h +++ b/src/include/kernel/tokens.h @@ -55,6 +55,12 @@ #define SOF_TKN_SRC_RATE_IN 300 #define SOF_TKN_SRC_RATE_OUT 301 +/* ASRC */ +#define SOF_TKN_ASRC_RATE_IN 320 +#define SOF_TKN_ASRC_RATE_OUT 321 +#define SOF_TKN_ASRC_ASYNCHRONOUS_MODE 322 +#define SOF_TKN_ASRC_OPERATION_MODE 323 + /* PCM */ #define SOF_TKN_PCM_DMAC_CONFIG 353 diff --git a/tools/testbench/include/testbench/common_test.h b/tools/testbench/include/testbench/common_test.h index 780864869..434395a54 100644 --- a/tools/testbench/include/testbench/common_test.h +++ b/tools/testbench/include/testbench/common_test.h @@ -18,7 +18,7 @@ #define MAX_LIB_NAME_LEN 256 /* number of widgets types supported in testbench */ -#define NUM_WIDGETS_SUPPORTED 3 +#define NUM_WIDGETS_SUPPORTED 4 struct testbench_prm { char *tplg_file; /* topology file to use */ diff --git a/tools/testbench/testbench.c b/tools/testbench/testbench.c index 0f0cdfa15..99143655f 100644 --- a/tools/testbench/testbench.c +++ b/tools/testbench/testbench.c @@ -21,6 +21,7 @@ struct shared_lib_table lib_table[NUM_WIDGETS_SUPPORTED] = { {"file", "", SND_SOC_TPLG_DAPM_AIF_IN, 0, NULL}, {"vol", "libsof_volume.so", SND_SOC_TPLG_DAPM_PGA, 0, NULL}, {"src", "libsof_src.so", SND_SOC_TPLG_DAPM_SRC, 0, NULL}, + {"asrc", "libsof_asrc.so", SND_SOC_TPLG_DAPM_ASRC, 0, NULL}, }; /* main firmware context */ diff --git a/tools/testbench/topology.c b/tools/testbench/topology.c index e36133a6d..9c0b18e4e 100644 --- a/tools/testbench/topology.c +++ b/tools/testbench/topology.c @@ -403,6 +403,40 @@ int load_src(void *dev, int comp_id, int pipeline_id, int size, return ret; } +/* load asrc dapm widget */ +int load_asrc(void *dev, int comp_id, int pipeline_id, int size, + void *params) +{ + struct testbench_prm *tp = (struct testbench_prm *)params; + struct sof *sof = (struct sof *)dev; + struct sof_ipc_comp_asrc asrc = {0}; + int ret = 0; + + ret = tplg_load_asrc(comp_id, pipeline_id, size, &asrc, file); + if (ret < 0) + return ret; + + /* set testbench input and output sample rate from topology */ + if (!tp->fs_out) { + tp->fs_out = asrc.sink_rate; + + if (!tp->fs_in) + tp->fs_in = asrc.source_rate; + else + asrc.source_rate = tp->fs_in; + } else { + asrc.sink_rate = tp->fs_out; + } + + /* load asrc component */ + if (ipc_comp_new(sof->ipc, (struct sof_ipc_comp *)&asrc) < 0) { + fprintf(stderr, "error: new asrc comp\n"); + return -EINVAL; + } + + return ret; +} + /* load mixer dapm widget */ int load_mixer(void *dev, int comp_id, int pipeline_id, int size) { diff --git a/tools/testbench/trace.c b/tools/testbench/trace.c index b2856c94a..d79e672bd 100644 --- a/tools/testbench/trace.c +++ b/tools/testbench/trace.c @@ -55,6 +55,7 @@ char *get_trace_class(uint32_t trace_class) CASE(ALH); CASE(KEYWORD); CASE(CHMAP); + CASE(ASRC); default: return "unknown"; } } diff --git a/tools/tplg_parser/include/tplg_parser/topology.h b/tools/tplg_parser/include/tplg_parser/topology.h index 2d8b76841..ee5443dc1 100644 --- a/tools/tplg_parser/include/tplg_parser/topology.h +++ b/tools/tplg_parser/include/tplg_parser/topology.h @@ -109,6 +109,21 @@ static const struct sof_topology_token src_tokens[] = { offsetof(struct sof_ipc_comp_src, sink_rate), 0}, }; +/* ASRC */ +static const struct sof_topology_token asrc_tokens[] = { + {SOF_TKN_ASRC_RATE_IN, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_uint32_t, + offsetof(struct sof_ipc_comp_asrc, source_rate), 0}, + {SOF_TKN_ASRC_RATE_OUT, SND_SOC_TPLG_TUPLE_TYPE_WORD, + get_token_uint32_t, + offsetof(struct sof_ipc_comp_asrc, sink_rate), 0}, + {SOF_TKN_ASRC_ASYNCHRONOUS_MODE, SND_SOC_TPLG_TUPLE_TYPE_WORD, + get_token_uint32_t, + offsetof(struct sof_ipc_comp_asrc, asynchronous_mode), 0}, + {SOF_TKN_ASRC_OPERATION_MODE, SND_SOC_TPLG_TUPLE_TYPE_WORD, + get_token_uint32_t, + offsetof(struct sof_ipc_comp_asrc, operation_mode), 0}, +}; + /* Tone */ static const struct sof_topology_token tone_tokens[] = { }; @@ -187,6 +202,8 @@ int tplg_load_pipeline(int comp_id, int pipeline_id, int size, int tplg_load_controls(int num_kcontrols, FILE *file); int tplg_load_src(int comp_id, int pipeline_id, int size, struct sof_ipc_comp_src *src, FILE *file); +int tplg_load_asrc(int comp_id, int pipeline_id, int size, + struct sof_ipc_comp_asrc *asrc, FILE *file); int tplg_load_mixer(int comp_id, int pipeline_id, int size, struct sof_ipc_comp_mixer *mixer, FILE *file); int tplg_load_graph(int num_comps, int pipeline_id, @@ -203,6 +220,7 @@ int load_buffer(void *dev, int comp_id, int pipeline_id, int size); int load_pipeline(void *dev, int comp_id, int pipeline_id, int size, int *sched_id); int load_src(void *dev, int comp_id, int pipeline_id, int size, void *params); +int load_asrc(void *dev, int comp_id, int pipeline_id, int size, void *params); int load_mixer(void *dev, int comp_id, int pipeline_id, int size); int load_widget(void *dev, int dev_type, struct comp_info *temp_comp_list, int comp_id, int comp_index, int pipeline_id, diff --git a/tools/tplg_parser/tplg_parser.c b/tools/tplg_parser/tplg_parser.c index 31672e4d2..df0c22ae7 100644 --- a/tools/tplg_parser/tplg_parser.c +++ b/tools/tplg_parser/tplg_parser.c @@ -535,6 +535,73 @@ int tplg_load_src(int comp_id, int pipeline_id, int size, return 0; } +/* load asrc dapm widget */ +int tplg_load_asrc(int comp_id, int pipeline_id, int size, + struct sof_ipc_comp_asrc *asrc, FILE *file) +{ + struct snd_soc_tplg_vendor_array *array = NULL; + size_t total_array_size = 0, read_size; + int ret = 0; + + /* allocate memory for vendor tuple array */ + array = (struct snd_soc_tplg_vendor_array *)malloc(size); + if (!array) { + fprintf(stderr, "error: mem alloc for asrc vendor array\n"); + return -EINVAL; + } + + /* read vendor tokens */ + while (total_array_size < size) { + read_size = sizeof(struct snd_soc_tplg_vendor_array); + ret = fread(array, read_size, 1, file); + if (ret != 1) { + free(array); + return -EINVAL; + } + + tplg_read_array(array, file); + + /* parse comp tokens */ + ret = sof_parse_tokens(&asrc->config, comp_tokens, + ARRAY_SIZE(comp_tokens), array, + array->size); + if (ret != 0) { + fprintf(stderr, "error: parse asrc comp_tokens %d\n", + size); + free(array); + return -EINVAL; + } + + /* parse asrc tokens */ + ret = sof_parse_tokens(asrc, asrc_tokens, + ARRAY_SIZE(asrc_tokens), array, + array->size); + if (ret != 0) { + fprintf(stderr, "error: parse asrc tokens %d\n", size); + free(array); + return -EINVAL; + } + + total_array_size += array->size; + + /* read next array */ + array = (void *)array + array->size; + } + + array = (void *)array - size; + + /* configure asrc */ + asrc->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; + asrc->comp.id = comp_id; + asrc->comp.hdr.size = sizeof(struct sof_ipc_comp_asrc); + asrc->comp.type = SOF_COMP_ASRC; + asrc->comp.pipeline_id = pipeline_id; + asrc->config.hdr.size = sizeof(struct sof_ipc_comp_config); + + free(array); + return 0; +} + /* load mixer dapm widget */ int tplg_load_mixer(int comp_id, int pipeline_id, int size, struct sof_ipc_comp_mixer *mixer, FILE *file) @@ -764,6 +831,13 @@ int load_widget(void *dev, int dev_type, struct comp_info *temp_comp_list, return -EINVAL; } break; + case(SND_SOC_TPLG_DAPM_ASRC): + if (load_asrc(dev, temp_comp_list[comp_index].id, + pipeline_id, widget->priv.size, tp) < 0) { + fprintf(stderr, "error: load src\n"); + return -EINVAL; + } + break; case(SND_SOC_TPLG_DAPM_MIXER): if (load_mixer(dev, temp_comp_list[comp_index].id, pipeline_id, widget->priv.size) < 0) {