add subdir-objects option
[platform/core/multimedia/avsystem.git] / avsys-audio.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 <stdlib.h>
23 #include <stdio.h>
24 #include <pthread.h>
25 #include <time.h>
26 #include <sys/types.h>
27 #include <sys/time.h>
28 #include <unistd.h>
29 #include <sys/syscall.h>
30 #include <signal.h>
31 #include <string.h>
32 #include <fcntl.h>
33
34 #include "avsys-types.h"
35 #include "avsys-error.h"
36 #include "avsys-debug.h"
37 #include "avsys-audio.h"
38 #include "avsys-audio-logical-volume.h"
39 #include "avsys-common.h"
40 #include "avsys-audio-sync.h"
41
42 #include "avsys-audio-path.h"
43 #include "avsys-audio-alsa.h"
44
45 #include "avsys-audio-pasimple.h"
46 #include "avsys-audio-pactrl.h"
47
48 /**
49  * Internal functions definition
50  */
51 #define FADEUP_CALC_BIAS        (1)
52
53 static int __avsys_audio_set_info(avsys_audio_handle_t *p, avsys_audio_param_t *param);
54 static int __avsys_audio_handle_init(int *handle,
55                                 avsys_audio_handle_t **ptr,
56                                 avsys_audio_param_t *param);
57
58
59 void __init_module(void);
60 void __fini_module(void);
61
62 #define AVSYS_GET_HANDLE_PTR(MODE) do { \
63         err = avsys_audio_handle_get_ptr((int)handle, &p, MODE);        \
64         if (AVSYS_FAIL(err)) {  \
65                 return err;     \
66         }       \
67 } while (0)
68
69 #define AVSYS_RELEASE_HANDLE_PTR(MODE) do {     \
70         if (AVSYS_FAIL(avsys_audio_handle_release_ptr((int)handle, MODE))) {    \
71                 avsys_error(AVAUDIO, "audio handle release failed\n");  \
72                 return AVSYS_STATE_ERR_INTERNAL;        \
73         }       \
74 } while (0)
75
76 #define AVSYS_STREAM_LOCK() do {        \
77         pthread_mutex_lock(&gmutex);\
78         avsys_info(AVAUDIO, "(+) LOCKED\n");    \
79 } while (0)
80
81 #define AVSYS_STREAM_UNLOCK() do {      \
82         pthread_mutex_unlock(&gmutex);\
83         avsys_info(AVAUDIO, "(-) UNLOCKED\n");  \
84 } while (0)
85
86 /**
87  * Internal global variable
88  */
89 static pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER;
90
91
92 /****************************************************************************
93  *
94  *  Interface
95  *
96  ***************************************************************************/
97 EXPORT_API
98 int avsys_audio_open(avsys_audio_param_t *param, avsys_handle_t *phandle, int *size)
99 {
100         int handle = -1;
101         avsys_audio_handle_t *p = NULL;
102         int err = AVSYS_STATE_ERR_UNKNOWN;
103
104         avsys_info(AVAUDIO, "%s\n", __func__);
105
106         if (param == NULL || phandle == NULL) {
107                 avsys_error(AVAUDIO, "param or phandle is null\n");
108                 return AVSYS_STATE_ERR_NULL_POINTER;
109         }
110
111         if (param->channels > AVSYS_CHANNEL_MAX || param->channels < AVSYS_CHANNEL_MIN) {
112                 return AVSYS_STATE_ERR_INVALID_CHANNEL;
113         }
114
115         if (param->mode < AVSYS_AUDIO_MODE_OUTPUT || param->mode >= AVSYS_AUDIO_MODE_NUM) {
116                 return AVSYS_STATE_ERR_INVALID_MODE;
117         }
118
119         if (param->format < AVSYS_AUDIO_FORMAT_MIN || param->format > AVSYS_AUDIO_FORMAT_MAX) {
120                 return AVSYS_STATE_ERR_INVALID_FORMAT;
121         }
122
123         AVSYS_STREAM_LOCK();
124
125         err = avsys_audio_handle_rejuvenation();
126         if (AVSYS_FAIL(err)) {
127                 avsys_error(AVAUDIO, "Unused handle cleanup before handle allocation failed in %s\n", __func__);
128                 goto error;
129         }
130
131         err = __avsys_audio_handle_init(&handle,&p,param);
132
133         if (AVSYS_STATE_ERR_RANGE_OVER == err) {
134                 avsys_error(AVAUDIO, "audio handle is fully allocated..try cleanup\n");
135                 err = avsys_audio_handle_rejuvenation();
136                 if (AVSYS_FAIL(err)) {
137                         avsys_error(AVAUDIO, "Unused handle cleanup failed in %s\n", __func__);
138                         goto error;
139                 }
140                 avsys_error(AVAUDIO, "one more try...to allocate audio handle\n");
141                 err = __avsys_audio_handle_init(&handle,&p,param);
142                 if (AVSYS_FAIL(err)) {
143                         avsys_error(AVAUDIO, "handle alloc failed 1 in %s\n", __func__);
144                         goto error;
145                 }
146         } else if ((AVSYS_FAIL(err)) && (err != AVSYS_STATE_ERR_RANGE_OVER)) {
147                 avsys_error(AVAUDIO, "handle alloc failed 2 in %s\n", __func__);
148                 goto error;
149         }
150
151         if (p->mode == AVSYS_AUDIO_MODE_OUTPUT || p->mode == AVSYS_AUDIO_MODE_OUTPUT_CLOCK ||
152                 p->mode == AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY || p->mode == AVSYS_AUDIO_MODE_OUTPUT_AP_CALL || p->mode == AVSYS_AUDIO_MODE_OUTPUT_VIDEO) {
153                 /* set volume table */
154                 err = avsys_audio_path_set_volume(handle);
155                 if (AVSYS_FAIL(err)) {
156                         goto error;
157                 }
158
159                 /* update volume by type */
160                 err = avsys_audio_handle_update_volume(p, p->gain_setting.volume_config);
161                 if (AVSYS_FAIL(err)) {
162                         goto error;
163                 }
164                 err = avsys_audio_handle_update_priority(handle, param->priority, param->handle_route, AVSYS_AUDIO_SET_PRIORITY);
165                 if (AVSYS_FAIL(err)) {
166                         goto error;
167                 }
168         }
169
170         /* open device */
171         err = avsys_audio_pasimple_open_device(p->mode, p->format, p->channels, p->samplerate, p, param->handle_route);
172         if (AVSYS_FAIL(err)) {
173                 goto error;
174         }
175         switch (p->mode) {
176         case AVSYS_AUDIO_MODE_OUTPUT:
177         case AVSYS_AUDIO_MODE_OUTPUT_CLOCK:
178         case AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY:
179         case AVSYS_AUDIO_MODE_OUTPUT_VIDEO:
180         case AVSYS_AUDIO_MODE_OUTPUT_AP_CALL:
181                 if (AVSYS_FAIL(avsys_audio_pasimple_set_volume(p, p->working_vol.level[AVSYS_AUDIO_CHANNEL_LEFT]))) {
182                         avsys_error(AVAUDIO, "can not set volume in %s\n", __func__);
183                 }
184                 break;
185         default:
186                 break;
187         }
188
189         *phandle = (avsys_handle_t) handle;
190         /* set recommended buffer size */
191         if (size != NULL)
192                 *size = p->period;
193         else
194                 avsys_warning(AVAUDIO, "Size is null\n");
195
196         err = avsys_audio_handle_release_ptr(handle, HANDLE_PTR_MODE_NORMAL);
197         if (AVSYS_FAIL(err)) {
198                 goto error;
199         }
200         AVSYS_STREAM_UNLOCK();
201         return AVSYS_STATE_SUCCESS;
202
203 error:
204         if (p) {
205                 avsys_audio_handle_release_ptr(handle, HANDLE_PTR_MODE_NORMAL);
206         }
207
208         if (handle != -1) {
209                 if (AVSYS_FAIL(avsys_audio_handle_free(handle))) {
210                         avsys_error(AVAUDIO, "Can not free handle %d\n", handle);
211                 }
212         }
213
214         avsys_error(AVAUDIO, "failed to open : REASON %x\n", err);
215
216         *phandle = (avsys_handle_t)-1;
217         AVSYS_STREAM_UNLOCK();
218         return err;
219 }
220
221 EXPORT_API
222 int avsys_audio_close(avsys_handle_t handle)
223 {
224         avsys_audio_handle_t *p = NULL;
225         int err = AVSYS_STATE_ERR_UNKNOWN;
226         bool cp_audio = false;
227         bool bt_path = false;
228
229         AVSYS_STREAM_LOCK();
230         avsys_info(AVAUDIO, "%s, handle=[%d]\n", __func__, (int)handle);
231
232         err = avsys_audio_handle_get_ptr((int)handle, &p, HANDLE_PTR_MODE_NORMAL);
233         if (AVSYS_FAIL(err)) {
234                 AVSYS_STREAM_UNLOCK();
235                 return err;
236         }
237
238         if (AVSYS_FAIL(avsys_audio_handle_update_priority((int)handle, p->priority, AVSYS_AUDIO_HANDLE_ROUTE_FOLLOWING_POLICY, AVSYS_AUDIO_UNSET_PRIORITY))) {
239                 avsys_error(AVAUDIO, "unset priority of handle %d error: %x\n", handle, err);
240         }
241
242         err = avsys_audio_pasimple_close_device(p);
243         if (AVSYS_FAIL(err)) {
244                 avsys_error_r(AVAUDIO, "audio device close error : %x\n", err);
245         }
246
247         if (AVSYS_FAIL(avsys_audio_path_check_cp_audio(&cp_audio, &bt_path))) {
248                 avsys_error(AVAUDIO, "Can not check cp audio status\n");
249         }
250
251         if (p->during_cp_audio && cp_audio && bt_path) {
252                 /* set cp bt path again */
253                 avsys_audio_path_set_single_ascn("cp_to_bt");
254         }
255
256         if (AVSYS_FAIL(avsys_audio_handle_release_ptr((int)handle, HANDLE_PTR_MODE_NORMAL))) {
257                 avsys_error(AVAUDIO, "audio handle release failed\n");
258                 AVSYS_STREAM_UNLOCK();
259                 return AVSYS_STATE_ERR_INTERNAL;
260         }
261
262         avsys_audio_handle_free((int)handle);
263
264         AVSYS_STREAM_UNLOCK();
265
266         return err;
267 }
268
269 EXPORT_API
270 int avsys_audio_update_volume_config(avsys_handle_t handle, int volume_config)
271 {
272         avsys_audio_handle_t *p = NULL;
273         int err = AVSYS_STATE_ERR_UNKNOWN;
274
275         AVSYS_STREAM_LOCK();
276         avsys_info(AVAUDIO, "%s, handle=[%d]\n", __func__, (int)handle);
277
278         err = avsys_audio_handle_get_ptr((int)handle, &p, HANDLE_PTR_MODE_NORMAL);
279         if (AVSYS_FAIL(err)) {
280                 AVSYS_STREAM_UNLOCK();
281                 return err;
282         }
283
284         if (p->mode == AVSYS_AUDIO_MODE_OUTPUT || p->mode == AVSYS_AUDIO_MODE_OUTPUT_CLOCK
285                 || p->mode == AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY || p->mode == AVSYS_AUDIO_MODE_OUTPUT_AP_CALL
286                 || p->mode == AVSYS_AUDIO_MODE_OUTPUT_VIDEO) {
287                 p->gain_setting.volume_config = volume_config;
288                 /* update volume by type */
289                 err = avsys_audio_handle_update_volume(p, p->gain_setting.volume_config);
290                 if (AVSYS_FAIL(err)) {
291                         AVSYS_STREAM_UNLOCK();
292                         return err;
293                 }
294                 err = avsys_audio_pasimple_set_volume(p, p->working_vol.level[AVSYS_AUDIO_CHANNEL_LEFT]);
295                 if (AVSYS_FAIL(err)) {
296                         avsys_error(AVAUDIO, "can not set volume in %s\n", __func__);
297                 }
298         }
299
300         AVSYS_STREAM_UNLOCK();
301         return err;
302 }
303
304 EXPORT_API
305 int avsys_audio_ampon(void)
306 {
307         avsys_info(AVAUDIO, "%s\n", __func__);
308         return avsys_audio_path_ex_set_amp(AVSYS_AUDIO_AMP_ON);
309 }
310
311 EXPORT_API
312 int avsys_audio_ampoff(void)
313 {
314         avsys_info(AVAUDIO, "%s\n", __func__);
315         return avsys_audio_path_ex_set_amp(AVSYS_AUDIO_AMP_OFF);
316 }
317
318
319 EXPORT_API
320 int avsys_audio_ext_device_ampon(avsysaudio_ext_device_t device_type)
321 {
322         avsys_info(AVAUDIO, "%s\n", __func__);
323         return avsys_audio_handle_ext_dev_set_mute(device_type, AVSYS_AUDIO_UNMUTE);
324 }
325
326 EXPORT_API
327 int avsys_audio_ext_device_ampoff(avsysaudio_ext_device_t device_type)
328 {
329         avsys_info(AVAUDIO, "%s\n", __func__);
330         return avsys_audio_handle_ext_dev_set_mute(device_type, AVSYS_AUDIO_MUTE);
331 }
332
333 EXPORT_API
334 int avsys_audio_set_ext_device_status(avsysaudio_ext_device_t device_type, int onoff)
335 {
336         avsys_info(AVAUDIO, "%s\n", __func__);
337         return avsys_audio_handle_ext_dev_status_update(device_type, onoff);
338 }
339
340 EXPORT_API
341 int avsys_audio_get_ext_device_status(avsysaudio_ext_device_t device_type, int *onoff)
342 {
343         avsys_info(AVAUDIO, "%s\n", __func__);
344         return avsys_audio_handle_ext_dev_status(device_type, onoff);
345 }
346
347 EXPORT_API
348 int avsys_audio_flush(avsys_handle_t handle)
349 {
350         int err = AVSYS_STATE_SUCCESS;
351         avsys_audio_handle_t *p = NULL;
352         avsys_info(AVAUDIO, "%s\n", __func__);
353
354         AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL);
355
356         err = avsys_audio_pasimple_reset(p);
357
358         AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL);
359
360         return err;
361 }
362
363 EXPORT_API
364 int avsys_audio_drain(avsys_handle_t handle)
365 {
366         int err = AVSYS_STATE_SUCCESS;
367         avsys_audio_handle_t *p = NULL;
368         avsys_info(AVAUDIO, "%s\n", __func__);
369
370         AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL);
371
372         err = avsys_audio_pasimple_drain(p);
373
374         AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL);
375
376         return err;
377 }
378
379 EXPORT_API
380 int avsys_audio_read(avsys_handle_t handle, void *buf, int size)
381 {
382         int err = AVSYS_STATE_SUCCESS;
383         avsys_audio_handle_t *p = NULL;
384
385         avsys_info(AVAUDIO, "%s\n", __func__);
386
387         if (buf == NULL) {
388                 avsys_error(AVAUDIO, "input buffer pointer is null\n");
389                 return AVSYS_STATE_ERR_NULL_POINTER;
390         }
391
392         AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_FAST);
393
394         if (p->mode != AVSYS_AUDIO_MODE_INPUT && p->mode != AVSYS_AUDIO_MODE_INPUT_LOW_LATENCY &&
395                 p->mode != AVSYS_AUDIO_MODE_INPUT_HIGH_LATENCY && p->mode != AVSYS_AUDIO_MODE_INPUT_AP_CALL) {
396                 avsys_error(AVAUDIO, "opened output mode\n");
397                 return AVSYS_STATE_ERR_INVALID_MODE;
398         }
399
400         err = avsys_audio_pasimple_read(p, buf, size);
401
402         AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_FAST);
403
404         return err;
405 }
406
407 EXPORT_API
408 int avsys_audio_write(avsys_handle_t handle, void *buf, int size)
409 {
410         int err = AVSYS_STATE_SUCCESS;
411         avsys_audio_handle_t *p = NULL;
412
413         avsys_info(AVAUDIO, "%s\n", __func__);
414
415         if (buf == NULL) {
416                 avsys_error(AVAUDIO, "buf is null\n");
417                 return AVSYS_STATE_ERR_NULL_POINTER;
418         }
419
420         AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_FAST);
421
422         if (p->mode != AVSYS_AUDIO_MODE_OUTPUT && p->mode != AVSYS_AUDIO_MODE_OUTPUT_CLOCK &&
423                 p->mode != AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY && p->mode != AVSYS_AUDIO_MODE_OUTPUT_AP_CALL && p->mode != AVSYS_AUDIO_MODE_OUTPUT_VIDEO) {
424                 avsys_error(AVAUDIO, "opened input mode\n");
425                 avsys_audio_handle_release_ptr((int)handle, HANDLE_PTR_MODE_FAST);
426                 return AVSYS_STATE_ERR_INVALID_MODE;
427         }
428
429         if (p->fadeup_vol > 1) {
430                 if (p->fadeup_multiplier == 0) {
431                         avsys_audio_volume_t fade_volume;
432                         fade_volume.level[AVSYS_AUDIO_CHANNEL_LEFT] = p->setting_vol.level[AVSYS_AUDIO_CHANNEL_LEFT] - (p->fadeup_vol - FADEUP_CALC_BIAS);
433                         fade_volume.level[AVSYS_AUDIO_CHANNEL_RIGHT] = p->setting_vol.level[AVSYS_AUDIO_CHANNEL_LEFT] - (p->fadeup_vol - FADEUP_CALC_BIAS);
434
435                         if (fade_volume.level[AVSYS_AUDIO_CHANNEL_LEFT] < 0) {
436                                 fade_volume.level[AVSYS_AUDIO_CHANNEL_LEFT] = 0;
437                         }
438                         if (fade_volume.level[AVSYS_AUDIO_CHANNEL_RIGHT] < 0) {
439                                 fade_volume.level[AVSYS_AUDIO_CHANNEL_RIGHT] = 0;
440                         }
441
442                         avsys_info(AVAUDIO, "fade_volume : %d (%d-(%d)+%d) p->fadeup_m = %d, p->msec_per_period = %d\n",
443                                                 fade_volume.level[AVSYS_AUDIO_CHANNEL_LEFT],p->setting_vol.level[AVSYS_AUDIO_CHANNEL_LEFT],p->fadeup_vol,FADEUP_CALC_BIAS,
444                                                 p->fadeup_multiplier, p->msec_per_period
445                                                 );
446
447                         avsys_audio_logical_volume_convert(&fade_volume, &p->working_vol, &p->gain_setting);
448                         avsys_audio_pasimple_set_volume(p, p->working_vol.level[AVSYS_AUDIO_CHANNEL_LEFT]);
449                         p->fadeup_vol--;
450                         if (p->msec_per_period > 50)
451                                 p->fadeup_multiplier = 0;
452                         else
453                                 p->fadeup_multiplier = FADE_UP_MULTIPLIER;
454                 } else {
455                         p->fadeup_multiplier--;
456                 }
457         } else if (p->fadeup_vol <= -1) {
458                 if (p->fadeup_multiplier == 0) {
459                         int fadedown_vol = 0;
460                         avsys_audio_volume_t fade_volume;
461
462                         fadedown_vol = (-1) * (p->fadeup_vol) - FADEUP_CALC_BIAS;
463                         fade_volume.level[AVSYS_AUDIO_CHANNEL_LEFT] = fadedown_vol;
464                         fade_volume.level[AVSYS_AUDIO_CHANNEL_RIGHT] = fadedown_vol;
465
466                         if (fade_volume.level[AVSYS_AUDIO_CHANNEL_LEFT] < 0) {
467                                 fade_volume.level[AVSYS_AUDIO_CHANNEL_LEFT] = 0;
468                         }
469                         if (fade_volume.level[AVSYS_AUDIO_CHANNEL_RIGHT] < 0) {
470                                 fade_volume.level[AVSYS_AUDIO_CHANNEL_RIGHT] = 0;
471                         }
472
473                         avsys_info(AVAUDIO, "fade_volume : %d (%d-%d) p->fadeup_m = %d, p->msec_per_period = %d\n",
474                                         fade_volume.level[AVSYS_AUDIO_CHANNEL_LEFT],p->fadeup_vol,FADEUP_CALC_BIAS,
475                                         p->fadeup_multiplier, p->msec_per_period);
476
477                         avsys_audio_logical_volume_convert(&fade_volume, &p->working_vol, &p->gain_setting);
478                         avsys_audio_pasimple_set_volume(p, p->working_vol.level[AVSYS_AUDIO_CHANNEL_LEFT]);
479                         if (p->fadeup_vol < -1) {
480                                 p->fadeup_vol++;
481                         } else if (p->fadeup_vol == -1) {
482                                 p->mute = AVSYS_AUDIO_MUTE;
483                         }
484                         if (p->msec_per_period > 50)
485                                 p->fadeup_multiplier = 0;
486                         else
487                                 p->fadeup_multiplier = FADE_DOWN_MULTIPLIER;
488                 } else {
489                         p->fadeup_multiplier--;
490                 }
491         }
492         err = avsys_audio_pasimple_write(p, buf, size);
493
494         AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_FAST);
495
496         return err;
497 }
498
499 EXPORT_API
500 int avsys_audio_set_volume_fadeup(avsys_handle_t handle)
501 {
502         int err = AVSYS_STATE_SUCCESS;
503         avsys_audio_handle_t *p = NULL;
504
505         avsys_warning(AVAUDIO, "%s\n", __func__);
506
507         AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL);
508
509         if (p->setting_vol.level[AVSYS_AUDIO_CHANNEL_LEFT] >= p->setting_vol.level[AVSYS_AUDIO_CHANNEL_RIGHT]) {
510                 p->fadeup_vol = p->setting_vol.level[AVSYS_AUDIO_CHANNEL_LEFT]; /* + FADEUP_CALC_BIAS */
511         } else {
512                 p->fadeup_vol = p->setting_vol.level[AVSYS_AUDIO_CHANNEL_RIGHT]; /* + FADEUP_CALC_BIAS; */
513         }
514         p->fadeup_multiplier = 0;
515
516         AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL);
517
518         return err;
519 }
520
521 EXPORT_API
522 int avsys_audio_set_mute_fadedown(avsys_handle_t handle)
523 {
524         int err = AVSYS_STATE_SUCCESS;
525         avsys_audio_handle_t *p = NULL;
526
527         avsys_warning(AVAUDIO, "%s\n", __func__);
528
529         AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL);
530
531         if (p->setting_vol.level[AVSYS_AUDIO_CHANNEL_LEFT] >= p->setting_vol.level[AVSYS_AUDIO_CHANNEL_RIGHT]) {
532                 p->fadeup_vol = (-1) * p->setting_vol.level[AVSYS_AUDIO_CHANNEL_LEFT];
533         } else {
534                 p->fadeup_vol = (-1) * p->setting_vol.level[AVSYS_AUDIO_CHANNEL_RIGHT];
535         }
536         p->fadeup_multiplier = 0;
537
538         AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL);
539
540         return err;
541 }
542
543 /* Tuning part */
544 EXPORT_API
545 int avsys_audio_set_volume_table(int volume_type, int dev_type, int step, int lv, int rv)
546 {
547         int ret = avsys_audio_logical_volume_set_to_table(volume_type, dev_type, step, lv, rv);
548         avsys_audio_handle_t *ptr = NULL;
549         int handle = -1;
550
551         if (AVSYS_FAIL(ret)) {
552                 return ret;
553         }
554
555         while(++handle < AVSYS_AUDIO_HANDLE_MAX) {
556                 ptr = NULL;
557
558                 if (AVSYS_SUCCESS(avsys_audio_handle_get_ptr(handle, &ptr, HANDLE_PTR_MODE_NORMAL))) {
559                         avsys_audio_logical_volume_convert(&ptr->setting_vol, &ptr->working_vol, &ptr->gain_setting);
560                         avsys_audio_handle_release_ptr(handle, HANDLE_PTR_MODE_NORMAL);
561                 }
562         }
563         return AVSYS_STATE_SUCCESS;
564 }
565
566 EXPORT_API
567 int avsys_audio_get_volume_table(int volume_type, int dev_type, int step, int *lv, int *rv)
568 {
569         return avsys_audio_logical_volume_get_from_table(volume_type, dev_type, step, lv, rv);
570 }
571
572 EXPORT_API
573 int avsys_audio_get_volume_max_ex(int volume_type, int *max_step)
574 {
575         if (max_step == NULL) {
576                 return AVSYS_STATE_ERR_NULL_POINTER;
577         }
578
579         return avsys_audio_logical_volume_get_max(volume_type, AVSYS_AUDIO_LVOL_DEV_TYPE_SPK, max_step);
580 }
581
582 EXPORT_API
583 int avsys_audio_set_volume_gain_table(int volume_gain_idx, int dev_type, float lv, float rv)
584 {
585         int ret = avsys_audio_logical_volume_set_gain_to_table(volume_gain_idx, dev_type, lv, rv);
586         avsys_audio_handle_t *ptr = NULL;
587         int handle = -1;
588
589         if (AVSYS_FAIL(ret)) {
590                 return ret;
591         }
592
593         while(++handle < AVSYS_AUDIO_HANDLE_MAX) {
594                 ptr = NULL;
595
596                 if (AVSYS_SUCCESS(avsys_audio_handle_get_ptr(handle, &ptr, HANDLE_PTR_MODE_NORMAL))) {
597                         avsys_audio_logical_volume_convert(&ptr->setting_vol, &ptr->working_vol, &ptr->gain_setting);
598                         avsys_audio_handle_release_ptr(handle, HANDLE_PTR_MODE_NORMAL);
599                 }
600         }
601         return AVSYS_STATE_SUCCESS;
602 }
603
604 EXPORT_API
605 int avsys_audio_get_volume_gain_table(int volume_gain_idx, int dev_type, float *lv, float *rv)
606 {
607         return avsys_audio_logical_volume_get_gain_from_table(volume_gain_idx, dev_type, lv, rv);
608 }
609
610 EXPORT_API
611 int avsys_audio_set_mute(avsys_handle_t handle, int mute)
612 {
613         avsys_info(AVAUDIO, "%s\n", __func__);
614
615         if (mute > AVSYS_AUDIO_MUTE || mute < AVSYS_AUDIO_UNMUTE) {
616                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
617         }
618
619         if (AVSYS_FAIL(avsys_audio_handle_set_mute((int)handle, mute))) {
620                 avsys_error(AVAUDIO, "failed to set handle mute\n");
621         }
622
623         return AVSYS_STATE_SUCCESS;
624 }
625
626 EXPORT_API
627 int avsys_audio_get_mute(avsys_handle_t handle, int *pmute)
628 {
629         int err = AVSYS_STATE_SUCCESS;
630         avsys_audio_handle_t *p = NULL;
631
632         avsys_info(AVAUDIO, "%s\n", __func__);
633
634         if (pmute == NULL) {
635                 avsys_error(AVAUDIO, "pvolume is null\n");
636                 return AVSYS_STATE_ERR_NULL_POINTER;
637         }
638
639         AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL);
640
641         *pmute = p->mute;
642
643         AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL);
644
645         return AVSYS_STATE_SUCCESS;
646 }
647
648 /*
649  * Option : AVSYS_AUDIO_PATH_OPTION_LEGACY_MODE support NowPlus style sound path function
650  * Option : AVSYS_AUDIO_PATH_OPTION_DUAL_OUT will effect only when out is speaker.
651  * Option : AVSYS_AUDIO_PATH_OPTION_JACK_AUTO will effect only when out is speaker or receiver.
652  * Option : AVSYS_AUDIO_PATH_OPTION_FORCED is avail only for shutdown animation
653  *
654  * Limitation : Only FORCED option can be used same time with other options (exclude LEGACY_MODE)
655  */
656 EXPORT_API
657 int avsys_audio_set_path_ex(int gain, int out, int in, int option)
658 {
659         if (AVSYS_AUDIO_GAIN_EX_KEYTONE > gain || AVSYS_AUDIO_GAIN_EX_MAX <= gain ||
660                 AVSYS_AUDIO_PATH_EX_NONE > out || AVSYS_AUDIO_PATH_EX_OUTMAX <= out ||
661                 AVSYS_AUDIO_PATH_EX_NONE > in || AVSYS_AUDIO_PATH_EX_INMAX <= in) {
662                 avsys_error(AVAUDIO, "Your input parameter is invalid. Please check\n");
663                 avsys_error(AVAUDIO, " gain %d, out %d, in %d\n", gain, out, in);
664                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
665         }
666
667         return avsys_audio_path_ex_set_path(gain, out, in, option);
668 }
669 EXPORT_API
670 int avsys_audio_get_path_ex(int *gain, int *out, int *in, int *option)
671 {
672         if (!gain || !out || !in || !option) {
673                 avsys_warning(AVAUDIO, "Your input parameter is NULL pointer. Please check.\n");
674                 avsys_warning(AVAUDIO, " gain %p, out %p, in %p, option %p\n", gain, out, in, option);
675                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
676         }
677         return avsys_audio_path_ex_get_path(gain, out, in, option);
678 }
679
680 EXPORT_API
681 int avsys_audio_set_global_mute(int mute)
682 {
683         int err = AVSYS_STATE_SUCCESS;
684
685         avsys_info(AVAUDIO, "%s : mute=%d\n", __func__, mute);
686
687         if (mute < AVSYS_AUDIO_UNMUTE && mute > AVSYS_AUDIO_MUTE_NOLOCK) {
688                 err = AVSYS_STATE_ERR_INVALID_PARAMETER;
689         } else {
690                 err = avsys_audio_path_ex_set_mute(mute);
691         }
692         return err;
693 }
694
695 EXPORT_API
696 int avsys_audio_get_global_mute(int *pmute)
697 {
698         int err = AVSYS_STATE_SUCCESS;
699
700         avsys_info(AVAUDIO, "%s\n", __func__);
701         if (pmute == NULL) {
702                 err = AVSYS_STATE_ERR_NULL_POINTER;
703         } else {
704                 err = avsys_audio_path_ex_get_mute(pmute);
705         }
706         return err;
707 }
708
709 /**
710  * Internal functions implementation
711  */
712
713 static int __avsys_audio_set_info(avsys_audio_handle_t *p, avsys_audio_param_t *param)
714 {
715         int vol_conf_type = AVSYS_AUDIO_VOLUME_CONFIG_TYPE(param->vol_type);
716         int vol_conf_gain = AVSYS_AUDIO_VOLUME_CONFIG_GAIN(param->vol_type);
717
718         avsys_info(AVAUDIO, "%s\n", __func__);
719
720         avsys_info(AVAUDIO, "=============================================\n");
721         avsys_info(AVAUDIO, "      Input Parameters (Basic Information)\n");
722         avsys_info(AVAUDIO, "=============================================\n");
723         avsys_info(AVAUDIO, " Op Mode    = %d (0:out, 1:input)\n", param->mode);
724         avsys_info(AVAUDIO, " format     = %d (0: 8bits, 1:16bits, 2:32bits)\n", param->format);
725         avsys_info(AVAUDIO, " channel    = %d\n", param->channels);
726         avsys_info(AVAUDIO, " samplerate = %d\n", param->samplerate);
727         avsys_info(AVAUDIO, " route      = %d (0: default, 1: handset)\n", param->handle_route);
728         avsys_info(AVAUDIO, " volume type= %d\n", vol_conf_type);
729         avsys_info(AVAUDIO, " volume gain= %d\n", vol_conf_gain);
730         avsys_info(AVAUDIO, "=============================================\n");
731
732         p->mode = param->mode;
733         p->channels = param->channels;
734         p->samplerate = param->samplerate;
735         p->format = param->format;
736         p->priority = param->priority;
737
738         if ((vol_conf_type < 0) || (vol_conf_type >= AVSYS_AUDIO_VOLUME_TYPE_MAX)) {
739                 avsys_error(AVAUDIO, "[%s] Invalid volume type %d. use default system type\n", __func__, vol_conf_type);
740                 p->gain_setting.volume_config = AVSYS_AUDIO_VOLUME_TYPE_SYSTEM;
741         } else {
742                 p->gain_setting.volume_config = param->vol_type;
743         }
744
745         /* trivial volume value */
746         p->setting_vol.level[AVSYS_AUDIO_CHANNEL_LEFT] = 0;
747         p->setting_vol.level[AVSYS_AUDIO_CHANNEL_RIGHT] = 0;
748         p->working_vol.level[AVSYS_AUDIO_CHANNEL_LEFT] = 0;
749         p->working_vol.level[AVSYS_AUDIO_CHANNEL_RIGHT] = 0;
750         p->fadeup_vol = 0;
751
752         return AVSYS_STATE_SUCCESS;
753 }
754
755 static int __avsys_audio_handle_init(int *handle,
756                                 avsys_audio_handle_t **ptr,
757                                 avsys_audio_param_t *param)
758 {
759         int err = AVSYS_STATE_ERR_UNKNOWN;
760
761         if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_HANDLE))) {
762                 avsys_error(AVAUDIO,"avsys_audio_lock_sync() failed in %s\n", __func__);
763                 return AVSYS_STATE_ERR_INTERNAL;
764         }
765
766         err = avsys_audio_handle_alloc_unlocked(handle);
767
768         if (AVSYS_STATE_SUCCESS == err) {
769
770                 err = avsys_audio_handle_get_ptr_unlocked(*handle, ptr, HANDLE_PTR_MODE_NORMAL);
771                 if(AVSYS_STATE_SUCCESS == err) {
772
773                         /* set information to handle */
774                         err = __avsys_audio_set_info(*ptr, param);
775                 }
776         }
777
778         if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_HANDLE))) {
779                 avsys_error(AVAUDIO,"avsys_audio_unlock_sync() failed in %s\n", __func__);
780                 return AVSYS_STATE_ERR_INTERNAL;
781         }
782
783         return err;
784 }
785
786 EXPORT_API
787 int avsys_audio_earjack_manager_init(int *earjack_type, int *waitfd)
788 {
789         return avsys_audio_path_earjack_init(earjack_type, waitfd);
790 }
791
792 EXPORT_API
793 int avsys_audio_earjack_manager_wait(int waitfd, int *current_earjack_type, int *new_earjack_type, int *need_mute)
794 {
795         return avsys_audio_path_earjack_wait(waitfd, current_earjack_type, new_earjack_type, need_mute);
796 }
797
798 EXPORT_API
799 int avsys_audio_earjack_manager_process(int new_earjack_type)
800 {
801         return avsys_audio_path_earjack_process(new_earjack_type);
802 }
803
804 EXPORT_API
805 int avsys_audio_earjack_manager_deinit(int waitfd)
806 {
807         return avsys_audio_path_earjack_deinit(waitfd);
808 }
809
810 EXPORT_API
811 int avsys_audio_earjack_manager_get_type(void)
812 {
813         return avsys_audio_path_earjack_get_type();
814 }
815
816 EXPORT_API
817 int avsys_audio_earjack_manager_unlock(void)
818 {
819         return avsys_audio_path_earjack_unlock();
820 }
821
822 EXPORT_API
823 int avsys_audio_set_route_policy(avsys_audio_route_policy_t route)
824 {
825         /* Deprecated */
826         return 0;
827 }
828
829 EXPORT_API
830 int avsys_audio_get_route_policy(avsys_audio_route_policy_t *route)
831 {
832         /* Deprecated */
833         return 0;
834 }
835
836 EXPORT_API
837 int avsys_audio_get_current_playing_volume_type(int *volume_type)
838 {
839         if (volume_type == NULL)
840                 return AVSYS_STATE_ERR_NULL_POINTER;
841         return avsys_audio_handle_current_playing_volume_type(volume_type);
842 }
843
844 static inline int __avsys_audio_validate_volume(const int type, const int value)
845 {
846         if (value < 0)
847                 return -1;
848         switch (type) {
849         case AVSYS_AUDIO_VOLUME_TYPE_CALL:
850         case AVSYS_AUDIO_VOLUME_TYPE_VOIP:
851                 if (value >= LVOLUME_MAX_BASIC) {
852                         return -1;
853                 }
854                 break;
855         case AVSYS_AUDIO_VOLUME_TYPE_ALARM:
856         case AVSYS_AUDIO_VOLUME_TYPE_RINGTONE:
857         case AVSYS_AUDIO_VOLUME_TYPE_NOTIFICATION:
858         case AVSYS_AUDIO_VOLUME_TYPE_SYSTEM:
859         case AVSYS_AUDIO_VOLUME_TYPE_MEDIA:
860         case AVSYS_AUDIO_VOLUME_TYPE_EXT_SYSTEM_JAVA:
861                 if (value >= LVOLUME_MAX_MULTIMEDIA) {
862                         return -1;
863                 }
864                 break;
865         case AVSYS_AUDIO_VOLUME_TYPE_EXT_SYSTEM_ANDROID:
866                 if (value >= LVOLUME_MAX_SINGLE) {
867                         return -1;
868                 }
869                 break;
870         default:
871                 return -1;
872                 break;
873         }
874         return 0;
875 }
876
877 EXPORT_API
878 int avsys_audio_set_volume_by_type(const int type, const int value)
879 {
880         if (type < 0 || type >= AVSYS_AUDIO_VOLUME_TYPE_MAX)
881                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
882         if (0 > __avsys_audio_validate_volume(type, value))
883                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
884         return avsys_audio_handle_update_volume_by_type(type, value);
885 }
886
887 EXPORT_API
888 int avsys_audio_set_primary_volume(const int pid, const int type)
889 {
890         return avsys_audio_handle_set_primary_volume_type(pid, type, AVSYS_AUDIO_PRIMARY_VOLUME_SET);
891 }
892
893 EXPORT_API
894 int avsys_audio_clear_primary_volume(const int pid)
895 {
896         return avsys_audio_handle_set_primary_volume_type(pid, 0, AVSYS_AUDIO_PRIMARY_VOLUME_CLEAR);
897 }
898
899 EXPORT_API
900 int avsys_audio_hibernation_reset(int *vol)
901 {
902         int err = AVSYS_STATE_SUCCESS;
903
904         err = avsys_audio_path_ex_reset(1);
905         if (AVSYS_FAIL(err)) {
906                 avsys_error(AVAUDIO, "avsys_audio_path_ex_reset(forced) failed 0x%x\n", err);
907                 return err;
908         }
909
910         err = avsys_audio_handle_reset(vol);
911         if (AVSYS_FAIL(err)) {
912                 avsys_error(AVAUDIO, "avsys_audio_handle_reset() failed 0x%x\n", err);
913                 return err;
914         }
915
916         return err;
917 }
918
919 EXPORT_API
920 int avsys_audio_delay(avsys_handle_t handle, int *delay)
921 {
922         int err = AVSYS_STATE_SUCCESS;
923         int frame_delay = 0;
924         avsys_audio_handle_t *p = NULL;
925
926         AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL);
927
928         err = avsys_audio_pasimple_delay(p, &frame_delay);
929         if (AVSYS_SUCCESS(err)) {
930                 *delay = frame_delay;
931         }
932
933         AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL);
934
935         return err;
936 }
937
938 EXPORT_API
939 int avsys_audio_reset(avsys_handle_t handle)
940 {
941         int err = AVSYS_STATE_SUCCESS;
942         avsys_audio_handle_t *p = NULL;
943
944         AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL);
945
946         err = avsys_audio_pasimple_reset(p);
947         if (AVSYS_FAIL(err)) {
948                 avsys_error(AVAUDIO, "avsys_audio_reset() failed, 0x%X\n", err);
949         }
950
951         AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL);
952
953         return err;
954
955 }
956
957 EXPORT_API
958 int avsys_audio_get_period_buffer_time(avsys_handle_t handle, unsigned int *period_time, unsigned int *buffer_time)
959 {
960         int err = AVSYS_STATE_SUCCESS;
961         avsys_audio_handle_t *p = NULL;
962         unsigned int p_time = 0, b_time=0;
963
964         AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL);
965
966         err = avsys_audio_pasimple_get_period_buffer_time(p, &p_time, &b_time);
967         if(AVSYS_FAIL(err)) {
968                 avsys_error(AVAUDIO, "avsys_audio_get_period_buffer_time() failed, 0x%X\n",err);
969         }
970         else
971         {
972                 *period_time = p_time;
973                 *buffer_time = b_time;
974                 avsys_info(AVAUDIO,"period time : %u, buffer_time : %u\n", p_time, b_time);
975         }
976
977         AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL);
978
979         return err;
980 }
981
982 EXPORT_API
983 int avsys_audio_cork (avsys_handle_t handle, int cork)
984 {
985         int err = AVSYS_STATE_SUCCESS;
986         avsys_audio_handle_t *p = NULL;
987
988         AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL);
989
990         err = avsys_audio_pasimple_cork(p, cork);
991         if(AVSYS_FAIL(err)) {
992                 avsys_error(AVAUDIO, "avsys_audio_pasimple_cork() failed, 0x%X\n",err);
993         }
994
995         AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL);
996
997         return err;
998 }
999
1000 EXPORT_API
1001 int avsys_audio_is_corked (avsys_handle_t handle, int *is_corked)
1002 {
1003         int err = AVSYS_STATE_SUCCESS;
1004         avsys_audio_handle_t *p = NULL;
1005
1006         if (is_corked == NULL) {
1007                 return AVSYS_STATE_ERR_NULL_POINTER;
1008         }
1009
1010         AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL);
1011
1012         err = avsys_audio_pasimple_is_corked(p, is_corked);
1013         if(AVSYS_FAIL(err)) {
1014                 avsys_error(AVAUDIO, "avsys_audio_pasimple_cork() failed, 0x%X\n",err);
1015         }
1016
1017         AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL);
1018
1019         return err;
1020 }
1021
1022 EXPORT_API
1023 int avsys_audio_get_capture_status(int *on_capture)
1024 {
1025         return avsys_audio_handle_current_capture_status(on_capture);
1026 }
1027
1028 __attribute__ ((constructor))
1029 void __init_module(void)
1030 {
1031 }
1032
1033 __attribute__ ((destructor))
1034 void __fini_module(void)
1035 {
1036 }