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