46cc47233136bd3e60cffb7cec664e2593e6038d
[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 /* Audio Out */
388 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)
389 {
390         audio_out_s *handle = NULL;
391         int ret = 0;
392
393         /* input condition check */
394         AUDIO_IO_NULL_ARG_CHECK(output);
395         if(__check_parameter(sample_rate, channel, type)!=AUDIO_IO_ERROR_NONE)
396                 return AUDIO_IO_ERROR_INVALID_PARAMETER;
397         if(sound_type < SOUND_TYPE_SYSTEM || sound_type > SOUND_TYPE_CALL) {
398                 LOGE("[%s] ERROR :  AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) : Invalid sample sound type : %d" ,__FUNCTION__,AUDIO_IO_ERROR_INVALID_PARAMETER,sound_type );
399                 return AUDIO_IO_ERROR_INVALID_PARAMETER;
400         }
401         
402         /* Create Handle */
403         handle = (audio_out_s*)malloc( sizeof(audio_out_s));
404         if (handle != NULL) {
405                 memset(handle, 0 , sizeof(audio_out_s));
406         } else {
407                 LOGE("[%s] ERROR :  AUDIO_IO_ERROR_OUT_OF_MEMORY(0x%08x)" ,__FUNCTION__,AUDIO_IO_ERROR_OUT_OF_MEMORY );
408                 return AUDIO_IO_ERROR_OUT_OF_MEMORY;
409         }
410         ret = mm_sound_pcm_play_open(&handle->mm_handle,sample_rate, channel, type, sound_type);
411         if( ret < 0) {
412                 free (handle);
413                 return __convert_error_code(ret, (char*)__FUNCTION__);
414         }
415         LOGI("[%s] mm_sound_pcm_play_open() success",__FUNCTION__);
416
417         /* Fill information */
418         *output = (audio_out_h)handle;
419         handle->_buffer_size = ret;
420         handle->_sample_rate = sample_rate;
421         handle->_channel = channel;
422         handle->_type = type;
423         handle->_sound_type = sound_type;
424
425         /* Set message interrupt callback */
426         ret = mm_sound_pcm_set_message_callback(handle->mm_handle, __mm_sound_pcm_playback_msg_cb, handle);
427         if( ret < 0) {
428                 return __convert_error_code(ret, (char*)__FUNCTION__);
429         }
430         LOGI("[%s] mm_sound_pcm_set_message_callback() success",__FUNCTION__);
431
432         return AUDIO_IO_ERROR_NONE;
433 }
434
435 int audio_out_destroy(audio_out_h output)
436 {
437         AUDIO_IO_NULL_ARG_CHECK(output);
438         audio_out_s *handle = (audio_out_s *) output;
439
440         int ret = mm_sound_pcm_play_close(handle->mm_handle);
441         if (ret != MM_ERROR_NONE) {
442                 return __convert_error_code(ret, (char*)__FUNCTION__);
443         }
444         free(handle);
445
446         LOGI("[%s] mm_sound_pcm_play_close() success",__FUNCTION__);
447         return AUDIO_IO_ERROR_NONE;
448 }
449
450 int audio_out_prepare(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_start(handle->mm_handle);
456         if (ret != MM_ERROR_NONE) {
457                 return __convert_error_code(ret, (char*)__FUNCTION__);
458         }
459
460         LOGI("[%s] mm_sound_pcm_play_start() success",__FUNCTION__);
461         return AUDIO_IO_ERROR_NONE;
462 }
463
464 int audio_out_unprepare(audio_out_h output)
465 {
466         AUDIO_IO_NULL_ARG_CHECK(output);
467         audio_out_s *handle = (audio_out_s *) output;
468
469         int ret = mm_sound_pcm_play_stop(handle->mm_handle);
470         if (ret != MM_ERROR_NONE) {
471                 return __convert_error_code(ret, (char*)__FUNCTION__);
472         }
473
474         LOGI("[%s] mm_sound_pcm_play_stop() success",__FUNCTION__);
475         return AUDIO_IO_ERROR_NONE;
476 }
477
478 int audio_out_write(audio_out_h output, void* buffer, unsigned int length)
479 {
480         AUDIO_IO_NULL_ARG_CHECK(output);
481         AUDIO_IO_NULL_ARG_CHECK(buffer);
482         audio_out_s *handle = (audio_out_s *) output;
483
484         int ret = mm_sound_pcm_play_write(handle->mm_handle, (void*) buffer, length);
485         if (ret > 0) {
486                 LOGI("[%s] (%d/%d) bytes written" ,__FUNCTION__, ret, length);
487                 return ret;
488         }
489         switch(ret)
490         {
491                 case MM_ERROR_SOUND_INVALID_STATE:
492                         ret = AUDIO_IO_ERROR_INVALID_OPERATION;
493                         LOGE("[%s] (0x%08x) : Not playing started yet.",(char*)__FUNCTION__, AUDIO_IO_ERROR_INVALID_OPERATION);
494                         break;
495                 default:
496                         ret = __convert_error_code(ret, (char*)__FUNCTION__);
497                         break;
498         }
499         return ret;
500 }
501
502
503 int audio_out_get_buffer_size(audio_out_h output, int *size)
504 {
505         AUDIO_IO_NULL_ARG_CHECK(output);
506         AUDIO_IO_NULL_ARG_CHECK(size);
507         audio_out_s *handle = (audio_out_s *) output;
508
509         *size = handle->_buffer_size;
510
511         LOGI("[%s] buffer size = %d",__FUNCTION__, *size);
512         return AUDIO_IO_ERROR_NONE;
513 }
514
515
516 int audio_out_get_sample_rate(audio_out_h output, int *sample_rate)
517 {
518         AUDIO_IO_NULL_ARG_CHECK(output);
519         AUDIO_IO_NULL_ARG_CHECK(sample_rate);
520         audio_out_s *handle = (audio_out_s *) output;
521
522         *sample_rate = handle->_sample_rate;
523
524         LOGI("[%s] sample rate = %d",__FUNCTION__, *sample_rate);
525         return AUDIO_IO_ERROR_NONE;
526 }
527
528
529 int audio_out_get_channel(audio_out_h output, audio_channel_e *channel)
530 {
531         AUDIO_IO_NULL_ARG_CHECK(output);
532         AUDIO_IO_NULL_ARG_CHECK(channel);
533         audio_out_s *handle = (audio_out_s *) output;
534
535         *channel = handle->_channel;
536
537         LOGI("[%s] channel = %d",__FUNCTION__, *channel);
538         return AUDIO_IO_ERROR_NONE;
539 }
540
541
542 int audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type)
543 {
544         AUDIO_IO_NULL_ARG_CHECK(output);
545         AUDIO_IO_NULL_ARG_CHECK(type);
546         audio_out_s *handle = (audio_out_s *) output;
547
548         *type = handle->_type;
549
550         LOGI("[%s] sample type = %d",__FUNCTION__, *type);
551         return AUDIO_IO_ERROR_NONE;
552 }
553
554
555 int audio_out_get_sound_type(audio_out_h output, sound_type_e *type)
556 {
557         AUDIO_IO_NULL_ARG_CHECK(output);
558         AUDIO_IO_NULL_ARG_CHECK(type);
559         audio_out_s *handle = (audio_out_s *) output;
560
561         *type = handle->_sound_type;
562
563         LOGI("[%s] sound type = %d",__FUNCTION__, *type);
564         return AUDIO_IO_ERROR_NONE;
565 }
566
567 int audio_out_set_interrupted_cb(audio_out_h output, audio_io_interrupted_cb callback, void *user_data)
568 {
569         AUDIO_IO_NULL_ARG_CHECK(output);
570         AUDIO_IO_NULL_ARG_CHECK(callback);
571         audio_out_s *handle = (audio_out_s *) output;
572
573         handle->user_cb = callback;
574         handle->user_data = user_data;
575
576         LOGI("[%s] current interrupted cb (%p) / data (%p)",__FUNCTION__, handle->user_cb, handle->user_data);
577         return AUDIO_IO_ERROR_NONE;
578 }
579
580 int audio_out_unset_interrupted_cb(audio_out_h output)
581 {
582         AUDIO_IO_NULL_ARG_CHECK(output);
583         audio_out_s *handle = (audio_out_s *) output;
584
585         handle->user_cb = NULL;
586         handle->user_data = NULL;
587
588         LOGI("[%s] current interrupted cb (%p) / data (%p)",__FUNCTION__, handle->user_cb, handle->user_data);
589         return AUDIO_IO_ERROR_NONE;
590 }