From cc1ec41093c3b0db3b8bdf8e8949ecdacceda190 Mon Sep 17 00:00:00 2001 From: Jonathan Aillet Date: Sat, 9 Jun 2018 00:22:05 +0200 Subject: Add value normalization of alsa control values Add functions that allows to normalize values that are requested to be sent with an alsa set control call (using alsacore). Change-Id: I5046a66d807c9b9b6751e036a47303ceddc0c16a Signed-off-by: Jonathan Aillet --- .../4a-hal-controllers-value-handler.c | 161 +++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 4a-hal/4a-hal-controllers/4a-hal-controllers-value-handler.c (limited to '4a-hal/4a-hal-controllers/4a-hal-controllers-value-handler.c') diff --git a/4a-hal/4a-hal-controllers/4a-hal-controllers-value-handler.c b/4a-hal/4a-hal-controllers/4a-hal-controllers-value-handler.c new file mode 100644 index 0000000..f749521 --- /dev/null +++ b/4a-hal/4a-hal-controllers/4a-hal-controllers-value-handler.c @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2018 "IoT.bzh" + * Author Jonathan Aillet + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _GNU_SOURCE + +#include +#include +#include + +#include +#include + +#include + +#include "4a-hal-controllers-value-handler.h" +#include "4a-hal-controllers-alsacore-link.h" + +/******************************************************************************* + * Simple conversion value to/from percentage functions * + ******************************************************************************/ + +int HalCtlsConvertValueToPercentage(double val, double min, double max) +{ + double range; + + range = max - min; + if(range <= 0) + return -INT_MAX; + + val -= min; + + return (int) round(val / range * 100); +} + +int HalCtlsConvertPercentageToValue(int percentage, int min, int max) +{ + int range; + + range = max - min; + if(range <= 0) + return -INT_MAX; + + return (int) round((double) percentage * (double) range * 0.01 + (double) min); +} + +/******************************************************************************* + * Convert json object from percentage to value * + ******************************************************************************/ + +int HalCtlsNormalizeJsonValues(AFB_ApiT apiHandle, struct CtlHalAlsaCtlProperties *alsaCtlProperties, json_object *toConvertJ, json_object ** ConvertedJ) +{ + int err = 0, idx, count, initialValue, convertedValue; + + json_object *toConvertObjectJ, *convertedValueJ, *convertedArrayJ; + + switch(json_object_get_type(toConvertJ)) { + case json_type_array: + count = json_object_array_length(toConvertJ); + break; + + case json_type_null: + case json_type_object: + count = 0; + AFB_ApiWarning(apiHandle, "%s: can't normalize json values :\n-- %s", __func__, json_object_get_string(toConvertJ)); + *ConvertedJ = json_object_get(toConvertJ); + return -1; + + default: + count = 1; + break; + } + + convertedArrayJ = json_object_new_array(); + + for(idx = 0; idx < count; idx++) { + if(count > 1) + toConvertObjectJ = json_object_array_get_idx(toConvertJ, idx); + else + toConvertObjectJ = toConvertJ; + + switch(alsaCtlProperties->type) { + case SND_CTL_ELEM_TYPE_INTEGER: + case SND_CTL_ELEM_TYPE_INTEGER64: + if(! json_object_is_type(toConvertObjectJ, json_type_int)) { + err += -10*idx; + AFB_ApiWarning(apiHandle, + "%s: Try normalize an integer control but value sent in json is not an integer : '%s'", + __func__, + json_object_get_string(toConvertObjectJ)); + convertedValueJ = toConvertObjectJ; + break; + } + + initialValue = json_object_get_int(toConvertObjectJ); + convertedValue = HalCtlsConvertPercentageToValue(initialValue, alsaCtlProperties->minval, alsaCtlProperties->maxval); + if(convertedValue == -INT_MAX) { + AFB_ApiWarning(apiHandle, + "%s: Can't normalize %i (using min %i et max %i), value set to 0", + __func__, + initialValue, + alsaCtlProperties->minval, + alsaCtlProperties->maxval); + convertedValue = 0; + } + + if(alsaCtlProperties->step) { + // Round value to the nearest step + convertedValue = (int) round((double) convertedValue / (double) alsaCtlProperties->step); + convertedValue *= alsaCtlProperties->step; + } + + convertedValueJ = json_object_new_int(convertedValue); + break; + + case SND_CTL_ELEM_TYPE_BOOLEAN: + if(! (json_object_is_type(toConvertObjectJ, json_type_int) || + json_object_is_type(toConvertObjectJ, json_type_boolean))) { + err += -1000*idx; + AFB_ApiWarning(apiHandle, + "%s: Try normalize a boolean control but value sent in json is not a boolean/integer : '%s'", + __func__, + json_object_get_string(toConvertObjectJ)); + convertedValueJ = toConvertObjectJ; + break; + } + + initialValue = json_object_get_int(toConvertObjectJ); + convertedValueJ = json_object_new_int(initialValue ? 1 : 0); + break; + + default: + AFB_ApiWarning(apiHandle, + "%s: Normalization not handle for the alsa control type %i, sending back the object as it was '%s'", + __func__, + (int) alsaCtlProperties->type, + json_object_get_string(toConvertJ)); + convertedValueJ = toConvertObjectJ; + break; + } + + json_object_array_put_idx(convertedArrayJ, idx, convertedValueJ); + } + + *ConvertedJ = convertedArrayJ; + + return 0; +} \ No newline at end of file -- cgit 1.2.3-korg