mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-09-20 01:59:57 +02:00
topology: pre-process-dapm: update automatic attributes for buffer
Add the function to compute the value for the "size" automatic attribute in the buffer objects. Signed-off-by: Chao Song <chao.song@linux.intel.com> Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
88c6dd6cf4
commit
b848786f42
3 changed files with 113 additions and 0 deletions
|
@ -422,3 +422,112 @@ err:
|
||||||
free(sink_widget_name);
|
free(sink_widget_name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tplg_get_sample_size_from_format(const char *format)
|
||||||
|
{
|
||||||
|
if (!strcmp(format, "s32le") || !strcmp(format, "s24le") || !strcmp(format, "float"))
|
||||||
|
return 4;
|
||||||
|
|
||||||
|
if (!strcmp(format, "s16le"))
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
SNDERR("Unsupported format: %s\n", format);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tplg_update_buffer_auto_attr(struct tplg_pre_processor *tplg_pp,
|
||||||
|
snd_config_t *buffer_cfg, snd_config_t *parent)
|
||||||
|
{
|
||||||
|
snd_config_iterator_t i, next;
|
||||||
|
snd_config_t *n, *pipeline_cfg, *child;
|
||||||
|
const char *buffer_id, *format;
|
||||||
|
long periods, channels, sample_size;
|
||||||
|
long sched_period, rate, frames;
|
||||||
|
long buffer_size;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (snd_config_get_id(buffer_cfg, &buffer_id) < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!parent) {
|
||||||
|
SNDERR("No parent for buffer %s\n", buffer_id);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* acquire attributes from buffer config */
|
||||||
|
snd_config_for_each(i, next, buffer_cfg) {
|
||||||
|
const char *id;
|
||||||
|
|
||||||
|
n = snd_config_iterator_entry(i);
|
||||||
|
if (snd_config_get_id(n, &id) < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!strcmp(id, "periods")) {
|
||||||
|
if (snd_config_get_integer(n, &periods)) {
|
||||||
|
SNDERR("Invalid number of periods for buffer %s\n", buffer_id);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(id, "channels")) {
|
||||||
|
if (snd_config_get_integer(n, &channels)) {
|
||||||
|
SNDERR("Invalid number of channels for buffer %s\n", buffer_id);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(id, "format")) {
|
||||||
|
if (snd_config_get_string(n, &format)) {
|
||||||
|
SNDERR("Invalid format for buffer %s\n", buffer_id);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pipeline_cfg = tplg_object_get_instance_config(tplg_pp, parent);
|
||||||
|
|
||||||
|
/* acquire some other attributes from parent pipeline config */
|
||||||
|
snd_config_for_each(i, next, pipeline_cfg) {
|
||||||
|
const char *id;
|
||||||
|
|
||||||
|
n = snd_config_iterator_entry(i);
|
||||||
|
if (snd_config_get_id(n, &id) < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!strcmp(id, "period")) {
|
||||||
|
if (snd_config_get_integer(n, &sched_period)) {
|
||||||
|
SNDERR("Invalid period for buffer %s\n", buffer_id);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(id, "rate")) {
|
||||||
|
if (snd_config_get_integer(n, &rate)) {
|
||||||
|
SNDERR("Invalid rate for buffer %s\n", buffer_id);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate buffer size */
|
||||||
|
sample_size = tplg_get_sample_size_from_format(format);
|
||||||
|
if (sample_size < 0) {
|
||||||
|
SNDERR("Invalid sample size value for %s\n", buffer_id);
|
||||||
|
return sample_size;
|
||||||
|
}
|
||||||
|
frames = (rate * sched_period) / 1000000;
|
||||||
|
buffer_size = periods * sample_size * channels * frames;
|
||||||
|
|
||||||
|
/* add size child config to buffer config */
|
||||||
|
err = tplg_config_make_add(&child, "size", SND_CONFIG_TYPE_INTEGER, buffer_cfg);
|
||||||
|
if (err < 0) {
|
||||||
|
SNDERR("Error creating size config for %s\n", buffer_id);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = snd_config_set_integer(child, buffer_size);
|
||||||
|
if (err < 0)
|
||||||
|
SNDERR("Error setting size config for %s\n", buffer_id);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
|
@ -941,6 +941,8 @@ const struct build_function_map object_build_map[] = {
|
||||||
&hwcfg_config},
|
&hwcfg_config},
|
||||||
{"Base", "fe_dai", "dai", &tplg_build_fe_dai_object, NULL, &fe_dai_config},
|
{"Base", "fe_dai", "dai", &tplg_build_fe_dai_object, NULL, &fe_dai_config},
|
||||||
{"Base", "route", "SectionGraph", &tplg_build_dapm_route_object, NULL, NULL},
|
{"Base", "route", "SectionGraph", &tplg_build_dapm_route_object, NULL, NULL},
|
||||||
|
{"Widget", "buffer", "SectionWidget", &tplg_build_generic_object,
|
||||||
|
tplg_update_buffer_auto_attr, &widget_config},
|
||||||
{"Widget", "", "SectionWidget", &tplg_build_generic_object, NULL, &widget_config},
|
{"Widget", "", "SectionWidget", &tplg_build_generic_object, NULL, &widget_config},
|
||||||
{"Control", "mixer", "SectionControlMixer", &tplg_build_mixer_control, NULL,
|
{"Control", "mixer", "SectionControlMixer", &tplg_build_mixer_control, NULL,
|
||||||
&mixer_control_config},
|
&mixer_control_config},
|
||||||
|
|
|
@ -81,6 +81,8 @@ int tplg_build_pcm_caps_object(struct tplg_pre_processor *tplg_pp,
|
||||||
snd_config_t *obj_cfg, snd_config_t *parent);
|
snd_config_t *obj_cfg, snd_config_t *parent);
|
||||||
int tplg_parent_update(struct tplg_pre_processor *tplg_pp, snd_config_t *parent,
|
int tplg_parent_update(struct tplg_pre_processor *tplg_pp, snd_config_t *parent,
|
||||||
const char *section_name, const char *item_name);
|
const char *section_name, const char *item_name);
|
||||||
|
int tplg_update_buffer_auto_attr(struct tplg_pre_processor *tplg_pp,
|
||||||
|
snd_config_t *buffer_cfg, snd_config_t *parent);
|
||||||
|
|
||||||
/* object helpers */
|
/* object helpers */
|
||||||
int tplg_pre_process_objects(struct tplg_pre_processor *tplg_pp, snd_config_t *cfg,
|
int tplg_pre_process_objects(struct tplg_pre_processor *tplg_pp, snd_config_t *cfg,
|
||||||
|
|
Loading…
Reference in a new issue