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