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