Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify the command line for plugin #9610

Merged
merged 3 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions tools/plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,19 @@ The command line is parsed as follows:
- "default": The second default is the device name
- "48k2c16b" is the config name for 48K, stereo, 16bit

Config name is optional in the command line. When it is not provided, hw_params will be used to
configure the endpoint. In this case, the command line can be simplified to:

```
aplay -Dsof:plugin:1:default:default
```

When using the default device, the command line can be further simplified to:

```
aplay -Dsof:plugin:1
```

This renders audio to the sof-pipe daemon using the sof-plugin topology playback PCM ID 1.
The above example needs to be 48k as example pipe has no SRC/ASRC.

Expand Down
43 changes: 30 additions & 13 deletions tools/plugin/alsaplug/pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ static int plug_pcm_prepare(snd_pcm_ioplug_t *io)
return err;
}

static int plug_init_shm_ctx(snd_sof_plug_t *plug);
static int plug_init_shm_ctx(snd_sof_plug_t *plug, snd_pcm_hw_params_t *params);

static int plug_pcm_hw_params(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params)
{
Expand All @@ -467,7 +467,7 @@ static int plug_pcm_hw_params(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params)
pcm->frame_us = ceil(1000000.0 / io->rate);

/* now send IPCs to set up widgets */
err = plug_set_up_pipelines(plug, pcm->capture);
err = plug_set_up_pipelines(plug, pcm->capture, params);
if (err < 0) {
fprintf(stderr, "error setting up pipelines\n");
return err;
Expand Down Expand Up @@ -565,7 +565,7 @@ static int plug_pcm_hw_params(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params)
}

/* set up the endpoint configs */
err = plug_init_shm_ctx(plug);
err = plug_init_shm_ctx(plug, params);
if (err < 0) {
SNDERR("error: failed to init sof-pipe ep context: %s:%s",
pcm->shm_pcm.name, strerror(err));
Expand Down Expand Up @@ -838,7 +838,7 @@ static int plug_create(snd_sof_plug_t *plug, snd_pcm_t **pcmp, const char *name,
return 0;
}

static int plug_init_shm_ctx(snd_sof_plug_t *plug)
static int plug_init_shm_ctx(snd_sof_plug_t *plug, snd_pcm_hw_params_t *params)
{
struct plug_shm_glb_state *glb = plug->glb_ctx.addr;
struct endpoint_hw_config *ep;
Expand Down Expand Up @@ -871,21 +871,38 @@ static int plug_init_shm_ctx(snd_sof_plug_t *plug)
ep->period_frames = pc->period_frames;
ep->period_time = pc->period_time;
ep->rate = pc->rate;
ep->pipeline = ci->pcm;
strncpy(ep->card_name, ci->card_name,
sizeof(ep->card_name));
strncpy(ep->dev_name, ci->dev_name,
sizeof(ep->dev_name));
strncpy(ep->config_name, ci->config_name,
sizeof(ep->config_name));
strncpy(ep->config_name, ci->config_name, sizeof(ep->config_name));
found = true;
break;
}

/* use hw_params if no matching config found or config missing in command line */
if (!found) {
SNDERR("error: config %s not found\n", ci->config_name);
return -EINVAL;
unsigned int channels, rate, dir, buffer_time, period_time;
snd_pcm_uframes_t buffer_size, period_size;
snd_pcm_format_t format;

snd_pcm_hw_params_get_channels(params, &channels);
snd_pcm_hw_params_get_rate(params, &rate, &dir);
snd_pcm_hw_params_get_buffer_size(params, &buffer_size);
snd_pcm_hw_params_get_period_size(params, &period_size, &dir);
snd_pcm_hw_params_get_buffer_time(params, &buffer_time, &dir);
snd_pcm_hw_params_get_period_time(params, &period_time, &dir);
snd_pcm_hw_params_get_format(params, &format);

ep = &glb->ep_config[glb->num_ep_configs++];
ep->buffer_frames = buffer_size;
ep->buffer_time = buffer_time;
ep->channels = channels;
ep->format = format;
ep->period_frames = period_size;
ep->period_time = period_time;
ep->rate = rate;
}

ep->pipeline = ci->pcm;
strncpy(ep->card_name, ci->card_name, sizeof(ep->card_name));
strncpy(ep->dev_name, ci->dev_name, sizeof(ep->dev_name));
}

return 0;
Expand Down
37 changes: 19 additions & 18 deletions tools/plugin/alsaplug/plugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,28 +270,29 @@ static int parse_client_cmdline(snd_sof_plug_t *plug, char *cmdline, bool just_t

cmd_item = &plug->cmdline[plug->num_cmdline];
card = strtok_r(next, ":", &next);
/* card/dev names and config are all optional */
if (!card) {
SNDERR("Invalid card name\n");
return -EINVAL;
}
dev = strtok_r(next, ":", &next);
if (!dev) {
SNDERR("Invalid dev name\n");
return -EINVAL;
}
config = strtok_r(next, ":", &next);

/* tuple needs all three, any missing ? */
if (!config) {
SNDERR("invalid cmdline, expected pcm(%s):card(%s):dev(%s):config(%s) from %s",
pcm, card, dev, config, tplg);
return -EINVAL;
strncpy(cmd_item->card_name, "default", sizeof(cmd_item->card_name));
strncpy(cmd_item->dev_name, "default", sizeof(cmd_item->dev_name));
fprintf(stdout, "no config name provided, will use hw_params\n");
} else {
strncpy(cmd_item->card_name, card, sizeof(cmd_item->card_name));
dev = strtok_r(next, ":", &next);
/* dev name must be provided along with card name */
if (!dev) {
SNDERR("Invalid dev name\n");
return -EINVAL;
}
strncpy(cmd_item->dev_name, dev, sizeof(cmd_item->dev_name));
config = strtok_r(next, ":", &next);
/* config name is optional */
if (!config)
fprintf(stdout, "no config name provided, will use hw_params\n");
else
strncpy(cmd_item->config_name, config, sizeof(cmd_item->config_name));
}

cmd_item->pcm = atoi(pcm);
strncpy(cmd_item->card_name, card, sizeof(cmd_item->card_name));
strncpy(cmd_item->dev_name, dev, sizeof(cmd_item->dev_name));
strncpy(cmd_item->config_name, config, sizeof(cmd_item->config_name));

/*
* dev name is special, we cant use "," in the command line
Expand Down
2 changes: 1 addition & 1 deletion tools/plugin/alsaplug/plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ int sofplug_load_hook(snd_config_t *root, snd_config_t *config,
int plug_parse_conf(snd_sof_plug_t *plug, const char *name,
snd_config_t *root, snd_config_t *conf, bool just_tplg);
int plug_parse_topology(snd_sof_plug_t *plug);
int plug_set_up_pipelines(snd_sof_plug_t *plug, int dir);
int plug_set_up_pipelines(snd_sof_plug_t *plug, int dir, snd_pcm_hw_params_t *params);
int plug_free_pipelines(snd_sof_plug_t *plug, struct tplg_pipeline_list *pipeline_list, int dir);
void plug_free_topology(snd_sof_plug_t *plug);
int plug_kcontrol_cb_new(struct snd_soc_tplg_ctl_hdr *tplg_ctl, void *_comp, void *arg, int index);
Expand Down
75 changes: 34 additions & 41 deletions tools/plugin/alsaplug/tplg.c
Original file line number Diff line number Diff line change
Expand Up @@ -688,23 +688,29 @@ static int plug_is_single_format(struct sof_ipc4_pin_format *fmts, int num_forma
}

static int plug_match_audio_format(snd_sof_plug_t *plug, struct tplg_comp_info *comp_info,
struct plug_config *config)
snd_pcm_hw_params_t *params)
{
struct sof_ipc4_available_audio_format *available_fmt = &comp_info->available_fmt;
struct ipc4_base_module_cfg *base_cfg = &comp_info->basecfg;
struct sof_ipc4_pin_format *fmt;
int config_valid_bits;
snd_pcm_format_t params_format;
unsigned int params_channels, params_rate, dir;
int params_valid_bits;
int i;

switch (config->format) {
snd_pcm_hw_params_get_channels(params, &params_channels);
snd_pcm_hw_params_get_rate(params, &params_rate, &dir);
snd_pcm_hw_params_get_format(params, &params_format);

switch (params_format) {
case SND_PCM_FORMAT_S16_LE:
config_valid_bits = 16;
params_valid_bits = 16;
break;
case SND_PCM_FORMAT_S32_LE:
config_valid_bits = 32;
params_valid_bits = 32;
break;
case SND_PCM_FORMAT_S24_LE:
config_valid_bits = 24;
params_valid_bits = 24;
break;
default:
break;
Expand All @@ -725,14 +731,14 @@ static int plug_match_audio_format(snd_sof_plug_t *plug, struct tplg_comp_info *
channels = fmt->audio_fmt.fmt_cfg & MASK(7, 0);
valid_bits = (fmt->audio_fmt.fmt_cfg & MASK(15, 8)) >> 8;

if (rate == config->rate && channels == config->channels &&
valid_bits == config_valid_bits)
if (rate == params_rate && channels == params_channels &&
valid_bits == params_valid_bits)
break;
}

if (i == available_fmt->num_input_formats) {
SNDERR("Cannot find matching format for rate %d channels %d valid_bits %d for %s\n",
config->rate, config->channels, config_valid_bits, comp_info->name);
params_rate, params_channels, params_valid_bits, comp_info->name);
return -EINVAL;
}
out:
Expand All @@ -755,29 +761,13 @@ static int plug_match_audio_format(snd_sof_plug_t *plug, struct tplg_comp_info *
return 0;
}

static int plug_set_up_widget_base_config(snd_sof_plug_t *plug, struct tplg_comp_info *comp_info)
static int plug_set_up_widget_base_config(snd_sof_plug_t *plug, struct tplg_comp_info *comp_info,
snd_pcm_hw_params_t *params)
{
struct plug_cmdline_item *cmd_item = &plug->cmdline[0];
struct plug_config *config;
bool config_found = false;
int ret, i;

for (i < 0; i < plug->num_configs; i++) {
config = &plug->config[i];

if (!strcmp(config->name, cmd_item->config_name)) {
config_found = true;
break;
}
}

if (!config_found) {
SNDERR("unsupported config requested %s\n", cmd_item->config_name);
return -ENOTSUP;
}

/* match audio formats and populate base config */
ret = plug_match_audio_format(plug, comp_info, config);
ret = plug_match_audio_format(plug, comp_info, params);
if (ret < 0)
return ret;

Expand Down Expand Up @@ -985,7 +975,8 @@ static int plug_set_up_pipeline(snd_sof_plug_t *plug, struct tplg_pipeline_info
}

static int plug_prepare_widget(snd_sof_plug_t *plug, struct tplg_pcm_info *pcm_info,
struct tplg_comp_info *comp_info, int dir)
struct tplg_comp_info *comp_info, int dir,
snd_pcm_hw_params_t *params)
{
struct tplg_pipeline_list *pipeline_list;
int ret, i;
Expand All @@ -996,7 +987,7 @@ static int plug_prepare_widget(snd_sof_plug_t *plug, struct tplg_pcm_info *pcm_i
pipeline_list = &pcm_info->playback_pipeline_list;

/* populate base config */
ret = plug_set_up_widget_base_config(plug, comp_info);
ret = plug_set_up_widget_base_config(plug, comp_info, params);
if (ret < 0)
return ret;

Expand All @@ -1021,7 +1012,8 @@ static int plug_prepare_widget(snd_sof_plug_t *plug, struct tplg_pcm_info *pcm_i

static int plug_prepare_widgets(snd_sof_plug_t *plug, struct tplg_pcm_info *pcm_info,
struct tplg_comp_info *starting_comp_info,
struct tplg_comp_info *current_comp_info)
struct tplg_comp_info *current_comp_info,
snd_pcm_hw_params_t *params)
{
struct list_item *item;
int ret;
Expand All @@ -1036,21 +1028,21 @@ static int plug_prepare_widgets(snd_sof_plug_t *plug, struct tplg_pcm_info *pcm_

/* set up source widget if it is the starting widget */
if (starting_comp_info == current_comp_info) {
ret = plug_prepare_widget(plug, pcm_info, current_comp_info, 0);
ret = plug_prepare_widget(plug, pcm_info, current_comp_info, 0, params);
if (ret < 0)
return ret;
}

/* set up the sink widget */
ret = plug_prepare_widget(plug, pcm_info, route_info->sink, 0);
ret = plug_prepare_widget(plug, pcm_info, route_info->sink, 0, params);
if (ret < 0)
return ret;

/* and then continue down the path */
if (route_info->sink->type != SND_SOC_TPLG_DAPM_DAI_IN ||
route_info->sink->type != SND_SOC_TPLG_DAPM_DAI_OUT) {
ret = plug_prepare_widgets(plug, pcm_info, starting_comp_info,
route_info->sink);
route_info->sink, params);
if (ret < 0)
return ret;
}
Expand All @@ -1061,7 +1053,8 @@ static int plug_prepare_widgets(snd_sof_plug_t *plug, struct tplg_pcm_info *pcm_

static int plug_prepare_widgets_capture(snd_sof_plug_t *plug, struct tplg_pcm_info *pcm_info,
struct tplg_comp_info *starting_comp_info,
struct tplg_comp_info *current_comp_info)
struct tplg_comp_info *current_comp_info,
snd_pcm_hw_params_t *params)
{
struct list_item *item;
int ret;
Expand All @@ -1076,21 +1069,21 @@ static int plug_prepare_widgets_capture(snd_sof_plug_t *plug, struct tplg_pcm_in

/* set up sink widget if it is the starting widget */
if (starting_comp_info == current_comp_info) {
ret = plug_prepare_widget(plug, pcm_info, current_comp_info, 1);
ret = plug_prepare_widget(plug, pcm_info, current_comp_info, 1, params);
if (ret < 0)
return ret;
}

/* set up the source widget */
ret = plug_prepare_widget(plug, pcm_info, route_info->source, 1);
ret = plug_prepare_widget(plug, pcm_info, route_info->source, 1, params);
if (ret < 0)
return ret;

/* and then continue up the path */
if (route_info->source->type != SND_SOC_TPLG_DAPM_DAI_IN &&
route_info->source->type != SND_SOC_TPLG_DAPM_DAI_OUT) {
ret = plug_prepare_widgets_capture(plug, pcm_info, starting_comp_info,
route_info->source);
route_info->source, params);
if (ret < 0)
return ret;
}
Expand Down Expand Up @@ -1282,7 +1275,7 @@ static int plug_set_up_widgets_capture(snd_sof_plug_t *plug,
return 0;
}

int plug_set_up_pipelines(snd_sof_plug_t *plug, int dir)
int plug_set_up_pipelines(snd_sof_plug_t *plug, int dir, snd_pcm_hw_params_t *params)
{
struct tplg_comp_info *host = NULL;
struct tplg_pcm_info *pcm_info;
Expand All @@ -1309,7 +1302,7 @@ int plug_set_up_pipelines(snd_sof_plug_t *plug, int dir)
plug->pcm_info = pcm_info;

if (dir) {
ret = plug_prepare_widgets_capture(plug, pcm_info, host, host);
ret = plug_prepare_widgets_capture(plug, pcm_info, host, host, params);
if (ret < 0)
return ret;

Expand All @@ -1322,7 +1315,7 @@ int plug_set_up_pipelines(snd_sof_plug_t *plug, int dir)
return 0;
}

ret = plug_prepare_widgets(plug, pcm_info, host, host);
ret = plug_prepare_widgets(plug, pcm_info, host, host, params);
if (ret < 0)
return ret;

Expand Down
Loading