]> git.alsa-project.org Git - alsa-utils.git/commitdiff
topology: pre-process-dapm: update automatic attributes for buffer
authorChao Song <chao.song@linux.intel.com>
Wed, 2 Jun 2021 05:59:53 +0000 (13:59 +0800)
committerJaroslav Kysela <perex@perex.cz>
Mon, 23 Aug 2021 14:49:56 +0000 (16:49 +0200)
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>
topology/pre-process-dapm.c
topology/pre-process-object.c
topology/pre-processor.h

index dc510e15d225e516f5efc01cbca30cd85d151862..647e66bba6ce3537e85dd49a0c1208e914278432 100644 (file)
@@ -422,3 +422,112 @@ err:
        free(sink_widget_name);
        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;
+}
index a976cd3956da9e54728e14908ca8e533bb240bb9..4f7e2573d55133e6f55e93ccb0795bbba2c647de 100644 (file)
@@ -941,6 +941,8 @@ const struct build_function_map object_build_map[] = {
         &hwcfg_config},
        {"Base", "fe_dai", "dai", &tplg_build_fe_dai_object, NULL, &fe_dai_config},
        {"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},
        {"Control", "mixer", "SectionControlMixer", &tplg_build_mixer_control, NULL,
         &mixer_control_config},
index fce7b477b755175249f1c7206080f450f7ae1ec2..0a8bd77c20dc5059a0897955ac7950a2af899451 100644 (file)
@@ -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);
 int tplg_parent_update(struct tplg_pre_processor *tplg_pp, snd_config_t *parent,
                          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 */
 int tplg_pre_process_objects(struct tplg_pre_processor *tplg_pp, snd_config_t *cfg,