Merge 1. Support DOCK Audio 2. Fix build breaks
[framework/multimedia/libmm-sound.git] / mm_sound.c
1 /*
2  * libmm-sound
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Seungbae Shin <seungbae.shin@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 <memory.h>
24 #include <unistd.h>
25 #include <pthread.h>
26 #include <stdio.h>
27 #include <sys/types.h>
28 #include <fcntl.h>
29
30 #include <sys/stat.h>
31 #include <errno.h>
32 #include <avsystem.h>
33
34 #include <vconf.h>
35 #include <mm_types.h>
36 #include <mm_error.h>
37 #include <mm_message.h>
38 #include <mm_debug.h>
39 #include "include/mm_sound_private.h"
40 #include "include/mm_sound.h"
41 #include "include/mm_sound_utils.h"
42 #include "include/mm_sound_client.h"
43 #include "include/mm_ipc.h"
44 #include "include/mm_sound_common.h"
45
46
47 #include <audio-session-manager.h>
48 #include <mm_session.h>
49 #include <mm_session_private.h>
50
51 #define MAX_FILE_LENGTH 256
52 #define MAX_MEMORY_SIZE 1048576 /* Max memory size 1024*1024 (1MB) */
53 #define _MIN_SYSTEM_SAMPLERATE  8000
54 #define _MAX_SYSTEM_SAMPLERATE  48000
55 #define MIN_TONE_PLAY_TIME 300
56
57 typedef struct {
58         volume_callback_fn      func;
59         void*                           data;
60         volume_type_t           type;
61 }volume_cb_param;
62
63 volume_cb_param g_volume_param[VOLUME_TYPE_MAX];
64
65 static pthread_mutex_t _volume_mutex = PTHREAD_MUTEX_INITIALIZER;
66
67 typedef struct {
68         avsys_handle_t          audio_handle;
69         int                                     asm_handle;
70         ASM_sound_events_t      asm_event;
71
72         bool                            is_started;
73         bool                            is_playback;
74
75         MMMessageCallback       msg_cb;
76         void *msg_cb_param;
77
78
79 } mm_sound_pcm_t;
80
81 static int _pcm_sound_start (MMSoundPcmHandle_t handle);
82 static int _pcm_sound_stop_internal (MMSoundPcmHandle_t handle);
83 static int _pcm_sound_stop(MMSoundPcmHandle_t handle);
84
85 static void __sound_pcm_send_message (mm_sound_pcm_t *pcmHandle, int message, int code);
86
87 int _validate_volume(volume_type_t type, int value)
88 {
89         if (value < 0)
90                 return -1;
91
92         switch (type)
93         {
94         case VOLUME_TYPE_CALL:
95                 if (value >= AVSYS_AUDIO_VOLUME_MAX_BASIC) {
96                         return -1;
97                 }
98                 break;
99         case VOLUME_TYPE_SYSTEM:
100         case VOLUME_TYPE_MEDIA:
101         case VOLUME_TYPE_ALARM:
102         case VOLUME_TYPE_EXT_JAVA:
103         case VOLUME_TYPE_NOTIFICATION:
104         case VOLUME_TYPE_RINGTONE:
105                 if (value >= AVSYS_AUDIO_VOLUME_MAX_MULTIMEDIA) {
106                         return -1;
107                 }
108                 break;
109         case VOLUME_TYPE_EXT_ANDROID:
110                 if (value >= AVSYS_AUDIO_VOLUME_MAX_SINGLE) {
111                         return -1;
112                 }
113                 break;
114         default:
115                 return -1;
116                 break;
117         }
118         return 0;
119 }
120
121 void volume_changed_cb(keynode_t* node, void* data)
122 {
123         volume_cb_param* param = (volume_cb_param*) data;
124
125         debug_msg("%s changed callback called\n",vconf_keynode_get_name(node));
126
127         MMSOUND_ENTER_CRITICAL_SECTION( &_volume_mutex )
128
129         if(param && (param->func != NULL)) {
130                 debug_msg("funcion 0x%x\n", param->func);
131                 ((volume_callback_fn)param->func)(param->data);
132         }
133
134         MMSOUND_LEAVE_CRITICAL_SECTION( &_volume_mutex )
135 }
136
137 EXPORT_API
138 int mm_sound_volume_add_callback(volume_type_t type, volume_callback_fn func, void* user_data)
139 {
140         char *keystr[] = {VCONF_KEY_VOLUME_TYPE_SYSTEM, VCONF_KEY_VOLUME_TYPE_NOTIFICATION, VCONF_KEY_VOLUME_TYPE_ALARM,
141                         VCONF_KEY_VOLUME_TYPE_RINGTONE, VCONF_KEY_VOLUME_TYPE_MEDIA, VCONF_KEY_VOLUME_TYPE_CALL,
142                         VCONF_KEY_VOLUME_TYPE_ANDROID,VCONF_KEY_VOLUME_TYPE_JAVA};
143
144         debug_fenter();
145
146         /* Check input param */
147         if(type < VOLUME_TYPE_SYSTEM || type >=VOLUME_TYPE_MAX) {
148                 return MM_ERROR_INVALID_ARGUMENT;
149         }
150         if(!func) {
151                 debug_warning("callback function is null\n");
152                 return MM_ERROR_INVALID_ARGUMENT;
153         }
154
155         MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN( &_volume_mutex, MM_ERROR_SOUND_INTERNAL )
156
157         g_volume_param[type].func = func;
158         g_volume_param[type].data = user_data;
159         g_volume_param[type].type = type;
160
161         MMSOUND_LEAVE_CRITICAL_SECTION( &_volume_mutex )
162
163         return vconf_notify_key_changed(keystr[type], volume_changed_cb, (void*)&g_volume_param[type]);
164 }
165
166 EXPORT_API
167 int mm_sound_volume_remove_callback(volume_type_t type)
168 {
169         char *keystr[] = {VCONF_KEY_VOLUME_TYPE_SYSTEM, VCONF_KEY_VOLUME_TYPE_NOTIFICATION, VCONF_KEY_VOLUME_TYPE_ALARM,
170                         VCONF_KEY_VOLUME_TYPE_RINGTONE, VCONF_KEY_VOLUME_TYPE_MEDIA, VCONF_KEY_VOLUME_TYPE_CALL,
171                         VCONF_KEY_VOLUME_TYPE_ANDROID,VCONF_KEY_VOLUME_TYPE_JAVA};
172         debug_fenter();
173
174         if(type < VOLUME_TYPE_SYSTEM || type >=VOLUME_TYPE_MAX) {
175                 return MM_ERROR_INVALID_ARGUMENT;
176         }
177
178         MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN( &_volume_mutex, MM_ERROR_SOUND_INTERNAL )
179
180         g_volume_param[type].func = NULL;
181         g_volume_param[type].data = NULL;
182         g_volume_param[type].type = type;
183
184         MMSOUND_LEAVE_CRITICAL_SECTION( &_volume_mutex )
185
186         return vconf_ignore_key_changed(keystr[type], volume_changed_cb);
187 }
188
189 EXPORT_API
190 int mm_sound_get_volume_step(volume_type_t type, int *step)
191 {
192         printf("\n**********\n\nTHIS FUNCTION HAS DEFPRECATED [%s]\n\n \
193                         use mm_sound_volume_get_step() instead\n\n**********\n", __func__);
194         return mm_sound_volume_get_step(type, step);
195 }
196
197 EXPORT_API
198 int mm_sound_volume_get_step(volume_type_t type, int *step)
199 {
200         int err;
201
202         debug_fenter();
203
204         /* Check input param */
205         if(step == NULL) {
206                 debug_error("second parameter is null\n");
207                 return MM_ERROR_INVALID_ARGUMENT;
208         }
209         if(type < VOLUME_TYPE_SYSTEM || type >= VOLUME_TYPE_MAX) {
210                 debug_error("Invalid type value %d\n", (int)type);
211                 return MM_ERROR_INVALID_ARGUMENT;
212         }
213
214         err = avsys_audio_get_volume_max_ex((int)type, step);
215         if (AVSYS_FAIL(err)) {
216                 err = MM_ERROR_INVALID_ARGUMENT;
217         }
218
219         debug_fleave();
220         return MM_ERROR_NONE;
221 }
222
223 EXPORT_API
224 int mm_sound_volume_set_value(volume_type_t type, const unsigned int value)
225 {
226         int ret = MM_ERROR_NONE;
227         char *keystr[] = {VCONF_KEY_VOLUME_TYPE_SYSTEM, VCONF_KEY_VOLUME_TYPE_NOTIFICATION, VCONF_KEY_VOLUME_TYPE_ALARM,
228                         VCONF_KEY_VOLUME_TYPE_RINGTONE, VCONF_KEY_VOLUME_TYPE_MEDIA, VCONF_KEY_VOLUME_TYPE_CALL,
229                         VCONF_KEY_VOLUME_TYPE_ANDROID,VCONF_KEY_VOLUME_TYPE_JAVA};
230         int vconf_value = 0;
231 #ifdef SEPARATE_EARPHONE_VOLUME
232         system_audio_route_device_t dev = 0;
233 #endif
234
235         debug_fenter();
236
237         /* Check input param */
238         if (0 > _validate_volume(type, (int)value)) {
239                 debug_error("invalid volume type %d, value %u\n", type, value);
240                 return MM_ERROR_INVALID_ARGUMENT;
241         }
242
243 #ifdef SEPARATE_EARPHONE_VOLUME
244         /* Get volume value from VCONF */
245         if (vconf_get_int(keystr[type], &vconf_value)){
246                 debug_error("Can not get %s as %d\n", keystr[type], vconf_value);
247                 return MM_ERROR_SOUND_INTERNAL;
248         }
249
250         /* Calculate volume value of current device */
251         mm_sound_route_get_playing_device(&dev);
252         if (dev == SYSTEM_AUDIO_ROUTE_PLAYBACK_DEVICE_EARPHONE) {
253                 vconf_value = 0x10000 | (vconf_value & 0x00FF) | (value << 8);
254                 debug_log("volume_set_value [earphone] %d(0x%04x)", value, vconf_value);
255         } else {
256                 vconf_value = (vconf_value & 0xFF00) | value;
257                 debug_log("volume_set_value [speaker] %d(0x%04x)", value, vconf_value);
258         }
259 #else
260         vconf_value = value;
261 #endif
262
263         /* Set volume value to VCONF */
264         if (vconf_set_int(keystr[type], vconf_value)) {
265                 debug_error("Can not set %s as %d\n", keystr[type], vconf_value);
266                 ret = MM_ERROR_SOUND_INTERNAL;
267         } else {
268                 /* update shared memory value */
269                 ret = avsys_audio_set_volume_by_type(type, value);
270                 if (AVSYS_FAIL(ret)) {
271                         debug_error("Can not set volume to shared memory 0x%x\n", ret);
272                 }
273         }
274
275         debug_fleave();
276         return ret;
277 }
278
279 EXPORT_API
280 int mm_sound_volume_get_value(volume_type_t type, unsigned int *value)
281 {
282         int ret = MM_ERROR_NONE;
283         char *keystr[] = {VCONF_KEY_VOLUME_TYPE_SYSTEM, VCONF_KEY_VOLUME_TYPE_NOTIFICATION, VCONF_KEY_VOLUME_TYPE_ALARM,
284                         VCONF_KEY_VOLUME_TYPE_RINGTONE, VCONF_KEY_VOLUME_TYPE_MEDIA, VCONF_KEY_VOLUME_TYPE_CALL,
285                         VCONF_KEY_VOLUME_TYPE_ANDROID,VCONF_KEY_VOLUME_TYPE_JAVA};
286         int vconf_value = 0;
287 #ifdef SEPARATE_EARPHONE_VOLUME
288         system_audio_route_device_t dev = 0;
289 #endif
290
291         debug_fenter();
292
293         /* Check input param */
294         if (value == NULL)
295                 return MM_ERROR_INVALID_ARGUMENT;
296         if (type < 0 || type >= VOLUME_TYPE_MAX) {
297                 debug_error("invalid volume type value %d\n", type);
298                 return MM_ERROR_INVALID_ARGUMENT;
299         }
300
301         /* Get volume value from VCONF */
302         if (vconf_get_int(keystr[type], &vconf_value)) {
303                 debug_error("Can not get value of %s\n", keystr[type]);
304                 ret = MM_ERROR_SOUND_INTERNAL;
305         }
306
307 #ifdef SEPARATE_EARPHONE_VOLUME
308         /* Get volume value of current device */
309         mm_sound_route_get_playing_device(&dev);
310         if (dev == SYSTEM_AUDIO_ROUTE_PLAYBACK_DEVICE_EARPHONE) {
311                 *value = (vconf_value >> 8) & 0x00FF;
312                 debug_log("volume_get_value [earphone] %d(0x%04x)", *value, vconf_value);
313         } else {
314                 *value = vconf_value & 0x00FF;
315                 debug_log("volume_get_value [speaker] %d(0x%04x)", *value, vconf_value);
316         }
317 #else
318         *value = vconf_value;
319 #endif
320
321         debug_fleave();
322         return ret;
323 }
324
325 EXPORT_API
326 int mm_sound_volume_primary_type_set(volume_type_t type)
327 {
328         pid_t mypid;
329         int ret = MM_ERROR_NONE;
330
331         /* Check input param */
332         if(type < VOLUME_TYPE_SYSTEM || type >= VOLUME_TYPE_MAX)
333                 return MM_ERROR_INVALID_ARGUMENT;
334
335         debug_fenter();
336
337         mypid = getpid();
338         if(AVSYS_FAIL(avsys_audio_set_primary_volume((int)mypid, type))) {
339                 debug_error("Can not set primary volume [%d, %d]\n", mypid, type);
340                 ret = MM_ERROR_SOUND_INTERNAL;
341         }
342
343         debug_fleave();
344         return ret;
345 }
346
347 EXPORT_API
348 int mm_sound_volume_primary_type_clear()
349 {
350         pid_t mypid;
351         int ret = MM_ERROR_NONE;
352
353         debug_fenter();
354
355         mypid = getpid();
356         if(AVSYS_FAIL(avsys_audio_clear_primary_volume((int)mypid))) {
357                 debug_error("Can not clear primary volume [%d]\n", mypid);
358                 ret = MM_ERROR_SOUND_INTERNAL;
359         }
360
361         debug_fleave();
362         return ret;
363 }
364
365 EXPORT_API
366 int mm_sound_volume_get_current_playing_type(volume_type_t *type)
367 {
368         int result = AVSYS_STATE_SUCCESS;
369         int voltype = AVSYS_AUDIO_VOLUME_TYPE_SYSTEM;
370
371         debug_fenter();
372
373         /* Check input param */
374         if(type == NULL) {
375                 return MM_ERROR_INVALID_ARGUMENT;
376         }
377
378         result = avsys_audio_get_current_playing_volume_type(&voltype);
379         if(result == AVSYS_STATE_SUCCESS) {
380                 *type = voltype;
381                 return MM_ERROR_NONE;
382         } else if(result ==AVSYS_STATE_ERR_ALLOCATION ) {
383                 return MM_ERROR_SOUND_VOLUME_NO_INSTANCE;
384         } else if(result == AVSYS_STATE_ERR_INVALID_MODE) {
385                 return MM_ERROR_SOUND_VOLUME_CAPTURE_ONLY;
386         } else {
387                 return MM_ERROR_SOUND_INTERNAL;
388         }
389 }
390
391 ///////////////////////////////////
392 ////     MMSOUND PCM APIs
393 ///////////////////////////////////
394
395
396 int _get_asm_event_type(ASM_sound_events_t *type)
397 {
398         int     sessionType = MM_SESSION_TYPE_SHARE;
399         ASM_sound_events_t asm_event;
400
401         if(type == NULL)
402                 return MM_ERROR_SOUND_INVALID_POINTER;
403
404         /* read session type */
405         if(_mm_session_util_read_type(-1, &sessionType) < 0) {
406                 debug_log("Read Session Type failed. Set default \"Share\" type\n");
407                 sessionType = MM_SESSION_TYPE_SHARE;
408                 if(mm_session_init(sessionType) < 0) {
409                         debug_error("mm_session_init() failed\n");
410                         return MM_ERROR_SOUND_INTERNAL;
411                 }
412         }
413
414         /* convert MM_SESSION_TYPE to ASM_EVENT_TYPE */
415         switch (sessionType)
416         {
417         case MM_SESSION_TYPE_SHARE:
418                 asm_event = ASM_EVENT_SHARE_MMSOUND;
419                 break;
420         case MM_SESSION_TYPE_EXCLUSIVE:
421                 asm_event = ASM_EVENT_EXCLUSIVE_MMSOUND;
422                 break;
423         case MM_SESSION_TYPE_NOTIFY:
424                 asm_event = ASM_EVENT_NOTIFY;
425                 break;
426         case MM_SESSION_TYPE_ALARM:
427                 asm_event = ASM_EVENT_ALARM;
428                 break;
429         case MM_SESSION_TYPE_CALL:
430                 asm_event = ASM_EVENT_CALL;
431                 break;
432         case MM_SESSION_TYPE_VIDEOCALL:
433                 asm_event = ASM_EVENT_VIDEOCALL;
434                 break;
435         default:
436                 debug_error("Unexpected %d\n", sessionType);
437                 return MM_ERROR_SOUND_INTERNAL;
438         }
439
440         *type = asm_event;
441         return MM_ERROR_NONE;
442 }
443
444 static void __sound_pcm_send_message (mm_sound_pcm_t *pcmHandle, int message, int code)
445 {
446         int ret = 0;
447         if (pcmHandle->msg_cb) {
448                 MMMessageParamType msg;
449                 msg.union_type = MM_MSG_UNION_CODE;
450                 msg.code = code;
451
452                 debug_log ("calling msg callback(%p) with message(%d), code(%d), msg callback param(%p)\n",
453                                 pcmHandle->msg_cb, message, msg.code, pcmHandle->msg_cb_param);
454                 ret = pcmHandle->msg_cb(message, &msg, pcmHandle->msg_cb_param);
455                 debug_log ("msg callback returned (%d)\n", ret);
456         } else {
457                 debug_log ("No pcm msg callback\n");
458         }
459 }
460
461 ASM_cb_result_t sound_pcm_asm_callback(int handle, ASM_event_sources_t event_src, ASM_sound_commands_t command, unsigned int sound_status, void *cb_data)
462 {
463         mm_sound_pcm_t *pcmHandle = NULL;
464         ASM_cb_result_t cb_res = ASM_CB_RES_IGNORE;
465
466         /* Check input param */
467         pcmHandle = (mm_sound_pcm_t *)cb_data;
468         if(pcmHandle == NULL) {
469                 debug_error("sound_pcm_asm_callback cb_data is null\n");
470                 return cb_res;
471         }
472
473         debug_log ("command = %d, handle = %p, is_started = %d\n",command, pcmHandle, pcmHandle->is_started);
474         switch(command)
475         {
476         case ASM_COMMAND_STOP:
477                 /* Do stop */
478                 _pcm_sound_stop_internal (pcmHandle);
479                 cb_res = ASM_CB_RES_PAUSE;
480                 break;
481
482         case ASM_COMMAND_RESUME:
483                 cb_res = ASM_CB_RES_IGNORE;
484                 break;
485
486         case ASM_COMMAND_PAUSE:
487         case ASM_COMMAND_PLAY:
488         case ASM_COMMAND_NONE:
489                 debug_error ("Not an expected case!!!!\n");
490                 break;
491         }
492
493         /* execute user callback if callback available */
494         __sound_pcm_send_message (pcmHandle, MM_MESSAGE_SOUND_PCM_INTERRUPTED, event_src);
495
496         return cb_res;
497 }
498
499 EXPORT_API
500 int mm_sound_pcm_capture_open(MMSoundPcmHandle_t *handle, const unsigned int rate, MMSoundPcmChannel_t channel, MMSoundPcmFormat_t format)
501 {
502         avsys_audio_param_t param;
503         mm_sound_pcm_t *pcmHandle = NULL;
504         int size = 0;
505         int result = AVSYS_STATE_SUCCESS;
506         int errorcode = 0;
507
508         debug_fenter();
509         memset(&param, 0, sizeof(avsys_audio_param_t));
510
511
512         if (rate < _MIN_SYSTEM_SAMPLERATE || rate > _MAX_SYSTEM_SAMPLERATE) {
513                 debug_error("unsupported sample rate %u", rate);
514                 return MM_ERROR_SOUND_DEVICE_INVALID_SAMPLERATE;
515         } else {
516                 param.samplerate = rate;
517         }
518
519         switch(channel)
520         {
521         case MMSOUND_PCM_MONO:
522                 param.channels = 1;
523                 break;
524         case MMSOUND_PCM_STEREO:
525                 param.channels = 2;
526                 break;
527
528         default:
529                 debug_error("Unsupported channel type\n");
530                 return MM_ERROR_SOUND_DEVICE_INVALID_CHANNEL;
531         }
532
533         switch(format)
534         {
535         case MMSOUND_PCM_U8:
536                 param.format = AVSYS_AUDIO_FORMAT_8BIT;
537                 break;
538         case MMSOUND_PCM_S16_LE:
539                 param.format = AVSYS_AUDIO_FORMAT_16BIT;
540                 break;
541         default:
542                 debug_error("Unsupported format type\n");
543                 return MM_ERROR_SOUND_DEVICE_INVALID_FORMAT;
544         }
545
546         pcmHandle = calloc(sizeof(mm_sound_pcm_t), 1);
547         if(pcmHandle == NULL)
548                 return MM_ERROR_OUT_OF_MEMORY;
549
550         /* Register ASM */
551         /* get session type */
552         if(MM_ERROR_NONE != _get_asm_event_type(&pcmHandle->asm_event)) {
553                 free(pcmHandle);
554                 return MM_ERROR_POLICY_INTERNAL;
555         }
556         /* register asm */
557         if(pcmHandle->asm_event != ASM_EVENT_CALL && pcmHandle->asm_event != ASM_EVENT_VIDEOCALL) {
558                 if(!ASM_register_sound(-1, &pcmHandle->asm_handle, pcmHandle->asm_event,
559                                 /* ASM_STATE_PLAYING */ ASM_STATE_NONE, sound_pcm_asm_callback, (void*)pcmHandle, ASM_RESOURCE_NONE, &errorcode))
560                 {
561                         debug_error("ASM_register_sound() failed 0x%x\n", errorcode);
562                         free(pcmHandle);
563                         return MM_ERROR_POLICY_BLOCKED;
564                 }
565         }
566
567         /* Open */
568         param.mode = AVSYS_AUDIO_MODE_INPUT;
569         param.vol_type = AVSYS_AUDIO_VOLUME_TYPE_SYSTEM; //dose not effect at capture mode
570         param.priority = AVSYS_AUDIO_PRIORITY_0;                //This does not affect anymore.
571         result = avsys_audio_open(&param, &pcmHandle->audio_handle, &size);
572         if(AVSYS_FAIL(result)) {
573                 debug_error("Device Open Error 0x%x\n", result);
574                 free(pcmHandle);
575                 return MM_ERROR_SOUND_DEVICE_NOT_OPENED;
576         }
577
578         pcmHandle->is_playback = false;
579
580         /* Set handle to return */
581         *handle = (MMSoundPcmHandle_t)pcmHandle;
582
583         debug_fleave();
584         return size;
585 }
586
587 static int _pcm_sound_start (MMSoundPcmHandle_t handle)
588 {
589         mm_sound_pcm_t *pcmHandle = NULL;
590         int errorcode = 0;
591
592         debug_fenter();
593
594         /* Check input param */
595         pcmHandle = (mm_sound_pcm_t*)handle;
596         if(pcmHandle == NULL) {
597                 debug_error ("Handle is null, return Invalid Argument\n");
598                 return MM_ERROR_INVALID_ARGUMENT;
599         }
600
601         /* ASM set state to PLAYING */
602         if (!ASM_set_sound_state(pcmHandle->asm_handle, pcmHandle->asm_event, ASM_STATE_PLAYING, ASM_RESOURCE_NONE, &errorcode)) {
603                 debug_error("ASM_set_sound_state(PLAYING) failed 0x%x\n", errorcode);
604                 return MM_ERROR_POLICY_BLOCKED;
605         }
606
607         /* Update State */
608         pcmHandle->is_started = true;
609
610         debug_fleave();
611
612         /* Un-Cork */
613         return avsys_audio_cork(pcmHandle->audio_handle, 0);
614 }
615
616
617 EXPORT_API
618 int mm_sound_pcm_capture_start(MMSoundPcmHandle_t handle)
619 {
620         int ret = MM_ERROR_NONE;
621
622         ret = _pcm_sound_start (handle);
623         if (ret != MM_ERROR_NONE)  {
624                 debug_error ("_pcm_sound_start() failed (%x)\n", ret);
625                 return ret;
626         }
627
628         return ret;
629 }
630
631 static int _pcm_sound_stop_internal (MMSoundPcmHandle_t handle)
632 {
633         mm_sound_pcm_t *pcmHandle = NULL;
634
635         /* Check input param */
636         pcmHandle = (mm_sound_pcm_t*)handle;
637         if(pcmHandle == NULL)
638                 return MM_ERROR_INVALID_ARGUMENT;
639
640         /* Check State */
641         if (pcmHandle->is_started == false) {
642                 debug_warning ("Can't stop because not started\n");
643                 return MM_ERROR_SOUND_INVALID_STATE;
644         }
645
646         /* Drain if playback mode */
647         if (pcmHandle->is_playback) {
648                 if(AVSYS_FAIL(avsys_audio_drain(pcmHandle->audio_handle))) {
649                         debug_error("drain failed\n");
650                 }
651         }
652
653         /* Update State */
654         pcmHandle->is_started = false;
655
656         /* Cork */
657         return avsys_audio_cork(pcmHandle->audio_handle, 1);
658 }
659
660 static int _pcm_sound_stop(MMSoundPcmHandle_t handle)
661 {
662         mm_sound_pcm_t *pcmHandle = NULL;
663         int errorcode = 0;
664         int ret = MM_ERROR_NONE;
665
666         debug_fenter();
667
668         /* Check input param */
669         pcmHandle = (mm_sound_pcm_t*)handle;
670         if(pcmHandle == NULL) {
671                 debug_error ("Handle is null, return Invalid Argument\n");
672                 return MM_ERROR_INVALID_ARGUMENT;
673         }
674
675         /* Do stop procedure */
676         ret = _pcm_sound_stop_internal(handle);
677         if (ret == MM_ERROR_NONE) {
678                 /* Set ASM State to STOP */
679                 if (!ASM_set_sound_state(pcmHandle->asm_handle, pcmHandle->asm_event, ASM_STATE_STOP, ASM_RESOURCE_NONE, &errorcode)) {
680                         debug_error("ASM_set_sound_state(STOP) failed 0x%x\n", errorcode);
681                         ret = MM_ERROR_POLICY_BLOCKED;
682                 }
683         }
684
685         debug_log ("pcm sound [%p] stopped success!!!\n", handle);
686
687         debug_fleave();
688
689         return ret;
690 }
691
692
693 EXPORT_API
694 int mm_sound_pcm_capture_stop(MMSoundPcmHandle_t handle)
695 {
696         return _pcm_sound_stop (handle);
697 }
698
699
700 EXPORT_API
701 int mm_sound_pcm_capture_read(MMSoundPcmHandle_t handle, void *buffer, const unsigned int length )
702 {
703         mm_sound_pcm_t *pcmHandle = NULL;
704
705         /* Check input param */
706         pcmHandle = (mm_sound_pcm_t*)handle;
707         if(pcmHandle == NULL) {
708                 debug_error ("Handle is null, return Invalid Argument\n");
709                 return MM_ERROR_INVALID_ARGUMENT;
710         }
711         if(buffer == NULL) {
712                 debug_error("Invalid buffer pointer\n");
713                 return MM_ERROR_SOUND_INVALID_POINTER;
714         }
715         if(length == 0 ) {
716                 debug_error ("length is 0, return 0\n");
717                 return 0;
718         }
719
720         /* Check State : return fail if not started */
721         if (!pcmHandle->is_started) {
722                 /*  not started, return fail */
723                 debug_error ("Not started yet, return Invalid State \n");
724                 return MM_ERROR_SOUND_INVALID_STATE;
725         }
726
727         /* Read */
728         return avsys_audio_read(pcmHandle->audio_handle, buffer, length);
729 }
730
731 EXPORT_API
732 int mm_sound_pcm_capture_close(MMSoundPcmHandle_t handle)
733 {
734         int result = MM_ERROR_NONE;
735         mm_sound_pcm_t *pcmHandle = NULL;
736         int errorcode = 0;
737
738         debug_fenter();
739
740         /* Check input param */
741         pcmHandle = (mm_sound_pcm_t*)handle;
742         if(pcmHandle == NULL) {
743                 debug_error ("Handle is null, return Invalid Argument\n");
744                 return MM_ERROR_INVALID_ARGUMENT;
745         }
746
747         /* Close */
748         result = avsys_audio_close(pcmHandle->audio_handle);
749         if(AVSYS_FAIL(result)) {
750                 debug_error("handle close failed 0x%X", result);
751                 result = MM_ERROR_SOUND_INTERNAL;
752         }
753
754         /* Unregister ASM */
755         if(pcmHandle->asm_event != ASM_EVENT_CALL && pcmHandle->asm_event != ASM_EVENT_VIDEOCALL) {
756                 if(!ASM_unregister_sound(pcmHandle->asm_handle, pcmHandle->asm_event, &errorcode)) {
757                 debug_error("ASM_unregister failed in %s with 0x%x\n", __func__, errorcode);
758         }
759     }
760
761         /* Free handle */
762         free(pcmHandle);    pcmHandle= NULL;
763
764         debug_fleave();
765         return result;
766 }
767
768 EXPORT_API
769 int mm_sound_pcm_set_message_callback (MMSoundPcmHandle_t handle, MMMessageCallback callback, void *user_param)
770 {
771         mm_sound_pcm_t *pcmHandle =  (mm_sound_pcm_t*)handle;
772
773         if(pcmHandle == NULL || callback == NULL)
774                 return MM_ERROR_INVALID_ARGUMENT;
775
776         pcmHandle->msg_cb = callback;
777         pcmHandle->msg_cb_param = user_param;
778
779         debug_log ("set pcm message callback (%p,%p)\n", callback, user_param);
780
781         return MM_ERROR_NONE;
782 }
783
784
785 EXPORT_API
786 int mm_sound_pcm_play_open_ex (MMSoundPcmHandle_t *handle, const unsigned int rate, MMSoundPcmChannel_t channel, MMSoundPcmFormat_t format, const volume_type_t vol_type, ASM_sound_events_t asm_event)
787 {
788         avsys_audio_param_t param;
789         mm_sound_pcm_t *pcmHandle = NULL;
790         int size = 0;
791         int result = AVSYS_STATE_SUCCESS;
792         int lvol_type = vol_type;
793         int errorcode = 0;
794
795         debug_fenter();
796         memset(&param, 0, sizeof(avsys_audio_param_t));
797
798         /* Check input param */
799         if(vol_type < 0) {
800                 debug_error("Volume type should not be negative value\n");
801                 return MM_ERROR_INVALID_ARGUMENT;
802         }
803         if(vol_type >= VOLUME_TYPE_MAX) {
804                 debug_error("Volume type should be under VOLUME_TYPE_MAX\n");
805                 return MM_ERROR_INVALID_ARGUMENT;
806         }
807         if(rate < _MIN_SYSTEM_SAMPLERATE || rate > _MAX_SYSTEM_SAMPLERATE) {
808                 debug_error("unsupported sample rate %u", rate);
809                 return MM_ERROR_SOUND_DEVICE_INVALID_SAMPLERATE;
810         } else {
811                 param.samplerate = rate;
812         }
813
814         switch(channel)
815         {
816         case MMSOUND_PCM_MONO:
817                 param.channels = 1;
818                 break;
819         case MMSOUND_PCM_STEREO:
820                 param.channels = 2;
821                 break;
822         default:
823                 debug_error("Unsupported channel type\n");
824                 return MM_ERROR_SOUND_DEVICE_INVALID_CHANNEL;
825         }
826
827         switch(format)
828         {
829         case MMSOUND_PCM_U8:
830                 param.format = AVSYS_AUDIO_FORMAT_8BIT;
831                 break;
832         case MMSOUND_PCM_S16_LE:
833                 param.format = AVSYS_AUDIO_FORMAT_16BIT;
834                 break;
835         default:
836                 debug_error("Unsupported format type\n");
837                 return MM_ERROR_SOUND_DEVICE_INVALID_FORMAT;
838         }
839
840         pcmHandle = calloc(sizeof(mm_sound_pcm_t),1);
841         if(pcmHandle == NULL)
842                 return MM_ERROR_OUT_OF_MEMORY;
843
844         /* Register ASM */
845         debug_log ("session start : input asm_event = %d-------------\n", asm_event);
846         if (asm_event == ASM_EVENT_NONE) {
847                 if(pcmHandle->asm_event != ASM_EVENT_CALL && pcmHandle->asm_event != ASM_EVENT_VIDEOCALL) {
848                         /* get session type */
849                         if(MM_ERROR_NONE != _get_asm_event_type(&pcmHandle->asm_event)) {
850                                 debug_error ("_get_asm_event_type failed....\n");
851                                 free(pcmHandle);
852                                 return MM_ERROR_POLICY_INTERNAL;
853                         }
854
855                         /* register asm */
856                         if(!ASM_register_sound(-1, &pcmHandle->asm_handle, pcmHandle->asm_event,
857                                         ASM_STATE_NONE, sound_pcm_asm_callback, (void*)pcmHandle, ASM_RESOURCE_NONE, &errorcode)) {
858                                 debug_error("ASM_register_sound() failed 0x%x\n", errorcode);
859                                 free(pcmHandle);
860                                 return MM_ERROR_POLICY_BLOCKED;
861                         }
862                 }
863         } else {
864                 /* register asm using asm_event input */
865                 if(!ASM_register_sound(-1, &pcmHandle->asm_handle, asm_event,
866                                 ASM_STATE_NONE, NULL, (void*)pcmHandle, ASM_RESOURCE_NONE, &errorcode)) {
867                         debug_error("ASM_register_sound() failed 0x%x\n", errorcode);
868                         free(pcmHandle);
869                         return MM_ERROR_POLICY_BLOCKED;
870                 }
871         }
872
873         param.mode = AVSYS_AUDIO_MODE_OUTPUT;
874         param.vol_type = lvol_type;
875         param.priority = AVSYS_AUDIO_PRIORITY_0;
876
877 //      avsys_audio_ampon();
878
879         /* Open */
880         debug_log ("avsys open -------------\n");
881         result = avsys_audio_open(&param, &pcmHandle->audio_handle, &size);
882         if(AVSYS_FAIL(result)) {
883                 debug_error("Device Open Error 0x%x\n", result);
884                 free(pcmHandle);
885                 return MM_ERROR_SOUND_DEVICE_NOT_OPENED;
886         }
887
888         pcmHandle->is_playback = true;
889
890         /* Set handle to return */
891         *handle = (MMSoundPcmHandle_t)pcmHandle;
892
893         debug_fleave();
894         return size;
895 }
896
897 EXPORT_API
898 int mm_sound_pcm_play_open(MMSoundPcmHandle_t *handle, const unsigned int rate, MMSoundPcmChannel_t channel, MMSoundPcmFormat_t format, const volume_type_t vol_type)
899 {
900         return mm_sound_pcm_play_open_ex (handle, rate, channel, format, vol_type, ASM_EVENT_NONE);
901 }
902
903 EXPORT_API
904 int mm_sound_pcm_play_start(MMSoundPcmHandle_t handle)
905 {
906         return _pcm_sound_start (handle);
907 }
908
909
910 EXPORT_API
911 int mm_sound_pcm_play_stop(MMSoundPcmHandle_t handle)
912 {
913         return _pcm_sound_stop(handle);
914 }
915
916
917 EXPORT_API
918 int mm_sound_pcm_play_write(MMSoundPcmHandle_t handle, void* ptr, unsigned int length_byte)
919 {
920         mm_sound_pcm_t *pcmHandle = NULL;
921
922         /* Check input param */
923         pcmHandle = (mm_sound_pcm_t*)handle;
924         if(pcmHandle == NULL) {
925                 debug_error ("Handle is null, return Invalid Argument\n");
926                 return MM_ERROR_INVALID_ARGUMENT;
927         }
928         if(ptr == NULL) {
929                 debug_error("Invalid buffer pointer\n");
930                 return MM_ERROR_SOUND_INVALID_POINTER;
931         }
932         if(length_byte == 0 ) {
933                 debug_error ("length is 0, return 0\n");
934                 return 0;
935         }
936
937         /* Check State : return fail if not started */
938         if (!pcmHandle->is_started) {
939                 /* not started, return fail */
940                 debug_error ("Not started yet, return Invalid State \n");
941                 return MM_ERROR_SOUND_INVALID_STATE;
942         }
943
944         /* Write */
945         return avsys_audio_write(pcmHandle->audio_handle, ptr, length_byte);
946 }
947
948 EXPORT_API
949 int mm_sound_pcm_play_close(MMSoundPcmHandle_t handle)
950 {
951         int result = AVSYS_STATE_SUCCESS;
952         mm_sound_pcm_t *pcmHandle = NULL;
953         int errorcode = 0;
954
955         debug_fenter();
956
957         /* Check input param */
958         pcmHandle = (mm_sound_pcm_t*)handle;
959         if(pcmHandle == NULL) {
960                 debug_error ("Handle is null, return Invalid Argument\n");
961                 return MM_ERROR_INVALID_ARGUMENT;
962         }
963
964         /* Drain if needed */
965         if (pcmHandle->is_started) {
966                 /* stop() is not called before close(), drain is needed */
967                 if(AVSYS_FAIL(avsys_audio_drain(pcmHandle->audio_handle))) {
968                         debug_error("drain failed\n");
969                 }
970         }
971
972         /* Close */
973         result = avsys_audio_close(pcmHandle->audio_handle);
974         if(AVSYS_FAIL(result)) {
975                 debug_error("handle close failed 0x%X", result);
976                 result = MM_ERROR_SOUND_INTERNAL;
977         }
978
979         /* Unregister ASM */
980         if(pcmHandle->asm_event != ASM_EVENT_CALL && pcmHandle->asm_event != ASM_EVENT_VIDEOCALL) {
981                 if(!ASM_unregister_sound(pcmHandle->asm_handle, pcmHandle->asm_event, &errorcode)) {
982                         debug_error("ASM_unregister failed in %s with 0x%x\n",__func__, errorcode);
983                 }
984         }
985
986         debug_log ("pcm sound [%p] closed success!!!\n", handle);
987
988         /* Free handle */
989         free(pcmHandle);    pcmHandle= NULL;
990
991         debug_fleave();
992
993         return result;
994 }
995
996 ///////////////////////////////////
997 ////     MMSOUND PLAY APIs
998 ///////////////////////////////////
999 EXPORT_API
1000 int mm_sound_play_loud_solo_sound(const char *filename, const volume_type_t volume_type, mm_sound_stop_callback_func callback, void *data, int *handle)
1001 {
1002         MMSoundParamType param = { 0, };
1003         int err;
1004         int lhandle = -1;
1005         int lvol_type = volume_type;
1006
1007         debug_fenter();
1008
1009         /* Check input param */
1010         if(filename == NULL) {
1011                 debug_error("filename is NULL\n");
1012                 return MM_ERROR_SOUND_FILE_NOT_FOUND;
1013         }
1014         if(volume_type < 0 || volume_type >= VOLUME_TYPE_MAX) {
1015                 debug_error("Volume type should not be negative value\n");
1016                 return MM_ERROR_INVALID_ARGUMENT;
1017         }
1018
1019         /* Play sound */
1020         param.filename = filename;
1021         param.volume = 0; //volume value dose not effect anymore
1022         param.callback = callback;
1023         param.data = data;
1024         param.loop = 1;
1025         param.volume_table = lvol_type;
1026         param.priority = AVSYS_AUDIO_PRIORITY_SOLO;
1027         param.handle_route = MM_SOUND_HANDLE_ROUTE_SPEAKER;
1028
1029         err = MMSoundClientPlaySound(&param, 0, 0, &lhandle);
1030         if (err < 0) {
1031                 debug_error("Failed to play sound\n");
1032                 return err;
1033         }
1034
1035         /* Set handle to return */
1036         if (handle) {
1037                 *handle = lhandle;
1038         } else {
1039                 debug_critical("The sound handle cannot be get [%d]\n", lhandle);
1040         }
1041
1042         debug_fleave();
1043         return MM_ERROR_NONE;
1044 }
1045
1046 EXPORT_API
1047 int mm_sound_play_solo_sound(const char *filename, const volume_type_t volume_type, mm_sound_stop_callback_func callback, void *data, int *handle)
1048 {
1049         MMSoundParamType param = { 0, };
1050         int err;
1051         int lhandle = -1;
1052         int lvol_type = volume_type;
1053
1054         debug_fenter();
1055
1056         /* Check input param */
1057         if(filename == NULL) {
1058                 debug_error("filename is NULL\n");
1059                 return MM_ERROR_SOUND_FILE_NOT_FOUND;
1060         }
1061         if(volume_type < 0 || volume_type >= VOLUME_TYPE_MAX) {
1062                 debug_error("Volume type should not be negative value\n");
1063                 return MM_ERROR_INVALID_ARGUMENT;
1064         }
1065
1066         /* Play sound */
1067         param.filename = filename;
1068         param.volume = 0; /* volume value dose not effect anymore */
1069         param.callback = callback;
1070         param.data = data;
1071         param.loop = 1;
1072         param.volume_table = lvol_type;
1073         param.priority = AVSYS_AUDIO_PRIORITY_SOLO;
1074         param.handle_route = MM_SOUND_HANDLE_ROUTE_USING_CURRENT;
1075
1076         err = MMSoundClientPlaySound(&param, 0, 0, &lhandle);
1077         if (err < 0) {
1078                 debug_error("Failed to play sound\n");
1079                 return err;
1080         }
1081
1082         /* Set handle to return */
1083         if (handle) {
1084                 *handle = lhandle;
1085         } else {
1086                 debug_critical("The sound handle cannot be get [%d]\n", lhandle);
1087         }
1088
1089         debug_fleave();
1090         return MM_ERROR_NONE;
1091 }
1092
1093
1094 EXPORT_API
1095 int mm_sound_play_sound(const char *filename, const volume_type_t volume_type, mm_sound_stop_callback_func callback, void *data, int *handle)
1096 {
1097         MMSoundParamType param = { 0, };
1098         int err;
1099         int lhandle = -1;
1100         int lvol_type = volume_type;
1101
1102         debug_fenter();
1103
1104         /* Check input param */
1105         if(filename == NULL) {
1106                 debug_error("filename is NULL\n");
1107                 return MM_ERROR_SOUND_FILE_NOT_FOUND;
1108         }
1109         if(volume_type < 0) {
1110                 debug_error("Volume type should not be negative value\n");
1111                 return MM_ERROR_INVALID_ARGUMENT;
1112         }
1113         if(volume_type >= VOLUME_TYPE_MAX) {
1114                 debug_error("Volume type should be under VOLUME_TYPE_MAX\n");
1115                 return MM_ERROR_INVALID_ARGUMENT;
1116         }
1117
1118         /* Play sound */
1119         param.filename = filename;
1120         param.volume = 0; /* volume value dose not effect anymore */
1121         param.callback = callback;
1122         param.data = data;
1123         param.loop = 1;
1124         param.volume_table = lvol_type;
1125         param.priority = AVSYS_AUDIO_PRIORITY_NORMAL;
1126         param.handle_route = MM_SOUND_HANDLE_ROUTE_USING_CURRENT;
1127
1128         err = MMSoundClientPlaySound(&param, 0, 0, &lhandle);
1129         if (err < 0) {
1130                 debug_error("Failed to play sound\n");
1131                 return err;
1132         }
1133
1134         /* Set handle to return */
1135         if (handle) {
1136                 *handle = lhandle;
1137         } else {
1138                 debug_critical("The sound handle cannot be get [%d]\n", lhandle);
1139         }
1140
1141         debug_fleave();
1142         return MM_ERROR_NONE;
1143 }
1144
1145
1146 EXPORT_API
1147 int mm_sound_play_sound_ex(MMSoundParamType *param, int *handle)
1148 {
1149         int err;
1150         int lhandle = -1;
1151
1152         debug_fenter();
1153
1154         /* Check input param */
1155         if (param == NULL) {
1156                 debug_error("param is null\n");
1157                 return MM_ERROR_INVALID_ARGUMENT;
1158         }
1159
1160         /* Play sound */
1161         err = MMSoundClientPlaySound(param, 0, 0, &lhandle);
1162         if (err < 0) {
1163                 debug_error("Failed to play sound\n");
1164                 return err;
1165         }
1166
1167         /* Set handle to return */
1168         if (handle) {
1169                 *handle = lhandle;
1170         } else {
1171                 debug_critical("The sound hadle cannot be get [%d]\n", lhandle);
1172         }
1173
1174         debug_fleave();
1175         return MM_ERROR_NONE;
1176 }
1177
1178
1179 EXPORT_API
1180 int mm_sound_stop_sound(int handle)
1181 {
1182         int err;
1183
1184         debug_fenter();
1185
1186         /* Stop sound */
1187         err = MMSoundClientStopSound(handle);
1188         if (err < 0) {
1189                 debug_error("Fail to stop sound\n");
1190                 return err;
1191         }
1192
1193         debug_fleave();
1194         return MM_ERROR_NONE;
1195 }
1196
1197 ///////////////////////////////////
1198 ////     MMSOUND TONE APIs
1199 ///////////////////////////////////
1200 EXPORT_API
1201 int mm_sound_play_tone (MMSoundTone_t num, const volume_type_t vol_type, const double volume, const int duration, int *handle)
1202 {
1203         int lhandle = -1;
1204         int err = MM_ERROR_NONE;
1205
1206         debug_fenter();
1207
1208         /* Check input param */
1209         if(duration < -1) {
1210                 debug_error("number is invalid %d\n", duration);
1211                 return MM_ERROR_INVALID_ARGUMENT;
1212         }
1213         if(num < MM_SOUND_TONE_DTMF_0 || num >= MM_SOUND_TONE_NUM) {
1214                 debug_error("TONE Value is invalid %d\n", num);
1215                 return MM_ERROR_INVALID_ARGUMENT;
1216         }
1217         if(vol_type < VOLUME_TYPE_SYSTEM || vol_type >= VOLUME_TYPE_MAX) {
1218                 debug_error("Volume Type is invalid %d\n", vol_type);
1219                 return MM_ERROR_INVALID_ARGUMENT;
1220         }
1221         if(volume < 0.0 || volume > 1.0) {
1222                 debug_error("Volume Value is invalid %d\n", vol_type);
1223                 return MM_ERROR_INVALID_ARGUMENT;
1224         }
1225
1226         /* Play tone */
1227         debug_msg("Call MMSoundClientPlayTone\n");
1228         err = MMSoundClientPlayTone (num, vol_type, volume, duration, &lhandle);
1229         if (err < 0) {
1230                 debug_error("Failed to play sound\n");
1231                 return err;
1232         }
1233
1234         /* Set handle to return */
1235         if (handle)
1236                 *handle = lhandle;
1237         else
1238                 debug_critical("The sound handle cannot be get [%d]\n", lhandle);
1239
1240         debug_fleave();
1241         return MM_ERROR_NONE;
1242 }
1243
1244 ///////////////////////////////////
1245 ////     MMSOUND ROUTING APIs
1246 ///////////////////////////////////
1247 EXPORT_API
1248 int mm_sound_set_path(int gain, int output, int input, int option)
1249 {
1250         int err;
1251
1252         debug_fenter();
1253
1254         debug_msg("gain: 0x%02X, output: %d, input: %d, option: 0x%x\n", gain, output, input, option);
1255
1256         err = avsys_audio_set_path_ex( gain, output, input, option);
1257         if (err < 0) {
1258                 debug_error("avsys_audio_set_path() failed\n");
1259                 return MM_ERROR_SOUND_INTERNAL;
1260         }
1261
1262         debug_fleave();
1263         return MM_ERROR_NONE;
1264 }
1265
1266 EXPORT_API
1267 int mm_sound_get_path(int *gain, int *output, int *input, int *option)
1268 {
1269         int err;
1270
1271         debug_fenter();
1272
1273         err = avsys_audio_get_path_ex( gain, output, input, option);
1274         if (err < 0) {
1275                 debug_error("SoundCtlPathGet() failed\n");
1276                 return MM_ERROR_SOUND_INTERNAL;
1277         }
1278
1279         debug_msg("gain: 0x%02X, output: %d, input: %d, option: 0x%x\n", *gain, *output, *input, *option);
1280
1281         debug_fleave();
1282         return MM_ERROR_NONE;
1283 }
1284
1285 #ifdef PULSE_CLIENT
1286 enum {
1287         USE_PA_SINK_ALSA = 0,
1288         USE_PA_SINK_A2DP,
1289 };
1290 EXPORT_API
1291 int mm_sound_route_set_system_policy (system_audio_route_t route)
1292 {
1293         return MM_ERROR_NONE;
1294 }
1295
1296
1297 EXPORT_API
1298 int mm_sound_route_get_system_policy (system_audio_route_t *route)
1299 {
1300         return MM_ERROR_NONE;
1301 }
1302
1303
1304 EXPORT_API
1305 int mm_sound_route_get_a2dp_status (int *connected, char **bt_name)
1306 {
1307         int ret = MM_ERROR_NONE;
1308
1309         debug_fenter();
1310
1311         if (connected == NULL || bt_name == NULL) {
1312                 debug_error ("argument is not valid\n");
1313                 return MM_ERROR_INVALID_ARGUMENT; 
1314         } 
1315
1316         ret = MMSoundClientIsBtA2dpOn (connected, bt_name);
1317         debug_msg ("connected=[%d] bt_name[%s]\n", *connected, *bt_name);
1318         if (ret < 0) {
1319                 debug_error("MMSoundClientIsBtA2dpOn() Failed\n");
1320                 return ret;
1321         }
1322
1323         debug_fleave();
1324
1325         return ret;
1326 }
1327
1328 EXPORT_API
1329 int mm_sound_route_get_playing_device(system_audio_route_device_t *dev)
1330 {
1331         mm_sound_device_in device_in = MM_SOUND_DEVICE_IN_NONE;
1332         mm_sound_device_out device_out = MM_SOUND_DEVICE_OUT_NONE;
1333
1334         if(!dev)
1335                 return MM_ERROR_INVALID_ARGUMENT;
1336
1337         if(MM_ERROR_NONE != mm_sound_get_active_device(&device_in, &device_out)) {
1338                 debug_error("Can not get active device info\n");
1339                 return MM_ERROR_SOUND_INTERNAL;
1340         }
1341
1342         switch(device_out)
1343         {
1344         case MM_SOUND_DEVICE_OUT_SPEAKER:
1345                 *dev = SYSTEM_AUDIO_ROUTE_PLAYBACK_DEVICE_HANDSET;
1346                 break;
1347         case MM_SOUND_DEVICE_OUT_BT_A2DP:
1348                 *dev = SYSTEM_AUDIO_ROUTE_PLAYBACK_DEVICE_BLUETOOTH;
1349                 break;
1350         case MM_SOUND_DEVICE_OUT_WIRED_ACCESSORY:
1351                 *dev = SYSTEM_AUDIO_ROUTE_PLAYBACK_DEVICE_EARPHONE;
1352                 break;
1353         default:
1354                 *dev = SYSTEM_AUDIO_ROUTE_PLAYBACK_DEVICE_NONE;
1355                 break;
1356         }
1357
1358         return MM_ERROR_NONE;
1359 }
1360
1361 EXPORT_API
1362 int mm_sound_route_add_change_callback(audio_route_policy_changed_callback_fn func, void *user_data)
1363 {
1364         /* Deprecated */
1365         return MM_ERROR_NONE;
1366 }
1367
1368 EXPORT_API
1369 int mm_sound_route_remove_change_callback()
1370 {
1371         /* Deprecated */
1372         return MM_ERROR_NONE;
1373 }
1374
1375 #endif /* PULSE_CLIENT */
1376
1377 EXPORT_API
1378 int mm_sound_system_get_capture_status(system_audio_capture_status_t *status)
1379 {
1380         int err = AVSYS_STATE_SUCCESS;
1381         int on_capture = 0;
1382
1383         if(!status)
1384                 return MM_ERROR_INVALID_ARGUMENT;
1385
1386         err = avsys_audio_get_capture_status(&on_capture);
1387         if(err < 0) {
1388                 debug_error("Can not get capture status with 0x%x\n", err);
1389                 return MM_ERROR_SOUND_INTERNAL;
1390         }
1391
1392         if(on_capture)
1393                 *status = SYSTEM_AUDIO_CAPTURE_ACTIVE;
1394         else
1395                 *status = SYSTEM_AUDIO_CAPTURE_NONE;
1396
1397         return MM_ERROR_NONE;
1398 }
1399
1400 EXPORT_API
1401 int mm_sound_is_route_available(mm_sound_route route, bool *is_available)
1402 {
1403         int ret = MM_ERROR_NONE;
1404
1405         debug_fenter();
1406
1407         if (!_mm_sound_is_route_valid(route)) {
1408                 debug_error("route is invalid %d\n", route);
1409                 return MM_ERROR_INVALID_ARGUMENT;
1410         }
1411         if (!is_available)
1412         {
1413                 debug_error("is_available is invalid\n");
1414                 return MM_ERROR_INVALID_ARGUMENT;
1415         }
1416
1417         ret = _mm_sound_client_is_route_available(route, is_available);
1418         if (ret < 0) {
1419                 debug_error("Can not check given route is available\n");
1420         }
1421
1422         debug_fleave();
1423         return ret;
1424 }
1425
1426 EXPORT_API
1427 int mm_sound_foreach_available_route_cb(mm_sound_available_route_cb available_route_cb, void *user_data)
1428 {
1429         int ret = MM_ERROR_NONE;
1430
1431         debug_fenter();
1432
1433         if (!available_route_cb)
1434         {
1435                 debug_error("available_route_cb is invalid\n");
1436                 return MM_ERROR_INVALID_ARGUMENT;
1437         }
1438
1439         ret = _mm_sound_client_foreach_available_route_cb(available_route_cb, user_data);
1440         if (ret < 0) {
1441                 debug_error("Can not set foreach available route callback\n");
1442         }
1443
1444         debug_fleave();
1445         return ret;
1446 }
1447
1448 EXPORT_API
1449 int mm_sound_set_active_route(mm_sound_route route)
1450 {
1451         int ret = MM_ERROR_NONE;
1452
1453         debug_fenter();
1454
1455         if (!_mm_sound_is_route_valid(route)) {
1456                 debug_error("route is invalid %d\n", route);
1457                 return MM_ERROR_INVALID_ARGUMENT;
1458         }
1459
1460         ret = _mm_sound_client_set_active_route(route);
1461         if (ret < 0) {
1462                 debug_error("Can not set active route\n");
1463         }
1464
1465         debug_fleave();
1466         return ret;
1467 }
1468
1469
1470 EXPORT_API
1471 int mm_sound_get_active_device(mm_sound_device_in *device_in, mm_sound_device_out *device_out)
1472 {
1473         int ret = MM_ERROR_NONE;
1474
1475         debug_fenter();
1476
1477         if (device_in == NULL || device_out == NULL) {
1478                 debug_error("argument is not valid\n");
1479                 return MM_ERROR_INVALID_ARGUMENT;
1480         }
1481
1482         ret = _mm_sound_client_get_active_device(device_in, device_out);
1483         if (ret < 0) {
1484                 debug_error("Can not add active device callback\n");
1485         }
1486
1487         debug_fleave();
1488         return ret;
1489 }
1490
1491 EXPORT_API
1492 int mm_sound_add_active_device_changed_callback(mm_sound_active_device_changed_cb func, void *user_data)
1493 {
1494         int ret = MM_ERROR_NONE;
1495
1496         debug_fenter();
1497
1498         if (func == NULL) {
1499                 debug_error("argument is not valid\n");
1500                 return MM_ERROR_INVALID_ARGUMENT;
1501         }
1502
1503         ret = _mm_sound_client_add_active_device_changed_callback(func, user_data);
1504         if (ret < 0) {
1505                 debug_error("Can not add active device changed callback\n");
1506         }
1507
1508         debug_fleave();
1509         return ret;
1510 }
1511
1512 EXPORT_API
1513 int mm_sound_remove_active_device_changed_callback(void)
1514 {
1515         int ret = MM_ERROR_NONE;
1516
1517         debug_fenter();
1518
1519         ret = _mm_sound_client_remove_active_device_changed_callback();
1520         if (ret < 0) {
1521                 debug_error("Can not remove active device changed callback\n");
1522         }
1523
1524         debug_fleave();
1525         return ret;
1526 }
1527
1528 EXPORT_API
1529 int mm_sound_add_available_route_changed_callback(mm_sound_available_route_changed_cb func, void *user_data)
1530 {
1531         int ret = MM_ERROR_NONE;
1532
1533         debug_fenter();
1534
1535         if (func == NULL) {
1536                 debug_error("argument is not valid\n");
1537                 return MM_ERROR_INVALID_ARGUMENT;
1538         }
1539
1540         ret = _mm_sound_client_add_available_route_changed_callback(func, user_data);
1541         if (ret < 0) {
1542                 debug_error("Can not add available route changed callback\n");
1543         }
1544
1545         debug_fleave();
1546         return ret;
1547 }
1548
1549 EXPORT_API
1550 int mm_sound_remove_available_route_changed_callback(void)
1551 {
1552         int ret = MM_ERROR_NONE;
1553
1554         debug_fenter();
1555
1556         ret = _mm_sound_client_remove_available_route_changed_callback();
1557         if (ret < 0) {
1558                 debug_error("Can not remove available route changed callback\n");
1559         }
1560
1561         debug_fleave();
1562         return ret;
1563 }
1564
1565 __attribute__ ((destructor))
1566 void __mmfsnd_finalize(void)
1567 {
1568         debug_fenter();
1569
1570         MMSoundClientCallbackFini();
1571
1572         debug_fleave();
1573 }
1574
1575 __attribute__ ((constructor))
1576 void __mmfsnd_initialize(void)
1577 {
1578         /* Will be Fixed */
1579 }