[Feature]add MT2731_MP2_MR2_SVN388 baseline version
Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/multimedia/audio-tuning/audio-xml-parser/mt2635/AudioParamTreeView.c b/src/multimedia/audio-tuning/audio-xml-parser/mt2635/AudioParamTreeView.c
new file mode 100644
index 0000000..b5254b1
--- /dev/null
+++ b/src/multimedia/audio-tuning/audio-xml-parser/mt2635/AudioParamTreeView.c
@@ -0,0 +1,398 @@
+#include "AudioParamParserPriv.h"
+
+EXPORT ParamTreeView *paramTreeViewCreate(AudioType *audioType, int verMaj, int verMin)
+{
+ ParamTreeView *paramTreeView = malloc(sizeof(ParamTreeView));
+ paramTreeView->audioType = audioType;
+ paramTreeView->verMaj = verMaj;
+ paramTreeView->verMin = verMin;
+ paramTreeView->treeRootHash = NULL;
+ return paramTreeView;
+}
+
+EXPORT void paramTreeViewRelease(ParamTreeView *paramTreeView)
+{
+ if (paramTreeView)
+ {
+ if (paramTreeView->treeRootHash)
+ {
+ TreeRoot *tmp, *item;
+ HASH_ITER(hh, paramTreeView->treeRootHash, item, tmp)
+ {
+ HASH_DEL(paramTreeView->treeRootHash, item);
+ treeRootRelease(item);
+ }
+ }
+ free(paramTreeView);
+ }
+}
+
+EXPORT TreeRoot *treeRootCreate(const char *name, xmlNode *treeRootNode, ParamTreeView *paramTreeView)
+{
+ TreeRoot *treeRoot = malloc(sizeof(TreeRoot));
+ treeRoot->name = strdup(name);
+ treeRoot->treeRootNode = treeRootNode;
+ treeRoot->paramTreeView = paramTreeView;
+ treeRoot->featureHash = NULL;
+ treeRoot->switchFieldInfo = NULL;
+ return treeRoot;
+}
+
+EXPORT void treeRootRelease(TreeRoot *treeRoot)
+{
+ if (treeRoot)
+ {
+ if (treeRoot->featureHash)
+ {
+ Feature *tmp, *item;
+ HASH_ITER(hh, treeRoot->featureHash, item, tmp)
+ {
+ HASH_DEL(treeRoot->featureHash, item);
+ featureRelease(item);
+ }
+ }
+
+ free(treeRoot->name);
+ free(treeRoot);
+ }
+}
+
+EXPORT Feature *featureCreate(const char *name, AudioType *audioType, FieldInfo *switchFieldInfo, const char *featureOption)
+{
+ Feature *feature = malloc(sizeof(Feature));
+ feature->name = strdup(name);
+ feature->audioType = audioType;
+
+ if (featureOption)
+ {
+ feature->featureOption = strdup(featureOption);
+ }
+ else
+ {
+ feature->featureOption = NULL;
+ }
+
+ feature->categoryPathHash = NULL;
+ feature->featureFieldHash = NULL;
+ feature->switchFieldInfo = switchFieldInfo;
+ return feature;
+}
+
+EXPORT void featureRelease(Feature *feature)
+{
+ if (feature)
+ {
+ if (feature->categoryPathHash)
+ {
+ CategoryPath *tmp, *item;
+ HASH_ITER(hh, feature->categoryPathHash, item, tmp)
+ {
+ HASH_DEL(feature->categoryPathHash, item);
+ categoryPathRelease(item);
+ }
+ }
+
+ if (feature->featureFieldHash)
+ {
+ FeatureField *tmp, *item;
+ HASH_ITER(hh, feature->featureFieldHash, item, tmp)
+ {
+ HASH_DEL(feature->featureFieldHash, item);
+ featureFieldRelease(item);
+ }
+ }
+
+ if (feature->name)
+ {
+ free(feature->name);
+ }
+
+ if (feature->featureOption)
+ {
+ free(feature->featureOption);
+ }
+
+ free(feature);
+ }
+}
+
+EXPORT APP_STATUS categoryPathValidation(CategoryPath *categoryPath)
+{
+ char *path;
+ char *categoryGroup;
+
+ if (!strcmp(categoryPath->path, ""))
+ {
+ return APP_NO_ERROR;
+ }
+
+ path = strdup(categoryPath->path);
+ categoryGroup = strtok(path, ARRAY_SEPERATOR);
+ if (audioTypeValidCategoryGroupName(categoryPath->feature->audioType, categoryGroup) == APP_ERROR)
+ {
+ free(path);
+ return APP_ERROR;
+ }
+
+ while ((categoryGroup = strtok(NULL, ARRAY_SEPERATOR)) != NULL)
+ {
+ if (audioTypeValidCategoryGroupName(categoryPath->feature->audioType, categoryGroup) == APP_ERROR)
+ {
+ free(path);
+ return APP_ERROR;
+ }
+ }
+
+ free(path);
+ return APP_NO_ERROR;
+}
+
+EXPORT CategoryPath *categoryPathCreate(Feature *feature, const char *path)
+{
+ CategoryPath *categoryPath = malloc(sizeof(CategoryPath));
+ categoryPath->path = strdup(path);
+ categoryPath->feature = feature;
+
+#ifdef WIN32
+ /* The category path validation only run on win32 */
+ if (categoryPathValidation(categoryPath) == APP_ERROR)
+ {
+ ERR_LOG("The %s feature's category path is not belong to categoryGroup! (%s)\n", feature->name, categoryPath->path);
+ categoryPathRelease(categoryPath);
+ return NULL;
+ }
+#endif
+
+ return categoryPath;
+}
+
+EXPORT void categoryPathRelease(CategoryPath *categoryPath)
+{
+ if (categoryPath)
+ {
+ free(categoryPath->path);
+ free(categoryPath);
+ }
+}
+
+EXPORT FeatureField *featureFieldCreate(FieldInfo *fieldInfo)
+{
+ FeatureField *featureField = malloc(sizeof(FeatureField));
+ featureField->fieldInfo = fieldInfo;
+
+ return featureField;
+}
+
+EXPORT void featureFieldRelease(FeatureField *featureField)
+{
+ if (featureField)
+ {
+ free(featureField);
+ }
+}
+
+EXPORT Feature *treeRootGetFeatureByName(TreeRoot *treeRoot, const char *featureName)
+{
+ Feature *feature;
+ HASH_FIND_STR(treeRoot->featureHash, featureName, feature);
+ return feature;
+}
+
+CategoryPath *findFeatureCategoryPath(char **arr, int *Switch, int n, Feature *feature)
+{
+ CategoryPath *categoryPath = NULL;
+ UT_string *path = NULL;
+ int i;
+
+ /* Generate the search string */
+ utstring_new(path);
+ for (i = 0; i < n; ++i)
+ {
+ if (i == n - 1)
+ {
+ utstring_printf(path, "%s", arr[Switch[i]]);
+ }
+ else
+ {
+ utstring_printf(path, "%s,", arr[Switch[i]]);
+ }
+ }
+
+ /* Find the categoryPath */
+ HASH_FIND_STR(feature->categoryPathHash, utstring_body(path), categoryPath);
+ DEBUG_LOG("Search path = %s, paramTree = 0x%p\n", utstring_body(path), categoryPath);
+
+ utstring_free(path);
+ return categoryPath;
+}
+
+CategoryPath *fuzzySearchFeatureCategoryPath(char **arr, int totalSize, int pickSize, Feature *feature)
+{
+ CategoryPath *categoryPath = NULL;
+ int i, j, pos = pickSize - 1;
+ int *swpArray;
+
+ if (pickSize > totalSize)
+ {
+ return categoryPath;
+ }
+
+ swpArray = (int *)malloc(sizeof(int) * totalSize);
+
+ for (i = 0; i < totalSize; ++i)
+ {
+ swpArray[i] = i;
+ }
+
+ categoryPath = findFeatureCategoryPath(arr, swpArray, pickSize, feature);
+ if (categoryPath)
+ {
+ free(swpArray);
+ return categoryPath;
+ }
+
+ do
+ {
+ if (swpArray[pickSize - 1] == totalSize - 1)
+ {
+ --pos;
+ }
+ else
+ {
+ pos = pickSize - 1;
+ }
+
+ ++swpArray[pos];
+
+ for (j = pos + 1; j < pickSize; ++j)
+ {
+ swpArray[j] = swpArray[j - 1] + 1;
+ }
+
+ categoryPath = findFeatureCategoryPath(arr, swpArray, pickSize, feature);
+ if (categoryPath)
+ {
+ free(swpArray);
+ return categoryPath;
+ }
+
+ }
+ while (swpArray[0] < totalSize - pickSize);
+
+ free(swpArray);
+ return categoryPath;
+}
+
+CategoryPath *searchFeatureCategoryPath(Feature *feature, const char *categoryPath)
+{
+ CategoryPath *featureCategoryPath;
+ char **categoryArray;
+ char *category;
+ char *tmpStr;
+ size_t numOfCategoryType;
+ size_t numOfCategory;
+ size_t i = 0;
+
+ DEBUG_LOG("+Feature = %s, categoryPath = %s\n", feature->name, categoryPath);
+
+ /* Full path search first */
+ HASH_FIND_STR(feature->categoryPathHash, categoryPath, featureCategoryPath);
+ if (featureCategoryPath)
+ {
+ DEBUG_LOG("fuzzySearch paramTree found. (path = %s)\n", featureCategoryPath->path);
+ return featureCategoryPath;
+ }
+ else if (!strcmp(categoryPath, ""))
+ {
+ return NULL;
+ }
+
+ /* Setup array for fuzzy search path enum */
+ numOfCategoryType = audioTypeGetNumOfCategoryType(feature->audioType);
+ categoryArray = malloc(sizeof(char *) * numOfCategoryType);
+
+ tmpStr = strdup(categoryPath ? categoryPath : "");
+ category = strtok(tmpStr, ARRAY_SEPERATOR);
+ if (!category)
+ {
+ ERR_LOG("Cannot parse category\n");
+ free(categoryArray);
+ free(tmpStr);
+ return NULL;
+ }
+ categoryArray[i++] = category;
+
+ while ((category = strtok(NULL, ARRAY_SEPERATOR)) != NULL)
+ {
+ categoryArray[i++] = category;
+ }
+ numOfCategory = i;
+
+ /* Fuzzy search */
+ for (i = 1; i < numOfCategory; i++)
+ {
+ featureCategoryPath = fuzzySearchFeatureCategoryPath(categoryArray, numOfCategory, numOfCategory - i, feature);
+ if (featureCategoryPath)
+ {
+ break;
+ }
+ }
+
+ if (!featureCategoryPath)
+ {
+ /* If no paramTree found, try to get the root paramTree */
+ HASH_FIND_STR(feature->categoryPathHash, "", featureCategoryPath);
+ }
+
+ free(categoryArray);
+ free(tmpStr);
+
+ DEBUG_LOG("-fuzzySearch featureCategoryPath %s found. \n", featureCategoryPath ? "" : "not ");
+ return featureCategoryPath;
+}
+
+EXPORT int featureIsCategoryPathSupport(Feature *feature, const char *categoryPath)
+{
+ /* Get the category path */
+ CategoryPath *featureCategoryPath = NULL;
+ UT_string *searchPath;
+
+ if (!feature)
+ {
+ ERR_LOG("feature is NULL\n");
+ return 0;
+ }
+
+ if (!categoryPath)
+ {
+ ERR_LOG("categoryPath is NULL\n");
+ return 0;
+ }
+
+ /* Check if feature support all categoryPath first */
+ featureCategoryPath = searchFeatureCategoryPath(feature, "");
+ if (featureCategoryPath)
+ {
+ return 1;
+ }
+
+ searchPath = utilNormalizeCategoryGroupPathForAudioType(categoryPath, feature->audioType);
+ if (!searchPath)
+ {
+ ERR_LOG("Cannot normalize categoryPath for %s AudioType. (path = %s)\n", feature->audioType->name, categoryPath);
+ return 0;
+ }
+
+ /* Search the feature's category path */
+ featureCategoryPath = searchFeatureCategoryPath(feature, utstring_body(searchPath));
+ utstring_free(searchPath);
+
+ if (featureCategoryPath)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}