audio-io handles not supported stream type
[platform/core/api/audio-io.git] / src / cpp / cpp_audio_io.cpp
1 /*
2  * Copyright (c) 2015 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
18 #include "audio_io.h"
19 #include "cpp_audio_io.h"
20 #include "CAudioIODef.h"
21 #include <sound_manager_internal.h>
22
23
24 using namespace std;
25 using namespace tizen_media_audio;
26
27
28 /**
29  * Defines Structures
30  * type : struct
31  * Name : audio_io_interrupted_cb_s
32  * Declaration : Keeps user callback pointer and user data for delivering an interrupt event
33  */
34 typedef struct audio_io_interrupted_cb_s {
35     void* user_data;
36     audio_io_interrupted_cb onInterrupt;
37
38     audio_io_interrupted_cb_s() : user_data(NULL), onInterrupt(NULL)
39     {/* Empty Body */}
40 }   audio_io_interrupted_cb_s;
41
42 /**
43  * Defines Structures
44  * type : struct
45  * Name : audio_io_stream_cb_s
46  * Declaration : Keeps user callback pointer and user data for delivering an stream event
47  */
48 typedef struct audio_io_stream_cb_s {
49     void* user_data;
50     audio_in_stream_cb onStream;
51
52     audio_io_stream_cb_s() : user_data(NULL), onStream(NULL)
53     {/* Empty Body */}
54 }   audio_io_stream_cb_s;
55
56 /**
57  * Defines Structures
58  * type : struct
59  * Name : audio_io_state_changed_cb_s
60  * Declaration : Keeps user callback pointer and user data for delivering an state changed event
61  */
62 typedef struct audio_io_state_changed_cb_s {
63     void* user_data;
64     audio_in_state_changed_cb onStateChanged;
65
66     audio_io_state_changed_cb_s() : user_data(NULL), onStateChanged(NULL)
67     {/* Empty Body */}
68 }   audio_io_state_changed_cb_s;
69
70 /**
71  * Defines Structures
72  * type : struct
73  * Name : audio_io_s
74  * Declaration : An handle of AudioIO
75  * The handle has two struct for user callback
76  * And the handle has a pointer of private audioIO object
77  * The CAudioIO is a abstract class object about Input and Output
78  */
79 typedef struct audio_io_s {
80     CAudioIO*                    audioIoHandle;
81     audio_io_interrupted_cb_s    interrupt_callback;
82     audio_io_stream_cb_s         stream_callback;
83     audio_io_state_changed_cb_s  state_changed_callback;
84
85     audio_io_s() : audioIoHandle(NULL)
86     {/* Empty Body */}
87 }   audio_io_s;
88
89
90 /**
91  * Internal functions
92  */
93 static audio_io_error_e _convert_CAudioError(CAudioError& error) {
94     audio_io_error_e    ret = AUDIO_IO_ERROR_NONE;
95     CAudioError::EError err = error.getError();
96
97     switch (err)
98     {
99     case CAudioError::ERROR_NONE:
100         ret = AUDIO_IO_ERROR_NONE;
101         break;
102     case CAudioError::ERROR_INVALID_ARGUMENT:
103     case CAudioError::ERROR_INVALID_HANDLE:
104     case CAudioError::ERROR_INVALID_SAMPLERATE:
105     case CAudioError::ERROR_INVALID_CHANNEL:
106     case CAudioError::ERROR_INVALID_FORMAT:
107         ret = AUDIO_IO_ERROR_INVALID_PARAMETER;
108         break;
109     case CAudioError::ERROR_DEVICE_NOT_OPENED:
110         ret = AUDIO_IO_ERROR_DEVICE_NOT_OPENED;
111         break;
112     case CAudioError::ERROR_DEVICE_NOT_CLOSED:
113         ret = AUDIO_IO_ERROR_DEVICE_NOT_CLOSED;
114         break;
115     case CAudioError::ERROR_PERMISSION_DENIED:
116         ret = AUDIO_IO_ERROR_PERMISSION_DENIED;
117         break;
118     case CAudioError::ERROR_NOT_SUPPORTED:
119         ret = AUDIO_IO_ERROR_NOT_SUPPORTED;
120         break;
121     case CAudioError::ERROR_NOT_SUPPORTED_TYPE:
122         ret = AUDIO_IO_ERROR_NOT_SUPPORTED_TYPE;
123         break;
124     case CAudioError::ERROR_MAX:
125     case CAudioError::ERROR_INTERNAL_OPERATION:
126     case CAudioError::ERROR_NOT_INITIALIZED:
127     case CAudioError::ERROR_FAILED_OPERATION:
128     case CAudioError::ERROR_INVALID_OPERATION:
129         ret = AUDIO_IO_ERROR_INVALID_OPERATION;
130         break;
131     case CAudioError::ERROR_OUT_OF_MEMORY:
132     case CAudioError::ERROR_INVALID_POINTER:
133         ret = AUDIO_IO_ERROR_INVALID_BUFFER;
134         break;
135     case CAudioError::ERROR_POLICY_BLOCKED:
136     case CAudioError::ERROR_POLICY_INTERRUPTED:
137     case CAudioError::ERROR_POLICY_DUPLICATED:
138         ret = AUDIO_IO_ERROR_SOUND_POLICY;
139         break;
140     }
141
142     return ret;
143 }
144
145 static void _convert_channel_2_audio_info_channel(const audio_channel_e& src_channel, CAudioInfo::EChannel& dst_channel) {
146     switch (src_channel) {
147     case AUDIO_CHANNEL_MONO:
148         dst_channel = CAudioInfo::CHANNEL_MONO;
149         break;
150     case AUDIO_CHANNEL_STEREO:
151         dst_channel = CAudioInfo::CHANNEL_STEREO;
152         break;
153     default:
154         dst_channel = CAudioInfo::CHANNEL_MONO;
155     }
156 }
157
158 static void _convert_audio_info_channel_2_channel(const CAudioInfo::EChannel& src_channel, audio_channel_e& dst_channel) {
159     switch (src_channel) {
160     case CAudioInfo::CHANNEL_MONO:
161         dst_channel = AUDIO_CHANNEL_MONO;
162         break;
163     case CAudioInfo::CHANNEL_STEREO:
164         dst_channel = AUDIO_CHANNEL_STEREO;
165         break;
166     default:
167         dst_channel = AUDIO_CHANNEL_MONO;
168     }
169 }
170
171 static void _convert_sample_type_2_audio_info_sample_type(const audio_sample_type_e& src_type, CAudioInfo::ESampleType& dst_type) {
172     switch (src_type) {
173     case AUDIO_SAMPLE_TYPE_U8:
174         dst_type = CAudioInfo::SAMPLE_TYPE_U8;
175         break;
176     case AUDIO_SAMPLE_TYPE_S16_LE:
177         dst_type = CAudioInfo::SAMPLE_TYPE_S16_LE;
178         break;
179     default:
180         dst_type = CAudioInfo::SAMPLE_TYPE_U8;
181     }
182 }
183
184 static void _convert_audio_info_sample_type_2_sample_type(const CAudioInfo::ESampleType& src_type, audio_sample_type_e& dst_type) {
185     switch (src_type) {
186     case CAudioInfo::SAMPLE_TYPE_U8:
187         dst_type = AUDIO_SAMPLE_TYPE_U8;
188         break;
189     case CAudioInfo::SAMPLE_TYPE_S16_LE:
190         dst_type = AUDIO_SAMPLE_TYPE_S16_LE;
191         break;
192     default:
193         dst_type = AUDIO_SAMPLE_TYPE_U8;
194     }
195 }
196
197 static void _convert_sound_type_2_audio_info_audio_type(const sound_type_e& src_type, CAudioInfo::EAudioType& dst_type) {
198     switch (src_type) {
199     case SOUND_TYPE_SYSTEM:
200         dst_type = CAudioInfo::AUDIO_OUT_TYPE_SYSTEM;
201         break;
202     case SOUND_TYPE_NOTIFICATION:
203         dst_type = CAudioInfo::AUDIO_OUT_TYPE_NOTIFICATION;
204         break;
205     case SOUND_TYPE_ALARM:
206         dst_type = CAudioInfo::AUDIO_OUT_TYPE_ALARM;
207         break;
208     case SOUND_TYPE_RINGTONE:
209         dst_type = CAudioInfo::AUDIO_OUT_TYPE_RINGTONE_VOIP;
210         break;
211     case SOUND_TYPE_MEDIA:
212         dst_type = CAudioInfo::AUDIO_OUT_TYPE_MEDIA;
213         break;
214     case SOUND_TYPE_CALL:
215         dst_type = CAudioInfo::AUDIO_OUT_TYPE_SYSTEM;
216         break;
217     case SOUND_TYPE_VOIP:
218         dst_type = CAudioInfo::AUDIO_OUT_TYPE_VOIP;
219         break;
220     case SOUND_TYPE_VOICE:
221         dst_type = CAudioInfo::AUDIO_OUT_TYPE_VOICE_INFORMATION;
222         break;
223     default:
224         dst_type = CAudioInfo::AUDIO_OUT_TYPE_MEDIA;
225         break;
226     }
227 }
228
229 static void _convert_audio_info_audio_type_2_sound_type(const CAudioInfo::EAudioType& src_type, sound_type_e& dst_type) {
230     switch (src_type) {
231     case CAudioInfo::AUDIO_OUT_TYPE_MEDIA:
232         dst_type = SOUND_TYPE_MEDIA;
233         break;
234     case CAudioInfo::AUDIO_OUT_TYPE_SYSTEM:
235         dst_type = SOUND_TYPE_SYSTEM;
236         break;
237     case CAudioInfo::AUDIO_OUT_TYPE_ALARM:
238         dst_type = SOUND_TYPE_ALARM;
239         break;
240     case CAudioInfo::AUDIO_OUT_TYPE_NOTIFICATION:
241     case CAudioInfo::AUDIO_OUT_TYPE_EMERGENCY:
242         dst_type = SOUND_TYPE_NOTIFICATION;
243         break;
244     case CAudioInfo::AUDIO_OUT_TYPE_VOICE_INFORMATION:
245         dst_type = SOUND_TYPE_VOICE;
246         break;
247     case CAudioInfo::AUDIO_OUT_TYPE_RINGTONE_VOIP:
248         dst_type = SOUND_TYPE_RINGTONE;
249         break;
250     case CAudioInfo::AUDIO_OUT_TYPE_VOIP:
251         dst_type = SOUND_TYPE_VOIP;
252         break;
253     default:
254         dst_type = SOUND_TYPE_MEDIA;
255         break;
256     }
257 }
258
259 static audio_io_state_e _convert_state_type(const CAudioInfo::EAudioIOState src_state) {
260     audio_io_state_e dst_state;
261     switch (src_state) {
262     case CAudioInfo::AUDIO_IO_STATE_NONE:
263         dst_state = AUDIO_IO_STATE_IDLE;
264         break;
265     case CAudioInfo::AUDIO_IO_STATE_IDLE:
266         dst_state = AUDIO_IO_STATE_IDLE;
267         break;
268     case CAudioInfo::AUDIO_IO_STATE_RUNNING:
269         dst_state = AUDIO_IO_STATE_RUNNING;
270         break;
271     case CAudioInfo::AUDIO_IO_STATE_PAUSED:
272         dst_state = AUDIO_IO_STATE_PAUSED;
273         break;
274     default:
275         dst_state = AUDIO_IO_STATE_IDLE;
276     }
277     return dst_state;
278 }
279
280 static void _check_audio_param(int sample_rate, audio_channel_e channel, audio_sample_type_e type)  throw (CAudioError) {
281
282     if (sample_rate < 0) {
283         THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Invalid sample rate :%d", sample_rate);
284     }
285
286     if (channel != AUDIO_CHANNEL_MONO && channel != AUDIO_CHANNEL_STEREO) {
287         THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Invalid channel :%d", channel);
288     }
289
290     if (type != AUDIO_SAMPLE_TYPE_U8 && type != AUDIO_SAMPLE_TYPE_S16_LE) {
291         THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Invalid sample type :%d", type);
292     }
293 }
294
295 static void _check_audio_param(int sample_rate, audio_channel_e channel, audio_sample_type_e type, sound_type_e sound_type) throw (CAudioError) {
296
297     _check_audio_param(sample_rate, channel, type);
298
299     if (sound_type < SOUND_TYPE_SYSTEM || sound_type > SOUND_TYPE_VOICE) {
300         THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Invalid sound type : %d", sound_type);
301     }
302 }
303
304 static CAudioInfo _generate_audio_input_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type) throw (CAudioError) {
305     CAudioInfo::EChannel     dstChannel;
306     CAudioInfo::ESampleType dstSampleType;
307     CAudioInfo::EAudioType  dstAudioType = CAudioInfo::AUDIO_IN_TYPE_MEDIA;
308
309     _convert_channel_2_audio_info_channel(channel, dstChannel);
310     _convert_sample_type_2_audio_info_sample_type(sample_type, dstSampleType);
311
312     return CAudioInfo(sampleRate, dstChannel, dstSampleType, dstAudioType, -1);
313 }
314
315 static CAudioInfo _generate_audio_input_loopback_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type) throw (CAudioError) {
316     CAudioInfo::EChannel     dstChannel;
317     CAudioInfo::ESampleType dstSampleType;
318     CAudioInfo::EAudioType  dstAudioType = CAudioInfo::AUDIO_IN_TYPE_LOOPBACK;
319
320     _convert_channel_2_audio_info_channel(channel, dstChannel);
321     _convert_sample_type_2_audio_info_sample_type(sample_type, dstSampleType);
322
323     return CAudioInfo(sampleRate, dstChannel, dstSampleType, dstAudioType, -1);
324 }
325
326 static CAudioInfo _generate_audio_output_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type, sound_type_e sound_type) throw (CAudioError) {
327     CAudioInfo::EChannel     dstChannel;
328     CAudioInfo::ESampleType dstSampleType;
329     CAudioInfo::EAudioType  dstAudioType;
330
331     _convert_channel_2_audio_info_channel(channel, dstChannel);
332     _convert_sample_type_2_audio_info_sample_type(sample_type, dstSampleType);
333     _convert_sound_type_2_audio_info_audio_type(sound_type, dstAudioType);
334
335     return CAudioInfo(sampleRate, dstChannel, dstSampleType, dstAudioType, -1);
336 }
337
338 static audio_io_interrupted_code_e _convert_interrupted_code(IAudioSessionEventListener::EInterruptCode code) {
339     switch (code) {
340     case IAudioSessionEventListener::INTERRUPT_COMPLETED:
341         return AUDIO_IO_INTERRUPTED_COMPLETED;
342     case IAudioSessionEventListener::INTERRUPT_BY_CALL:
343         return AUDIO_IO_INTERRUPTED_BY_CALL;
344     case IAudioSessionEventListener::INTERRUPT_BY_EARJACK_UNPLUG:
345         return AUDIO_IO_INTERRUPTED_BY_EARJACK_UNPLUG;
346     case IAudioSessionEventListener::INTERRUPT_BY_RESOURCE_CONFLICT:
347         return AUDIO_IO_INTERRUPTED_BY_RESOURCE_CONFLICT;
348     case IAudioSessionEventListener::INTERRUPT_BY_ALARM:
349         return AUDIO_IO_INTERRUPTED_BY_ALARM;
350     case IAudioSessionEventListener::INTERRUPT_BY_EMERGENCY:
351         return AUDIO_IO_INTERRUPTED_BY_EMERGENCY;
352     case IAudioSessionEventListener::INTERRUPT_BY_NOTIFICATION:
353         return AUDIO_IO_INTERRUPTED_BY_NOTIFICATION;
354     case IAudioSessionEventListener::INTERRUPT_BY_MEDIA:
355     case IAudioSessionEventListener::INTERRUPT_MAX:
356     default:
357         return AUDIO_IO_INTERRUPTED_BY_MEDIA;
358     }
359 }
360
361 /**
362  * Implements CAPI functions
363  */
364 int cpp_audio_in_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_in_h *input) {
365     audio_io_s* handle = NULL;
366     try {
367         if (input == NULL) {
368             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
369         }
370
371         _check_audio_param(sample_rate, channel, type);
372
373         handle = new audio_io_s;
374         if (handle == NULL) {
375             THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed allocation handle");
376         }
377
378         CAudioInfo audioInfo = _generate_audio_input_info(sample_rate, channel, type);
379
380         handle->audioIoHandle = new CAudioInput(audioInfo);
381         if (handle == NULL) {
382             THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed allocation internal handle");
383         }
384
385         handle->audioIoHandle->initialize();
386
387         *input = handle;
388     } catch (CAudioError e) {
389         AUDIO_IO_LOGE("%s", e.getErrorMsg());
390
391         VALID_POINTER_START(handle)
392             SAFE_FINALIZE(handle->audioIoHandle);
393             SAFE_DELETE(handle->audioIoHandle);
394             SAFE_DELETE(handle);
395         VALID_POINTER_END
396
397         VALID_POINTER_START(input)
398             *input = NULL;
399         VALID_POINTER_END
400
401         return _convert_CAudioError(e);
402     }
403
404     return AUDIO_IO_ERROR_NONE;
405
406 }
407
408 int cpp_audio_in_create_loopback(int sample_rate, audio_channel_e channel, audio_sample_type_e type , audio_in_h* input) {
409     audio_io_s* handle = NULL;
410     try {
411         if (input == NULL) {
412             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
413         }
414
415         _check_audio_param(sample_rate, channel, type);
416
417         handle = new audio_io_s;
418         if (handle == NULL) {
419             THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed allocation handle");
420         }
421
422         CAudioInfo audioInfo = _generate_audio_input_loopback_info(sample_rate, channel, type);
423
424         handle->audioIoHandle = new CAudioInput(audioInfo);
425         if (handle == NULL) {
426             THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed allocation internal handle");
427         }
428
429         handle->audioIoHandle->initialize();
430
431         *input = handle;
432     } catch (CAudioError e) {
433         AUDIO_IO_LOGE("%s", e.getErrorMsg());
434
435         VALID_POINTER_START(handle)
436             SAFE_FINALIZE(handle->audioIoHandle);
437             SAFE_DELETE(handle->audioIoHandle);
438             SAFE_DELETE(handle);
439         VALID_POINTER_END
440
441         VALID_POINTER_START(input)
442             *input = NULL;
443         VALID_POINTER_END
444
445         return _convert_CAudioError(e);
446     }
447
448     return AUDIO_IO_ERROR_NONE;
449 }
450
451 int cpp_audio_in_destroy(audio_in_h input) {
452     audio_io_s* handle = static_cast<audio_io_s*>(input);
453
454     try {
455         if (handle == NULL) {
456             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
457         }
458
459         assert(handle->audioIoHandle);
460
461         SAFE_FINALIZE(handle->audioIoHandle);
462         SAFE_DELETE(handle->audioIoHandle);
463         SAFE_DELETE(handle);
464     } catch (CAudioError e) {
465         AUDIO_IO_LOGE("%s", e.getErrorMsg());
466         return _convert_CAudioError(e);
467     }
468
469     return AUDIO_IO_ERROR_NONE;
470 }
471
472 int cpp_audio_in_set_stream_info(audio_in_h input, sound_stream_info_h stream_info) {
473     audio_io_s* handle = static_cast<audio_io_s*>(input);
474
475     try {
476         if (handle == NULL || stream_info == NULL) {
477             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, stream_info:%p", input, stream_info);
478         }
479
480         assert(handle->audioIoHandle);
481
482         int errorCode = SOUND_MANAGER_ERROR_NONE;
483         CAudioInfo::EAudioType AudioType = CAudioInfo::AUDIO_IN_TYPE_MEDIA;
484         char *type = NULL;
485         int index = -1;
486
487         if ((errorCode = sound_manager_get_type_from_stream_information (stream_info, &type)) != SOUND_MANAGER_ERROR_NONE) {
488             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->stream_type is invalid [ret:%d]", errorCode);
489         }
490         handle->audioIoHandle->getAudioInfo().convertInputStreamType2AudioType(type, &AudioType);
491         handle->audioIoHandle->getAudioInfo().setAudioType(AudioType);
492
493         if ((errorCode = sound_manager_get_index_from_stream_information (stream_info, &index)) != SOUND_MANAGER_ERROR_NONE) {
494             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->index is invalid [ret:%d]", errorCode);
495         }
496         handle->audioIoHandle->getAudioInfo().setAudioIndex(index);
497     } catch (CAudioError e) {
498         AUDIO_IO_LOGE("%s", e.getErrorMsg());
499         return _convert_CAudioError(e);
500     }
501
502     return AUDIO_IO_ERROR_NONE;
503 }
504
505 int cpp_audio_in_prepare(audio_in_h input) {
506     audio_io_s* handle = static_cast<audio_io_s*>(input);
507
508     try {
509         if (handle == NULL) {
510             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
511         }
512
513         assert(handle->audioIoHandle);
514
515         handle->audioIoHandle->prepare();
516     } catch (CAudioError e) {
517         AUDIO_IO_LOGE("%s", e.getErrorMsg());
518         return _convert_CAudioError(e);
519     }
520
521     return AUDIO_IO_ERROR_NONE;
522 }
523
524 int cpp_audio_in_unprepare(audio_in_h input) {
525     audio_io_s* handle = static_cast<audio_io_s*>(input);
526
527     try {
528         if (handle == NULL) {
529             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
530         }
531
532         assert(handle->audioIoHandle);
533
534         handle->audioIoHandle->unprepare();
535     } catch (CAudioError e) {
536         AUDIO_IO_LOGE("%s", e.getErrorMsg());
537         return _convert_CAudioError(e);
538     }
539
540     return AUDIO_IO_ERROR_NONE;
541 }
542
543 int cpp_audio_in_pause(audio_in_h input) {
544     audio_io_s* handle = static_cast<audio_io_s*>(input);
545
546     try {
547         if (handle == NULL) {
548             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
549         }
550
551         assert(handle->audioIoHandle);
552
553         handle->audioIoHandle->pause();
554     } catch (CAudioError e) {
555         AUDIO_IO_LOGE("%s", e.getErrorMsg());
556         return _convert_CAudioError(e);
557     }
558
559     return AUDIO_IO_ERROR_NONE;
560 }
561
562 int cpp_audio_in_resume(audio_in_h input) {
563     audio_io_s* handle = static_cast<audio_io_s*>(input);
564
565     try {
566         if (handle == NULL) {
567             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
568         }
569
570         assert(handle->audioIoHandle);
571
572         handle->audioIoHandle->resume();
573     } catch (CAudioError e) {
574         AUDIO_IO_LOGE("%s", e.getErrorMsg());
575         return _convert_CAudioError(e);
576     }
577
578     return AUDIO_IO_ERROR_NONE;
579 }
580
581 int cpp_audio_in_drain(audio_in_h input) {
582     audio_io_s* handle = static_cast<audio_io_s*>(input);
583
584     try {
585         if (handle == NULL) {
586             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
587         }
588
589         assert(handle->audioIoHandle);
590
591         handle->audioIoHandle->drain();
592     } catch (CAudioError e) {
593         AUDIO_IO_LOGE("%s", e.getErrorMsg());
594         return _convert_CAudioError(e);
595     }
596
597     return AUDIO_IO_ERROR_NONE;
598 }
599
600 int cpp_audio_in_flush(audio_in_h input) {
601     audio_io_s* handle = static_cast<audio_io_s*>(input);
602
603     try {
604         if (handle == NULL) {
605             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
606         }
607
608         assert(handle->audioIoHandle);
609
610         handle->audioIoHandle->flush();
611     } catch (CAudioError e) {
612         AUDIO_IO_LOGE("%s", e.getErrorMsg());
613         return _convert_CAudioError(e);
614     }
615
616     return AUDIO_IO_ERROR_NONE;
617 }
618
619 int cpp_audio_in_read(audio_in_h input, void *buffer, unsigned int length) {
620     audio_io_s* handle = static_cast<audio_io_s*>(input);
621     int ret = 0;
622
623     try {
624         if (handle == NULL || buffer == NULL) {
625             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, buffer:%p", input, buffer);
626         }
627
628         assert(handle->audioIoHandle);
629
630         CAudioInput* inputHandle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
631         size_t readn = inputHandle->read(buffer, static_cast<size_t>(length));
632         ret = static_cast<int>(readn);
633 #ifdef _AUDIO_IO_DEBUG_TIMING_
634         AUDIO_IO_LOGD("readn:%d", readn);
635 #endif
636     } catch (CAudioError e) {
637         AUDIO_IO_LOGE("%s", e.getErrorMsg());
638         return _convert_CAudioError(e);
639     }
640
641     return ret;
642 }
643
644 int cpp_audio_in_get_buffer_size(audio_in_h input, int *size) {
645     audio_io_s* handle = static_cast<audio_io_s*>(input);
646
647     try {
648         if (handle == NULL || size == NULL) {
649             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, size:%p", input, size);
650         }
651
652         assert(handle->audioIoHandle);
653
654         CAudioIO* inputHandle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
655         *size = inputHandle->getBufferSize();
656     } catch (CAudioError e) {
657         AUDIO_IO_LOGE("%s", e.getErrorMsg());
658         return _convert_CAudioError(e);
659     }
660
661     return AUDIO_IO_ERROR_NONE;
662 }
663
664 int cpp_audio_in_get_sample_rate(audio_in_h input, int *sample_rate) {
665     audio_io_s* handle = static_cast<audio_io_s*>(input);
666
667     try {
668         if (handle == NULL || sample_rate == NULL) {
669             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, sample_rate:%p", input, sample_rate);
670         }
671
672         assert(handle->audioIoHandle);
673         *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
674     } catch (CAudioError e) {
675         AUDIO_IO_LOGE("%s", e.getErrorMsg());
676         return _convert_CAudioError(e);
677     }
678
679     return AUDIO_IO_ERROR_NONE;
680 }
681
682 int cpp_audio_in_get_channel(audio_in_h input, audio_channel_e *channel) {
683     audio_io_s* handle = static_cast<audio_io_s*>(input);
684
685     try {
686         if (handle == NULL || channel == NULL) {
687             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, channel:%p", input, channel);
688         }
689
690         assert(handle->audioIoHandle);
691
692         const CAudioInfo::EChannel srcChannel = handle->audioIoHandle->getAudioInfo().getChannel();
693         audio_channel_e dstChannel = AUDIO_CHANNEL_MONO;
694         _convert_audio_info_channel_2_channel(srcChannel, dstChannel);
695
696         *channel = dstChannel;
697     } catch (CAudioError e) {
698         AUDIO_IO_LOGE("%s", e.getErrorMsg());
699         return _convert_CAudioError(e);
700     }
701
702     return AUDIO_IO_ERROR_NONE;
703 }
704
705 int cpp_audio_in_get_sample_type(audio_in_h input, audio_sample_type_e *type) {
706     audio_io_s* handle = static_cast<audio_io_s*>(input);
707
708     try {
709         if (handle == NULL || type == NULL) {
710             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, type:%p", input, type);
711         }
712
713         assert(handle->audioIoHandle);
714
715         const CAudioInfo::ESampleType srcSampleType = handle->audioIoHandle->getAudioInfo().getSampleType();
716         audio_sample_type_e     dstSampleType = AUDIO_SAMPLE_TYPE_U8;
717         _convert_audio_info_sample_type_2_sample_type(srcSampleType, dstSampleType);
718
719         *type = dstSampleType;
720     } catch (CAudioError e) {
721         AUDIO_IO_LOGE("%s", e.getErrorMsg());
722         return _convert_CAudioError(e);
723     }
724
725     return AUDIO_IO_ERROR_NONE;
726 }
727
728 static void _interrupt_cb_internal(IAudioSessionEventListener::EInterruptCode _code, void* user_data) {
729     audio_io_s* handle = static_cast<audio_io_s*>(user_data);
730     audio_io_interrupted_code_e code = _convert_interrupted_code(_code);
731
732     assert(handle);
733
734     if (handle->interrupt_callback.onInterrupt != NULL) {
735         handle->interrupt_callback.onInterrupt(code, handle->interrupt_callback.user_data);
736     }
737 }
738
739 int cpp_audio_in_set_interrupted_cb(audio_in_h input, audio_io_interrupted_cb callback, void *user_data) {
740     audio_io_s* handle = static_cast<audio_io_s*>(input);
741
742     try {
743         if (handle == NULL || callback == NULL) {
744             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, callback:%p", input, callback);
745         }
746
747         assert(handle->audioIoHandle);
748
749         handle->interrupt_callback.onInterrupt = callback;
750         handle->interrupt_callback.user_data    = user_data;
751
752         CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
753         cb.mUserData   = static_cast<void*>(handle);
754         cb.onInterrupt = _interrupt_cb_internal;
755
756         handle->audioIoHandle->setInterruptCallback(cb);
757     } catch (CAudioError e) {
758         AUDIO_IO_LOGE("%s", e.getErrorMsg());
759         return _convert_CAudioError(e);
760     }
761
762     return AUDIO_IO_ERROR_NONE;
763 }
764
765 int cpp_audio_in_unset_interrupted_cb(audio_in_h input) {
766     audio_io_s* handle = static_cast<audio_io_s*>(input);
767
768     try {
769         if (handle == NULL) {
770             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
771         }
772
773         assert(handle->audioIoHandle);
774
775         handle->interrupt_callback.onInterrupt = NULL;
776         handle->interrupt_callback.user_data    = NULL;
777
778         CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
779         cb.mUserData   = NULL;
780         cb.onInterrupt = NULL;
781
782         handle->audioIoHandle->setInterruptCallback(cb);
783     } catch (CAudioError e) {
784         AUDIO_IO_LOGE("%s", e.getErrorMsg());
785         return _convert_CAudioError(e);
786     }
787
788     return AUDIO_IO_ERROR_NONE;
789 }
790
791 int cpp_audio_in_ignore_session(audio_in_h input) {
792     audio_io_s* handle = static_cast<audio_io_s*>(input);
793
794     try {
795         if (handle == NULL) {
796             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
797         }
798
799         if (handle->stream_callback.onStream) {
800             THROW_ERROR_MSG(CAudioError::ERROR_INVALID_OPERATION, "Not support ignore session in async mode");
801         }
802
803         assert(handle->audioIoHandle);
804
805         handle->audioIoHandle->ignoreSession();
806     } catch (CAudioError e) {
807         AUDIO_IO_LOGE("%s", e.getErrorMsg());
808         return _convert_CAudioError(e);
809     }
810
811     return AUDIO_IO_ERROR_NONE;
812 }
813
814 static void _stream_cb_internal(size_t nbytes, void *user_data) {
815     audio_io_s* audioIo = static_cast<audio_io_s*>(user_data);
816     assert(audioIo);
817
818     if (audioIo->stream_callback.onStream != NULL) {
819         audioIo->stream_callback.onStream(audioIo, nbytes, audioIo->stream_callback.user_data);
820     }
821 }
822
823 static void _state_changed_cb_internal(CAudioInfo::EAudioIOState state, CAudioInfo::EAudioIOState state_prev, bool by_policy, void *user_data) {
824     audio_io_s* audioIo = static_cast<audio_io_s*>(user_data);
825     assert(audioIo);
826
827     if (audioIo->state_changed_callback.onStateChanged != NULL) {
828         audioIo->state_changed_callback.onStateChanged(audioIo, _convert_state_type(state_prev), _convert_state_type(state), by_policy, audioIo->state_changed_callback.user_data);
829     }
830 }
831
832 int cpp_audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* user_data) {
833     audio_io_s* handle = static_cast<audio_io_s*>(input);
834
835     try {
836         if (handle == NULL || callback == NULL) {
837             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, callback:%p", input, callback);
838         }
839
840         assert(handle->audioIoHandle);
841
842         handle->stream_callback.onStream = callback;
843         handle->stream_callback.user_data = user_data;
844
845         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
846         cb.mUserData = static_cast<void*>(handle);
847         cb.onStream  = _stream_cb_internal;
848
849         handle->audioIoHandle->setStreamCallback(cb);
850     } catch (CAudioError e) {
851         AUDIO_IO_LOGE("%s", e.getErrorMsg());
852         return _convert_CAudioError(e);
853     }
854
855     return AUDIO_IO_ERROR_NONE;
856 }
857
858 int cpp_audio_in_unset_stream_cb(audio_in_h input) {
859     audio_io_s* handle = static_cast<audio_io_s*>(input);
860
861     try {
862         if (handle == NULL) {
863             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
864         }
865
866         assert(handle->audioIoHandle);
867
868         handle->stream_callback.onStream = NULL;
869         handle->stream_callback.user_data = NULL;
870
871         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
872         cb.mUserData = NULL;
873         cb.onStream  = NULL;
874
875         handle->audioIoHandle->setStreamCallback(cb);
876     } catch (CAudioError e) {
877         AUDIO_IO_LOGE("%s", e.getErrorMsg());
878         return _convert_CAudioError(e);
879     }
880
881     return AUDIO_IO_ERROR_NONE;
882 }
883
884 int cpp_audio_in_peek(audio_in_h input, const void **buffer, unsigned int *length) {
885     audio_io_s* handle = static_cast<audio_io_s*>(input);
886
887     try {
888         if (handle == NULL || buffer == NULL) {
889             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, buffer:%p", input, buffer);
890         }
891
892         CAudioInput* inputHandle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
893         assert(inputHandle);
894
895         inputHandle->peek(buffer, (size_t*)length);
896     } catch (CAudioError e) {
897         AUDIO_IO_LOGE("%s", e.getErrorMsg());
898         return _convert_CAudioError(e);
899     }
900
901     return AUDIO_IO_ERROR_NONE;
902 }
903
904 int cpp_audio_in_drop(audio_in_h input) {
905     audio_io_s* handle = static_cast<audio_io_s*>(input);
906
907     try {
908         if (handle == NULL) {
909             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
910         }
911
912         CAudioInput* inputHandle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
913         assert(inputHandle);
914
915         inputHandle->drop();
916     } catch (CAudioError e) {
917         AUDIO_IO_LOGE("%s", e.getErrorMsg());
918         return _convert_CAudioError(e);
919     }
920
921     return AUDIO_IO_ERROR_NONE;
922 }
923
924 int cpp_audio_in_set_state_changed_cb(audio_in_h input, audio_in_state_changed_cb callback, void* user_data) {
925     audio_io_s* handle = static_cast<audio_io_s*>(input);
926
927     try {
928         if (handle == NULL || callback == NULL) {
929             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, callback:%p", input, callback);
930         }
931
932         assert(handle->audioIoHandle);
933
934         handle->state_changed_callback.onStateChanged = callback;
935         handle->state_changed_callback.user_data = user_data;
936
937         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
938         cb.mUserData = static_cast<void*>(handle);
939         cb.onStateChanged = _state_changed_cb_internal;
940
941         handle->audioIoHandle->setStateChangedCallback(cb);
942     } catch (CAudioError e) {
943         AUDIO_IO_LOGE("%s", e.getErrorMsg());
944         return _convert_CAudioError(e);
945     }
946
947     return AUDIO_IO_ERROR_NONE;
948 }
949
950 int cpp_audio_in_unset_state_changed_cb(audio_in_h input) {
951     audio_io_s* handle = static_cast<audio_io_s*>(input);
952
953     try {
954         if (handle == NULL) {
955             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", input);
956         }
957
958         assert(handle->audioIoHandle);
959
960         handle->state_changed_callback.onStateChanged = NULL;
961         handle->state_changed_callback.user_data = NULL;
962
963         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
964         cb.mUserData = NULL;
965         cb.onStateChanged  = NULL;
966
967         handle->audioIoHandle->setStateChangedCallback(cb);
968     } catch (CAudioError e) {
969         AUDIO_IO_LOGE("%s", e.getErrorMsg());
970         return _convert_CAudioError(e);
971     }
972
973     return AUDIO_IO_ERROR_NONE;
974 }
975
976
977 /**
978  * Audio Out
979  */
980 int cpp_audio_out_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, sound_type_e sound_type, audio_out_h *output) {
981     audio_io_s* handle = NULL;
982     try {
983         if (output == NULL) {
984             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
985         }
986
987         _check_audio_param(sample_rate, channel, type, sound_type);
988
989         handle = new audio_io_s;
990         if (handle == NULL) {
991             THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed allocation handle");
992         }
993
994         CAudioInfo audioInfo = _generate_audio_output_info(sample_rate, channel, type, sound_type);
995
996         handle->audioIoHandle = new CAudioOutput(audioInfo);
997         if (handle == NULL) {
998             THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed allocation internal handle");
999         }
1000
1001         handle->audioIoHandle->initialize();
1002
1003         *output = handle;
1004     } catch (CAudioError e) {
1005         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1006
1007         VALID_POINTER_START(handle)
1008             SAFE_FINALIZE(handle->audioIoHandle);
1009             SAFE_DELETE(handle->audioIoHandle);
1010             SAFE_DELETE(handle);
1011         VALID_POINTER_END
1012
1013         VALID_POINTER_START(output)
1014             *output = NULL;
1015         VALID_POINTER_END
1016
1017         return _convert_CAudioError(e);
1018     }
1019
1020     return AUDIO_IO_ERROR_NONE;
1021 }
1022
1023 int cpp_audio_out_create_new(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_out_h *output) {
1024     audio_io_s* handle = NULL;
1025     try {
1026         if (output == NULL) {
1027             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
1028         }
1029
1030         _check_audio_param(sample_rate, channel, type, SOUND_TYPE_SYSTEM /*default check */);
1031
1032         handle = new audio_io_s;
1033         if (handle == NULL) {
1034             THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed allocation handle");
1035         }
1036
1037         CAudioInfo audioInfo = _generate_audio_output_info(sample_rate, channel, type, SOUND_TYPE_MEDIA /* default sound_type */);
1038
1039         handle->audioIoHandle = new CAudioOutput(audioInfo);
1040         if (handle == NULL) {
1041             THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed allocation internal handle");
1042         }
1043
1044         handle->audioIoHandle->initialize();
1045
1046         *output = handle;
1047     } catch (CAudioError e) {
1048         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1049
1050         VALID_POINTER_START(handle)
1051             SAFE_FINALIZE(handle->audioIoHandle);
1052             SAFE_DELETE(handle->audioIoHandle);
1053             SAFE_DELETE(handle);
1054         VALID_POINTER_END
1055
1056         VALID_POINTER_START(output)
1057             *output = NULL;
1058         VALID_POINTER_END
1059
1060         return _convert_CAudioError(e);
1061     }
1062
1063     return AUDIO_IO_ERROR_NONE;
1064 }
1065
1066 int cpp_audio_out_destroy(audio_out_h output) {
1067     audio_io_s* handle = static_cast<audio_io_s*>(output);
1068
1069     try {
1070         if (handle == NULL) {
1071             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
1072         }
1073
1074         assert(handle->audioIoHandle);
1075
1076         SAFE_FINALIZE(handle->audioIoHandle);
1077         SAFE_DELETE(handle->audioIoHandle);
1078         SAFE_DELETE(handle);
1079     } catch (CAudioError e) {
1080         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1081         return _convert_CAudioError(e);
1082     }
1083
1084     return AUDIO_IO_ERROR_NONE;
1085 }
1086
1087 int cpp_audio_out_set_stream_info(audio_out_h output, sound_stream_info_h stream_info) {
1088     audio_io_s* handle = static_cast<audio_io_s*>(output);
1089
1090     try {
1091         if (handle == NULL || stream_info == NULL) {
1092             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, stream_info:%p", output, stream_info);
1093         }
1094
1095         assert(handle->audioIoHandle);
1096
1097         int errorCode = SOUND_MANAGER_ERROR_NONE;
1098         CAudioInfo::EAudioType AudioType = CAudioInfo::AUDIO_OUT_TYPE_MEDIA;
1099         char *type = NULL;
1100         int index = -1;
1101
1102         if ((errorCode = sound_manager_get_type_from_stream_information (stream_info, &type)) != SOUND_MANAGER_ERROR_NONE) {
1103             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->stream_type is invalid [ret:%d]", errorCode);
1104         }
1105         handle->audioIoHandle->getAudioInfo().convertOutputStreamType2AudioType(type, &AudioType);
1106         handle->audioIoHandle->getAudioInfo().setAudioType(AudioType);
1107
1108         if ((errorCode = sound_manager_get_index_from_stream_information (stream_info, &index)) != SOUND_MANAGER_ERROR_NONE) {
1109             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->index is invalid [ret:%d]", errorCode);
1110         }
1111         handle->audioIoHandle->getAudioInfo().setAudioIndex(index);
1112     } catch (CAudioError e) {
1113         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1114         return _convert_CAudioError(e);
1115     }
1116
1117     return AUDIO_IO_ERROR_NONE;
1118 }
1119
1120 int cpp_audio_out_prepare(audio_out_h output) {
1121     audio_io_s* handle = static_cast<audio_io_s*>(output);
1122
1123     try {
1124         if (handle == NULL) {
1125             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
1126         }
1127
1128         assert(handle->audioIoHandle);
1129
1130         handle->audioIoHandle->prepare();
1131     } catch (CAudioError e) {
1132         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1133         return _convert_CAudioError(e);
1134     }
1135
1136     return AUDIO_IO_ERROR_NONE;
1137 }
1138
1139 int cpp_audio_out_unprepare(audio_out_h output) {
1140     audio_io_s* handle = static_cast<audio_io_s*>(output);
1141
1142     try {
1143         if (handle == NULL) {
1144             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
1145         }
1146
1147         assert(handle->audioIoHandle);
1148
1149         handle->audioIoHandle->unprepare();
1150     } catch (CAudioError e) {
1151         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1152         return _convert_CAudioError(e);
1153     }
1154
1155     return AUDIO_IO_ERROR_NONE;
1156 }
1157
1158 int cpp_audio_out_pause(audio_out_h output) {
1159     audio_io_s* handle = static_cast<audio_io_s*>(output);
1160
1161     try {
1162         if (handle == NULL) {
1163             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
1164         }
1165
1166         assert(handle->audioIoHandle);
1167
1168         handle->audioIoHandle->pause();
1169     } catch (CAudioError e) {
1170         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1171         return _convert_CAudioError(e);
1172     }
1173
1174     return AUDIO_IO_ERROR_NONE;
1175 }
1176
1177 int cpp_audio_out_resume(audio_out_h output) {
1178     audio_io_s* handle = static_cast<audio_io_s*>(output);
1179
1180     try {
1181         if (handle == NULL) {
1182             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
1183         }
1184
1185         assert(handle->audioIoHandle);
1186
1187         handle->audioIoHandle->resume();
1188     } catch (CAudioError e) {
1189         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1190         return _convert_CAudioError(e);
1191     }
1192
1193     return AUDIO_IO_ERROR_NONE;
1194 }
1195
1196 int cpp_audio_out_drain(audio_out_h output) {
1197     audio_io_s* handle = static_cast<audio_io_s*>(output);
1198
1199     try {
1200         if (handle == NULL) {
1201             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
1202         }
1203
1204         assert(handle->audioIoHandle);
1205
1206         handle->audioIoHandle->drain();
1207     } catch (CAudioError e) {
1208         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1209         return _convert_CAudioError(e);
1210     }
1211
1212     return AUDIO_IO_ERROR_NONE;
1213 }
1214
1215 int cpp_audio_out_flush(audio_out_h output) {
1216     audio_io_s* handle = static_cast<audio_io_s*>(output);
1217
1218     try {
1219         if (handle == NULL) {
1220             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
1221         }
1222
1223         assert(handle->audioIoHandle);
1224
1225         handle->audioIoHandle->flush();
1226     } catch (CAudioError e) {
1227         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1228         return _convert_CAudioError(e);
1229     }
1230
1231     return AUDIO_IO_ERROR_NONE;
1232 }
1233
1234 int cpp_audio_out_write(audio_out_h output, void *buffer, unsigned int length) {
1235     audio_io_s* handle = static_cast<audio_io_s*>(output);
1236     int ret = 0;
1237
1238     try {
1239         if (handle == NULL || buffer == NULL) {
1240             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p, buffer:%p", output, buffer);
1241         }
1242
1243         assert(handle->audioIoHandle);
1244
1245         CAudioOutput* outputHandle = dynamic_cast<CAudioOutput*>(handle->audioIoHandle);
1246         size_t writen = outputHandle->write(buffer, static_cast<size_t>(length));
1247         ret = static_cast<int>(writen);
1248 #ifdef _AUDIO_IO_DEBUG_TIMING_
1249         AUDIO_IO_LOGD("writen:%d", writen);
1250 #endif
1251     } catch (CAudioError e) {
1252         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1253         return _convert_CAudioError(e);
1254     }
1255
1256     return ret;
1257 }
1258
1259 int cpp_audio_out_get_buffer_size(audio_out_h output, int *size) {
1260     audio_io_s* handle = static_cast<audio_io_s*>(output);
1261
1262     try {
1263         if (handle == NULL || size == NULL) {
1264             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, size:%p", output, size);
1265         }
1266
1267         assert(handle->audioIoHandle);
1268
1269         CAudioOutput* outputHandle = dynamic_cast<CAudioOutput*>(handle->audioIoHandle);
1270         *size = outputHandle->getBufferSize();
1271     } catch (CAudioError e) {
1272         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1273         return _convert_CAudioError(e);
1274     }
1275
1276     return AUDIO_IO_ERROR_NONE;
1277 }
1278
1279 int cpp_audio_out_get_sample_rate(audio_out_h output, int *sample_rate) {
1280     audio_io_s* handle = static_cast<audio_io_s*>(output);
1281
1282     try {
1283         if (handle == NULL || sample_rate == NULL) {
1284             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, sample_rate:%p", output, sample_rate);
1285         }
1286
1287         assert(handle->audioIoHandle);
1288         *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
1289     } catch (CAudioError e) {
1290         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1291         return _convert_CAudioError(e);
1292     }
1293
1294     return AUDIO_IO_ERROR_NONE;
1295 }
1296
1297 int cpp_audio_out_get_channel(audio_out_h output, audio_channel_e *channel) {
1298     audio_io_s* handle = static_cast<audio_io_s*>(output);
1299
1300     try {
1301         if (handle == NULL || channel == NULL) {
1302             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, channel:%p", output, channel);
1303         }
1304
1305         assert(handle->audioIoHandle);
1306
1307         const CAudioInfo::EChannel srcChannel = handle->audioIoHandle->getAudioInfo().getChannel();
1308         audio_channel_e dstChannel = AUDIO_CHANNEL_MONO;
1309         _convert_audio_info_channel_2_channel(srcChannel, dstChannel);
1310
1311         *channel = dstChannel;
1312     } catch (CAudioError e) {
1313         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1314         return _convert_CAudioError(e);
1315     }
1316
1317     return AUDIO_IO_ERROR_NONE;
1318 }
1319
1320 int cpp_audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type) {
1321     audio_io_s* handle = static_cast<audio_io_s*>(output);
1322
1323     try {
1324         if (handle == NULL || type == NULL) {
1325             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, type:%p", output, type);
1326         }
1327
1328         assert(handle->audioIoHandle);
1329
1330         const CAudioInfo::ESampleType srcSampleType = handle->audioIoHandle->getAudioInfo().getSampleType();
1331         audio_sample_type_e     dstSampleType = AUDIO_SAMPLE_TYPE_U8;
1332         _convert_audio_info_sample_type_2_sample_type(srcSampleType, dstSampleType);
1333
1334         *type = dstSampleType;
1335     } catch (CAudioError e) {
1336         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1337         return _convert_CAudioError(e);
1338     }
1339
1340     return AUDIO_IO_ERROR_NONE;
1341 }
1342
1343 int cpp_audio_out_get_sound_type(audio_out_h output, sound_type_e *type) {
1344     audio_io_s* handle = static_cast<audio_io_s*>(output);
1345
1346     try {
1347         if (handle == NULL || type == NULL) {
1348             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, type:%p", output, type);
1349         }
1350
1351         assert(handle->audioIoHandle);
1352
1353         const CAudioInfo::EAudioType srcAudioType = handle->audioIoHandle->getAudioInfo().getAudioType();
1354         sound_type_e                 dstSoundType = SOUND_TYPE_MEDIA;
1355         _convert_audio_info_audio_type_2_sound_type(srcAudioType, dstSoundType);
1356
1357         *type = dstSoundType;
1358     } catch (CAudioError e) {
1359         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1360         return _convert_CAudioError(e);
1361     }
1362
1363     return AUDIO_IO_ERROR_NONE;
1364 }
1365
1366 int cpp_audio_out_set_interrupted_cb(audio_out_h output, audio_io_interrupted_cb callback, void *user_data) {
1367     audio_io_s* handle = static_cast<audio_io_s*>(output);
1368
1369     try {
1370         if (handle == NULL || callback == NULL) {
1371             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, callback:%p", output, callback);
1372         }
1373
1374         assert(handle->audioIoHandle);
1375
1376         handle->interrupt_callback.onInterrupt = callback;
1377         handle->interrupt_callback.user_data    = user_data;
1378
1379         CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
1380         cb.mUserData   = static_cast<void*>(handle);
1381         cb.onInterrupt = _interrupt_cb_internal;
1382
1383         handle->audioIoHandle->setInterruptCallback(cb);
1384     } catch (CAudioError e) {
1385         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1386         return _convert_CAudioError(e);
1387     }
1388
1389     return AUDIO_IO_ERROR_NONE;
1390 }
1391
1392 int cpp_audio_out_unset_interrupted_cb(audio_out_h output) {
1393     audio_io_s* handle = static_cast<audio_io_s*>(output);
1394
1395     try {
1396         if (handle == NULL) {
1397             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
1398         }
1399
1400         assert(handle->audioIoHandle);
1401
1402         handle->interrupt_callback.onInterrupt = NULL;
1403         handle->interrupt_callback.user_data    = NULL;
1404
1405         CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
1406         cb.mUserData   = NULL;
1407         cb.onInterrupt = NULL;
1408
1409         handle->audioIoHandle->setInterruptCallback(cb);
1410     } catch (CAudioError e) {
1411         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1412         return _convert_CAudioError(e);
1413     }
1414
1415     return AUDIO_IO_ERROR_NONE;
1416 }
1417
1418 int cpp_audio_out_ignore_session(audio_out_h output) {
1419     audio_io_s* handle = static_cast<audio_io_s*>(output);
1420
1421     try {
1422         if (handle == NULL) {
1423             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
1424         }
1425
1426         if (handle->stream_callback.onStream) {
1427             THROW_ERROR_MSG(CAudioError::ERROR_INVALID_OPERATION, "Not support ignore session in async mode");
1428         }
1429
1430         assert(handle->audioIoHandle);
1431
1432         handle->audioIoHandle->ignoreSession();
1433     } catch (CAudioError e) {
1434         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1435         return _convert_CAudioError(e);
1436     }
1437
1438     return AUDIO_IO_ERROR_NONE;
1439 }
1440
1441 int cpp_audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* user_data) {
1442     audio_io_s* handle = static_cast<audio_io_s*>(output);
1443
1444     try {
1445         if (handle == NULL || callback == NULL) {
1446             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, callback:%p", output, callback);
1447         }
1448
1449         assert(handle->audioIoHandle);
1450
1451         handle->stream_callback.onStream = callback;
1452         handle->stream_callback.user_data = user_data;
1453
1454         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
1455         cb.mUserData = static_cast<void*>(handle);
1456         cb.onStream  = _stream_cb_internal;
1457
1458         handle->audioIoHandle->setStreamCallback(cb);
1459     } catch (CAudioError e) {
1460         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1461         return _convert_CAudioError(e);
1462     }
1463
1464     return AUDIO_IO_ERROR_NONE;
1465 }
1466
1467 int cpp_audio_out_unset_stream_cb(audio_out_h output) {
1468     audio_io_s* handle = static_cast<audio_io_s*>(output);
1469
1470     try {
1471         if (handle == NULL) {
1472             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
1473         }
1474
1475         assert(handle->audioIoHandle);
1476
1477         handle->stream_callback.onStream = NULL;
1478         handle->stream_callback.user_data = NULL;
1479
1480         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
1481         cb.mUserData = NULL;
1482         cb.onStream  = NULL;
1483
1484         handle->audioIoHandle->setStreamCallback(cb);
1485     } catch (CAudioError e) {
1486         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1487         return _convert_CAudioError(e);
1488     }
1489
1490     return AUDIO_IO_ERROR_NONE;
1491 }
1492
1493 int cpp_audio_out_set_state_changed_cb(audio_out_h output, audio_in_state_changed_cb callback, void* user_data) {
1494     audio_io_s* handle = static_cast<audio_io_s*>(output);
1495
1496     try {
1497         if (handle == NULL || callback == NULL) {
1498             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, callback:%p", output, callback);
1499         }
1500
1501         assert(handle->audioIoHandle);
1502
1503         handle->state_changed_callback.onStateChanged = callback;
1504         handle->state_changed_callback.user_data = user_data;
1505
1506         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
1507         cb.mUserData = static_cast<void*>(handle);
1508         cb.onStateChanged = _state_changed_cb_internal;
1509
1510         handle->audioIoHandle->setStateChangedCallback(cb);
1511     } catch (CAudioError e) {
1512         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1513         return _convert_CAudioError(e);
1514     }
1515
1516     return AUDIO_IO_ERROR_NONE;
1517 }
1518
1519 int cpp_audio_out_unset_state_changed_cb(audio_out_h output) {
1520     audio_io_s* handle = static_cast<audio_io_s*>(output);
1521
1522     try {
1523         if (handle == NULL) {
1524             THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
1525         }
1526
1527         assert(handle->audioIoHandle);
1528
1529         handle->state_changed_callback.onStateChanged = NULL;
1530         handle->state_changed_callback.user_data = NULL;
1531
1532         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
1533         cb.mUserData = NULL;
1534         cb.onStateChanged  = NULL;
1535
1536         handle->audioIoHandle->setStateChangedCallback(cb);
1537     } catch (CAudioError e) {
1538         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1539         return _convert_CAudioError(e);
1540     }
1541
1542     return AUDIO_IO_ERROR_NONE;
1543 }