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