4 * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
29 #include <iniparser.h>
31 #include "tizen-audio-internal.h"
32 #include "tizen-audio-impl.h"
34 #define VOLUME_INI_DEFAULT_PATH SYSCONFDIR"/multimedia/mmfw_audio_volume.ini" /* SYSCONFDIR is defined at .spec */
35 #define VOLUME_INI_TEMP_PATH "/opt/system/mmfw_audio_volume.ini"
36 #define VOLUME_VALUE_MAX (1.0f)
37 #define GAIN_VALUE_MAX (1.0f)
38 #define RADIO_TUNING_DEFUALT_FILE SYSCONFDIR"/multimedia/mmfw_fmradio.ini"
39 #define RADIO_TUNING_TEMP_FILE "/opt/system/.mmfw_fmradio.ini"
40 #define RADIO_TUNING_ENABLE "tuning:enable"
41 #define RADIO_TUNING_VOLUME_LEVELS "fmradio:volume_levels"
42 #define RADIO_TUNING_VOLUME_TABLE "fmradio:volume_table"
44 uint32_t g_master_volume_level = 100;
46 static const char *g_volume_vconf[AUDIO_VOLUME_TYPE_MAX] = {
47 "file/private/sound/volume/system", /* AUDIO_VOLUME_TYPE_SYSTEM */
48 "file/private/sound/volume/notification", /* AUDIO_VOLUME_TYPE_NOTIFICATION */
49 "file/private/sound/volume/alarm", /* AUDIO_VOLUME_TYPE_ALARM */
50 "file/private/sound/volume/ringtone", /* AUDIO_VOLUME_TYPE_RINGTONE */
51 "file/private/sound/volume/media", /* AUDIO_VOLUME_TYPE_MEDIA */
52 "file/private/sound/volume/call", /* AUDIO_VOLUME_TYPE_CALL */
53 "file/private/sound/volume/voip", /* AUDIO_VOLUME_TYPE_VOIP */
54 "file/private/sound/volume/voice", /* AUDIO_VOLUME_TYPE_VOICE */
57 static const char *__get_volume_type_string_by_idx(uint32_t vol_type_idx)
59 switch (vol_type_idx) {
60 case AUDIO_VOLUME_TYPE_SYSTEM: return "system";
61 case AUDIO_VOLUME_TYPE_NOTIFICATION: return "notification";
62 case AUDIO_VOLUME_TYPE_ALARM: return "alarm";
63 case AUDIO_VOLUME_TYPE_RINGTONE: return "ringtone";
64 case AUDIO_VOLUME_TYPE_MEDIA: return "media";
65 case AUDIO_VOLUME_TYPE_CALL: return "call";
66 case AUDIO_VOLUME_TYPE_VOIP: return "voip";
67 case AUDIO_VOLUME_TYPE_VOICE: return "voice";
68 default: return "invalid";
72 static uint32_t __get_volume_idx_by_string_type(const char *vol_type)
74 if (!strncmp(vol_type, "system", strlen(vol_type)) || !strncmp(vol_type, "0", strlen(vol_type)))
75 return AUDIO_VOLUME_TYPE_SYSTEM;
76 else if (!strncmp(vol_type, "notification", strlen(vol_type)) || !strncmp(vol_type, "1", strlen(vol_type)))
77 return AUDIO_VOLUME_TYPE_NOTIFICATION;
78 else if (!strncmp(vol_type, "alarm", strlen(vol_type)) || !strncmp(vol_type, "2", strlen(vol_type)))
79 return AUDIO_VOLUME_TYPE_ALARM;
80 else if (!strncmp(vol_type, "ringtone", strlen(vol_type)) || !strncmp(vol_type, "3", strlen(vol_type)))
81 return AUDIO_VOLUME_TYPE_RINGTONE;
82 else if (!strncmp(vol_type, "media", strlen(vol_type)) || !strncmp(vol_type, "4", strlen(vol_type)))
83 return AUDIO_VOLUME_TYPE_MEDIA;
84 else if (!strncmp(vol_type, "call", strlen(vol_type)) || !strncmp(vol_type, "5", strlen(vol_type)))
85 return AUDIO_VOLUME_TYPE_CALL;
86 else if (!strncmp(vol_type, "voip", strlen(vol_type)) || !strncmp(vol_type, "6", strlen(vol_type)))
87 return AUDIO_VOLUME_TYPE_VOIP;
88 else if (!strncmp(vol_type, "voice", strlen(vol_type)) || !strncmp(vol_type, "7", strlen(vol_type)))
89 return AUDIO_VOLUME_TYPE_VOICE;
91 return AUDIO_VOLUME_TYPE_MEDIA;
94 static const char *__get_gain_type_string_by_idx(uint32_t gain_type_idx)
96 switch (gain_type_idx) {
97 case AUDIO_GAIN_TYPE_DEFAULT: return "default";
98 case AUDIO_GAIN_TYPE_DIALER: return "dialer";
99 case AUDIO_GAIN_TYPE_TOUCH: return "touch";
100 case AUDIO_GAIN_TYPE_AF: return "af";
101 case AUDIO_GAIN_TYPE_SHUTTER1: return "shutter1";
102 case AUDIO_GAIN_TYPE_SHUTTER2: return "shutter2";
103 case AUDIO_GAIN_TYPE_CAMCODING: return "camcording";
104 case AUDIO_GAIN_TYPE_MIDI: return "midi";
105 case AUDIO_GAIN_TYPE_BOOTING: return "booting";
106 case AUDIO_GAIN_TYPE_VIDEO: return "video";
107 case AUDIO_GAIN_TYPE_TTS: return "tts";
108 default: return "invalid";
112 static void __dump_tb(audio_hal_t *ah)
114 audio_volume_value_table_t *volume_value_table = ah->volume.volume_value_table;
115 uint32_t vol_type_idx, vol_level_idx, gain_type_idx;
116 const char *gain_type_str[] = {
117 "def", /* AUDIO_GAIN_TYPE_DEFAULT */
118 "dial", /* AUDIO_GAIN_TYPE_DIALER */
119 "touch", /* AUDIO_GAIN_TYPE_TOUCH */
120 "af", /* AUDIO_GAIN_TYPE_AF */
121 "shut1", /* AUDIO_GAIN_TYPE_SHUTTER1 */
122 "shut2", /* AUDIO_GAIN_TYPE_SHUTTER2 */
123 "cam", /* AUDIO_GAIN_TYPE_CAMCODING */
124 "midi", /* AUDIO_GAIN_TYPE_MIDI */
125 "boot", /* AUDIO_GAIN_TYPE_BOOTING */
126 "video", /* AUDIO_GAIN_TYPE_VIDEO */
127 "tts", /* AUDIO_GAIN_TYPE_TTS */
129 char dump_str[AUDIO_DUMP_STR_LEN], *dump_str_ptr;
131 /* Dump volume table */
132 AUDIO_LOG_INFO("<<<<< volume table >>>>>");
134 const char *table_str = "volumes";
136 AUDIO_LOG_INFO("<< %s >>", table_str);
138 for (vol_type_idx = 0; vol_type_idx < AUDIO_VOLUME_TYPE_MAX; vol_type_idx++) {
139 const char *vol_type_str = __get_volume_type_string_by_idx(vol_type_idx);
141 dump_str_ptr = &dump_str[0];
142 memset(dump_str, 0x00, sizeof(char) * sizeof(dump_str));
143 snprintf(dump_str_ptr, 8, "%6s:", vol_type_str);
144 dump_str_ptr += strlen(dump_str_ptr);
146 for (vol_level_idx = 0; vol_level_idx < ah->volume.volume_level_max[vol_type_idx]; vol_level_idx++) {
147 snprintf(dump_str_ptr, 6, "%01.2f ", volume_value_table->volume[vol_type_idx][vol_level_idx]);
148 dump_str_ptr += strlen(dump_str_ptr);
150 AUDIO_LOG_INFO("%s", dump_str);
153 volume_value_table = ah->volume.volume_value_table;
155 /* Dump gain table */
156 AUDIO_LOG_INFO("<<<<< gain table >>>>>");
158 dump_str_ptr = &dump_str[0];
159 memset(dump_str, 0x00, sizeof(char) * sizeof(dump_str));
161 snprintf(dump_str_ptr, 11, "%10s", " ");
162 dump_str_ptr += strlen(dump_str_ptr);
164 for (gain_type_idx = 0; gain_type_idx < AUDIO_GAIN_TYPE_MAX; gain_type_idx++) {
165 snprintf(dump_str_ptr, 7, "%5s ", gain_type_str[gain_type_idx]);
166 dump_str_ptr += strlen(dump_str_ptr);
168 AUDIO_LOG_INFO("%s", dump_str);
170 dump_str_ptr = &dump_str[0];
171 memset(dump_str, 0x00, sizeof(char) * sizeof(dump_str));
173 snprintf(dump_str_ptr, 11, "%9s:", table_str);
174 dump_str_ptr += strlen(dump_str_ptr);
176 for (gain_type_idx = 0; gain_type_idx < AUDIO_GAIN_TYPE_MAX; gain_type_idx++) {
177 snprintf(dump_str_ptr, 7, "%01.3f ", volume_value_table->gain[gain_type_idx]);
178 dump_str_ptr += strlen(dump_str_ptr);
180 AUDIO_LOG_INFO("%s", dump_str);
184 static audio_return_e __load_volume_value_table_from_ini(audio_hal_t *ah)
186 dictionary * dict = NULL;
187 uint32_t vol_type_idx, vol_level_idx, gain_type_idx;
188 audio_volume_value_table_t *volume_value_table = ah->volume.volume_value_table;
190 const char delimiter[] = ", ";
191 const char *table_str = "volumes";
192 const char *tmp_str = NULL;
193 const char *gain_str = NULL;
194 char *list_str = NULL, *ptr = NULL;
197 if (access(VOLUME_INI_TEMP_PATH, F_OK) == 0)
198 dict = iniparser_load(VOLUME_INI_TEMP_PATH);
200 AUDIO_LOG_DEBUG("Use default volume&gain ini file");
201 dict = iniparser_load(VOLUME_INI_DEFAULT_PATH);
203 AUDIO_LOG_WARN("Loading volume&gain table from ini file failed");
204 return AUDIO_ERR_UNDEFINED;
208 /* Load volume table */
209 for (vol_type_idx = 0; vol_type_idx < AUDIO_VOLUME_TYPE_MAX; vol_type_idx++) {
210 const char *vol_type_str = __get_volume_type_string_by_idx(vol_type_idx);
212 ah->volume.volume_level_max[vol_type_idx] = 0;
213 size = strlen(table_str) + strlen(vol_type_str) + 2;
216 snprintf(key, size, "%s:%s", table_str, vol_type_str);
217 if ((tmp_str = iniparser_getstring(dict, key, NULL)))
218 list_str = strdup(tmp_str);
221 token = strtok_r(list_str, delimiter, &ptr);
223 /* convert dB volume to linear volume */
224 double vol_value = 0.0f;
225 if (strncmp(token, "0", strlen(token)))
226 vol_value = pow(10.0, (atof(token) - 100) / 20.0);
227 volume_value_table->volume[vol_type_idx][ah->volume.volume_level_max[vol_type_idx]++] = vol_value;
228 token = strtok_r(NULL, delimiter, &ptr);
233 ah->volume.volume_level_max[vol_type_idx] = 1;
234 for (vol_level_idx = 0; vol_level_idx < AUDIO_VOLUME_LEVEL_MAX; vol_level_idx++) {
235 volume_value_table->volume[vol_type_idx][vol_level_idx] = VOLUME_VALUE_MAX;
242 /* Load gain table */
243 volume_value_table->gain[AUDIO_GAIN_TYPE_DEFAULT] = GAIN_VALUE_MAX;
244 for (gain_type_idx = AUDIO_GAIN_TYPE_DEFAULT + 1; gain_type_idx < AUDIO_GAIN_TYPE_MAX; gain_type_idx++) {
245 const char *gain_type_str = __get_gain_type_string_by_idx(gain_type_idx);
247 size = strlen(table_str) + strlen("gain") + strlen(gain_type_str) + 3;
250 snprintf(key, size, "%s:gain_%s", table_str, gain_type_str);
251 gain_str = iniparser_getstring(dict, key, NULL);
253 volume_value_table->gain[gain_type_idx] = atof(gain_str);
255 volume_value_table->gain[gain_type_idx] = GAIN_VALUE_MAX;
259 volume_value_table->gain[gain_type_idx] = GAIN_VALUE_MAX;
263 iniparser_freedict(dict);
270 static audio_return_e __load_radio_volume_table(int** volume_table, int *number_of_elements)
272 dictionary * dict = NULL;
273 const char delimiter[] = ", ";
274 const char *tmp_str = NULL;
277 char* list_str = NULL;
278 int* temp_table = NULL;
282 bool tuning_enable = 0;
286 dict = iniparser_load(RADIO_TUNING_DEFUALT_FILE);
288 AUDIO_LOG_ERROR("%s load failed", RADIO_TUNING_DEFUALT_FILE);
289 return AUDIO_ERR_UNDEFINED;
292 value = iniparser_getboolean(dict, RADIO_TUNING_ENABLE, not_found);
293 if (value == not_found) {
294 AUDIO_LOG_ERROR("Can't get Tuning Enable value");
296 tuning_enable = value;
297 AUDIO_LOG_INFO("Tuning enabled.");
299 iniparser_freedict(dict); /*Cleanup*/
303 AUDIO_LOG_INFO("Tuning enabled. load temp tuning file.");
304 dict = iniparser_load(RADIO_TUNING_TEMP_FILE);
306 AUDIO_LOG_WARN("%s load failed. Tuning enabled but there is not tuning temp file. Use temporary file", RADIO_TUNING_TEMP_FILE);
307 dict = iniparser_load(RADIO_TUNING_DEFUALT_FILE);
309 AUDIO_LOG_ERROR("%s load failed", RADIO_TUNING_DEFUALT_FILE);
310 return AUDIO_ERR_UNDEFINED;
314 AUDIO_LOG_INFO("Tuning diabled. load default tuning file.");
315 dict = iniparser_load(RADIO_TUNING_DEFUALT_FILE);
317 AUDIO_LOG_ERROR("%s load failed", RADIO_TUNING_DEFUALT_FILE);
318 return AUDIO_ERR_UNDEFINED;
322 *number_of_elements = iniparser_getint(dict, RADIO_TUNING_VOLUME_LEVELS, -1);
323 if (*number_of_elements <= 0 || *number_of_elements > RADIO_VOLUME_LEVEL_MAX) {
324 AUDIO_LOG_ERROR("invalid number of elements, %d", *number_of_elements);
325 ret = AUDIO_ERR_INTERNAL;
328 temp_table = (int *)malloc((*number_of_elements) * sizeof(int));
332 *volume_table = temp_table;
334 if ((tmp_str = iniparser_getstring(dict, RADIO_TUNING_VOLUME_TABLE, NULL)))
335 list_str = strdup(tmp_str);
338 token = strtok_r(list_str, delimiter, &ptr);
340 temp_table[index] = atoi(token);
341 AUDIO_LOG_INFO("fm volume index %d is %d", index, temp_table[index]);
343 token = strtok_r(NULL, delimiter, &ptr);
349 iniparser_freedict(dict);
353 static audio_return_e _audio_volume_set_ratio_radio(audio_hal_t *ah, double ratio)
355 audio_return_e audio_ret = AUDIO_RET_OK;
362 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
364 /* Applying mute at volume zero */
366 if ((audio_ret = _mixer_control_set_value(ah, MIXER_FMRADIO_MUTE, FMRADIO_MUTE_ON))) {
367 AUDIO_LOG_ERROR("[mute on] set mixer(%s) failed", MIXER_FMRADIO_MUTE);
368 return AUDIO_ERR_INTERNAL;
374 max_value = ah->volume.radio_volume_value_table[ah->volume.radio_volume_num_of_levels - 1];
375 min_value = ah->volume.radio_volume_value_table[0];
376 new_value = (int) (ratio * (max_value - min_value) + min_value);
380 if ((_mixer_control_get_value(ah, MIXER_FMRADIO_L_VOLUME, &prev_value)))
381 AUDIO_LOG_ERROR("[volume get] get mixer(%s) failed", MIXER_FMRADIO_L_VOLUME);
382 if (new_value != prev_value) {
383 AUDIO_LOG_INFO("[volume set] set mixer(%s), %d", MIXER_FMRADIO_L_VOLUME, new_value);
384 if ((audio_ret = _mixer_control_set_value(ah, MIXER_FMRADIO_L_VOLUME, new_value))) {
385 AUDIO_LOG_ERROR("[volume set] set mixer(%s) failed", MIXER_FMRADIO_L_VOLUME);
391 if ((_mixer_control_get_value(ah, MIXER_FMRADIO_R_VOLUME, &prev_value)))
392 AUDIO_LOG_ERROR("[volume get] get mixer(%s) failed", MIXER_FMRADIO_R_VOLUME);
393 if (new_value != prev_value) {
394 AUDIO_LOG_INFO("[volume set] set mixer(%s), %d", MIXER_FMRADIO_R_VOLUME, new_value);
395 if ((audio_ret = _mixer_control_set_value(ah, MIXER_FMRADIO_R_VOLUME, new_value))) {
396 AUDIO_LOG_ERROR("[volume set] set mixer(%s) failed", MIXER_FMRADIO_R_VOLUME);
404 /* Unmute if muted */
405 if ((audio_ret = _mixer_control_get_value(ah, MIXER_FMRADIO_MUTE, &mute))) {
406 AUDIO_LOG_ERROR("[mute get] get mixer(%s) failed", MIXER_FMRADIO_MUTE);
409 if (mute == FMRADIO_MUTE_ON) {
410 if ((audio_ret = _mixer_control_set_value(ah, MIXER_FMRADIO_MUTE, FMRADIO_MUTE_OFF))) {
411 AUDIO_LOG_ERROR("[mute off] set mixer(%s) failed", MIXER_FMRADIO_MUTE);
419 audio_return_e _audio_volume_init(audio_hal_t *ah)
423 audio_return_e audio_ret = AUDIO_RET_OK;
424 int init_value[AUDIO_VOLUME_TYPE_MAX] = { 9, 11, 7, 11, 7, 4, 4, 7 };
425 int* fm_table = NULL;
427 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
429 for (i = 0; i < AUDIO_VOLUME_TYPE_MAX; i++) {
430 ah->volume.volume_level[i] = init_value[i];
433 for (i = 0; i < AUDIO_VOLUME_TYPE_MAX; i++) {
434 /* Get volume value string from VCONF */
435 if (vconf_get_int(g_volume_vconf[i], &val) < 0) {
436 AUDIO_LOG_ERROR("vconf_get_int(%s) failed", g_volume_vconf[i]);
440 AUDIO_LOG_INFO("read vconf. %s = %d", g_volume_vconf[i], val);
441 ah->volume.volume_level[i] = val;
444 if (!(ah->volume.volume_value_table = malloc(AUDIO_VOLUME_DEVICE_MAX * sizeof(audio_volume_value_table_t)))) {
445 AUDIO_LOG_ERROR("volume_value_table malloc failed");
446 return AUDIO_ERR_RESOURCE;
449 audio_ret = __load_volume_value_table_from_ini(ah);
450 if (audio_ret != AUDIO_RET_OK) {
451 AUDIO_LOG_ERROR("gain table load error");
452 return AUDIO_ERR_UNDEFINED;
455 /* radio volume table */
456 __load_radio_volume_table(&fm_table, &ah->volume.radio_volume_num_of_levels);
458 AUDIO_LOG_DEBUG("number of levels -> %d", ah->volume.radio_volume_num_of_levels);
459 /*copy from temp structure to main strcture*/
460 for (i = 0; i < ah->volume.radio_volume_num_of_levels; i++)
461 ah->volume.radio_volume_value_table[i] = fm_table[i];
470 audio_return_e _audio_volume_deinit(audio_hal_t *ah)
472 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
474 if (ah->volume.volume_value_table) {
475 free(ah->volume.volume_value_table);
476 ah->volume.volume_value_table = NULL;
482 audio_return_e audio_get_volume_level_max(void *audio_handle, audio_volume_info_s *info, uint32_t *level)
484 audio_hal_t *ah = (audio_hal_t *)audio_handle;
486 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
487 AUDIO_RETURN_VAL_IF_FAIL(info, AUDIO_ERR_PARAMETER);
488 AUDIO_RETURN_VAL_IF_FAIL(level, AUDIO_ERR_PARAMETER);
490 /* Get max volume level by device & type */
491 *level = ah->volume.volume_level_max[__get_volume_idx_by_string_type(info->type)];
493 AUDIO_LOG_DEBUG("get_[%s] volume_level_max: %d", info->type, *level);
498 audio_return_e audio_get_volume_level(void *audio_handle, audio_volume_info_s *info, uint32_t *level)
500 audio_hal_t *ah = (audio_hal_t *)audio_handle;
502 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
503 AUDIO_RETURN_VAL_IF_FAIL(info, AUDIO_ERR_PARAMETER);
504 AUDIO_RETURN_VAL_IF_FAIL(level, AUDIO_ERR_PARAMETER);
506 if (!strncmp(info->type, "master", strlen("master"))) {
507 *level = g_master_volume_level;
511 *level = ah->volume.volume_level[__get_volume_idx_by_string_type(info->type)];
513 AUDIO_LOG_INFO("get [%s] volume_level: %d, direction(%d)", info->type, *level, info->direction);
518 audio_return_e audio_get_volume_value(void *audio_handle, audio_volume_info_s *info, uint32_t level, double *value)
520 audio_hal_t *ah = (audio_hal_t *)audio_handle;
521 audio_volume_value_table_t *volume_value_table;
522 char dump_str[AUDIO_DUMP_STR_LEN] = {0,};
524 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
525 AUDIO_RETURN_VAL_IF_FAIL(info, AUDIO_ERR_PARAMETER);
526 AUDIO_RETURN_VAL_IF_FAIL(value, AUDIO_ERR_PARAMETER);
527 AUDIO_RETURN_VAL_IF_FAIL(ah->volume.volume_value_table, AUDIO_ERR_PARAMETER);
529 /* Get basic volume by device & type & level */
530 volume_value_table = ah->volume.volume_value_table;
531 if (ah->volume.volume_level_max[__get_volume_idx_by_string_type(info->type)] < level)
532 *value = VOLUME_VALUE_MAX;
534 *value = volume_value_table->volume[__get_volume_idx_by_string_type(info->type)][level];
535 *value *= volume_value_table->gain[AUDIO_GAIN_TYPE_DEFAULT]; /* need to fix getting gain via audio_info_t */
537 AUDIO_LOG_DEBUG("get_volume_value:%d(%s)=>%f %s", level, info->type, *value, &dump_str[0]);
542 audio_return_e audio_set_volume_level(void *audio_handle, audio_volume_info_s *info, uint32_t level)
544 audio_return_e audio_ret = AUDIO_RET_OK;
545 audio_hal_t *ah = (audio_hal_t *)audio_handle;
547 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
548 AUDIO_RETURN_VAL_IF_FAIL(info, AUDIO_ERR_PARAMETER);
549 if (!strncmp(info->type, "master", strlen("master"))) {
550 g_master_volume_level = level;
553 AUDIO_RETURN_VAL_IF_FAIL((ah->volume.volume_level_max[__get_volume_idx_by_string_type(info->type)] >= level), AUDIO_ERR_PARAMETER);
555 /* Update volume level */
556 ah->volume.volume_level[__get_volume_idx_by_string_type(info->type)] = level;
557 AUDIO_LOG_INFO("set [%s] volume_level: %d, direction(%d)", info->type, level, info->direction);
562 audio_return_e audio_get_volume_mute(void *audio_handle, audio_volume_info_s *info, uint32_t *mute)
564 audio_return_e audio_ret = AUDIO_RET_OK;
565 audio_hal_t *ah = (audio_hal_t *)audio_handle;
567 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
568 AUDIO_RETURN_VAL_IF_FAIL(info, AUDIO_ERR_PARAMETER);
569 AUDIO_RETURN_VAL_IF_FAIL(mute, AUDIO_ERR_PARAMETER);
571 /* TODO. Not implemented */
576 audio_return_e audio_set_volume_mute(void *audio_handle, audio_volume_info_s *info, uint32_t mute)
578 audio_return_e audio_ret = AUDIO_RET_OK;
579 audio_hal_t *ah = (audio_hal_t *)audio_handle;
581 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
582 AUDIO_RETURN_VAL_IF_FAIL(info, AUDIO_ERR_PARAMETER);
584 /* TODO. Not implemented */
589 audio_return_e audio_set_volume_ratio(void *audio_handle, audio_stream_info_s *info, double ratio)
591 audio_return_e audio_ret = AUDIO_RET_OK;
592 audio_hal_t *ah = (audio_hal_t *)audio_handle;
594 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
595 AUDIO_RETURN_VAL_IF_FAIL(info, AUDIO_ERR_PARAMETER);
597 AUDIO_LOG_INFO("set [%s] volume_ratio: %f, direction(%u), index(%u)", info->role, ratio, info->direction, info->idx);
599 if (!strncmp(info->role, "radio", strlen(info->role))) {
600 AUDIO_LOG_INFO("set radio volume according to the ratio[%f]", ratio);
601 audio_ret = _audio_volume_set_ratio_radio(ah, ratio);