]> git.alsa-project.org Git - alsa-utils.git/commitdiff
topology:pre-process-object: merge object config with parent object config
authorRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Tue, 15 Jun 2021 23:38:32 +0000 (16:38 -0700)
committerJaroslav Kysela <perex@perex.cz>
Mon, 23 Aug 2021 14:49:56 +0000 (16:49 +0200)
An object can be declared within a class definition as follows:

Class.Pipeline.volume-playback {
Object.Widget.pga.0 {
ramp_step_ms 250
}
}

While instantiating the volume-pipeline class, the pga object
could be modified as follows:

Object.Pipeline.volume-playback.0 {
Object.Widget.pga.0 {
format "s24le"
}
}

When building the pga.0 object in the class definition, merge
the attributes declared in the volume-playback.0 object to create
a new config as follows to make sure that all attributes are
set for the pga object.

Object.Widget.pga.0 {
ramp_step_ms 250
                format "s24le"
        }

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
topology/pre-process-object.c

index 1baa9b63887629b98a72e2e28ced9d2c2a36dce5..89cdad0b941e9185d7bb8f8b1bb5dde4aba23e3a 100644 (file)
@@ -1595,16 +1595,90 @@ int tplg_pre_process_objects(struct tplg_pre_processor *tplg_pp, snd_config_t *c
                if (snd_config_get_id(n, &class_name) < 0)
                        continue;
                snd_config_for_each(i2, next2, n) {
+                       snd_config_t *temp_n2;
+
                        n2 = snd_config_iterator_entry(i2);
                        if (snd_config_get_id(n2, &id) < 0) {
                                SNDERR("Invalid id for object\n");
                                return -EINVAL;
                        }
 
+                       ret = snd_config_copy(&temp_n2, n2);
+                       if (ret < 0)
+                               return ret;
+
+                       /*
+                        * An object declared within a class definition as follows:
+                        * Class.Pipeline.volume-playback {
+                        *      Object.Widget.pga.0 {
+                        *              ramp_step_ms 250
+                        *      }
+                        * }
+                        * 
+                        * While instantiating the volume-pipeline class, the pga object
+                        * could be modified as follows:
+                        * Object.Pipeline.volume-playback.0 {
+                        *      Object.Widget.pga.0 {
+                        *              format "s24le"
+                        *      }
+                        * }
+                        * When building the pga.0 object in the class definition, merge
+                        * the attributes declared in the volume-playback.0 object to create
+                        * a new config as follows to make sure that all attributes are
+                        * set for the pga object.
+                        * Object.Widget.pga.0 {
+                        *      ramp_step_ms 250
+                        *      format "s24le"
+                        * }
+                        */ 
+
+                       if (parent) {
+                               snd_config_t *parent_instance, *parent_obj, *temp;
+                               char *obj_cfg_name;
+
+                               obj_cfg_name = tplg_snprintf("%s%s.%s.%s", "Object.",
+                                                            class_type, class_name, id);
+
+                               /* search for object instance in the parent */
+                               parent_instance = tplg_object_get_instance_config(tplg_pp, parent);
+                               if (!parent_instance)
+                                       goto temp_cfg;
+
+                               ret = snd_config_search(parent_instance, obj_cfg_name, &parent_obj);
+                               free(obj_cfg_name);
+                               if (ret < 0)
+                                       goto temp_cfg;
+
+                               /* don't merge if the object configs are the same */
+                               if (parent_obj == n2)
+                                       goto temp_cfg;
+
+                               /* create a temp config copying the parent object config */
+                               ret = snd_config_copy(&temp, parent_obj);
+                               if (ret < 0) {
+                                       snd_config_delete(temp_n2);
+                                       return ret;
+                               }
+
+                               /*
+                                * Merge parent object with the current object instance.
+                                * temp will be deleted by merge
+                                */
+                               ret = snd_config_merge(temp_n2, temp, false);
+                               if (ret < 0) {
+                                       SNDERR("error merging parent object config for %s.%s.%s\n",
+                                              class_type, class_name, id);
+                                       snd_config_delete(temp_n2);
+                                       return ret;
+                               }
+                       }
+temp_cfg:
                        /* create a temp config for object with class type as the root node */
                        ret = snd_config_make(&_obj_type, class_type, SND_CONFIG_TYPE_COMPOUND);
-                       if (ret < 0)
+                       if (ret < 0) {
+                               snd_config_delete(temp_n2);
                                return ret;
+                       }
 
                        ret = snd_config_make(&_obj_class, class_name, SND_CONFIG_TYPE_COMPOUND);
                        if (ret < 0)
@@ -1616,7 +1690,7 @@ int tplg_pre_process_objects(struct tplg_pre_processor *tplg_pp, snd_config_t *c
                                goto err;
                        }
 
-                       ret = snd_config_copy(&_obj, n2);
+                       ret = snd_config_copy(&_obj, temp_n2);
                        if (ret < 0)
                                goto err;
 
@@ -1632,6 +1706,7 @@ int tplg_pre_process_objects(struct tplg_pre_processor *tplg_pp, snd_config_t *c
                                SNDERR("Error building object %s.%s.%s\n",
                                       class_type, class_name, id);
 err:
+                       snd_config_delete(temp_n2);
                        snd_config_delete(_obj_type);
                        if (ret < 0)
                                return ret;