Fix SVACE defects
[platform/adaptation/spreadtrum/audio-hal-sc7727.git] / tizen-audio-volume.c
1 /*
2  * audio-hal
3  *
4  * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <stdbool.h>
26 #include <string.h>
27 #include <math.h>
28 #include <vconf.h>
29 #include <iniparser.h>
30
31 #include "tizen-audio-internal.h"
32 #include "tizen-audio-impl.h"
33
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"
43
44 static const char *g_volume_vconf[AUDIO_VOLUME_TYPE_MAX] = {
45     "file/private/sound/volume/system",         /* AUDIO_VOLUME_TYPE_SYSTEM */
46     "file/private/sound/volume/notification",   /* AUDIO_VOLUME_TYPE_NOTIFICATION */
47     "file/private/sound/volume/alarm",          /* AUDIO_VOLUME_TYPE_ALARM */
48     "file/private/sound/volume/ringtone",       /* AUDIO_VOLUME_TYPE_RINGTONE */
49     "file/private/sound/volume/media",          /* AUDIO_VOLUME_TYPE_MEDIA */
50     "file/private/sound/volume/call",           /* AUDIO_VOLUME_TYPE_CALL */
51     "file/private/sound/volume/voip",           /* AUDIO_VOLUME_TYPE_VOIP */
52     "file/private/sound/volume/voice",          /* AUDIO_VOLUME_TYPE_VOICE */
53 };
54
55 static const char *__get_volume_type_string_by_idx(uint32_t vol_type_idx)
56 {
57     switch (vol_type_idx) {
58     case AUDIO_VOLUME_TYPE_SYSTEM:          return "system";
59     case AUDIO_VOLUME_TYPE_NOTIFICATION:    return "notification";
60     case AUDIO_VOLUME_TYPE_ALARM:           return "alarm";
61     case AUDIO_VOLUME_TYPE_RINGTONE:        return "ringtone";
62     case AUDIO_VOLUME_TYPE_MEDIA:           return "media";
63     case AUDIO_VOLUME_TYPE_CALL:            return "call";
64     case AUDIO_VOLUME_TYPE_VOIP:            return "voip";
65     case AUDIO_VOLUME_TYPE_VOICE:           return "voice";
66     default:                                return "invalid";
67     }
68 }
69
70 static uint32_t __get_volume_idx_by_string_type(const char *vol_type)
71 {
72     if (!strncmp(vol_type, "system", strlen(vol_type)) || !strncmp(vol_type, "0", strlen(vol_type)))
73         return AUDIO_VOLUME_TYPE_SYSTEM;
74     else if (!strncmp(vol_type, "notification", strlen(vol_type)) || !strncmp(vol_type, "1", strlen(vol_type)))
75         return AUDIO_VOLUME_TYPE_NOTIFICATION;
76     else if (!strncmp(vol_type, "alarm", strlen(vol_type)) || !strncmp(vol_type, "2", strlen(vol_type)))
77         return AUDIO_VOLUME_TYPE_ALARM;
78     else if (!strncmp(vol_type, "ringtone", strlen(vol_type)) || !strncmp(vol_type, "3", strlen(vol_type)))
79         return AUDIO_VOLUME_TYPE_RINGTONE;
80     else if (!strncmp(vol_type, "media", strlen(vol_type)) || !strncmp(vol_type, "4", strlen(vol_type)))
81         return AUDIO_VOLUME_TYPE_MEDIA;
82     else if (!strncmp(vol_type, "call", strlen(vol_type)) || !strncmp(vol_type, "5", strlen(vol_type)))
83         return AUDIO_VOLUME_TYPE_CALL;
84     else if (!strncmp(vol_type, "voip", strlen(vol_type)) || !strncmp(vol_type, "6", strlen(vol_type)))
85         return AUDIO_VOLUME_TYPE_VOIP;
86     else if (!strncmp(vol_type, "voice", strlen(vol_type)) || !strncmp(vol_type, "7", strlen(vol_type)))
87         return AUDIO_VOLUME_TYPE_VOICE;
88     else
89         return AUDIO_VOLUME_TYPE_MEDIA;
90 }
91
92 static const char *__get_gain_type_string_by_idx(uint32_t gain_type_idx)
93 {
94     switch (gain_type_idx) {
95     case AUDIO_GAIN_TYPE_DEFAULT:           return "default";
96     case AUDIO_GAIN_TYPE_DIALER:            return "dialer";
97     case AUDIO_GAIN_TYPE_TOUCH:             return "touch";
98     case AUDIO_GAIN_TYPE_AF:                return "af";
99     case AUDIO_GAIN_TYPE_SHUTTER1:          return "shutter1";
100     case AUDIO_GAIN_TYPE_SHUTTER2:          return "shutter2";
101     case AUDIO_GAIN_TYPE_CAMCODING:         return "camcording";
102     case AUDIO_GAIN_TYPE_MIDI:              return "midi";
103     case AUDIO_GAIN_TYPE_BOOTING:           return "booting";
104     case AUDIO_GAIN_TYPE_VIDEO:             return "video";
105     case AUDIO_GAIN_TYPE_TTS:               return "tts";
106     default:                                return "invalid";
107     }
108 }
109
110 static void __dump_tb(audio_hal_t *ah)
111 {
112     audio_volume_value_table_t *volume_value_table = ah->volume.volume_value_table;
113     uint32_t vol_type_idx, vol_level_idx, gain_type_idx;
114     const char *gain_type_str[] = {
115         "def",          /* AUDIO_GAIN_TYPE_DEFAULT */
116         "dial",         /* AUDIO_GAIN_TYPE_DIALER */
117         "touch",        /* AUDIO_GAIN_TYPE_TOUCH */
118         "af",           /* AUDIO_GAIN_TYPE_AF */
119         "shut1",        /* AUDIO_GAIN_TYPE_SHUTTER1 */
120         "shut2",        /* AUDIO_GAIN_TYPE_SHUTTER2 */
121         "cam",          /* AUDIO_GAIN_TYPE_CAMCODING */
122         "midi",         /* AUDIO_GAIN_TYPE_MIDI */
123         "boot",         /* AUDIO_GAIN_TYPE_BOOTING */
124         "video",        /* AUDIO_GAIN_TYPE_VIDEO */
125         "tts",          /* AUDIO_GAIN_TYPE_TTS */
126     };
127     char dump_str[AUDIO_DUMP_STR_LEN], *dump_str_ptr;
128
129     /* Dump volume table */
130     AUDIO_LOG_INFO("<<<<< volume table >>>>>");
131
132     const char *table_str = "volumes";
133
134     AUDIO_LOG_INFO("<< %s >>", table_str);
135
136     for (vol_type_idx = 0; vol_type_idx < AUDIO_VOLUME_TYPE_MAX; vol_type_idx++) {
137         const char *vol_type_str = __get_volume_type_string_by_idx(vol_type_idx);
138
139         dump_str_ptr = &dump_str[0];
140         memset(dump_str, 0x00, sizeof(char) * sizeof(dump_str));
141         snprintf(dump_str_ptr, 8, "%6s:", vol_type_str);
142         dump_str_ptr += strlen(dump_str_ptr);
143
144         for (vol_level_idx = 0; vol_level_idx < volume_value_table->volume_level_max[vol_type_idx]; vol_level_idx++) {
145             snprintf(dump_str_ptr, 6, "%01.2f ", volume_value_table->volume[vol_type_idx][vol_level_idx]);
146             dump_str_ptr += strlen(dump_str_ptr);
147         }
148         AUDIO_LOG_INFO("%s", dump_str);
149     }
150
151     volume_value_table = ah->volume.volume_value_table;
152
153     /* Dump gain table */
154     AUDIO_LOG_INFO("<<<<< gain table >>>>>");
155
156     dump_str_ptr = &dump_str[0];
157     memset(dump_str, 0x00, sizeof(char) * sizeof(dump_str));
158
159     snprintf(dump_str_ptr, 11, "%10s", " ");
160     dump_str_ptr += strlen(dump_str_ptr);
161
162     for (gain_type_idx = 0; gain_type_idx < AUDIO_GAIN_TYPE_MAX; gain_type_idx++) {
163         snprintf(dump_str_ptr, 7, "%5s ", gain_type_str[gain_type_idx]);
164         dump_str_ptr += strlen(dump_str_ptr);
165     }
166     AUDIO_LOG_INFO("%s", dump_str);
167
168     dump_str_ptr = &dump_str[0];
169     memset(dump_str, 0x00, sizeof(char) * sizeof(dump_str));
170
171     snprintf(dump_str_ptr, 11, "%9s:", table_str);
172     dump_str_ptr += strlen(dump_str_ptr);
173
174     for (gain_type_idx = 0; gain_type_idx < AUDIO_GAIN_TYPE_MAX; gain_type_idx++) {
175         snprintf(dump_str_ptr, 7, "%01.3f ", volume_value_table->gain[gain_type_idx]);
176         dump_str_ptr += strlen(dump_str_ptr);
177     }
178     AUDIO_LOG_INFO("%s", dump_str);
179
180 }
181
182 static audio_return_t __load_volume_value_table_from_ini(audio_hal_t *ah)
183 {
184     dictionary * dict = NULL;
185     uint32_t vol_type_idx, vol_level_idx, gain_type_idx;
186     audio_volume_value_table_t *volume_value_table = ah->volume.volume_value_table;
187     int size = 0;
188
189     dict = iniparser_load(VOLUME_INI_TEMP_PATH);
190     if (!dict) {
191         AUDIO_LOG_DEBUG("Use default volume&gain ini file");
192         dict = iniparser_load(VOLUME_INI_DEFAULT_PATH);
193         if (!dict) {
194             AUDIO_LOG_WARN("Loading volume&gain table from ini file failed");
195             return AUDIO_ERR_UNDEFINED;
196         }
197     }
198
199     const char delimiter[] = ", ";
200     char *key, *list_str, *token, *ptr = NULL;
201     const char *table_str = "volumes";
202
203     /* Load volume table */
204     for (vol_type_idx = 0; vol_type_idx < AUDIO_VOLUME_TYPE_MAX; vol_type_idx++) {
205         const char *vol_type_str = __get_volume_type_string_by_idx(vol_type_idx);
206
207         volume_value_table->volume_level_max[vol_type_idx] = 0;
208         size = strlen(table_str) + strlen(vol_type_str) + 2;
209         key = malloc(size);
210         if (key) {
211             snprintf(key, size, "%s:%s", table_str, vol_type_str);
212             list_str = iniparser_getstring(dict, key, NULL);
213             if (list_str) {
214                 token = strtok_r(list_str, delimiter, &ptr);
215                 while (token) {
216                     /* convert dB volume to linear volume */
217                     double vol_value = 0.0f;
218                     if (strncmp(token, "0", strlen(token)))
219                         vol_value = pow(10.0, (atof(token) - 100) / 20.0);
220                     volume_value_table->volume[vol_type_idx][volume_value_table->volume_level_max[vol_type_idx]++] = vol_value;
221                     token = strtok_r(NULL, delimiter, &ptr);
222                 }
223             } else {
224                 volume_value_table->volume_level_max[vol_type_idx] = 1;
225                 for (vol_level_idx = 0; vol_level_idx < AUDIO_VOLUME_LEVEL_MAX; vol_level_idx++) {
226                     volume_value_table->volume[vol_type_idx][vol_level_idx] = VOLUME_VALUE_MAX;
227                 }
228             }
229             free(key);
230         }
231     }
232
233     /* Load gain table */
234     volume_value_table->gain[AUDIO_GAIN_TYPE_DEFAULT] = GAIN_VALUE_MAX;
235     for (gain_type_idx = AUDIO_GAIN_TYPE_DEFAULT + 1; gain_type_idx < AUDIO_GAIN_TYPE_MAX; gain_type_idx++) {
236         const char *gain_type_str = __get_gain_type_string_by_idx(gain_type_idx);
237
238         size = strlen(table_str) + strlen("gain") + strlen(gain_type_str) + 3;
239         key = malloc(size);
240         if (key) {
241             snprintf(key, size, "%s:gain_%s", table_str, gain_type_str);
242             token = iniparser_getstring(dict, key, NULL);
243             if (token) {
244                 volume_value_table->gain[gain_type_idx] = atof(token);
245             } else {
246                 volume_value_table->gain[gain_type_idx] = GAIN_VALUE_MAX;
247             }
248             free(key);
249         } else {
250             volume_value_table->gain[gain_type_idx] = GAIN_VALUE_MAX;
251         }
252     }
253
254     iniparser_freedict(dict);
255
256     __dump_tb(ah);
257
258     return AUDIO_RET_OK;
259 }
260
261 static audio_return_t __load_radio_volume_table(int** volume_table, int *number_of_elements)
262 {
263     dictionary * dict = NULL;
264     const char delimiter[] = ", ";
265     char* ptr = NULL;
266     char* token = NULL;
267     char* list_str = NULL;
268     int* temp_table = NULL;
269     int index = 0;
270     int ret = 0;
271
272     bool tuning_enable = 0;
273     int not_found = -1;
274     int value = 0;
275
276     dict = iniparser_load(RADIO_TUNING_DEFUALT_FILE);
277     if (dict == NULL) {
278         AUDIO_LOG_ERROR("%s load failed", RADIO_TUNING_DEFUALT_FILE);
279         return AUDIO_ERR_UNDEFINED;
280     } else {
281         /*tuning enable */
282         value = iniparser_getboolean(dict, RADIO_TUNING_ENABLE, not_found);
283         if (value == not_found) {
284             AUDIO_LOG_ERROR("Can't get Tuning Enable value");
285         } else {
286             tuning_enable = value;
287             AUDIO_LOG_INFO("Tuning enabled.");
288         }
289         iniparser_freedict(dict); /*Cleanup*/
290     }
291
292     if (tuning_enable) {
293         AUDIO_LOG_INFO("Tuning enabled. load temp tuning file.");
294         dict = iniparser_load(RADIO_TUNING_TEMP_FILE);
295         if (!dict) {
296             AUDIO_LOG_WARN("%s load failed. Tuning enabled but there is not tuning temp file.  Use temporary file", RADIO_TUNING_TEMP_FILE);
297             dict = iniparser_load(RADIO_TUNING_DEFUALT_FILE);
298             if (!dict) {
299                 AUDIO_LOG_ERROR("%s load failed", RADIO_TUNING_DEFUALT_FILE);
300                 return AUDIO_ERR_UNDEFINED;
301             }
302         }
303     } else {
304         AUDIO_LOG_INFO("Tuning diabled. load default tuning file.");
305         dict = iniparser_load(RADIO_TUNING_DEFUALT_FILE);
306         if (!dict) {
307             AUDIO_LOG_ERROR("%s load failed", RADIO_TUNING_DEFUALT_FILE);
308             return AUDIO_ERR_UNDEFINED;
309         }
310     }
311
312     *number_of_elements = iniparser_getint(dict, RADIO_TUNING_VOLUME_LEVELS, -1);
313     if (*number_of_elements <= 0) {
314         AUDIO_LOG_ERROR("invalid number of elements, %d", *number_of_elements);
315         ret = AUDIO_ERR_INTERNAL;
316         goto error;
317     }
318     temp_table = (int *)malloc((*number_of_elements) * sizeof(int));
319     if (!temp_table) {
320         goto error;
321     }
322     *volume_table = temp_table;
323
324     list_str = iniparser_getstring(dict, RADIO_TUNING_VOLUME_TABLE, NULL);
325     if (list_str) {
326         token = strtok_r(list_str, delimiter, &ptr);
327         while (token) {
328             temp_table[index] = atoi(token);
329             AUDIO_LOG_INFO("fm volume index %d is %d", index, temp_table[index]);
330             index++;
331             token = strtok_r(NULL, delimiter, &ptr);
332         }
333     }
334 error:
335     iniparser_freedict(dict);
336     return ret;
337 }
338
339 audio_return_t _audio_volume_set_level_radio(audio_hal_t *ah, uint32_t level)
340 {
341     audio_return_t audio_ret = AUDIO_RET_OK;
342
343     int volume = 0;
344     int mute = -1;
345
346     /* Applying mute at volume zero */
347     if (level == 0) {
348         if ((audio_ret = _mixer_control_set_value(ah, MIXER_FMRADIO_MUTE, 0)))
349             AUDIO_LOG_ERROR("set mixer(%s) failed", MIXER_FMRADIO_MUTE);
350
351     } else {
352         if ((audio_ret = _mixer_control_get_value(ah, MIXER_FMRADIO_MUTE, &mute))) {
353             AUDIO_LOG_ERROR("get mixer(%s) failed", MIXER_FMRADIO_MUTE);
354             return audio_ret;
355         }
356         if (mute == 0) {
357             if ((audio_ret = _mixer_control_set_value(ah, MIXER_FMRADIO_MUTE, 1))) {
358                 AUDIO_LOG_ERROR("set mixer(%s) failed", MIXER_FMRADIO_MUTE);
359                 return audio_ret;
360             }
361         }
362     }
363
364     if ((_mixer_control_get_value(ah, MIXER_FMRADIO_L_VOLUME, &volume)))
365         AUDIO_LOG_ERROR("get mixer(%s) failed", MIXER_FMRADIO_L_VOLUME);
366     else {
367         if (volume != ah->volume.radio_volume_value_table[level]) {
368             if ((audio_ret = _mixer_control_set_value(ah, MIXER_FMRADIO_L_VOLUME, ah->volume.radio_volume_value_table[level]))) {
369                 AUDIO_LOG_ERROR("set mixer(%s) failed", MIXER_FMRADIO_L_VOLUME);
370                 return audio_ret;
371             }
372         }
373     }
374
375     if ((_mixer_control_get_value(ah, MIXER_FMRADIO_R_VOLUME, &volume)))
376         AUDIO_LOG_ERROR("get mixer(%s) failed", MIXER_FMRADIO_R_VOLUME);
377     else {
378         if (volume != ah->volume.radio_volume_value_table[level]) {
379             if ((audio_ret = _mixer_control_set_value(ah, MIXER_FMRADIO_R_VOLUME, ah->volume.radio_volume_value_table[level])))
380                 AUDIO_LOG_ERROR("set mixer(%s) failed", MIXER_FMRADIO_R_VOLUME);
381         }
382     }
383
384     return audio_ret;
385 }
386
387 audio_return_t _audio_volume_init(audio_hal_t *ah)
388 {
389     int i;
390     int val = 0;
391     audio_return_t audio_ret = AUDIO_RET_OK;
392     int init_value[AUDIO_VOLUME_TYPE_MAX] = { 9, 11, 7, 11, 7, 4, 4, 7 };
393     int* fm_table = NULL;
394     int number_of_steps = 0;
395
396     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
397
398     for (i = 0; i < AUDIO_VOLUME_TYPE_MAX; i++) {
399         ah->volume.volume_level[i] = init_value[i];
400     }
401
402     for (i = 0; i < AUDIO_VOLUME_TYPE_MAX; i++) {
403         /* Get volume value string from VCONF */
404         if (vconf_get_int(g_volume_vconf[i], &val) < 0) {
405             AUDIO_LOG_ERROR("vconf_get_int(%s) failed", g_volume_vconf[i]);
406             continue;
407         }
408
409         AUDIO_LOG_INFO("read vconf. %s = %d", g_volume_vconf[i], val);
410         ah->volume.volume_level[i] = val;
411     }
412
413     if (!(ah->volume.volume_value_table = malloc(AUDIO_VOLUME_DEVICE_MAX * sizeof(audio_volume_value_table_t)))) {
414         AUDIO_LOG_ERROR("volume_value_table malloc failed");
415         return AUDIO_ERR_RESOURCE;
416     }
417
418     audio_ret = __load_volume_value_table_from_ini(ah);
419     if (audio_ret != AUDIO_RET_OK) {
420         AUDIO_LOG_ERROR("gain table load error");
421         return AUDIO_ERR_UNDEFINED;
422     }
423
424     /* radio volume table */
425     __load_radio_volume_table(&fm_table, &number_of_steps);
426     if (fm_table) {
427         AUDIO_LOG_DEBUG("number of steps -> %d", number_of_steps);
428         /*copy from temp structure to main strcture*/
429         for (i = 0; i < number_of_steps; i++) {
430             ah->volume.radio_volume_value_table[i] = fm_table[i];
431         }
432         free(fm_table);
433         fm_table = NULL;
434     }
435
436     return audio_ret;
437 }
438
439 audio_return_t _audio_volume_deinit(audio_hal_t *ah)
440 {
441     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
442
443     if (ah->volume.volume_value_table) {
444         free(ah->volume.volume_value_table);
445         ah->volume.volume_value_table = NULL;
446     }
447
448     return AUDIO_RET_OK;
449 }
450
451 audio_return_t audio_get_volume_level_max(void *audio_handle, audio_volume_info_t *info, uint32_t *level)
452 {
453     audio_hal_t *ah = (audio_hal_t *)audio_handle;
454     audio_volume_value_table_t *volume_value_table;
455
456     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
457     AUDIO_RETURN_VAL_IF_FAIL(ah->volume.volume_value_table, AUDIO_ERR_PARAMETER);
458
459     /* Get max volume level by device & type */
460     volume_value_table = ah->volume.volume_value_table;
461     *level = volume_value_table->volume_level_max[__get_volume_idx_by_string_type(info->type)];
462
463     AUDIO_LOG_DEBUG("get_[%s] volume_level_max: %d", info->type, *level);
464
465     return AUDIO_RET_OK;
466 }
467
468 audio_return_t audio_get_volume_level(void *audio_handle, audio_volume_info_t *info, uint32_t *level)
469 {
470     audio_hal_t *ah = (audio_hal_t *)audio_handle;
471
472     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
473
474     *level = ah->volume.volume_level[__get_volume_idx_by_string_type(info->type)];
475
476     AUDIO_LOG_INFO("get [%s] volume_level: %d, direction(%d)", info->type, *level, info->direction);
477
478     return AUDIO_RET_OK;
479 }
480
481 audio_return_t audio_get_volume_value(void *audio_handle, audio_volume_info_t *info, uint32_t level, double *value)
482 {
483     audio_hal_t *ah = (audio_hal_t *)audio_handle;
484     audio_volume_value_table_t *volume_value_table;
485     char dump_str[AUDIO_DUMP_STR_LEN] = {0,};
486
487     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
488     AUDIO_RETURN_VAL_IF_FAIL(ah->volume.volume_value_table, AUDIO_ERR_PARAMETER);
489
490     /* Get basic volume by device & type & level */
491     volume_value_table = ah->volume.volume_value_table;
492     if (volume_value_table->volume_level_max[__get_volume_idx_by_string_type(info->type)] < level)
493         *value = VOLUME_VALUE_MAX;
494     else
495         *value = volume_value_table->volume[__get_volume_idx_by_string_type(info->type)][level];
496     *value *= volume_value_table->gain[AUDIO_GAIN_TYPE_DEFAULT]; /* need to fix getting gain via audio_info_t */
497
498     AUDIO_LOG_DEBUG("get_volume_value:%d(%s)=>%f %s", level, info->type, *value, &dump_str[0]);
499
500     return AUDIO_RET_OK;
501 }
502
503 audio_return_t audio_set_volume_level(void *audio_handle, audio_volume_info_t *info, uint32_t level)
504 {
505     audio_return_t audio_ret = AUDIO_RET_OK;
506     audio_hal_t *ah = (audio_hal_t *)audio_handle;
507
508     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
509
510     /* Update volume level */
511     ah->volume.volume_level[__get_volume_idx_by_string_type(info->type)] = level;
512     AUDIO_LOG_INFO("set [%s] volume_level: %d, direction(%d)", info->type, level, info->direction);
513
514     /* set mixer related to H/W volume if needed */
515     if ((__get_volume_idx_by_string_type(info->type) == AUDIO_VOLUME_TYPE_MEDIA) && ah->device.is_radio_on)
516         audio_ret = _audio_volume_set_level_radio(ah, level);
517
518     return audio_ret;
519 }
520
521 audio_return_t audio_get_volume_mute(void *audio_handle, audio_volume_info_t *info, uint32_t *mute)
522 {
523     audio_return_t audio_ret = AUDIO_RET_OK;
524     audio_hal_t *ah = (audio_hal_t *)audio_handle;
525
526     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
527
528     /* TODO. Not implemented */
529
530     return audio_ret;
531 }
532
533 audio_return_t audio_set_volume_mute(void *audio_handle, audio_volume_info_t *info, uint32_t mute)
534 {
535     audio_return_t audio_ret = AUDIO_RET_OK;
536     audio_hal_t *ah = (audio_hal_t *)audio_handle;
537
538     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
539     /* TODO. Not implemented */
540
541     return audio_ret;
542 }