Use static_cast instead of dynamic cast
[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 = static_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 = static_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 = static_cast<CAudioInput*>(handle->audioIoHandle);
926         if (inputHandle == NULL) {
927             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
928         }
929
930         inputHandle->peek(buffer, &_length);
931     } catch (CAudioError e) {
932         AUDIO_IO_LOGE("%s", e.getErrorMsg());
933         return __convert_CAudioError(e);
934     }
935
936     *length = (unsigned int)_length;
937
938     return AUDIO_IO_ERROR_NONE;
939 }
940
941 int cpp_audio_in_drop(audio_in_h input) {
942     audio_io_s* handle = static_cast<audio_io_s*>(input);
943
944     try {
945         if (handle == NULL) {
946             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
947                                    "Parameters are NULL input:%p", input);
948         }
949
950         CAudioInput* inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
951         if (inputHandle == NULL) {
952             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
953         }
954
955         inputHandle->drop();
956     } catch (CAudioError e) {
957         AUDIO_IO_LOGE("%s", e.getErrorMsg());
958         return __convert_CAudioError(e);
959     }
960
961     return AUDIO_IO_ERROR_NONE;
962 }
963
964 int cpp_audio_in_set_state_changed_cb(audio_in_h input, audio_in_state_changed_cb callback, void* user_data) {
965     audio_io_s* handle = static_cast<audio_io_s*>(input);
966
967     try {
968         if (handle == NULL || callback == NULL) {
969             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
970                                    "Parameters are NULL input:%p, callback:%p", input, callback);
971         }
972         assert(handle->audioIoHandle);
973
974         handle->state_changed_callback.onStateChanged = callback;
975         handle->state_changed_callback.user_data = user_data;
976
977         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
978         cb.mUserData = static_cast<void*>(handle);
979         cb.onStateChanged = __state_changed_cb_internal;
980
981         handle->audioIoHandle->setStateChangedCallback(cb);
982     } catch (CAudioError e) {
983         AUDIO_IO_LOGE("%s", e.getErrorMsg());
984         return __convert_CAudioError(e);
985     }
986
987     return AUDIO_IO_ERROR_NONE;
988 }
989
990 int cpp_audio_in_unset_state_changed_cb(audio_in_h input) {
991     audio_io_s* handle = static_cast<audio_io_s*>(input);
992
993     try {
994         if (handle == NULL) {
995             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
996                                    "Parameters are NULL output:%p", input);
997         }
998         assert(handle->audioIoHandle);
999
1000         handle->state_changed_callback.onStateChanged = NULL;
1001         handle->state_changed_callback.user_data = NULL;
1002
1003         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
1004         cb.mUserData = NULL;
1005         cb.onStateChanged  = NULL;
1006
1007         handle->audioIoHandle->setStateChangedCallback(cb);
1008     } catch (CAudioError e) {
1009         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1010         return __convert_CAudioError(e);
1011     }
1012
1013     return AUDIO_IO_ERROR_NONE;
1014 }
1015
1016
1017 /**
1018  * Audio Out
1019  */
1020 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) {
1021     audio_io_s* handle = NULL;
1022     try {
1023         if (output == NULL) {
1024             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1025                                    "Parameters are NULL output:%p", output);
1026         }
1027
1028         __check_audio_param(sample_rate, channel, type, sound_type);
1029
1030         handle = new audio_io_s;
1031         if (handle == NULL) {
1032             THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation handle");
1033         }
1034
1035         CAudioInfo audioInfo = __generate_audio_output_info(sample_rate, channel, type, sound_type);
1036
1037         handle->audioIoHandle = new CAudioOutput(audioInfo);
1038         if (handle->audioIoHandle == NULL) {
1039             THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation internal handle");
1040         }
1041
1042         handle->audioIoHandle->initialize();
1043
1044         *output = handle;
1045     } catch (CAudioError e) {
1046         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1047
1048         VALID_POINTER_START(handle)
1049             SAFE_FINALIZE(handle->audioIoHandle);
1050             SAFE_DELETE(handle->audioIoHandle);
1051             SAFE_DELETE(handle);
1052         VALID_POINTER_END
1053
1054         VALID_POINTER_START(output)
1055             *output = NULL;
1056         VALID_POINTER_END
1057
1058         return __convert_CAudioError(e);
1059     }
1060
1061     return AUDIO_IO_ERROR_NONE;
1062 }
1063
1064 int cpp_audio_out_create_new(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_out_h *output) {
1065     audio_io_s* handle = NULL;
1066     try {
1067         if (output == NULL) {
1068             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1069                                    "Parameters are NULL output:%p", output);
1070         }
1071
1072         __check_audio_param(sample_rate, channel, type, SOUND_TYPE_SYSTEM /*default check */);
1073
1074         handle = new audio_io_s;
1075         if (handle == NULL) {
1076             THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation handle");
1077         }
1078
1079         CAudioInfo audioInfo = __generate_audio_output_info(sample_rate, channel, type, SOUND_TYPE_MEDIA);
1080
1081         handle->audioIoHandle = new CAudioOutput(audioInfo);
1082         if (handle->audioIoHandle == NULL) {
1083             THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation internal handle");
1084         }
1085
1086         handle->audioIoHandle->initialize();
1087
1088         *output = handle;
1089     } catch (CAudioError e) {
1090         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1091
1092         VALID_POINTER_START(handle)
1093             SAFE_FINALIZE(handle->audioIoHandle);
1094             SAFE_DELETE(handle->audioIoHandle);
1095             SAFE_DELETE(handle);
1096         VALID_POINTER_END
1097
1098         VALID_POINTER_START(output)
1099             *output = NULL;
1100         VALID_POINTER_END
1101
1102         return __convert_CAudioError(e);
1103     }
1104
1105     return AUDIO_IO_ERROR_NONE;
1106 }
1107
1108 int cpp_audio_out_destroy(audio_out_h output) {
1109     audio_io_s* handle = static_cast<audio_io_s*>(output);
1110
1111     try {
1112         if (handle == NULL) {
1113             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1114                                    "Parameter is NULL output:%p", output);
1115         }
1116         assert(handle->audioIoHandle);
1117
1118         /* Internal unprepare for backward compatibility */
1119         handle->audioIoHandle->unprepare();
1120
1121         SAFE_FINALIZE(handle->audioIoHandle);
1122         SAFE_DELETE(handle->audioIoHandle);
1123         SAFE_DELETE(handle);
1124     } catch (CAudioError e) {
1125         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1126         return __convert_CAudioError(e);
1127     }
1128
1129     return AUDIO_IO_ERROR_NONE;
1130 }
1131
1132 int cpp_audio_out_set_sound_stream_info(audio_out_h output, sound_stream_info_h stream_info) {
1133     audio_io_s* handle = static_cast<audio_io_s*>(output);
1134
1135     try {
1136         if (handle == NULL || stream_info == NULL) {
1137             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1138                                    "Parameters are NULL output:%p, stream_info:%p", output, stream_info);
1139         }
1140         assert(handle->audioIoHandle);
1141
1142         handle->audioIoHandle->setStreamInfo(stream_info);
1143     } catch (CAudioError e) {
1144         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1145         return __convert_CAudioError(e);
1146     }
1147
1148     return AUDIO_IO_ERROR_NONE;
1149 }
1150
1151 int cpp_audio_out_prepare(audio_out_h output) {
1152     audio_io_s* handle = static_cast<audio_io_s*>(output);
1153
1154     try {
1155         if (handle == NULL) {
1156             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1157                                    "Parameter is NULL output:%p", output);
1158         }
1159         assert(handle->audioIoHandle);
1160
1161         handle->audioIoHandle->prepare();
1162     } catch (CAudioError e) {
1163         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1164         return __convert_CAudioError(e);
1165     }
1166
1167     return AUDIO_IO_ERROR_NONE;
1168 }
1169
1170 int cpp_audio_out_unprepare(audio_out_h output) {
1171     audio_io_s* handle = static_cast<audio_io_s*>(output);
1172
1173     try {
1174         if (handle == NULL) {
1175             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1176                                    "Parameter is NULL output:%p", output);
1177         }
1178         assert(handle->audioIoHandle);
1179
1180         handle->audioIoHandle->unprepare();
1181     } catch (CAudioError e) {
1182         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1183         return __convert_CAudioError(e);
1184     }
1185
1186     return AUDIO_IO_ERROR_NONE;
1187 }
1188
1189 int cpp_audio_out_pause(audio_out_h output) {
1190     audio_io_s* handle = static_cast<audio_io_s*>(output);
1191
1192     try {
1193         if (handle == NULL) {
1194             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1195                                    "Parameter is NULL output:%p", output);
1196         }
1197         assert(handle->audioIoHandle);
1198
1199         handle->audioIoHandle->pause();
1200     } catch (CAudioError e) {
1201         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1202         return __convert_CAudioError(e);
1203     }
1204
1205     return AUDIO_IO_ERROR_NONE;
1206 }
1207
1208 int cpp_audio_out_resume(audio_out_h output) {
1209     audio_io_s* handle = static_cast<audio_io_s*>(output);
1210
1211     try {
1212         if (handle == NULL) {
1213             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1214                                    "Parameter is NULL output:%p", output);
1215         }
1216         assert(handle->audioIoHandle);
1217
1218         handle->audioIoHandle->resume();
1219     } catch (CAudioError e) {
1220         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1221         return __convert_CAudioError(e);
1222     }
1223
1224     return AUDIO_IO_ERROR_NONE;
1225 }
1226
1227 int cpp_audio_out_drain(audio_out_h output) {
1228     audio_io_s* handle = static_cast<audio_io_s*>(output);
1229
1230     try {
1231         if (handle == NULL) {
1232             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1233                                    "Parameter is NULL output:%p", output);
1234         }
1235         assert(handle->audioIoHandle);
1236
1237         handle->audioIoHandle->drain();
1238     } catch (CAudioError e) {
1239         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1240         return __convert_CAudioError(e);
1241     }
1242
1243     return AUDIO_IO_ERROR_NONE;
1244 }
1245
1246 int cpp_audio_out_flush(audio_out_h output) {
1247     audio_io_s* handle = static_cast<audio_io_s*>(output);
1248
1249     try {
1250         if (handle == NULL) {
1251             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1252                                    "Parameter is NULL output:%p", output);
1253         }
1254         assert(handle->audioIoHandle);
1255
1256         handle->audioIoHandle->flush();
1257     } catch (CAudioError e) {
1258         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1259         return __convert_CAudioError(e);
1260     }
1261
1262     return AUDIO_IO_ERROR_NONE;
1263 }
1264
1265 int cpp_audio_out_write(audio_out_h output, void *buffer, unsigned int length) {
1266     audio_io_s* handle = static_cast<audio_io_s*>(output);
1267     int ret = 0;
1268
1269     try {
1270         if (handle == NULL || buffer == NULL) {
1271             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1272                                    "Parameter is NULL output:%p, buffer:%p", output, buffer);
1273         }
1274         assert(handle->audioIoHandle);
1275
1276         CAudioOutput* outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
1277         if (outputHandle == NULL) {
1278             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1279         }
1280
1281         size_t written = outputHandle->write(buffer, static_cast<size_t>(length));
1282         ret = static_cast<int>(written);
1283 #ifdef _AUDIO_IO_DEBUG_TIMING_
1284         AUDIO_IO_LOGD("written:%d", written);
1285 #endif
1286     } catch (CAudioError e) {
1287         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1288         return __convert_CAudioError(e);
1289     }
1290
1291     return ret;
1292 }
1293
1294 int cpp_audio_out_get_buffer_size(audio_out_h output, int *size) {
1295     audio_io_s* handle = static_cast<audio_io_s*>(output);
1296
1297     try {
1298         if (handle == NULL || size == NULL) {
1299             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1300                                    "Parameters are NULL output:%p, size:%p", output, size);
1301         }
1302         assert(handle->audioIoHandle);
1303
1304         CAudioOutput* outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
1305         if (outputHandle == NULL) {
1306             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1307         }
1308         *size = outputHandle->getBufferSize();
1309     } catch (CAudioError e) {
1310         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1311         return __convert_CAudioError(e);
1312     }
1313
1314     return AUDIO_IO_ERROR_NONE;
1315 }
1316
1317 int cpp_audio_out_get_sample_rate(audio_out_h output, int *sample_rate) {
1318     audio_io_s* handle = static_cast<audio_io_s*>(output);
1319
1320     try {
1321         if (handle == NULL || sample_rate == NULL) {
1322             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1323                                    "Parameters are NULL output:%p, sample_rate:%p", output, sample_rate);
1324         }
1325         assert(handle->audioIoHandle);
1326
1327         *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
1328     } catch (CAudioError e) {
1329         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1330         return __convert_CAudioError(e);
1331     }
1332
1333     return AUDIO_IO_ERROR_NONE;
1334 }
1335
1336 int cpp_audio_out_get_channel(audio_out_h output, audio_channel_e *channel) {
1337     audio_io_s* handle = static_cast<audio_io_s*>(output);
1338
1339     try {
1340         if (handle == NULL || channel == NULL) {
1341             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1342                                    "Parameters are NULL output:%p, channel:%p", output, channel);
1343         }
1344         assert(handle->audioIoHandle);
1345
1346         const CAudioInfo::EChannel srcChannel = handle->audioIoHandle->getAudioInfo().getChannel();
1347         audio_channel_e dstChannel = AUDIO_CHANNEL_MONO;
1348         __convert_audio_info_channel_2_channel(srcChannel, dstChannel);
1349
1350         *channel = dstChannel;
1351     } catch (CAudioError e) {
1352         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1353         return __convert_CAudioError(e);
1354     }
1355
1356     return AUDIO_IO_ERROR_NONE;
1357 }
1358
1359 int cpp_audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type) {
1360     audio_io_s* handle = static_cast<audio_io_s*>(output);
1361
1362     try {
1363         if (handle == NULL || type == NULL) {
1364             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1365                                    "Parameters are NULL output:%p, type:%p", output, type);
1366         }
1367         assert(handle->audioIoHandle);
1368
1369         const CAudioInfo::ESampleType srcSampleType = handle->audioIoHandle->getAudioInfo().getSampleType();
1370         audio_sample_type_e     dstSampleType = AUDIO_SAMPLE_TYPE_U8;
1371         __convert_audio_info_sample_type_2_sample_type(srcSampleType, dstSampleType);
1372
1373         *type = dstSampleType;
1374     } catch (CAudioError e) {
1375         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1376         return __convert_CAudioError(e);
1377     }
1378
1379     return AUDIO_IO_ERROR_NONE;
1380 }
1381
1382 int cpp_audio_out_get_sound_type(audio_out_h output, sound_type_e *type) {
1383     audio_io_s* handle = static_cast<audio_io_s*>(output);
1384
1385     try {
1386         if (handle == NULL || type == NULL) {
1387             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1388                                    "Parameters are NULL output:%p, type:%p", output, type);
1389         }
1390         assert(handle->audioIoHandle);
1391
1392         const CAudioInfo::EAudioType srcAudioType = handle->audioIoHandle->getAudioInfo().getAudioType();
1393         sound_type_e                 dstSoundType = SOUND_TYPE_MEDIA;
1394         __convert_audio_info_audio_type_2_sound_type(srcAudioType, dstSoundType);
1395
1396         *type = dstSoundType;
1397     } catch (CAudioError e) {
1398         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1399         return __convert_CAudioError(e);
1400     }
1401
1402     return AUDIO_IO_ERROR_NONE;
1403 }
1404
1405 int cpp_audio_out_set_interrupted_cb(audio_out_h output, audio_io_interrupted_cb callback, void *user_data) {
1406     audio_io_s* handle = static_cast<audio_io_s*>(output);
1407
1408     try {
1409         if (handle == NULL || callback == NULL) {
1410             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1411                                    "Parameters are NULL output:%p, callback:%p", output, callback);
1412         }
1413         assert(handle->audioIoHandle);
1414
1415         handle->interrupt_callback.onInterrupt = callback;
1416         handle->interrupt_callback.user_data    = user_data;
1417
1418         CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
1419         cb.mUserData   = static_cast<void*>(handle);
1420         cb.onInterrupt = __interrupt_cb_internal;
1421
1422         handle->audioIoHandle->setInterruptCallback(cb);
1423     } catch (CAudioError e) {
1424         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1425         return __convert_CAudioError(e);
1426     }
1427
1428     return AUDIO_IO_ERROR_NONE;
1429 }
1430
1431 int cpp_audio_out_unset_interrupted_cb(audio_out_h output) {
1432     audio_io_s* handle = static_cast<audio_io_s*>(output);
1433
1434     try {
1435         if (handle == NULL) {
1436             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1437                                    "Parameters are NULL output:%p", output);
1438         }
1439         assert(handle->audioIoHandle);
1440
1441         handle->interrupt_callback.onInterrupt = NULL;
1442         handle->interrupt_callback.user_data = NULL;
1443
1444         CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
1445         cb.mUserData = NULL;
1446         cb.onInterrupt = NULL;
1447
1448         handle->audioIoHandle->setInterruptCallback(cb);
1449     } catch (CAudioError e) {
1450         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1451         return __convert_CAudioError(e);
1452     }
1453
1454     return AUDIO_IO_ERROR_NONE;
1455 }
1456
1457 int cpp_audio_out_ignore_session(audio_out_h output) {
1458     audio_io_s* handle = static_cast<audio_io_s*>(output);
1459
1460     try {
1461         if (handle == NULL) {
1462             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1463                                    "Parameters are NULL output:%p", output);
1464         }
1465
1466         if (handle->stream_callback.onStream) {
1467             THROW_ERROR_MSG(CAudioError::EError::ERROR_INVALID_OPERATION,
1468                             "Not support ignore session in async mode");
1469         }
1470         assert(handle->audioIoHandle);
1471
1472         handle->audioIoHandle->ignoreSession();
1473     } catch (CAudioError e) {
1474         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1475         return __convert_CAudioError(e);
1476     }
1477
1478     return AUDIO_IO_ERROR_NONE;
1479 }
1480
1481 int cpp_audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* user_data) {
1482     audio_io_s* handle = static_cast<audio_io_s*>(output);
1483
1484     try {
1485         if (handle == NULL || callback == NULL) {
1486             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1487                                    "Parameters are NULL output:%p, callback:%p", output, callback);
1488         }
1489         assert(handle->audioIoHandle);
1490
1491         handle->stream_callback.onStream = callback;
1492         handle->stream_callback.user_data = user_data;
1493
1494         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
1495         cb.mUserData = static_cast<void*>(handle);
1496         cb.onStream  = __stream_cb_internal;
1497
1498         handle->audioIoHandle->setStreamCallback(cb);
1499     } catch (CAudioError e) {
1500         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1501         return __convert_CAudioError(e);
1502     }
1503
1504     return AUDIO_IO_ERROR_NONE;
1505 }
1506
1507 int cpp_audio_out_unset_stream_cb(audio_out_h output) {
1508     audio_io_s* handle = static_cast<audio_io_s*>(output);
1509
1510     try {
1511         if (handle == NULL) {
1512             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1513                                    "Parameters are NULL output:%p", output);
1514         }
1515         assert(handle->audioIoHandle);
1516
1517         handle->stream_callback.onStream = NULL;
1518         handle->stream_callback.user_data = NULL;
1519
1520         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
1521         cb.mUserData = NULL;
1522         cb.onStream = NULL;
1523
1524         handle->audioIoHandle->setStreamCallback(cb);
1525     } catch (CAudioError e) {
1526         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1527         return __convert_CAudioError(e);
1528     }
1529
1530     return AUDIO_IO_ERROR_NONE;
1531 }
1532
1533 int cpp_audio_out_set_state_changed_cb(audio_out_h output, audio_in_state_changed_cb callback, void* user_data) {
1534     audio_io_s* handle = static_cast<audio_io_s*>(output);
1535
1536     try {
1537         if (handle == NULL || callback == NULL) {
1538             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1539                                    "Parameters are NULL output:%p, callback:%p", output, callback);
1540         }
1541         assert(handle->audioIoHandle);
1542
1543         handle->state_changed_callback.onStateChanged = callback;
1544         handle->state_changed_callback.user_data = user_data;
1545
1546         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
1547         cb.mUserData = static_cast<void*>(handle);
1548         cb.onStateChanged = __state_changed_cb_internal;
1549
1550         handle->audioIoHandle->setStateChangedCallback(cb);
1551     } catch (CAudioError e) {
1552         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1553         return __convert_CAudioError(e);
1554     }
1555
1556     return AUDIO_IO_ERROR_NONE;
1557 }
1558
1559 int cpp_audio_out_unset_state_changed_cb(audio_out_h output) {
1560     audio_io_s* handle = static_cast<audio_io_s*>(output);
1561
1562     try {
1563         if (handle == NULL) {
1564             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1565                                    "Parameters are NULL output:%p", output);
1566         }
1567         assert(handle->audioIoHandle);
1568
1569         handle->state_changed_callback.onStateChanged = NULL;
1570         handle->state_changed_callback.user_data = NULL;
1571
1572         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
1573         cb.mUserData = NULL;
1574         cb.onStateChanged = NULL;
1575
1576         handle->audioIoHandle->setStateChangedCallback(cb);
1577     } catch (CAudioError e) {
1578         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1579         return __convert_CAudioError(e);
1580     }
1581
1582     return AUDIO_IO_ERROR_NONE;
1583 }