blob: ab3014f2b60bf3a3a259dc8cc82bcf5815f0964f
1 | #define LOG_TAG "CAudioAlsa" |
2 | |
3 | #include <stdio.h> |
4 | #include <stdlib.h> |
5 | #include <string.h> |
6 | #include <getopt.h> |
7 | #include <pthread.h> |
8 | #include <stdarg.h> |
9 | #include <ctype.h> |
10 | #include <math.h> |
11 | #include <errno.h> |
12 | #include <assert.h> |
13 | #include <fcntl.h> |
14 | #include <tinyalsa/asoundlib.h> |
15 | #include "CFbcCommunication.h" |
16 | #include <sys/poll.h> |
17 | #include "tvsetting/audio_cfg.h" |
18 | #include "audio_alsa.h" |
19 | #include <cutils/properties.h> |
20 | #include "CTvLog.h" |
21 | #include "audio_amaudio.h" |
22 | |
23 | static const int DEFAULT_MAIN_DIGIT_LUT[] = { |
24 | // |
25 | 0, 40, 50, 60, 70, 87, 110, 120, 130, 140, // 0~9 |
26 | 150, 152, 155, 158, 161, 164, 167, 170, 173, 174, // 10~19 |
27 | 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, // 20~29 |
28 | 191, 191, 192, 193, 194, 195, 196, 196, 197, 197, // 30~39 |
29 | 198, 198, 198, 199, 199, 200, 200, 201, 201, 201, // 40~49 |
30 | 202, 202, 202, 203, 203, 203, 203, 204, 204, 204, // 50~59 |
31 | 205, 205, 205, 205, 206, 206, 206, 206, 206, 207, // 60~69 |
32 | 207, 207, 207, 207, 207, 207, 207, 208, 208, 208, // 70~79 |
33 | 208, 208, 208, 208, 208, 208, 208, 208, 208, 209, // 80~89 |
34 | 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, // 90~99 |
35 | 209, // 100 |
36 | }; |
37 | |
38 | static const int DEFAULT_SUPPER_BASS_DIGIT_LUT_BUF[] = { |
39 | // |
40 | 0, 122, 123, 124, 125, 126, 127, 128, 129, 130, // 0~9 |
41 | 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, // 10~19 |
42 | 141, 142, 143, 144, 145, 147, 147, 148, 148, 149, // 20~29 |
43 | 149, 150, 150, 151, 151, 152, 152, 153, 153, 154, // 30~39 |
44 | 154, 155, 155, 156, 156, 157, 157, 158, 158, 159, // 40~49 |
45 | 160, 160, 160, 160, 161, 161, 161, 161, 162, 162, // 50~59 |
46 | 162, 163, 163, 163, 163, 164, 164, 164, 165, 165, // 60~69 |
47 | 165, 165, 166, 166, 166, 167, 168, 169, 170, 171, // 70~79 |
48 | 173, 174, 175, 176, 177, 179, 180, 181, 182, 183, // 80~89 |
49 | 185, 186, 187, 188, 189, 191, 192, 193, 194, 195, // 90~99 |
50 | 197 // 100 |
51 | }; |
52 | |
53 | CAudioAlsa::CAudioAlsa() |
54 | { |
55 | int card_id; |
56 | card_id = get_aml_card(); |
57 | LOGD("[%s:%d] card_id:%d\n", __FUNCTION__, __LINE__, card_id); |
58 | mpMixer = mixer_open(card_id); |
59 | |
60 | card_id = get_USB_Audio_card(); |
61 | LOGD("[%s:%d] card_id:%d\n", __FUNCTION__, __LINE__, card_id); |
62 | mpUsbMixer = mixer_open(card_id); |
63 | mMainVolumeGainVal = 0; |
64 | mSupperBassVolumeGainVal = 0; |
65 | ArrayCopy(mMainDigitLutBuf, DEFAULT_MAIN_DIGIT_LUT, CC_VOL_TRANS_LUT_BUF_SIZE); |
66 | ArrayCopy(mSupperBassDigitLutBuf, DEFAULT_SUPPER_BASS_DIGIT_LUT_BUF, CC_VOL_TRANS_LUT_BUF_SIZE); |
67 | } |
68 | |
69 | CAudioAlsa::~CAudioAlsa() |
70 | { |
71 | if (NULL != mpMixer) { |
72 | mixer_close(mpMixer); |
73 | } |
74 | |
75 | if (NULL != mpUsbMixer) { |
76 | mixer_close(mpUsbMixer); |
77 | } |
78 | } |
79 | |
80 | int CAudioAlsa::get_aml_card() |
81 | { |
82 | int card = -1, err = 0; |
83 | int fd = -1; |
84 | char read_buf[512], *pd = NULL; |
85 | static const char *const SOUND_CARDS_PATH = "/proc/asound/cards"; |
86 | fd = open(SOUND_CARDS_PATH, O_RDONLY); |
87 | if (fd < 0) { |
88 | LOGE("ERROR: failed to open config file %s error: %d\n", SOUND_CARDS_PATH, errno); |
89 | close(fd); |
90 | return -EINVAL; |
91 | } |
92 | memset(read_buf, 0x0, 512); |
93 | err = read(fd, read_buf, 512); |
94 | if (fd < 0) { |
95 | LOGE("ERROR: failed to read config file %s error: %d\n", SOUND_CARDS_PATH, errno); |
96 | close(fd); |
97 | return -EINVAL; |
98 | } |
99 | pd = strstr(read_buf, "AML"); |
100 | card = *(pd - 3) - '0'; |
101 | close(fd); |
102 | return card; |
103 | } |
104 | |
105 | int CAudioAlsa::AudioControlSetValue(int val_count, int data_buf[], char *match_names) |
106 | { |
107 | struct mixer_ctl *pctl; |
108 | unsigned int expected_val_count; |
109 | unsigned int value_index; |
110 | |
111 | if (NULL == mpMixer) { |
112 | LOGE("[%s:%d] Failed to open mixer\n", __FUNCTION__, __LINE__); |
113 | goto err_exit; |
114 | } |
115 | |
116 | pctl = mixer_get_ctl_by_name(mpMixer, match_names); |
117 | if (NULL == pctl) { |
118 | LOGE("[%s:%d] Failed to get mixer control for:%s\n", __FUNCTION__, __LINE__, match_names); |
119 | goto err_exit; |
120 | } |
121 | expected_val_count = mixer_ctl_get_num_values(pctl); |
122 | if (expected_val_count != (unsigned int)val_count) { |
123 | LOGE("[%s:%d] val_count != expected_val_count\n", __FUNCTION__, __LINE__); |
124 | goto err_exit; |
125 | } |
126 | for (value_index = 0; value_index < expected_val_count; value_index++) { |
127 | if (mixer_ctl_set_value(pctl, value_index, data_buf[value_index]) != 0) { |
128 | LOGE("[%s:%d] Failed to set value:%d\n", __FUNCTION__, __LINE__, value_index); |
129 | goto err_exit; |
130 | } |
131 | } |
132 | return 0; |
133 | err_exit: |
134 | return -1; |
135 | } |
136 | |
137 | int CAudioAlsa::AudioControlGetValue(int val_count, int ret_buf[], char *match_names) |
138 | { |
139 | struct mixer_ctl *pctl; |
140 | unsigned int expected_val_count; |
141 | unsigned int value_index; |
142 | |
143 | if (NULL == mpMixer) { |
144 | LOGE("[%s:%d] Failed to open mixer\n", __FUNCTION__, __LINE__); |
145 | goto err_exit; |
146 | } |
147 | pctl = mixer_get_ctl_by_name(mpMixer, match_names); |
148 | if (NULL == pctl) { |
149 | LOGE("[%s:%d] Failed to get mixer control for:%s\n", __FUNCTION__, __LINE__, match_names); |
150 | goto err_exit; |
151 | } |
152 | expected_val_count = mixer_ctl_get_num_values(pctl); |
153 | if (expected_val_count != (unsigned int)val_count) { |
154 | LOGE("[%s:%d] val_count != expected_val_count\n", __FUNCTION__, __LINE__); |
155 | goto err_exit; |
156 | } |
157 | for (value_index = 0; value_index < expected_val_count; value_index++) { |
158 | ret_buf[value_index] = mixer_ctl_get_value(pctl, value_index); |
159 | } |
160 | return 0; |
161 | err_exit: |
162 | return -1; |
163 | } |
164 | |
165 | int CAudioAlsa::get_USB_Audio_card() |
166 | { |
167 | int card = -1, err = 0; |
168 | int fd = -1; |
169 | char read_buf[512], *pd = NULL; |
170 | static const char *const SOUND_CARDS_PATH = "/proc/asound/cards"; |
171 | fd = open(SOUND_CARDS_PATH, O_RDONLY); |
172 | if (fd < 0) { |
173 | LOGE("ERROR: failed to open config file %s error: %d\n", SOUND_CARDS_PATH, errno); |
174 | close(fd); |
175 | return -EINVAL; |
176 | } |
177 | memset(read_buf, 0x0, 512); |
178 | err = read(fd, read_buf, 512); |
179 | if (fd < 0) { |
180 | LOGE("ERROR: failed to read config file %s error: %d\n", SOUND_CARDS_PATH, errno); |
181 | close(fd); |
182 | return -EINVAL; |
183 | } |
184 | pd = strstr(read_buf, "Receiver"); |
185 | if (pd == NULL) { |
186 | LOGE("ERROR: failed to read config file %s error: %d\n", SOUND_CARDS_PATH, errno); |
187 | close(fd); |
188 | return -EINVAL; |
189 | } |
190 | |
191 | card = *(pd - 3) - '0'; |
192 | close(fd); |
193 | return card; |
194 | } |
195 | |
196 | int CAudioAlsa::HandleUSBAudioControlValue(int val_count, int data_buf[], int match_count, char **match_names) |
197 | { |
198 | |
199 | struct mixer_ctl *pctl; |
200 | unsigned int expected_val_count; |
201 | unsigned int match_index; |
202 | unsigned int value_index; |
203 | char card_id_str[9] = {0}; |
204 | |
205 | if (NULL == mpUsbMixer) { |
206 | LOGE("[%s:%d] Failed to open mixer\n", __FUNCTION__, __LINE__); |
207 | goto err_exit; |
208 | } |
209 | |
210 | for (match_index = 0; match_index < (unsigned int)match_count; match_index++) { |
211 | pctl = mixer_get_ctl_by_name(mpUsbMixer, match_names[match_index]); |
212 | if (NULL == pctl) { |
213 | LOGE("[%s:%d] Failed to get mixer control for:%s\n", __FUNCTION__, __LINE__, match_names[match_index]); |
214 | goto err_exit; |
215 | } |
216 | expected_val_count = mixer_ctl_get_num_values(pctl); |
217 | if (expected_val_count != (unsigned int)val_count) { |
218 | LOGE("[%s:%d] val_count != expected_val_count\n", __FUNCTION__, __LINE__); |
219 | goto err_exit; |
220 | } |
221 | for (value_index = 0; value_index < expected_val_count; value_index++) { |
222 | if (mixer_ctl_set_value(pctl, value_index, data_buf[value_index]) != 0) { |
223 | LOGE("[%s:%d] Failed to set value:%d\n", __FUNCTION__, __LINE__, value_index); |
224 | goto err_exit; |
225 | } |
226 | } |
227 | } |
228 | |
229 | return 0; |
230 | err_exit: |
231 | return -1; |
232 | } |
233 | |
234 | int CAudioAlsa::CheckVolume(int digit_vol, int digit_min __unused, int digit_max __unused, |
235 | int hd_min, int hd_max) |
236 | { |
237 | if (digit_vol < hd_min) { |
238 | return hd_min; |
239 | } else if (digit_vol > hd_max) { |
240 | return hd_max; |
241 | } |
242 | |
243 | return digit_vol; |
244 | } |
245 | |
246 | int CAudioAlsa::GetTwoChannelVolume(int vol_buf[], |
247 | int l_min_vol __unused, int l_max_vol __unused, |
248 | int r_min_vol __unused, int r_max_vol __unused, |
249 | char *match_names, |
250 | int hd_min __unused, int hd_max __unused) |
251 | { |
252 | vol_buf[0] = 0; |
253 | vol_buf[1] = 0; |
254 | return AudioControlGetValue(2, vol_buf, match_names); |
255 | } |
256 | |
257 | int CAudioAlsa::GetLineInMaxVol() |
258 | { |
259 | return 127; |
260 | } |
261 | |
262 | int CAudioAlsa::GetLineOutMaxVol() |
263 | { |
264 | return 255; |
265 | } |
266 | |
267 | #define CC_GET_ALSA_CTL_AUDIO_IN_SOURCE_NAME (0) |
268 | #define CC_GET_ALSA_CTL_INTERNAL_DAC_PGA_IN_GAIN (1) |
269 | #define CC_GET_ALSA_CTL_INTERNAL_DAC_ADC_DIGITAL_CAPTURE_VOLUME_NAME (2) |
270 | #define CC_GET_ALSA_CTL_INTERNAL_DAC_DAC_DIGITAL_PLAYBACK_VOLUME_NAME (3) |
271 | #define CC_GET_ALSA_CTL_INTERNAL_DAC_LEFT_LINEIN_SEL_NAME (4) |
272 | #define CC_GET_ALSA_CTL_INTERNAL_DAC_RIGHT_LINEIN_SEL_NAME (5) |
273 | #define CC_GET_ALSA_CTL_INTERNAL_DAC_LINEIN_CAPTURE_VOLUME_NAME (6) |
274 | #define CC_GET_ALSA_CTL_INTERNAL_DAC_LINEOUT_PLAYBACK_VOLUME_NAME (7) |
275 | #define CC_GET_ALSA_CTL_I2S_MUTE_NAME (8) |
276 | #define CC_GET_ALSA_CTL_SPDIF_MUTE_NAME (9) |
277 | #define CC_GET_ALSA_CTL_HW_RESAMPLE_NAME (10) |
278 | #define CC_GET_ALSA_CTL_EXTERNAL_DAC_MASTER_VOLUME_NAME (11) |
279 | #define CC_GET_ALSA_CTL_EXTERNAL_DAC_CH1_VOLUME_NAME (12) |
280 | #define CC_GET_ALSA_CTL_EXTERNAL_DAC_CH2_VOLUME_NAME (13) |
281 | #define CC_GET_ALSA_CTL_EXTERNAL_DAC_CH3_VOLUME_NAME (14) |
282 | #define CC_GET_ALSA_CTL_EXTERNAL_DAC_CH1_SWITCH_NAME (15) |
283 | #define CC_GET_ALSA_CTL_EXTERNAL_DAC_CH2_SWITCH_NAME (16) |
284 | #define CC_GET_ALSA_CTL_EXTERNAL_DAC_CH3_SWITCH_NAME (17) |
285 | #define CC_GET_ALSA_CTL_EXTERNAL_DAC_EQ_MODE_NAME (18) |
286 | #define CC_GET_ALSA_CTL_PCM_PLAYBACK_VOLUME (19) |
287 | #define CC_GET_ALSA_CTL_PCM_PLAYBACK_SWITCH (20) |
288 | #define CC_GET_ALSA_CTL_SETOUTPUT_SWAP (21) |
289 | #define CC_GET_ALSA_CTL_AUDIO_IN_SWITCH (22) |
290 | |
291 | static char gG9AlsaNames[32][48] = { |
292 | {"Audio In Source"},//0 |
293 | {"PGA IN Gain"},//1 |
294 | {"ADC Digital Capture Volume"},//2 |
295 | {"DAC Digital Playback Volume"},//3 |
296 | {"Linein right switch"},//4 |
297 | {"Linein left switch"}, |
298 | {"ADC Digital Capture Volume"}, |
299 | {"DAC Digital Playback Volume"}, |
300 | {"Audio i2s mute"},//8 |
301 | {"Audio spdif mute"}, |
302 | {"Hardware resample enable"},//10 |
303 | {"AMP Master Volume"}, |
304 | {"AMP Ch1 Volume"},//12 |
305 | {"AMP Ch2 Volume"}, |
306 | {"AMP Ch3 Volume"}, |
307 | {"AMP Ch1 Switch"}, |
308 | {"AMP Ch2 Switch"}, |
309 | {"AMP Ch3 Switch"},//17 |
310 | {"AMP EQ Mode"}, |
311 | {"PCM Playback Volume"}, |
312 | {"PCM Playback Switch"}, |
313 | {"Output Swap"}, |
314 | {"AudioIn Switch"},//22 |
315 | }; |
316 | |
317 | |
318 | char *CAudioAlsa::GetAlsaControlName(int get_type) |
319 | { |
320 | return gG9AlsaNames[get_type]; |
321 | } |
322 | |
323 | |
324 | int CAudioAlsa::SetAudioInSource(int source_type) |
325 | { |
326 | int set_val = 0; |
327 | char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_AUDIO_IN_SOURCE_NAME); |
328 | set_val = source_type; |
329 | return AudioControlSetValue(1, &set_val, match_names); |
330 | } |
331 | |
332 | int CAudioAlsa::GetAudioInSource(void) |
333 | { |
334 | char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_AUDIO_IN_SOURCE_NAME); |
335 | int source_type = 0; |
336 | AudioControlGetValue(1, &source_type, match_names); |
337 | return source_type; |
338 | } |
339 | |
340 | int CAudioAlsa::SetAudioInternalDacPGAInGain(int gain_l_val, int gain_r_val) |
341 | { |
342 | int GainBuf[2] = {0, 0}; |
343 | char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_PGA_IN_GAIN); |
344 | |
345 | GainBuf[0] = gain_l_val; |
346 | GainBuf[1] = gain_r_val; |
347 | if (gain_l_val < 0 || gain_l_val > 31) { |
348 | GainBuf[0] = 16; |
349 | } |
350 | if (gain_r_val < 0 || gain_r_val > 31) { |
351 | GainBuf[1] = 16; |
352 | } |
353 | |
354 | return AudioControlSetValue(2, GainBuf, match_names); |
355 | } |
356 | |
357 | int CAudioAlsa::GetAudioInternalDacPGAInGain(int *gain_l_val, int *gain_r_val) |
358 | { |
359 | int GainBuf[2] = {0, 0}; |
360 | char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_PGA_IN_GAIN); |
361 | |
362 | AudioControlGetValue(2, GainBuf, match_names); |
363 | |
364 | *gain_l_val = GainBuf[0]; |
365 | *gain_r_val = GainBuf[1]; |
366 | |
367 | return 0; |
368 | } |
369 | |
370 | int CAudioAlsa::SetAudioInternalDacADCDigitalCaptureVolume(int vol_l_val, int vol_r_val) |
371 | { |
372 | int VolumeBuf[2] = {0, 0}; |
373 | char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_ADC_DIGITAL_CAPTURE_VOLUME_NAME); |
374 | |
375 | VolumeBuf[0] = vol_l_val; |
376 | VolumeBuf[1] = vol_r_val; |
377 | if (vol_l_val < 0 || vol_l_val > 127) { |
378 | VolumeBuf[0] = 82; |
379 | } |
380 | if (vol_r_val < 0 || vol_r_val > 127) { |
381 | VolumeBuf[1] = 82; |
382 | } |
383 | |
384 | return AudioControlSetValue(2, VolumeBuf, match_names); |
385 | } |
386 | |
387 | int CAudioAlsa::GetAudioInternalDacADCDigitalCaptureVolume(int *vol_l_val, int *vol_r_val) |
388 | { |
389 | int VolumeBuf[2] = {0, 0}; |
390 | char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_ADC_DIGITAL_CAPTURE_VOLUME_NAME); |
391 | |
392 | AudioControlGetValue(2, VolumeBuf, match_names); |
393 | |
394 | *vol_l_val = VolumeBuf[0]; |
395 | *vol_r_val = VolumeBuf[1]; |
396 | |
397 | return 0; |
398 | } |
399 | |
400 | int CAudioAlsa::SetAudioInternalDacDACDigitalPlayBackVolume(int vol_l_val, int vol_r_val) |
401 | { |
402 | int VolumeBuf[2] = {0, 0}; |
403 | char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_DAC_DIGITAL_PLAYBACK_VOLUME_NAME); |
404 | |
405 | VolumeBuf[0] = vol_l_val; |
406 | VolumeBuf[1] = vol_r_val; |
407 | if (vol_l_val < 0 || vol_l_val > 255) { |
408 | VolumeBuf[0] = 255; |
409 | } |
410 | if (vol_r_val < 0 || vol_r_val > 255) { |
411 | VolumeBuf[1] = 255; |
412 | } |
413 | |
414 | return AudioControlSetValue(2, VolumeBuf, match_names); |
415 | } |
416 | |
417 | int CAudioAlsa::GetAudioInternalDacDACDigitalPlayBackVolume(int *vol_l_val, int *vol_r_val) |
418 | { |
419 | int VolumeBuf[2] = {0, 0}; |
420 | char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_DAC_DIGITAL_PLAYBACK_VOLUME_NAME); |
421 | |
422 | AudioControlGetValue(2, VolumeBuf, match_names); |
423 | |
424 | *vol_l_val = VolumeBuf[0]; |
425 | *vol_r_val = VolumeBuf[1]; |
426 | |
427 | return 0; |
428 | } |
429 | |
430 | int CAudioAlsa::SetInternalDacLineInSelectChannel(int line_in_number) |
431 | { |
432 | int tmp_ret = 0; |
433 | char *match_names = NULL; |
434 | |
435 | if (line_in_number < 0 || line_in_number > 7) { |
436 | return -1; |
437 | } |
438 | |
439 | match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_LEFT_LINEIN_SEL_NAME); |
440 | tmp_ret |= AudioControlSetValue(1, &line_in_number, match_names); |
441 | |
442 | match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_RIGHT_LINEIN_SEL_NAME); |
443 | tmp_ret |= AudioControlSetValue(1, &line_in_number, match_names); |
444 | |
445 | return tmp_ret; |
446 | } |
447 | |
448 | int CAudioAlsa::SetInternalDacLineInCaptureVolume(int l_vol, int r_vol) |
449 | { |
450 | int max_val = GetLineInMaxVol(); |
451 | char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_LINEIN_CAPTURE_VOLUME_NAME); |
452 | int VolumeBuf[2]; |
453 | |
454 | VolumeBuf[0] = CheckVolume(l_vol, 0, max_val, 0, max_val); |
455 | VolumeBuf[1] = CheckVolume(r_vol, 0, max_val, 0, max_val); |
456 | |
457 | return AudioControlSetValue(2, VolumeBuf, match_names); |
458 | } |
459 | |
460 | int CAudioAlsa::GetInternalDacLineInCaptureVolume(int vol_buf[]) |
461 | { |
462 | int max_val = GetLineInMaxVol(); |
463 | char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_LINEIN_CAPTURE_VOLUME_NAME); |
464 | |
465 | return GetTwoChannelVolume(vol_buf, 0, max_val, 0, max_val, match_names, 0, max_val); |
466 | } |
467 | |
468 | int CAudioAlsa::SetInternalDacLineOutPlayBackVolume(int l_vol, int r_vol) |
469 | { |
470 | int max_val = GetLineOutMaxVol(); |
471 | char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_LINEOUT_PLAYBACK_VOLUME_NAME); |
472 | int VolumeBuf[2]; |
473 | |
474 | VolumeBuf[0] = CheckVolume(l_vol, 0, max_val, 0, max_val); |
475 | VolumeBuf[1] = CheckVolume(r_vol, 0, max_val, 0, max_val); |
476 | |
477 | return AudioControlSetValue(2, VolumeBuf, match_names); |
478 | } |
479 | |
480 | int CAudioAlsa::GetInternalDacLineOutPlayBackVolume(int vol_buf[]) |
481 | { |
482 | int max_val = GetLineOutMaxVol(); |
483 | char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_INTERNAL_DAC_LINEOUT_PLAYBACK_VOLUME_NAME); |
484 | |
485 | return GetTwoChannelVolume(vol_buf, 0, max_val, 0, max_val, match_names, 0, max_val); |
486 | } |
487 | |
488 | int CAudioAlsa::SetAudioPcmPlaybackVolume(int vol) |
489 | { |
490 | if (get_USB_Audio_card() == -EINVAL) return 0; |
491 | char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_PCM_PLAYBACK_VOLUME); |
492 | return HandleUSBAudioControlValue(1, &vol, 1, &match_names); |
493 | } |
494 | |
495 | int CAudioAlsa::SetAudioPcmPlaybackSwitch(int vol) |
496 | { |
497 | if (get_USB_Audio_card() == -EINVAL) return 0; |
498 | char *match_names = GetAlsaControlName(CC_GET_ALSA_CTL_PCM_PLAYBACK_SWITCH); |
499 | return HandleUSBAudioControlValue(1, &vol, 1, &match_names); |
500 | } |
501 | |
502 | int CAudioAlsa::SetExternalDacChannelSwitch(int chan_ind, int switch_val) |
503 | { |
504 | char *match_names = NULL; |
505 | |
506 | if (chan_ind == 1) { |
507 | match_names = GetAlsaControlName(CC_GET_ALSA_CTL_EXTERNAL_DAC_CH1_SWITCH_NAME); |
508 | } else if (chan_ind == 2) { |
509 | match_names = GetAlsaControlName(CC_GET_ALSA_CTL_EXTERNAL_DAC_CH2_SWITCH_NAME); |
510 | } else if (chan_ind == 3) { |
511 | match_names = GetAlsaControlName(CC_GET_ALSA_CTL_EXTERNAL_DAC_CH3_SWITCH_NAME); |
512 | } else { |
513 | return -1; |
514 | } |
515 | |
516 | return AudioControlSetValue(1, &switch_val, match_names); |
517 | } |
518 | |
519 | int CAudioAlsa::SetExternalDacChannelVolume(int chan_ind, int main_vol) |
520 | { |
521 | int tmp_ret = 0; |
522 | char *match_names = NULL; |
523 | |
524 | if (chan_ind == 0) { |
525 | match_names = GetAlsaControlName(CC_GET_ALSA_CTL_EXTERNAL_DAC_MASTER_VOLUME_NAME); |
526 | } else if (chan_ind == 1) { |
527 | match_names = GetAlsaControlName(CC_GET_ALSA_CTL_EXTERNAL_DAC_CH1_VOLUME_NAME); |
528 | } else if (chan_ind == 2) { |
529 | match_names = GetAlsaControlName(CC_GET_ALSA_CTL_EXTERNAL_DAC_CH2_VOLUME_NAME); |
530 | } else if (chan_ind == 3) { |
531 | match_names = GetAlsaControlName(CC_GET_ALSA_CTL_EXTERNAL_DAC_CH3_VOLUME_NAME); |
532 | } else { |
533 | return -1; |
534 | } |
535 | |
536 | return AudioControlSetValue(1, &main_vol, match_names); |
537 | } |
538 | int CAudioAlsa::SetAudioSwitchIO(int value) |
539 | { |
540 | char *match_names = gG9AlsaNames[CC_GET_ALSA_CTL_AUDIO_IN_SWITCH]; |
541 | |
542 | return AudioControlSetValue(1, &value, match_names); |
543 | } |
544 | int CAudioAlsa::SetOutput_Swap(int value) |
545 | { |
546 | char *match_names = gG9AlsaNames[CC_GET_ALSA_CTL_SETOUTPUT_SWAP]; |
547 | |
548 | return AudioControlSetValue(1, &value, match_names); |
549 | } |
550 | |
551 | int CAudioAlsa::SetExternalDacEQMode(int mode_val) |
552 | { |
553 | char *match_names = NULL; |
554 | |
555 | match_names = GetAlsaControlName(CC_GET_ALSA_CTL_EXTERNAL_DAC_EQ_MODE_NAME); |
556 | return AudioControlSetValue(1, &mode_val, match_names); |
557 | } |
558 | |
559 | int CAudioAlsa::SetI2SMute(int mute_status) |
560 | { |
561 | char *match_names = NULL; |
562 | |
563 | if (mute_status != CC_I2S_MUTE_ON && mute_status != CC_I2S_MUTE_OFF) { |
564 | LOGE("%s, I2S mute value (%d) error!\n", __FUNCTION__, mute_status); |
565 | return -1; |
566 | } |
567 | |
568 | match_names = GetAlsaControlName(CC_GET_ALSA_CTL_I2S_MUTE_NAME); |
569 | return AudioControlSetValue(1, &mute_status, match_names); |
570 | } |
571 | |
572 | int CAudioAlsa::SetSPDIFMute(int mute_status) |
573 | { |
574 | int set_val = 0; |
575 | char *match_names = NULL; |
576 | |
577 | if (mute_status == CC_AUDIO_MUTE) { |
578 | set_val = CC_SPDIF_MUTE_ON; |
579 | } else if (mute_status == CC_AUDIO_UNMUTE) { |
580 | set_val = CC_SPDIF_MUTE_OFF; |
581 | } else { |
582 | return -1; |
583 | } |
584 | match_names = GetAlsaControlName(CC_GET_ALSA_CTL_SPDIF_MUTE_NAME); |
585 | return AudioControlSetValue(1, &mute_status, match_names); |
586 | } |
587 | |
588 | #define CC_SAMPLE_BUF_SIZE (32) |
589 | |
590 | enum CC_HW_RESAMPLE_TYPE { |
591 | CC_HW_RESAMPLE_DISABLE, |
592 | CC_HW_RESAMPLE_48K, |
593 | CC_HW_RESAMPLE_44K, |
594 | CC_HW_RESAMPLE_32K, |
595 | }; |
596 | |
597 | int CAudioAlsa::SetHardwareResample(int sr) |
598 | { |
599 | int i = 0, set_val = 0, tmp_val = 0; |
600 | int diff_val = 0x7FFFFFFF, diff_ind = -1; |
601 | char *match_names = NULL; |
602 | int sample_buf[CC_SAMPLE_BUF_SIZE] = {48000, 44100, 32000, -1}; |
603 | |
604 | if (sr < 0) { |
605 | set_val = 0; |
606 | } else { |
607 | for (i = 0; i < CC_SAMPLE_BUF_SIZE; i++) { |
608 | if (sample_buf[i] < 0) { |
609 | break; |
610 | } |
611 | |
612 | if (sample_buf[i] >= sr) { |
613 | tmp_val = sample_buf[i] - sr; |
614 | } else { |
615 | tmp_val = sr - sample_buf[i]; |
616 | } |
617 | |
618 | if (tmp_val <= diff_val) { |
619 | diff_val = tmp_val; |
620 | diff_ind = i; |
621 | } |
622 | } |
623 | |
624 | if (diff_ind < 0) { |
625 | set_val = 0; |
626 | } else { |
627 | set_val = diff_ind + 1; |
628 | } |
629 | } |
630 | |
631 | LOGD("%s, set_val = %d.\n", __FUNCTION__, set_val); |
632 | match_names = GetAlsaControlName(CC_GET_ALSA_CTL_HW_RESAMPLE_NAME); |
633 | return AudioControlSetValue(1, &set_val, match_names); |
634 | } |
635 | |
636 | int CAudioAlsa::SetMixerBypassSwitch(int switch_val) |
637 | { |
638 | char match_names[48] = "Output Mixer Bypass Switch" ; |
639 | int ctl_buf[2]; |
640 | |
641 | if (switch_val != 0 && switch_val != 1) { |
642 | return -1; |
643 | } |
644 | |
645 | ctl_buf[0] = switch_val; |
646 | ctl_buf[1] = switch_val; |
647 | |
648 | return AudioControlSetValue(2, ctl_buf, match_names); |
649 | } |
650 | |
651 | int CAudioAlsa::GetMixerBypassSwitch(void) |
652 | { |
653 | char match_names[48] = "Output Mixer Bypass Switch" ; |
654 | int ctl_buf[2]; |
655 | |
656 | AudioControlSetValue(2, ctl_buf, match_names); |
657 | |
658 | return ctl_buf[0]; |
659 | } |
660 | |
661 | int CAudioAlsa::SetMixerDacSwitch(int switch_val) |
662 | { |
663 | char match_names[48] = "Output Mixer DAC Switch" ; |
664 | int ctl_buf[2]; |
665 | |
666 | if (switch_val != 0 && switch_val != 1) { |
667 | return -1; |
668 | } |
669 | |
670 | ctl_buf[0] = switch_val; |
671 | ctl_buf[1] = switch_val; |
672 | |
673 | return AudioControlSetValue(2, ctl_buf, match_names); |
674 | } |
675 | |
676 | int CAudioAlsa::GetMixerDacSwitch(void) |
677 | { |
678 | int ctl_buf[2]; |
679 | AudioControlGetValue(2, ctl_buf, (char *)"Output Mixer DAC Switch"); |
680 | return ctl_buf[0]; |
681 | } |
682 | |
683 | int CAudioAlsa::TransVolumeBarVolToDigitalVol(int digit_lut_buf[], int digit_vol) |
684 | { |
685 | return digit_lut_buf[digit_vol]; |
686 | } |
687 | |
688 | int CAudioAlsa::TransDigitalVolToVolumeBarVol(int digit_lut_buf[], int hd_vol, |
689 | int hd_min __unused, int hd_max __unused, |
690 | int digit_min __unused, int digit_max) |
691 | { |
692 | int i = 0; |
693 | for (; i < CC_VOL_TRANS_LUT_BUF_SIZE - 1; i++) { |
694 | if (digit_lut_buf[i] >= hd_vol && digit_lut_buf[i + 1] < hd_vol) |
695 | break; |
696 | } |
697 | |
698 | if (i < CC_VOL_TRANS_LUT_BUF_SIZE - 1) |
699 | return i; |
700 | |
701 | return digit_max; |
702 | } |
703 | |
704 | void CAudioAlsa::SetMainVolDigitLutBuf(int digit_lut_buf[]) |
705 | { |
706 | memcpy((void *) mMainDigitLutBuf, digit_lut_buf, |
707 | CC_VOL_TRANS_LUT_BUF_SIZE * sizeof(int)); |
708 | } |
709 | |
710 | int *CAudioAlsa::GetMainVolDigitLutBuf() |
711 | { |
712 | return mMainDigitLutBuf; |
713 | } |
714 | void CAudioAlsa::SetSupperBassVolDigitLutBuf(int digit_lut_buf[]) |
715 | { |
716 | memcpy((void *) mSupperBassDigitLutBuf, digit_lut_buf, |
717 | CC_VOL_TRANS_LUT_BUF_SIZE * sizeof(int)); |
718 | } |
719 | |
720 | |
721 | int CAudioAlsa::SetMainVolumeGain(int gain_val) |
722 | { |
723 | mMainVolumeGainVal = gain_val; |
724 | return mMainVolumeGainVal; |
725 | } |
726 | |
727 | int CAudioAlsa::GetMainVolumeGain() |
728 | { |
729 | return mMainVolumeGainVal; |
730 | } |
731 | |
732 | int CAudioAlsa::SetSupperBassVolumeGain(int gain_val) |
733 | { |
734 | int tmp_val = 0; |
735 | tmp_val = mSupperBassVolumeGainVal; |
736 | mSupperBassVolumeGainVal = gain_val; |
737 | return tmp_val; |
738 | } |
739 | |
740 | int CAudioAlsa::GetSupperBassVolumeGain() |
741 | { |
742 | int tmp_val = 0; |
743 | tmp_val = mSupperBassVolumeGainVal; |
744 | return tmp_val; |
745 | } |
746 | |
747 | |
748 | int CAudioAlsa::CalculateBalanceVol(int max_vol, int balance_val, int vol_buf[]) |
749 | { |
750 | int bal_mid_vol = 0, bal_cal_len = 0; |
751 | int tmp_val = 0; |
752 | |
753 | vol_buf[0] = max_vol; |
754 | vol_buf[1] = max_vol; |
755 | |
756 | bal_mid_vol = (CC_MIN_SOUND_BALANCE_VAL + CC_MAX_SOUND_BALANCE_VAL) / 2; |
757 | bal_cal_len = (CC_MAX_SOUND_BALANCE_VAL - CC_MIN_SOUND_BALANCE_VAL) / 2; |
758 | |
759 | if (balance_val == bal_mid_vol) { |
760 | LOGD( |
761 | "%s, balance value = %d, bal_mid_vol = %d, vol_buf[0] = %d, vol_buf[1] = %d.\n", |
762 | __FUNCTION__, balance_val, bal_mid_vol, vol_buf[0], vol_buf[1]); |
763 | return 0; |
764 | } else if (balance_val < bal_mid_vol) { |
765 | vol_buf[1] = (bal_cal_len - (bal_mid_vol - balance_val)) * max_vol / bal_cal_len; |
766 | } else if (balance_val > bal_mid_vol) { |
767 | vol_buf[0] = (bal_cal_len - (balance_val - bal_mid_vol)) * max_vol / bal_cal_len; |
768 | } |
769 | |
770 | if (GetAudioAmplifierBalanceExchangeCFG() != 0) { |
771 | tmp_val = vol_buf[0]; |
772 | vol_buf[0] = vol_buf[1]; |
773 | vol_buf[1] = tmp_val; |
774 | } |
775 | |
776 | LOGD( |
777 | "%s, balance value = %d, bal_mid_vol = %d, vol_buf[0] = %d, vol_buf[1] = %d.\n", |
778 | __FUNCTION__, balance_val, bal_mid_vol, vol_buf[0], vol_buf[1]); |
779 | return 0; |
780 | } |
781 | |
782 | |
783 | int CAudioAlsa::SetInternalDacMute(int mute_state) |
784 | { |
785 | int ret = 0; |
786 | if (mute_state == CC_AUDIO_MUTE) |
787 | ret = SetAudioInternalDacDACDigitalPlayBackVolume(0, 0); |
788 | else |
789 | ret = SetAudioInternalDacDACDigitalPlayBackVolume(255, 255); |
790 | return ret; |
791 | } |
792 | |
793 | int CAudioAlsa::setAudioPcmPlaybackMute(int mute_state) |
794 | { |
795 | char prop[256]; |
796 | property_get("audio.output.double_output", prop, "null"); |
797 | if ( Get2d4gHeadsetEnable() == 1 && (strcmp(prop, "0") == 0 || strcmp(prop, "null") == 0)) { |
798 | SetAudioPcmPlaybackSwitch(mute_state); |
799 | } |
800 | return 0; |
801 | } |
802 | |
803 | |
804 | int CAudioAlsa::SetInternalDacMainVolume(int main_vol) |
805 | { |
806 | int tmp_ret = 0, digit_vol = 0; |
807 | digit_vol = TransVolumeBarVolToDigitalVol(mMainDigitLutBuf, main_vol); |
808 | |
809 | return SetInternalDacLineOutPlayBackVolume(digit_vol, digit_vol); |
810 | } |
811 | |
812 | |
813 | static int gDigitalMuteStatus = CC_AUDIO_UNMUTE; |
814 | static int gDigitalLeftVol = 0; |
815 | static int gDigitalRightVol = 0; |
816 | |
817 | int CAudioAlsa::SetDigitalVolume(int l_val, int r_val) |
818 | { |
819 | amAudioSetLeftGain(l_val); |
820 | amAudioSetRightGain(r_val); |
821 | LOGD("%s, l_val = %d, r_val = %d.\n", __FUNCTION__, l_val, r_val); |
822 | return 0; |
823 | } |
824 | |
825 | int CAudioAlsa::SetDigitalMainVolume(int l_vol, int r_vol) |
826 | { |
827 | int tmp_ret = 0, l_val = 0, r_val = 0; |
828 | |
829 | //handle l&r channel volume for balance |
830 | l_val = TransVolumeBarVolToDigitalVol(mMainDigitLutBuf, l_vol); |
831 | r_val = TransVolumeBarVolToDigitalVol(mMainDigitLutBuf, r_vol); |
832 | |
833 | gDigitalLeftVol = l_val; |
834 | gDigitalRightVol = r_val; |
835 | if (gDigitalMuteStatus == CC_AUDIO_UNMUTE) { |
836 | SetDigitalVolume(l_val, r_val); |
837 | } |
838 | |
839 | return tmp_ret; |
840 | } |
841 | |
842 | int CAudioAlsa::SetDigitalMute(int mute_status) |
843 | { |
844 | gDigitalMuteStatus = mute_status; |
845 | if (mute_status == CC_AUDIO_MUTE) { |
846 | SetDigitalVolume(0, 0); |
847 | } else if (mute_status == CC_AUDIO_UNMUTE) { |
848 | SetDigitalVolume(gDigitalLeftVol, gDigitalRightVol); |
849 | } |
850 | |
851 | return 0; |
852 | } |
853 | |
854 |