tizen beta release
[framework/multimedia/avsystem.git] / avsys-audio-logical-volume.c
1 /*
2  * avsystem
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include "avsys-audio-logical-volume.h"
26 #include "avsys-audio-shm.h"
27 #include "avsys-error.h"
28 #include "avsys-debug.h"
29
30 /* {TYPE, {MAXLEN, {MAXLEN, SPK{L,R}...}, {MAXLEN, RECV {L,R}...}, {MAXLEN, HEADSET{L,R}...}, {MAXLEN, BT{L,R}...}}} */
31 static const avsys_logical_gain_t g_volume_table[AVSYS_AUDIO_LVOL_GAIN_TYPE_MAX] = {
32         { AVSYS_AUDIO_LVOL_GAIN_TYPE_0, /* system : 0~15, default : 5 */
33                 { /* FNT DEFAULT */
34                         {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{19000,19000}}, {{22323,22323}}, {{25647,25647}}, {{28971,28971}}, {{32295,32295}}, {{35619,35619}}, {{38943,38943}}, {{42267,42267}}, {{45591,45591}}, {{48915,48915}}, {{52239,52239}}, {{55563,55563}}, {{58887,58887}}, {{62211,62211}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_SPK */
35                         {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET0 */
36                         {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET */
37                 },
38         },
39         { AVSYS_AUDIO_LVOL_GAIN_TYPE_1, /* notification : 0~15, default : 7 */
40                 { /* FNT DEFAULT */
41                         {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{19000,19000}}, {{22323,22323}}, {{25647,25647}}, {{28971,28971}}, {{32295,32295}}, {{35619,35619}}, {{38943,38943}}, {{42267,42267}}, {{45591,45591}}, {{48915,48915}}, {{52239,52239}}, {{55563,55563}}, {{58887,58887}}, {{62211,62211}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_SPK */
42                         {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET0 */
43                         {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET */
44                 },
45         },
46         { AVSYS_AUDIO_LVOL_GAIN_TYPE_2, /* alarm */
47                 { /* FNT DEFAULT */
48                         {LVOLUME_MAX_BASIC, {{{0,0}}, {{19000,19000}}, {{25991,25991}}, {{32982,32982}}, {{39973,39973}}, {{46964,46964}}, {{53955,53955}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_SPK */
49                         {LVOLUME_MAX_BASIC, {{{0,0}}, {{20480,20480}}, {{27225,27225}}, {{33969,33969}}, {{40714,40714}}, {{47458,47458}}, {{54203,54203}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET0 */
50                         {LVOLUME_MAX_BASIC, {{{0,0}}, {{20480,20480}}, {{27225,27225}}, {{33969,33969}}, {{40714,40714}}, {{47458,47458}}, {{54203,54203}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET */
51                 },
52         },
53         { AVSYS_AUDIO_LVOL_GAIN_TYPE_3, /* ringtone : 0~15, default : 13 */
54                 { /* FNT DEFAULT */
55                         {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{19000,19000}}, {{22323,22323}}, {{25647,25647}}, {{28971,28971}}, {{32295,32295}}, {{35619,35619}}, {{38943,38943}}, {{42267,42267}}, {{45591,45591}}, {{48915,48915}}, {{52239,52239}}, {{55563,55563}}, {{58887,58887}}, {{62211,62211}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_SPK */
56                         {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET0 */
57                         {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET */
58                 },
59         },
60         { AVSYS_AUDIO_LVOL_GAIN_TYPE_4, /* media */
61                 { /* FNT DEFAULT */
62                         {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{19000,19000}}, {{22323,22323}}, {{25647,25647}}, {{28971,28971}}, {{32295,32295}}, {{35619,35619}}, {{38943,38943}}, {{42267,42267}}, {{45591,45591}}, {{48915,48915}}, {{52239,52239}}, {{55563,55563}}, {{58887,58887}}, {{62211,62211}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_SPK */
63                         {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET0 */
64                         {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET */
65                 },
66         },
67         { AVSYS_AUDIO_LVOL_GAIN_TYPE_5, /* call */
68                 { /* FNT DEFAULT */
69                         {LVOLUME_MAX_BASIC, {{{0,0}}, {{19000,19000}}, {{25991,25991}}, {{32982,32982}}, {{39973,39973}}, {{46964,46964}}, {{53955,53955}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_SPK */
70                         {LVOLUME_MAX_BASIC, {{{0,0}}, {{20480,20480}}, {{27225,27225}}, {{33969,33969}}, {{40714,40714}}, {{47458,47458}}, {{54203,54203}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET0 */
71                         {LVOLUME_MAX_BASIC, {{{0,0}}, {{20480,20480}}, {{27225,27225}}, {{33969,33969}}, {{40714,40714}}, {{47458,47458}}, {{54203,54203}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET */
72                 },
73         },
74         { AVSYS_AUDIO_LVOL_GAIN_TYPE_6, /* fixed */
75                 { /* FNT DEFAULT */
76                         {LVOLUME_MAX_SINGLE, {{{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_SPK */
77                         {LVOLUME_MAX_SINGLE, {{{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET0 */
78                         {LVOLUME_MAX_SINGLE, {{{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET */
79                 },
80         },
81         { AVSYS_AUDIO_LVOL_GAIN_TYPE_7, /* java */
82                 { /* FNT DEFAULT */
83                         {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{19000,19000}}, {{22323,22323}}, {{25647,25647}}, {{28971,28971}}, {{32295,32295}}, {{35619,35619}}, {{38943,38943}}, {{42267,42267}}, {{45591,45591}}, {{48915,48915}}, {{52239,52239}}, {{55563,55563}}, {{58887,58887}}, {{62211,62211}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_SPK */
84                         {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET0 */
85                         {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET */
86                 },
87         },
88         { AVSYS_AUDIO_LVOL_GAIN_TYPE_8, /* music only (max level) */
89                 { /* FNT DEFAULT */
90                         {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{19000,19000}}, {{22323,22323}}, {{25647,25647}}, {{28971,28971}}, {{32295,32295}}, {{35619,35619}}, {{38943,38943}}, {{42267,42267}}, {{45591,45591}}, {{48915,48915}}, {{52239,52239}}, {{55563,55563}}, {{58887,58887}}, {{62211,62211}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_SPK */
91                         {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET0 */
92                         {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET */
93                 },
94         },
95 };
96
97 int avsys_audio_logical_volume_get_max(int vol_type, int dev_type, int *max)
98 {
99         void **data = NULL;
100         avsys_logical_gain_t *table = NULL;
101         data = (void **)&table;
102         if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_LVOLUME, data))) {
103                 avsys_error(AVAUDIO, "attach shared memory failed\n");
104                 return AVSYS_STATE_ERR_ALLOCATION;
105         }
106
107         if (vol_type < 0 || vol_type >= AVSYS_AUDIO_LVOL_GAIN_TYPE_MAX ||
108                 dev_type < 0 || dev_type >= AVSYS_AUDIO_LVOL_DEV_TYPE_MAX ||
109                 max == NULL) {
110                 avsys_error(AVAUDIO, "Input param wrong. Please check params\n\t type %d\n\tdevicetype %d\n",
111                                         vol_type, dev_type);
112                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
113         }
114
115         *max = table[vol_type].devices[dev_type].max_len;
116         return AVSYS_STATE_SUCCESS;
117 }
118
119 int avsys_audio_logical_volume_set_table(int vol_type, int dev_type, avsys_audio_volume_setting_t *setting)
120 {
121         void **data = NULL;
122         avsys_logical_gain_t *table = NULL;
123         data = (void**)&table;
124         if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_LVOLUME, data))) {
125                 avsys_error(AVAUDIO, "attach shared memory failed\n");
126                 return AVSYS_STATE_ERR_ALLOCATION;
127         }
128
129         avsys_info(AVAUDIO, "Set Logical gain table\n");
130         avsys_info(AVAUDIO, "\t vol_type %d dev_type %d\n", vol_type, dev_type);
131
132         if (setting == NULL) {
133                 avsys_error(AVAUDIO, "setting is null in %s\n", __func__);
134                 return AVSYS_STATE_ERR_NULL_POINTER;
135         }
136
137         /* Change  ">" -> ">=" for CRASH LOGGER */
138         if ((vol_type < 0 || vol_type >= AVSYS_AUDIO_LVOL_GAIN_TYPE_MAX) ||
139                 (dev_type < 0 || dev_type >= AVSYS_AUDIO_LVOL_DEV_TYPE_MAX)) {
140                 avsys_error(AVAUDIO, "Input param wrong. Please check params\n\ttype %d\n\tdevicetype %d\n",
141                                         vol_type, dev_type);
142                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
143         }
144
145         if (table[vol_type].type != vol_type) {
146                 avsys_error(AVAUDIO, "volume type does not match (%d, %d)in %s\n", table[vol_type].type, vol_type, __func__);
147                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
148         }
149
150         setting->vol_type = vol_type;
151         setting->dev_type = dev_type;
152         setting->max_len = table[vol_type].devices[dev_type].max_len;
153         setting->table = (avsys_audio_volume_t *)(((int)table[vol_type].devices[dev_type].gain) - (int)table);
154
155         avsys_info(AVAUDIO, "vol %d, dev%d table setted.\n", vol_type, dev_type);
156         return AVSYS_STATE_SUCCESS;
157 }
158
159 int avsys_audio_logical_volume_update_table(int dev_type, avsys_audio_volume_setting_t *setting)
160 {
161         void **data = NULL;
162         avsys_logical_gain_t *table = NULL;
163         data = (void **)&table;
164         if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_LVOLUME, data))) {
165                 avsys_error(AVAUDIO, "attach shared memory failed\n");
166                 return AVSYS_STATE_ERR_ALLOCATION;
167         }
168
169         avsys_info(AVAUDIO, "Update Logical gain table\n");
170         avsys_info(AVAUDIO, "\t dev_type %d\n", dev_type);
171
172         if (setting == NULL) {
173                 avsys_error(AVAUDIO, "setting is null in %s\n", __func__);
174                 return AVSYS_STATE_ERR_NULL_POINTER;
175         }
176         if (table[setting->vol_type].type != setting->vol_type) {
177                 avsys_error(AVAUDIO, "volume type does not match in %s\n", __func__);
178                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
179         }
180
181         if (dev_type < 0 || dev_type >= AVSYS_AUDIO_LVOL_DEV_TYPE_MAX) {
182                 avsys_error(AVAUDIO, "Input param wrong. Please check params\tdevicetype %d\n", dev_type);
183                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
184         }
185         setting->dev_type = dev_type;
186         setting->max_len = table[setting->vol_type].devices[dev_type].max_len;
187         setting->table = (avsys_audio_volume_t *)(((int)table[setting->vol_type].devices[dev_type].gain) - (int)table);
188         return AVSYS_STATE_SUCCESS;
189 }
190
191 int avsys_audio_logical_volume_convert(avsys_audio_volume_t *level, avsys_audio_volume_t *converted, avsys_audio_volume_setting_t *setting)
192 {
193         void **data = NULL;
194         avsys_logical_gain_t *table = NULL;
195         data = (void **)&table;
196         if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_LVOLUME, data))) {
197                 avsys_error(AVAUDIO, "attach shared memory failed\n");
198                 return AVSYS_STATE_ERR_ALLOCATION;
199         }
200
201         if (level == NULL) {
202                 avsys_error(AVAUDIO, "level is null in %s\n", __func__);
203                 return AVSYS_STATE_ERR_NULL_POINTER;
204         }
205         if (level->level[AVSYS_AUDIO_CHANNEL_LEFT] < 0) {
206                 avsys_error(AVAUDIO, "negative volume level (left) in %s : %d\n", __func__, level->level[AVSYS_AUDIO_CHANNEL_LEFT]);
207                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
208         }
209         if (level->level[AVSYS_AUDIO_CHANNEL_RIGHT] < 0) {
210                 avsys_error(AVAUDIO, "negative volume level (right) in %s : %d\n", __func__, level->level[AVSYS_AUDIO_CHANNEL_RIGHT]);
211                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
212         }
213
214         if (setting->max_len <= level->level[AVSYS_AUDIO_CHANNEL_LEFT] ||
215                 setting->max_len <= level->level[AVSYS_AUDIO_CHANNEL_RIGHT] ||
216                 0 > level->level[AVSYS_AUDIO_CHANNEL_LEFT] ||
217                 0 > level->level[AVSYS_AUDIO_CHANNEL_RIGHT])
218         {
219                 avsys_error(AVAUDIO, "Input param wrong. Please check params\n\t level %d %d\n", level->level[AVSYS_AUDIO_CHANNEL_LEFT], level->level[AVSYS_AUDIO_CHANNEL_RIGHT]);
220
221                 return AVSYS_STATE_ERR_INVALID_VALUE;
222         }
223
224         converted->level[AVSYS_AUDIO_CHANNEL_LEFT] = ((avsys_audio_volume_t *)((int)table + (int)setting->table))[level->level[AVSYS_AUDIO_CHANNEL_LEFT]].level[AVSYS_AUDIO_CHANNEL_LEFT];
225         converted->level[AVSYS_AUDIO_CHANNEL_RIGHT] = ((avsys_audio_volume_t *)((int)table + (int)setting->table))[level->level[AVSYS_AUDIO_CHANNEL_RIGHT]].level[AVSYS_AUDIO_CHANNEL_RIGHT];
226
227         avsys_warning(AVAUDIO, "Volume converted vol_type %d dev_type %d\n", setting->vol_type, setting->dev_type);
228         avsys_warning(AVAUDIO, "\tL: %d to %d\n", level->level[AVSYS_AUDIO_CHANNEL_LEFT], converted->level[AVSYS_AUDIO_CHANNEL_LEFT]);
229         avsys_warning(AVAUDIO, "\tR: %d to %d\n", level->level[AVSYS_AUDIO_CHANNEL_RIGHT], converted->level[AVSYS_AUDIO_CHANNEL_RIGHT]);
230
231         return AVSYS_STATE_SUCCESS;
232 }
233
234 int avsys_audio_logical_volume_init(void)
235 {
236         void *data = NULL;
237         avsys_audio_create_shm(AVSYS_AUDIO_SHM_IDEN_LVOLUME);
238         if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_LVOLUME, &data))) {
239                 avsys_error(AVAUDIO, "attach shared memory failed\n");
240                 return AVSYS_STATE_ERR_ALLOCATION;
241         }
242         memcpy(data, g_volume_table, sizeof(avsys_logical_gain_t) * AVSYS_AUDIO_LVOL_GAIN_TYPE_MAX);
243         if (AVSYS_FAIL(avsys_audio_load_volume_from_file())) {
244                 avsys_error(AVAUDIO, "Loading volume table from file failed. use default table\n");
245         }
246         return AVSYS_STATE_SUCCESS;
247 }
248
249 int avsys_audio_logical_volume_set_to_table(int gain_type, int dev_type, int step, int lv, int rv)
250 {
251         void **data = NULL;
252         avsys_logical_gain_t *table = NULL;
253         data = (void **)&table;
254         if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_LVOLUME, data))) {
255                 avsys_error(AVAUDIO, "attach shared memory failed\n");
256                 return AVSYS_STATE_ERR_ALLOCATION;
257         }
258
259         table[gain_type].devices[dev_type].gain[step].level[0] = lv;
260         table[gain_type].devices[dev_type].gain[step].level[1] = rv;
261         return AVSYS_STATE_SUCCESS;
262 }
263
264 int avsys_audio_logical_volume_get_from_table(int gain_type, int dev_type, int step, int *lv, int *rv)
265 {
266         void **data = NULL;
267         avsys_logical_gain_t *table = NULL;
268         data = (void **)&table;
269         if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_LVOLUME, data))) {
270                 avsys_error(AVAUDIO, "attach shared memory failed\n");
271                 return AVSYS_STATE_ERR_ALLOCATION;
272         }
273
274         *lv = table[gain_type].devices[dev_type].gain[step].level[0];
275         *rv = table[gain_type].devices[dev_type].gain[step].level[1];
276         return AVSYS_STATE_SUCCESS;
277 }
278
279 int avsys_audio_load_volume_from_file()
280 {
281         FILE *fp = NULL;
282         int result = AVSYS_STATE_SUCCESS;
283         char strBuffer[128];
284
285         fp = fopen(VOLUME_FILE_PATH, "r");
286         if (fp == NULL) {
287                 printf("Loading volume table from file failed\n");
288                 return AVSYS_STATE_ERR_INTERNAL;
289         }
290
291         memset(strBuffer, '\0', sizeof(strBuffer));
292         while (fgets(strBuffer, sizeof(strBuffer), fp) != NULL) {
293                 char *pEnd = NULL;
294                 char *pStart = NULL;
295                 int volumetable = 0;
296                 int device = 0;
297                 int level = 0;
298                 int lvalue = 0, rvalue = 0;
299                 char parseBuf[10] = "";
300
301                 /* remove newline */
302                 if (strBuffer[strlen(strBuffer) - 1] == '\n')
303                         strBuffer[strlen(strBuffer) - 1] = '\0';
304                 if (strBuffer[strlen(strBuffer) - 1] == '\r')
305                         strBuffer[strlen(strBuffer) - 1] = '\0';
306                 if (strBuffer[0] == '#')
307                         continue;
308
309                 pStart = strBuffer;
310                 pEnd = strstr(pStart, ":");
311                 if (pEnd) {
312                         memset(parseBuf, '\0', sizeof(parseBuf));
313                         memcpy(parseBuf, pStart, pEnd - pStart);
314                         volumetable = atoi(parseBuf);
315                 } else {
316                         result = AVSYS_STATE_ERR_INTERNAL;
317                         break;
318                 }
319
320                 pStart = ++pEnd;
321                 pEnd = strstr(pStart, ":");
322                 if (pEnd) {
323                         memset(parseBuf, '\0', sizeof(parseBuf));
324                         memcpy(parseBuf, pStart, pEnd - pStart);
325                         if (strcmp(parseBuf, "SPK") == 0)
326                                 device = 0;
327                         else if (strcmp(parseBuf, "HEADSET") == 0)
328                                 device = 1;
329                         else if (strcmp(parseBuf, "BTHEADSET") == 0)
330                                 device = 2;
331                 } else {
332                         result = AVSYS_STATE_ERR_INTERNAL;
333                         break;
334                 }
335
336                 pStart = ++pEnd;
337                 pEnd = strstr(pStart, ":");
338                 if (pEnd) {
339                         memset(parseBuf, '\0', sizeof(parseBuf));
340                         memcpy(parseBuf, pStart, pEnd - pStart);
341                         level = atoi(parseBuf);
342                 } else {
343                         result = AVSYS_STATE_ERR_INTERNAL;
344                         break;
345                 }
346
347                 pStart = ++pEnd;
348                 if (pEnd) {
349                         pEnd = strstr(pStart, ":");
350                         memset(parseBuf, '\0', sizeof(parseBuf));
351                         memcpy(parseBuf, pStart, pEnd - pStart);
352                         lvalue = atoi(parseBuf);
353                 } else {
354                         result = AVSYS_STATE_ERR_INTERNAL;
355                         break;
356                 }
357
358                 pStart = ++pEnd;
359                 rvalue = atoi(pStart);
360                 avsys_audio_set_volume_table(volumetable, device, level, lvalue, rvalue);
361         }
362         fclose(fp);
363         //avsys_info(AVAUDIO,"Load volume table from file success\n");
364         return result;
365 }