merge with master
[platform/core/api/audio-io.git] / src / audio_io.c
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License. 
15 */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <mm.h>
21 #include <glib.h>
22 #include <audio_io_private.h>
23 #include <dlog.h>
24
25 #ifdef LOG_TAG
26 #undef LOG_TAG
27 #endif
28 #define LOG_TAG "TIZEN_N_AUDIO_IO"
29
30 /*
31 * Internal Macros
32 */
33 #define AUDIO_IO_CHECK_CONDITION(condition,error,msg)   \
34                 if(condition) {} else \
35                 { LOGE("[%s] %s(0x%08x)",__FUNCTION__, msg,error); return error;}; \
36
37 #define AUDIO_IO_NULL_ARG_CHECK(arg)    \
38         AUDIO_IO_CHECK_CONDITION(arg != NULL, AUDIO_IO_ERROR_INVALID_PARAMETER, "AUDIO_IO_ERROR_INVALID_PARAMETER" )
39
40 /*
41 * Internal Implementation
42 */
43 static int __convert_error_code(int code, char *func_name)
44 {
45         int ret = AUDIO_IO_ERROR_NONE;
46         char* msg = "AUDIO_IO_ERROR_NONE";
47
48         switch(code)
49         {
50                 case MM_ERROR_NONE:
51                         ret = AUDIO_IO_ERROR_NONE;
52                         msg = "AUDIO_IO_ERROR_NONE";
53                         break;
54                 case MM_ERROR_INVALID_ARGUMENT:
55                 case MM_ERROR_SOUND_DEVICE_INVALID_SAMPLERATE:
56                 case MM_ERROR_SOUND_DEVICE_INVALID_CHANNEL:
57                 case MM_ERROR_SOUND_DEVICE_INVALID_FORMAT:
58                         ret = AUDIO_IO_ERROR_INVALID_PARAMETER;
59                         msg = "AUDIO_IO_ERROR_INVALID_PARAMETER";
60                         break;
61                 case MM_ERROR_SOUND_DEVICE_NOT_OPENED:
62                         ret = AUDIO_IO_ERROR_DEVICE_NOT_OPENED;
63                         msg = "AUDIO_IO_ERROR_DEVICE_NOT_OPENED";
64                         break;
65                 case MM_ERROR_SOUND_INTERNAL:
66                         ret = AUDIO_IO_ERROR_DEVICE_NOT_CLOSED;
67                         msg = "AUDIO_IO_ERROR_DEVICE_NOT_CLOSED";
68                         break;
69                 case MM_ERROR_SOUND_INVALID_POINTER:
70                         ret = AUDIO_IO_ERROR_INVALID_BUFFER;
71                         msg = "AUDIO_IO_ERROR_INVALID_BUFFER";
72                         break;          
73                 case MM_ERROR_POLICY_BLOCKED:
74                 case MM_ERROR_POLICY_INTERRUPTED:
75                 case MM_ERROR_POLICY_INTERNAL:
76                 case MM_ERROR_POLICY_DUPLICATED:
77                         ret = AUDIO_IO_ERROR_SOUND_POLICY;
78                         msg = "AUDIO_IO_ERROR_SOUND_POLICY";
79                         break;
80         } 
81         LOGE("[%s] %s(0x%08x) : core fw error(0x%x)",func_name,msg, ret, code);
82         return ret;     
83 }
84
85 static int __check_parameter(int sample_rate, audio_channel_e channel, audio_sample_type_e type)
86 {
87         if(sample_rate<8000 || sample_rate > 48000)     {
88                 LOGE("[%s] AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) :  Invalid sample rate (8000~48000Hz) : %d",__FUNCTION__, AUDIO_IO_ERROR_INVALID_PARAMETER,sample_rate);
89                 return AUDIO_IO_ERROR_INVALID_PARAMETER;
90         }
91         if (channel < AUDIO_CHANNEL_MONO || channel > AUDIO_CHANNEL_STEREO) {
92                 LOGE("[%s] AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) :  Invalid audio channel : %d",__FUNCTION__, AUDIO_IO_ERROR_INVALID_PARAMETER,channel);
93                 return AUDIO_IO_ERROR_INVALID_PARAMETER;
94         }
95         if (type < AUDIO_SAMPLE_TYPE_U8 || type > AUDIO_SAMPLE_TYPE_S16_LE) {
96                 LOGE("[%s] AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) :  Invalid sample typel : %d",__FUNCTION__, AUDIO_IO_ERROR_INVALID_PARAMETER,type);
97                 return AUDIO_IO_ERROR_INVALID_PARAMETER;
98         }
99         return AUDIO_IO_ERROR_NONE;
100 }
101
102
103 static audio_io_interrupted_code_e __translate_interrupted_code (int code)
104 {
105         audio_io_interrupted_code_e e = AUDIO_IO_INTERRUPTED_COMPLETED;
106
107         switch(code)
108         {
109         case MM_MSG_CODE_INTERRUPTED_BY_ALARM_END:
110         case MM_MSG_CODE_INTERRUPTED_BY_EMERGENCY_END:
111                 e = AUDIO_IO_INTERRUPTED_COMPLETED;
112                 break;
113
114         case MM_MSG_CODE_INTERRUPTED_BY_MEDIA:
115         case MM_MSG_CODE_INTERRUPTED_BY_OTHER_PLAYER_APP:
116                 e = AUDIO_IO_INTERRUPTED_BY_MEDIA;
117                 break;
118
119         case MM_MSG_CODE_INTERRUPTED_BY_CALL_START:
120                 e = AUDIO_IO_INTERRUPTED_BY_CALL;
121                 break;
122
123         case MM_MSG_CODE_INTERRUPTED_BY_EARJACK_UNPLUG:
124                 e = AUDIO_IO_INTERRUPTED_BY_EARJACK_UNPLUG;
125                 break;
126
127         case MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT:
128                 e = AUDIO_IO_INTERRUPTED_BY_RESOURCE_CONFLICT;
129                 break;
130
131         case MM_MSG_CODE_INTERRUPTED_BY_ALARM_START:
132                 e = AUDIO_IO_INTERRUPTED_BY_ALARM;
133                 break;
134
135         case MM_MSG_CODE_INTERRUPTED_BY_EMERGENCY_START:
136                 e = AUDIO_IO_INTERRUPTED_BY_EMERGENCY;
137                 break;
138
139         case MM_MSG_CODE_INTERRUPTED_BY_RESUMABLE_MEDIA:
140                 e = AUDIO_IO_INTERRUPTED_BY_RESUMABLE_MEDIA;
141                 break;
142         }
143
144         return e;
145 }
146
147 static int __mm_sound_pcm_capture_msg_cb (int message, void *param, void *user_param)
148 {
149         audio_io_interrupted_code_e e = AUDIO_IO_INTERRUPTED_COMPLETED;
150         audio_in_s *handle = (audio_in_s *) user_param;
151         MMMessageParamType *msg = (MMMessageParamType*)param;
152
153         LOGI("[%s] Got message type : 0x%x with code : %d" ,__FUNCTION__, message, msg->code);
154
155         if (handle->user_cb == NULL) {
156                 LOGI("[%s] No interrupt callback is set. Skip this" ,__FUNCTION__);
157                 return 0;
158         }
159
160         if (message == MM_MESSAGE_SOUND_PCM_INTERRUPTED) {
161                 e = __translate_interrupted_code (msg->code);
162         } else if (message == MM_MESSAGE_SOUND_PCM_CAPTURE_RESTRICTED) {
163                 /* TODO : handling restricted code is needed */
164                 /* e = _translate_restricted_code (msg->code); */
165         }
166
167         handle->user_cb (e, handle->user_data);
168
169         return 0;
170 }
171
172 static int __mm_sound_pcm_playback_msg_cb (int message, void *param, void *user_param)
173 {
174         audio_io_interrupted_code_e e = AUDIO_IO_INTERRUPTED_COMPLETED;
175         audio_out_s *handle = (audio_out_s *) user_param;
176         MMMessageParamType *msg = (MMMessageParamType*)param;
177
178         LOGI("[%s] Got message type : 0x%x with code : %d" ,__FUNCTION__, message, msg->code);
179
180         if (handle->user_cb == NULL) {
181                 LOGI("[%s] No interrupt callback is set. Skip this" ,__FUNCTION__);
182                 return 0;
183         }
184
185         if (message == MM_MESSAGE_SOUND_PCM_INTERRUPTED) {
186                 e = __translate_interrupted_code (msg->code);
187         }
188
189         handle->user_cb (e, handle->user_data);
190
191         return 0;
192 }
193
194
195 /*
196 * Public Implementation
197 */
198
199 /* Audio In */
200 int audio_in_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type , audio_in_h* input)
201 {
202         int ret = 0;
203         audio_in_s *handle = NULL;
204
205         /* input condition check */
206         AUDIO_IO_NULL_ARG_CHECK(input);
207         if(__check_parameter(sample_rate, channel, type) != AUDIO_IO_ERROR_NONE)
208                 return AUDIO_IO_ERROR_INVALID_PARAMETER;
209
210         /* Create Handle */
211         handle = (audio_in_s*)malloc( sizeof(audio_in_s));
212         if (handle != NULL) {
213                 memset(handle, 0, sizeof(audio_in_s));
214         } else {
215                 LOGE("[%s] ERROR :  AUDIO_IO_ERROR_OUT_OF_MEMORY(0x%08x)" ,__FUNCTION__, AUDIO_IO_ERROR_OUT_OF_MEMORY );
216                 return AUDIO_IO_ERROR_OUT_OF_MEMORY;
217         }
218
219         ret = mm_sound_pcm_capture_open( &handle->mm_handle,sample_rate, channel, type);
220         if( ret < 0) {
221                 free (handle);
222                 return __convert_error_code(ret, (char*)__FUNCTION__);
223         }
224         LOGI("[%s] mm_sound_pcm_capture_open() success",__FUNCTION__);
225
226         /* Fill information */
227         *input = (audio_in_h)handle;
228         handle->_buffer_size= ret;
229         handle->_sample_rate= sample_rate;
230         handle->_channel= channel;
231         handle->_type= type;
232
233         /* Set message interrupt callback */
234         ret = mm_sound_pcm_set_message_callback(handle->mm_handle, __mm_sound_pcm_capture_msg_cb, handle);
235         if( ret < 0) {
236                 return __convert_error_code(ret, (char*)__FUNCTION__);
237         }
238         LOGI("[%s] mm_sound_pcm_set_message_callback() success",__FUNCTION__);
239
240         return AUDIO_IO_ERROR_NONE;
241 }
242
243 int audio_in_destroy(audio_in_h input)
244 {
245         AUDIO_IO_NULL_ARG_CHECK(input);
246         audio_in_s *handle = (audio_in_s *) input;
247
248         int ret = mm_sound_pcm_capture_close(handle->mm_handle);
249         if (ret != MM_ERROR_NONE) {
250                 return __convert_error_code(ret, (char*)__FUNCTION__);
251         }
252         free(handle);
253
254         LOGI("[%s] mm_sound_pcm_capture_close() success",__FUNCTION__);
255         return AUDIO_IO_ERROR_NONE;
256 }
257
258 int audio_in_prepare(audio_in_h input)
259 {
260         AUDIO_IO_NULL_ARG_CHECK(input);
261         audio_in_s *handle = (audio_in_s *) input;
262
263         int ret = mm_sound_pcm_capture_start(handle->mm_handle);
264         if (ret != MM_ERROR_NONE) {
265                 return __convert_error_code(ret, (char*)__FUNCTION__);
266         }
267
268         LOGI("[%s] mm_sound_pcm_capture_start() success",__FUNCTION__);
269         return AUDIO_IO_ERROR_NONE;
270 }
271
272 int audio_in_unprepare(audio_in_h input)
273 {
274         AUDIO_IO_NULL_ARG_CHECK(input);
275         audio_in_s *handle = (audio_in_s *) input;
276
277         int ret = mm_sound_pcm_capture_stop(handle->mm_handle);
278         if (ret != MM_ERROR_NONE) {
279                 return __convert_error_code(ret, (char*)__FUNCTION__);
280         }
281
282         LOGI("[%s] mm_sound_pcm_capture_stop() success",__FUNCTION__);
283         return AUDIO_IO_ERROR_NONE;
284 }
285
286 int audio_in_read(audio_in_h input, void *buffer, unsigned int length )
287 {
288         AUDIO_IO_NULL_ARG_CHECK(input);
289         AUDIO_IO_NULL_ARG_CHECK(buffer);
290         audio_in_s *handle = (audio_in_s *) input;
291         int ret = 0;
292         int result = 0;
293
294         ret = mm_sound_pcm_capture_read(handle->mm_handle, (void*) buffer, length);
295         if (ret > 0) {
296                 LOGI("[%s] (%d/%d) bytes read" ,__FUNCTION__, ret, length);
297                 return ret;
298         }
299
300         switch(ret)
301         {
302                 case MM_ERROR_SOUND_INVALID_STATE:
303                         result = AUDIO_IO_ERROR_INVALID_OPERATION;
304                         LOGE("[%s] (0x%08x) : Not recording started yet.",(char*)__FUNCTION__, AUDIO_IO_ERROR_INVALID_OPERATION);
305                         break;
306                 default:
307                         result = __convert_error_code(ret, (char*)__FUNCTION__);
308                         break;
309         }
310         return result;
311 }
312
313 int audio_in_get_buffer_size(audio_in_h input, int *size)
314 {
315         AUDIO_IO_NULL_ARG_CHECK(input);
316         AUDIO_IO_NULL_ARG_CHECK(size);
317         audio_in_s *handle = (audio_in_s *) input;
318
319         *size = handle->_buffer_size;
320
321         LOGI("[%s] buffer size = %d",__FUNCTION__, *size);
322         return AUDIO_IO_ERROR_NONE;
323 }
324
325 int audio_in_get_sample_rate(audio_in_h input, int *sample_rate)
326 {
327         AUDIO_IO_NULL_ARG_CHECK(input);
328         AUDIO_IO_NULL_ARG_CHECK(sample_rate);
329         audio_in_s *handle = (audio_in_s *) input;
330
331         *sample_rate = handle->_sample_rate;
332
333         LOGI("[%s] sample rate = %d",__FUNCTION__, *sample_rate);
334         return AUDIO_IO_ERROR_NONE;
335 }
336
337
338 int audio_in_get_channel(audio_in_h input, audio_channel_e *channel)
339 {
340         AUDIO_IO_NULL_ARG_CHECK(input);
341         AUDIO_IO_NULL_ARG_CHECK(channel);
342         audio_in_s *handle = (audio_in_s *) input;
343
344         *channel = handle->_channel;
345
346         LOGI("[%s] channel = %d",__FUNCTION__, *channel);
347         return AUDIO_IO_ERROR_NONE;
348 }
349
350 int audio_in_get_sample_type(audio_in_h input, audio_sample_type_e *type)
351 {
352         AUDIO_IO_NULL_ARG_CHECK(input);
353         AUDIO_IO_NULL_ARG_CHECK(type);
354         audio_in_s *handle = (audio_in_s *) input;
355
356         *type = handle->_type;
357
358         LOGI("[%s] sample type = %d",__FUNCTION__, *type);
359         return AUDIO_IO_ERROR_NONE;
360 }
361
362 int audio_in_set_interrupted_cb(audio_in_h input, audio_io_interrupted_cb callback, void *user_data)
363 {
364         AUDIO_IO_NULL_ARG_CHECK(input);
365         AUDIO_IO_NULL_ARG_CHECK(callback);
366         audio_in_s *handle = (audio_in_s *) input;
367
368         handle->user_cb = callback;
369         handle->user_data = user_data;
370
371         LOGI("[%s] current interrupted cb (%p) / data (%p)",__FUNCTION__, handle->user_cb, handle->user_data);
372         return AUDIO_IO_ERROR_NONE;
373 }
374
375 int audio_in_unset_interrupted_cb(audio_in_h input)
376 {
377         AUDIO_IO_NULL_ARG_CHECK(input);
378         audio_in_s  * handle = (audio_in_s  *) input;
379
380         handle->user_cb = NULL;
381         handle->user_data = NULL;
382
383         LOGI("[%s] current interrupted cb (%p) / data (%p)",__FUNCTION__, handle->user_cb, handle->user_data);
384         return AUDIO_IO_ERROR_NONE;
385 }
386
387 int audio_in_ignore_session(audio_in_h input)
388 {
389         AUDIO_IO_NULL_ARG_CHECK(input);
390         audio_in_s  * handle = (audio_in_s  *) input;
391         int ret = 0;
392
393         ret = mm_sound_pcm_capture_ignore_session(handle->mm_handle);
394         if (ret != MM_ERROR_NONE) {
395                 return __convert_error_code(ret, (char*)__FUNCTION__);
396         }
397
398         LOGI("[%s] mm_sound_pcm_capture_ignore_session() success",__FUNCTION__);
399         return AUDIO_IO_ERROR_NONE;
400 }
401
402 /* Audio Out */
403 int audio_out_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, sound_type_e sound_type,  audio_out_h* output)
404 {
405         audio_out_s *handle = NULL;
406         int ret = 0;
407
408         /* input condition check */
409         AUDIO_IO_NULL_ARG_CHECK(output);
410         if(__check_parameter(sample_rate, channel, type)!=AUDIO_IO_ERROR_NONE)
411                 return AUDIO_IO_ERROR_INVALID_PARAMETER;
412         if(sound_type < SOUND_TYPE_SYSTEM || sound_type > SOUND_TYPE_CALL) {
413                 LOGE("[%s] ERROR :  AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) : Invalid sample sound type : %d" ,__FUNCTION__,AUDIO_IO_ERROR_INVALID_PARAMETER,sound_type );
414                 return AUDIO_IO_ERROR_INVALID_PARAMETER;
415         }
416         
417         /* Create Handle */
418         handle = (audio_out_s*)malloc( sizeof(audio_out_s));
419         if (handle != NULL) {
420                 memset(handle, 0 , sizeof(audio_out_s));
421         } else {
422                 LOGE("[%s] ERROR :  AUDIO_IO_ERROR_OUT_OF_MEMORY(0x%08x)" ,__FUNCTION__,AUDIO_IO_ERROR_OUT_OF_MEMORY );
423                 return AUDIO_IO_ERROR_OUT_OF_MEMORY;
424         }
425         ret = mm_sound_pcm_play_open(&handle->mm_handle,sample_rate, channel, type, sound_type);
426         if( ret < 0) {
427                 free (handle);
428                 return __convert_error_code(ret, (char*)__FUNCTION__);
429         }
430         LOGI("[%s] mm_sound_pcm_play_open() success",__FUNCTION__);
431
432         /* Fill information */
433         *output = (audio_out_h)handle;
434         handle->_buffer_size = ret;
435         handle->_sample_rate = sample_rate;
436         handle->_channel = channel;
437         handle->_type = type;
438         handle->_sound_type = sound_type;
439
440         /* Set message interrupt callback */
441         ret = mm_sound_pcm_set_message_callback(handle->mm_handle, __mm_sound_pcm_playback_msg_cb, handle);
442         if( ret < 0) {
443                 return __convert_error_code(ret, (char*)__FUNCTION__);
444         }
445         LOGI("[%s] mm_sound_pcm_set_message_callback() success",__FUNCTION__);
446
447         return AUDIO_IO_ERROR_NONE;
448 }
449
450 int audio_out_destroy(audio_out_h output)
451 {
452         AUDIO_IO_NULL_ARG_CHECK(output);
453         audio_out_s *handle = (audio_out_s *) output;
454
455         int ret = mm_sound_pcm_play_close(handle->mm_handle);
456         if (ret != MM_ERROR_NONE) {
457                 return __convert_error_code(ret, (char*)__FUNCTION__);
458         }
459         free(handle);
460
461         LOGI("[%s] mm_sound_pcm_play_close() success",__FUNCTION__);
462         return AUDIO_IO_ERROR_NONE;
463 }
464
465 int audio_out_prepare(audio_out_h output)
466 {
467         AUDIO_IO_NULL_ARG_CHECK(output);
468         audio_out_s *handle = (audio_out_s *) output;
469
470         int ret = mm_sound_pcm_play_start(handle->mm_handle);
471         if (ret != MM_ERROR_NONE) {
472                 return __convert_error_code(ret, (char*)__FUNCTION__);
473         }
474
475         LOGI("[%s] mm_sound_pcm_play_start() success",__FUNCTION__);
476         return AUDIO_IO_ERROR_NONE;
477 }
478
479 int audio_out_unprepare(audio_out_h output)
480 {
481         AUDIO_IO_NULL_ARG_CHECK(output);
482         audio_out_s *handle = (audio_out_s *) output;
483
484         int ret = mm_sound_pcm_play_stop(handle->mm_handle);
485         if (ret != MM_ERROR_NONE) {
486                 return __convert_error_code(ret, (char*)__FUNCTION__);
487         }
488
489         LOGI("[%s] mm_sound_pcm_play_stop() success",__FUNCTION__);
490         return AUDIO_IO_ERROR_NONE;
491 }
492
493 int audio_out_write(audio_out_h output, void* buffer, unsigned int length)
494 {
495         AUDIO_IO_NULL_ARG_CHECK(output);
496         AUDIO_IO_NULL_ARG_CHECK(buffer);
497         audio_out_s *handle = (audio_out_s *) output;
498
499         int ret = mm_sound_pcm_play_write(handle->mm_handle, (void*) buffer, length);
500         if (ret > 0) {
501                 LOGI("[%s] (%d/%d) bytes written" ,__FUNCTION__, ret, length);
502                 return ret;
503         }
504         switch(ret)
505         {
506                 case MM_ERROR_SOUND_INVALID_STATE:
507                         ret = AUDIO_IO_ERROR_INVALID_OPERATION;
508                         LOGE("[%s] (0x%08x) : Not playing started yet.",(char*)__FUNCTION__, AUDIO_IO_ERROR_INVALID_OPERATION);
509                         break;
510                 default:
511                         ret = __convert_error_code(ret, (char*)__FUNCTION__);
512                         break;
513         }
514         return ret;
515 }
516
517
518 int audio_out_get_buffer_size(audio_out_h output, int *size)
519 {
520         AUDIO_IO_NULL_ARG_CHECK(output);
521         AUDIO_IO_NULL_ARG_CHECK(size);
522         audio_out_s *handle = (audio_out_s *) output;
523
524         *size = handle->_buffer_size;
525
526         LOGI("[%s] buffer size = %d",__FUNCTION__, *size);
527         return AUDIO_IO_ERROR_NONE;
528 }
529
530
531 int audio_out_get_sample_rate(audio_out_h output, int *sample_rate)
532 {
533         AUDIO_IO_NULL_ARG_CHECK(output);
534         AUDIO_IO_NULL_ARG_CHECK(sample_rate);
535         audio_out_s *handle = (audio_out_s *) output;
536
537         *sample_rate = handle->_sample_rate;
538
539         LOGI("[%s] sample rate = %d",__FUNCTION__, *sample_rate);
540         return AUDIO_IO_ERROR_NONE;
541 }
542
543
544 int audio_out_get_channel(audio_out_h output, audio_channel_e *channel)
545 {
546         AUDIO_IO_NULL_ARG_CHECK(output);
547         AUDIO_IO_NULL_ARG_CHECK(channel);
548         audio_out_s *handle = (audio_out_s *) output;
549
550         *channel = handle->_channel;
551
552         LOGI("[%s] channel = %d",__FUNCTION__, *channel);
553         return AUDIO_IO_ERROR_NONE;
554 }
555
556
557 int audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type)
558 {
559         AUDIO_IO_NULL_ARG_CHECK(output);
560         AUDIO_IO_NULL_ARG_CHECK(type);
561         audio_out_s *handle = (audio_out_s *) output;
562
563         *type = handle->_type;
564
565         LOGI("[%s] sample type = %d",__FUNCTION__, *type);
566         return AUDIO_IO_ERROR_NONE;
567 }
568
569
570 int audio_out_get_sound_type(audio_out_h output, sound_type_e *type)
571 {
572         AUDIO_IO_NULL_ARG_CHECK(output);
573         AUDIO_IO_NULL_ARG_CHECK(type);
574         audio_out_s *handle = (audio_out_s *) output;
575
576         *type = handle->_sound_type;
577
578         LOGI("[%s] sound type = %d",__FUNCTION__, *type);
579         return AUDIO_IO_ERROR_NONE;
580 }
581
582 int audio_out_set_interrupted_cb(audio_out_h output, audio_io_interrupted_cb callback, void *user_data)
583 {
584         AUDIO_IO_NULL_ARG_CHECK(output);
585         AUDIO_IO_NULL_ARG_CHECK(callback);
586         audio_out_s *handle = (audio_out_s *) output;
587
588         handle->user_cb = callback;
589         handle->user_data = user_data;
590
591         LOGI("[%s] current interrupted cb (%p) / data (%p)",__FUNCTION__, handle->user_cb, handle->user_data);
592         return AUDIO_IO_ERROR_NONE;
593 }
594
595 int audio_out_unset_interrupted_cb(audio_out_h output)
596 {
597         AUDIO_IO_NULL_ARG_CHECK(output);
598         audio_out_s *handle = (audio_out_s *) output;
599
600         handle->user_cb = NULL;
601         handle->user_data = NULL;
602
603         LOGI("[%s] current interrupted cb (%p) / data (%p)",__FUNCTION__, handle->user_cb, handle->user_data);
604         return AUDIO_IO_ERROR_NONE;
605 }
606
607 int audio_out_ignore_session(audio_out_h output)
608 {
609         AUDIO_IO_NULL_ARG_CHECK(output);
610         audio_out_s *handle = (audio_out_s *) output;
611         int ret = 0;
612
613         ret = mm_sound_pcm_play_ignore_session(handle->mm_handle);
614         if (ret != MM_ERROR_NONE) {
615                 return __convert_error_code(ret, (char*)__FUNCTION__);
616         }
617         LOGI("[%s] mm_sound_pcm_play_ignore_session() success",__FUNCTION__);
618
619         return AUDIO_IO_ERROR_NONE;
620 }