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