Cleanup code
[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
488         assert(handle->audioIoHandle);
489
490         /* Internal unprepare for backward compatibility */
491         handle->audioIoHandle->unprepare();
492
493         SAFE_FINALIZE(handle->audioIoHandle);
494         SAFE_DELETE(handle->audioIoHandle);
495         SAFE_DELETE(handle);
496     } catch (CAudioError e) {
497         AUDIO_IO_LOGE("%s", e.getErrorMsg());
498         return __convert_CAudioError(e);
499     }
500
501     return AUDIO_IO_ERROR_NONE;
502 }
503
504 int cpp_audio_in_set_sound_stream_info(audio_in_h input, sound_stream_info_h stream_info) {
505     audio_io_s* handle = static_cast<audio_io_s*>(input);
506
507     try {
508         if (handle == NULL || stream_info == NULL) {
509             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
510                                    "Parameters are NULL input:%p, stream_info:%p", input, stream_info);
511         }
512
513         assert(handle->audioIoHandle);
514
515         int errorCode = SOUND_MANAGER_ERROR_NONE;
516         CAudioInfo::EAudioType audioType = CAudioInfo::EAudioType::AUDIO_IN_TYPE_MEDIA;
517         char *type = NULL;
518         int index = -1;
519         bool avail = false;
520
521         if ((errorCode = sound_manager_is_available_stream_information(stream_info, NATIVE_API_AUDIO_IO, &avail)) != SOUND_MANAGER_ERROR_NONE) {
522             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info is invalid [ret:%d]", errorCode);
523         }
524
525         if (avail) {
526             if ((errorCode = sound_manager_get_type_from_stream_information(stream_info, &type)) != SOUND_MANAGER_ERROR_NONE) {
527                 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->stream_type is invalid [ret:%d]", errorCode);
528             }
529             handle->audioIoHandle->getAudioInfo().convertInputStreamType2AudioType(type, &audioType);
530             handle->audioIoHandle->getAudioInfo().setAudioType(audioType);
531
532             if ((errorCode = sound_manager_get_index_from_stream_information(stream_info, &index)) != SOUND_MANAGER_ERROR_NONE) {
533                 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->index is invalid [ret:%d]", errorCode);
534             }
535             handle->audioIoHandle->getAudioInfo().setAudioIndex(index);
536         } else {
537             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_NOT_SUPPORTED_TYPE, "Input stream is not supported");
538         }
539     } catch (CAudioError e) {
540         AUDIO_IO_LOGE("%s", e.getErrorMsg());
541         return __convert_CAudioError(e);
542     }
543
544     return AUDIO_IO_ERROR_NONE;
545 }
546
547 int cpp_audio_in_prepare(audio_in_h input) {
548     audio_io_s* handle = static_cast<audio_io_s*>(input);
549
550     try {
551         if (handle == NULL) {
552             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
553                                    "Parameters are NULL input:%p", input);
554         }
555
556         assert(handle->audioIoHandle);
557
558         handle->audioIoHandle->prepare();
559     } catch (CAudioError e) {
560         AUDIO_IO_LOGE("%s", e.getErrorMsg());
561         return __convert_CAudioError(e);
562     }
563
564     return AUDIO_IO_ERROR_NONE;
565 }
566
567 int cpp_audio_in_unprepare(audio_in_h input) {
568     audio_io_s* handle = static_cast<audio_io_s*>(input);
569
570     try {
571         if (handle == NULL) {
572             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
573                                    "Parameters are NULL input:%p", input);
574         }
575         assert(handle->audioIoHandle);
576
577         handle->audioIoHandle->unprepare();
578     } catch (CAudioError e) {
579         AUDIO_IO_LOGE("%s", e.getErrorMsg());
580         return __convert_CAudioError(e);
581     }
582
583     return AUDIO_IO_ERROR_NONE;
584 }
585
586 int cpp_audio_in_pause(audio_in_h input) {
587     audio_io_s* handle = static_cast<audio_io_s*>(input);
588
589     try {
590         if (handle == NULL) {
591             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
592                                    "Parameters are NULL input:%p", input);
593         }
594         assert(handle->audioIoHandle);
595
596         handle->audioIoHandle->pause();
597     } catch (CAudioError e) {
598         AUDIO_IO_LOGE("%s", e.getErrorMsg());
599         return __convert_CAudioError(e);
600     }
601
602     return AUDIO_IO_ERROR_NONE;
603 }
604
605 int cpp_audio_in_resume(audio_in_h input) {
606     audio_io_s* handle = static_cast<audio_io_s*>(input);
607
608     try {
609         if (handle == NULL) {
610             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
611                                    "Parameters are NULL input:%p", input);
612         }
613         assert(handle->audioIoHandle);
614
615         handle->audioIoHandle->resume();
616     } catch (CAudioError e) {
617         AUDIO_IO_LOGE("%s", e.getErrorMsg());
618         return __convert_CAudioError(e);
619     }
620
621     return AUDIO_IO_ERROR_NONE;
622 }
623
624 int cpp_audio_in_drain(audio_in_h input) {
625     audio_io_s* handle = static_cast<audio_io_s*>(input);
626
627     try {
628         if (handle == NULL) {
629             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
630                                    "Parameters are NULL input:%p", input);
631         }
632         assert(handle->audioIoHandle);
633
634         handle->audioIoHandle->drain();
635     } catch (CAudioError e) {
636         AUDIO_IO_LOGE("%s", e.getErrorMsg());
637         return __convert_CAudioError(e);
638     }
639
640     return AUDIO_IO_ERROR_NONE;
641 }
642
643 int cpp_audio_in_flush(audio_in_h input) {
644     audio_io_s* handle = static_cast<audio_io_s*>(input);
645
646     try {
647         if (handle == NULL) {
648             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
649                                    "Parameters are NULL input:%p", input);
650         }
651
652         assert(handle->audioIoHandle);
653
654         handle->audioIoHandle->flush();
655     } catch (CAudioError e) {
656         AUDIO_IO_LOGE("%s", e.getErrorMsg());
657         return __convert_CAudioError(e);
658     }
659
660     return AUDIO_IO_ERROR_NONE;
661 }
662
663 int cpp_audio_in_read(audio_in_h input, void *buffer, unsigned int length) {
664     audio_io_s* handle = static_cast<audio_io_s*>(input);
665     int ret = 0;
666
667     try {
668         if (handle == NULL || buffer == NULL) {
669             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
670                                    "Parameters are NULL input:%p, buffer:%p", input, buffer);
671         }
672         assert(handle->audioIoHandle);
673
674         CAudioInput* inputHandle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
675         if (inputHandle == NULL) {
676             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
677         }
678
679         size_t readn = inputHandle->read(buffer, static_cast<size_t>(length));
680         ret = static_cast<int>(readn);
681 #ifdef _AUDIO_IO_DEBUG_TIMING_
682         AUDIO_IO_LOGD("readn:%d", readn);
683 #endif
684     } catch (CAudioError e) {
685         AUDIO_IO_LOGE("%s", e.getErrorMsg());
686         return __convert_CAudioError(e);
687     }
688
689     return ret;
690 }
691
692 int cpp_audio_in_get_buffer_size(audio_in_h input, int *size) {
693     audio_io_s* handle = static_cast<audio_io_s*>(input);
694
695     try {
696         if (handle == NULL || size == NULL) {
697             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
698                                    "Parameters are NULL input:%p, size:%p", input, size);
699         }
700
701         assert(handle->audioIoHandle);
702
703         CAudioIO* inputHandle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
704         if (inputHandle == NULL) {
705             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
706         }
707         *size = inputHandle->getBufferSize();
708     } catch (CAudioError e) {
709         AUDIO_IO_LOGE("%s", e.getErrorMsg());
710         return __convert_CAudioError(e);
711     }
712
713     return AUDIO_IO_ERROR_NONE;
714 }
715
716 int cpp_audio_in_get_sample_rate(audio_in_h input, int *sample_rate) {
717     audio_io_s* handle = static_cast<audio_io_s*>(input);
718
719     try {
720         if (handle == NULL || sample_rate == NULL) {
721             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
722                                    "Parameters are NULL input:%p, sample_rate:%p", input, sample_rate);
723         }
724
725         assert(handle->audioIoHandle);
726         *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
727     } catch (CAudioError e) {
728         AUDIO_IO_LOGE("%s", e.getErrorMsg());
729         return __convert_CAudioError(e);
730     }
731
732     return AUDIO_IO_ERROR_NONE;
733 }
734
735 int cpp_audio_in_get_channel(audio_in_h input, audio_channel_e *channel) {
736     audio_io_s* handle = static_cast<audio_io_s*>(input);
737
738     try {
739         if (handle == NULL || channel == NULL) {
740             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
741                                    "Parameters are NULL input:%p, channel:%p", input, channel);
742         }
743
744         assert(handle->audioIoHandle);
745
746         const CAudioInfo::EChannel srcChannel = handle->audioIoHandle->getAudioInfo().getChannel();
747         audio_channel_e dstChannel = AUDIO_CHANNEL_MONO;
748         __convert_audio_info_channel_2_channel(srcChannel, dstChannel);
749
750         *channel = dstChannel;
751     } catch (CAudioError e) {
752         AUDIO_IO_LOGE("%s", e.getErrorMsg());
753         return __convert_CAudioError(e);
754     }
755
756     return AUDIO_IO_ERROR_NONE;
757 }
758
759 int cpp_audio_in_get_sample_type(audio_in_h input, audio_sample_type_e *type) {
760     audio_io_s* handle = static_cast<audio_io_s*>(input);
761
762     try {
763         if (handle == NULL || type == NULL) {
764             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
765                                    "Parameters are NULL input:%p, type:%p", input, type);
766         }
767         assert(handle->audioIoHandle);
768
769         const CAudioInfo::ESampleType srcSampleType = handle->audioIoHandle->getAudioInfo().getSampleType();
770         audio_sample_type_e dstSampleType = AUDIO_SAMPLE_TYPE_U8;
771         __convert_audio_info_sample_type_2_sample_type(srcSampleType, dstSampleType);
772
773         *type = dstSampleType;
774     } catch (CAudioError e) {
775         AUDIO_IO_LOGE("%s", e.getErrorMsg());
776         return __convert_CAudioError(e);
777     }
778
779     return AUDIO_IO_ERROR_NONE;
780 }
781
782 static void __interrupt_cb_internal(IAudioSessionEventListener::EInterruptCode _code, void* user_data) {
783     audio_io_s* handle = static_cast<audio_io_s*>(user_data);
784     audio_io_interrupted_code_e code = __convert_interrupted_code(_code);
785
786     assert(handle);
787
788     if (handle->interrupt_callback.onInterrupt) {
789         handle->interrupt_callback.onInterrupt(code, handle->interrupt_callback.user_data);
790     }
791 }
792
793 int cpp_audio_in_set_interrupted_cb(audio_in_h input, audio_io_interrupted_cb callback, void *user_data) {
794     audio_io_s* handle = static_cast<audio_io_s*>(input);
795
796     try {
797         if (handle == NULL || callback == NULL) {
798             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
799                                    "Parameters are NULL input:%p, callback:%p", input, callback);
800         }
801
802         assert(handle->audioIoHandle);
803
804         handle->interrupt_callback.onInterrupt = callback;
805         handle->interrupt_callback.user_data = user_data;
806
807         CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
808         cb.mUserData = static_cast<void*>(handle);
809         cb.onInterrupt = __interrupt_cb_internal;
810
811         handle->audioIoHandle->setInterruptCallback(cb);
812     } catch (CAudioError e) {
813         AUDIO_IO_LOGE("%s", e.getErrorMsg());
814         return __convert_CAudioError(e);
815     }
816
817     return AUDIO_IO_ERROR_NONE;
818 }
819
820 int cpp_audio_in_unset_interrupted_cb(audio_in_h input) {
821     audio_io_s* handle = static_cast<audio_io_s*>(input);
822
823     try {
824         if (handle == NULL) {
825             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
826                                    "Parameters are NULL input:%p", input);
827         }
828
829         assert(handle->audioIoHandle);
830
831         handle->interrupt_callback.onInterrupt = NULL;
832         handle->interrupt_callback.user_data    = NULL;
833
834         CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
835         cb.mUserData = NULL;
836         cb.onInterrupt = NULL;
837
838         handle->audioIoHandle->setInterruptCallback(cb);
839     } catch (CAudioError e) {
840         AUDIO_IO_LOGE("%s", e.getErrorMsg());
841         return __convert_CAudioError(e);
842     }
843
844     return AUDIO_IO_ERROR_NONE;
845 }
846
847 int cpp_audio_in_ignore_session(audio_in_h input) {
848     audio_io_s* handle = static_cast<audio_io_s*>(input);
849
850     try {
851         if (handle == NULL) {
852             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
853                                    "Parameters are NULL input:%p", input);
854         }
855
856         if (handle->stream_callback.onStream) {
857             THROW_ERROR_MSG(CAudioError::EError::ERROR_INVALID_OPERATION,
858                             "Not support ignore session in async mode");
859         }
860
861         assert(handle->audioIoHandle);
862
863         handle->audioIoHandle->ignoreSession();
864     } catch (CAudioError e) {
865         AUDIO_IO_LOGE("%s", e.getErrorMsg());
866         return __convert_CAudioError(e);
867     }
868
869     return AUDIO_IO_ERROR_NONE;
870 }
871
872 static void __stream_cb_internal(size_t nbytes, void *user_data) {
873     audio_io_s* audioIo = static_cast<audio_io_s*>(user_data);
874     assert(audioIo);
875
876     if (audioIo->stream_callback.onStream) {
877         audioIo->stream_callback.onStream(audioIo, nbytes, audioIo->stream_callback.user_data);
878     }
879 }
880
881 static void __state_changed_cb_internal(CAudioInfo::EAudioIOState state,
882                                         CAudioInfo::EAudioIOState state_prev,
883                                         bool by_policy,
884                                         void *user_data) {
885     audio_io_s* audioIo = static_cast<audio_io_s*>(user_data);
886     assert(audioIo);
887
888     if (audioIo->state_changed_callback.onStateChanged) {
889         audioIo->state_changed_callback.onStateChanged(audioIo, __convert_state_type(state_prev),
890                                                        __convert_state_type(state), by_policy,
891                                                        audioIo->state_changed_callback.user_data);
892     }
893 }
894
895 int cpp_audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* user_data) {
896     audio_io_s* handle = static_cast<audio_io_s*>(input);
897
898     try {
899         if (handle == NULL || callback == NULL) {
900             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
901                                    "Parameters are NULL input:%p, callback:%p", input, callback);
902         }
903
904         assert(handle->audioIoHandle);
905
906         handle->stream_callback.onStream = callback;
907         handle->stream_callback.user_data = user_data;
908
909         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
910         cb.mUserData = static_cast<void*>(handle);
911         cb.onStream  = __stream_cb_internal;
912
913         handle->audioIoHandle->setStreamCallback(cb);
914     } catch (CAudioError e) {
915         AUDIO_IO_LOGE("%s", e.getErrorMsg());
916         return __convert_CAudioError(e);
917     }
918
919     return AUDIO_IO_ERROR_NONE;
920 }
921
922 int cpp_audio_in_unset_stream_cb(audio_in_h input) {
923     audio_io_s* handle = static_cast<audio_io_s*>(input);
924
925     try {
926         if (handle == NULL) {
927             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
928                                    "Parameters are NULL input:%p", input);
929         }
930
931         assert(handle->audioIoHandle);
932
933         handle->stream_callback.onStream = NULL;
934         handle->stream_callback.user_data = NULL;
935
936         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
937         cb.mUserData = NULL;
938         cb.onStream  = NULL;
939
940         handle->audioIoHandle->setStreamCallback(cb);
941     } catch (CAudioError e) {
942         AUDIO_IO_LOGE("%s", e.getErrorMsg());
943         return __convert_CAudioError(e);
944     }
945
946     return AUDIO_IO_ERROR_NONE;
947 }
948
949 int cpp_audio_in_peek(audio_in_h input, const void **buffer, unsigned int *length) {
950     audio_io_s* handle = static_cast<audio_io_s*>(input);
951     size_t _length = 0;
952
953     try {
954         if (handle == NULL || buffer == NULL) {
955             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
956                                    "Parameters are NULL input:%p, buffer:%p", input, buffer);
957         }
958
959         CAudioInput* inputHandle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
960         assert(inputHandle);
961
962         inputHandle->peek(buffer, &_length);
963     } catch (CAudioError e) {
964         AUDIO_IO_LOGE("%s", e.getErrorMsg());
965         return __convert_CAudioError(e);
966     }
967
968     *length = (unsigned int)_length;
969
970     return AUDIO_IO_ERROR_NONE;
971 }
972
973 int cpp_audio_in_drop(audio_in_h input) {
974     audio_io_s* handle = static_cast<audio_io_s*>(input);
975
976     try {
977         if (handle == NULL) {
978             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
979                                    "Parameters are NULL input:%p", input);
980         }
981
982         CAudioInput* inputHandle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
983         assert(inputHandle);
984
985         inputHandle->drop();
986     } catch (CAudioError e) {
987         AUDIO_IO_LOGE("%s", e.getErrorMsg());
988         return __convert_CAudioError(e);
989     }
990
991     return AUDIO_IO_ERROR_NONE;
992 }
993
994 int cpp_audio_in_set_state_changed_cb(audio_in_h input, audio_in_state_changed_cb callback, void* user_data) {
995     audio_io_s* handle = static_cast<audio_io_s*>(input);
996
997     try {
998         if (handle == NULL || callback == NULL) {
999             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1000                                    "Parameters are NULL input:%p, callback:%p", input, callback);
1001         }
1002
1003         assert(handle->audioIoHandle);
1004
1005         handle->state_changed_callback.onStateChanged = callback;
1006         handle->state_changed_callback.user_data = user_data;
1007
1008         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
1009         cb.mUserData = static_cast<void*>(handle);
1010         cb.onStateChanged = __state_changed_cb_internal;
1011
1012         handle->audioIoHandle->setStateChangedCallback(cb);
1013     } catch (CAudioError e) {
1014         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1015         return __convert_CAudioError(e);
1016     }
1017
1018     return AUDIO_IO_ERROR_NONE;
1019 }
1020
1021 int cpp_audio_in_unset_state_changed_cb(audio_in_h input) {
1022     audio_io_s* handle = static_cast<audio_io_s*>(input);
1023
1024     try {
1025         if (handle == NULL) {
1026             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1027                                    "Parameters are NULL output:%p", input);
1028         }
1029
1030         assert(handle->audioIoHandle);
1031
1032         handle->state_changed_callback.onStateChanged = NULL;
1033         handle->state_changed_callback.user_data = NULL;
1034
1035         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
1036         cb.mUserData = NULL;
1037         cb.onStateChanged  = NULL;
1038
1039         handle->audioIoHandle->setStateChangedCallback(cb);
1040     } catch (CAudioError e) {
1041         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1042         return __convert_CAudioError(e);
1043     }
1044
1045     return AUDIO_IO_ERROR_NONE;
1046 }
1047
1048
1049 /**
1050  * Audio Out
1051  */
1052 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) {
1053     audio_io_s* handle = NULL;
1054     try {
1055         if (output == NULL) {
1056             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1057                                    "Parameters are NULL output:%p", output);
1058         }
1059
1060         __check_audio_param(sample_rate, channel, type, sound_type);
1061
1062         handle = new audio_io_s;
1063         if (handle == NULL) {
1064             THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation handle");
1065         }
1066
1067         CAudioInfo audioInfo = __generate_audio_output_info(sample_rate, channel, type, sound_type);
1068
1069         handle->audioIoHandle = new CAudioOutput(audioInfo);
1070         if (handle->audioIoHandle == NULL) {
1071             THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation internal handle");
1072         }
1073
1074         handle->audioIoHandle->initialize();
1075
1076         *output = handle;
1077     } catch (CAudioError e) {
1078         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1079
1080         VALID_POINTER_START(handle)
1081             SAFE_FINALIZE(handle->audioIoHandle);
1082             SAFE_DELETE(handle->audioIoHandle);
1083             SAFE_DELETE(handle);
1084         VALID_POINTER_END
1085
1086         VALID_POINTER_START(output)
1087             *output = NULL;
1088         VALID_POINTER_END
1089
1090         return __convert_CAudioError(e);
1091     }
1092
1093     return AUDIO_IO_ERROR_NONE;
1094 }
1095
1096 int cpp_audio_out_create_new(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_out_h *output) {
1097     audio_io_s* handle = NULL;
1098     try {
1099         if (output == NULL) {
1100             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1101                                    "Parameters are NULL output:%p", output);
1102         }
1103
1104         __check_audio_param(sample_rate, channel, type, SOUND_TYPE_SYSTEM /*default check */);
1105
1106         handle = new audio_io_s;
1107         if (handle == NULL) {
1108             THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation handle");
1109         }
1110
1111         CAudioInfo audioInfo = __generate_audio_output_info(sample_rate, channel, type, SOUND_TYPE_MEDIA);
1112
1113         handle->audioIoHandle = new CAudioOutput(audioInfo);
1114         if (handle->audioIoHandle == NULL) {
1115             THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation internal handle");
1116         }
1117
1118         handle->audioIoHandle->initialize();
1119
1120         *output = handle;
1121     } catch (CAudioError e) {
1122         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1123
1124         VALID_POINTER_START(handle)
1125             SAFE_FINALIZE(handle->audioIoHandle);
1126             SAFE_DELETE(handle->audioIoHandle);
1127             SAFE_DELETE(handle);
1128         VALID_POINTER_END
1129
1130         VALID_POINTER_START(output)
1131             *output = NULL;
1132         VALID_POINTER_END
1133
1134         return __convert_CAudioError(e);
1135     }
1136
1137     return AUDIO_IO_ERROR_NONE;
1138 }
1139
1140 int cpp_audio_out_destroy(audio_out_h output) {
1141     audio_io_s* handle = static_cast<audio_io_s*>(output);
1142
1143     try {
1144         if (handle == NULL) {
1145             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1146                                    "Parameter is NULL output:%p", output);
1147         }
1148
1149         assert(handle->audioIoHandle);
1150
1151         /* Internal unprepare for backward compatibility */
1152         handle->audioIoHandle->unprepare();
1153
1154         SAFE_FINALIZE(handle->audioIoHandle);
1155         SAFE_DELETE(handle->audioIoHandle);
1156         SAFE_DELETE(handle);
1157     } catch (CAudioError e) {
1158         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1159         return __convert_CAudioError(e);
1160     }
1161
1162     return AUDIO_IO_ERROR_NONE;
1163 }
1164
1165 int cpp_audio_out_set_sound_stream_info(audio_out_h output, sound_stream_info_h stream_info) {
1166     audio_io_s* handle = static_cast<audio_io_s*>(output);
1167
1168     try {
1169         if (handle == NULL || stream_info == NULL) {
1170             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1171                                    "Parameters are NULL output:%p, stream_info:%p", output, stream_info);
1172         }
1173
1174         assert(handle->audioIoHandle);
1175
1176         int errorCode = SOUND_MANAGER_ERROR_NONE;
1177         CAudioInfo::EAudioType audioType = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA;
1178         char *type = NULL;
1179         int index = -1;
1180         bool avail = false;
1181
1182         if ((errorCode = sound_manager_is_available_stream_information(stream_info, NATIVE_API_AUDIO_IO, &avail)) != SOUND_MANAGER_ERROR_NONE) {
1183             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info is invalid [ret:%d]", errorCode);
1184         }
1185
1186         if (avail) {
1187             if ((errorCode = sound_manager_get_type_from_stream_information(stream_info, &type)) != SOUND_MANAGER_ERROR_NONE) {
1188                 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->stream_type is invalid [ret:%d]", errorCode);
1189             }
1190             handle->audioIoHandle->getAudioInfo().convertOutputStreamType2AudioType(type, &audioType);
1191             handle->audioIoHandle->getAudioInfo().setAudioType(audioType);
1192
1193             if ((errorCode = sound_manager_get_index_from_stream_information(stream_info, &index)) != SOUND_MANAGER_ERROR_NONE) {
1194                 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->index is invalid [ret:%d]", errorCode);
1195             }
1196             handle->audioIoHandle->getAudioInfo().setAudioIndex(index);
1197         } else {
1198             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_NOT_SUPPORTED_TYPE,
1199                                    "Output stream is not supported");
1200         }
1201     } catch (CAudioError e) {
1202         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1203         return __convert_CAudioError(e);
1204     }
1205
1206     return AUDIO_IO_ERROR_NONE;
1207 }
1208
1209 int cpp_audio_out_prepare(audio_out_h output) {
1210     audio_io_s* handle = static_cast<audio_io_s*>(output);
1211
1212     try {
1213         if (handle == NULL) {
1214             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1215                                    "Parameter is NULL output:%p", output);
1216         }
1217
1218         assert(handle->audioIoHandle);
1219
1220         handle->audioIoHandle->prepare();
1221     } catch (CAudioError e) {
1222         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1223         return __convert_CAudioError(e);
1224     }
1225
1226     return AUDIO_IO_ERROR_NONE;
1227 }
1228
1229 int cpp_audio_out_unprepare(audio_out_h output) {
1230     audio_io_s* handle = static_cast<audio_io_s*>(output);
1231
1232     try {
1233         if (handle == NULL) {
1234             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1235                                    "Parameter is NULL output:%p", output);
1236         }
1237
1238         assert(handle->audioIoHandle);
1239
1240         handle->audioIoHandle->unprepare();
1241     } catch (CAudioError e) {
1242         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1243         return __convert_CAudioError(e);
1244     }
1245
1246     return AUDIO_IO_ERROR_NONE;
1247 }
1248
1249 int cpp_audio_out_pause(audio_out_h output) {
1250     audio_io_s* handle = static_cast<audio_io_s*>(output);
1251
1252     try {
1253         if (handle == NULL) {
1254             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1255                                    "Parameter is NULL output:%p", output);
1256         }
1257
1258         assert(handle->audioIoHandle);
1259
1260         handle->audioIoHandle->pause();
1261     } catch (CAudioError e) {
1262         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1263         return __convert_CAudioError(e);
1264     }
1265
1266     return AUDIO_IO_ERROR_NONE;
1267 }
1268
1269 int cpp_audio_out_resume(audio_out_h output) {
1270     audio_io_s* handle = static_cast<audio_io_s*>(output);
1271
1272     try {
1273         if (handle == NULL) {
1274             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1275                                    "Parameter is NULL output:%p", output);
1276         }
1277
1278         assert(handle->audioIoHandle);
1279
1280         handle->audioIoHandle->resume();
1281     } catch (CAudioError e) {
1282         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1283         return __convert_CAudioError(e);
1284     }
1285
1286     return AUDIO_IO_ERROR_NONE;
1287 }
1288
1289 int cpp_audio_out_drain(audio_out_h output) {
1290     audio_io_s* handle = static_cast<audio_io_s*>(output);
1291
1292     try {
1293         if (handle == NULL) {
1294             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1295                                    "Parameter is NULL output:%p", output);
1296         }
1297
1298         assert(handle->audioIoHandle);
1299
1300         handle->audioIoHandle->drain();
1301     } catch (CAudioError e) {
1302         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1303         return __convert_CAudioError(e);
1304     }
1305
1306     return AUDIO_IO_ERROR_NONE;
1307 }
1308
1309 int cpp_audio_out_flush(audio_out_h output) {
1310     audio_io_s* handle = static_cast<audio_io_s*>(output);
1311
1312     try {
1313         if (handle == NULL) {
1314             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1315                                    "Parameter is NULL output:%p", output);
1316         }
1317
1318         assert(handle->audioIoHandle);
1319
1320         handle->audioIoHandle->flush();
1321     } catch (CAudioError e) {
1322         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1323         return __convert_CAudioError(e);
1324     }
1325
1326     return AUDIO_IO_ERROR_NONE;
1327 }
1328
1329 int cpp_audio_out_write(audio_out_h output, void *buffer, unsigned int length) {
1330     audio_io_s* handle = static_cast<audio_io_s*>(output);
1331     int ret = 0;
1332
1333     try {
1334         if (handle == NULL || buffer == NULL) {
1335             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1336                                    "Parameter is NULL output:%p, buffer:%p", output, buffer);
1337         }
1338
1339         assert(handle->audioIoHandle);
1340
1341         CAudioOutput* outputHandle = dynamic_cast<CAudioOutput*>(handle->audioIoHandle);
1342         if (outputHandle == NULL) {
1343             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1344         }
1345
1346         size_t written = outputHandle->write(buffer, static_cast<size_t>(length));
1347         ret = static_cast<int>(written);
1348 #ifdef _AUDIO_IO_DEBUG_TIMING_
1349         AUDIO_IO_LOGD("written:%d", written);
1350 #endif
1351     } catch (CAudioError e) {
1352         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1353         return __convert_CAudioError(e);
1354     }
1355
1356     return ret;
1357 }
1358
1359 int cpp_audio_out_get_buffer_size(audio_out_h output, int *size) {
1360     audio_io_s* handle = static_cast<audio_io_s*>(output);
1361
1362     try {
1363         if (handle == NULL || size == NULL) {
1364             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1365                                    "Parameters are NULL output:%p, size:%p", output, size);
1366         }
1367
1368         assert(handle->audioIoHandle);
1369
1370         CAudioOutput* outputHandle = dynamic_cast<CAudioOutput*>(handle->audioIoHandle);
1371         if (outputHandle == NULL) {
1372             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1373         }
1374         *size = outputHandle->getBufferSize();
1375     } catch (CAudioError e) {
1376         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1377         return __convert_CAudioError(e);
1378     }
1379
1380     return AUDIO_IO_ERROR_NONE;
1381 }
1382
1383 int cpp_audio_out_get_sample_rate(audio_out_h output, int *sample_rate) {
1384     audio_io_s* handle = static_cast<audio_io_s*>(output);
1385
1386     try {
1387         if (handle == NULL || sample_rate == NULL) {
1388             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1389                                    "Parameters are NULL output:%p, sample_rate:%p", output, sample_rate);
1390         }
1391
1392         assert(handle->audioIoHandle);
1393         *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
1394     } catch (CAudioError e) {
1395         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1396         return __convert_CAudioError(e);
1397     }
1398
1399     return AUDIO_IO_ERROR_NONE;
1400 }
1401
1402 int cpp_audio_out_get_channel(audio_out_h output, audio_channel_e *channel) {
1403     audio_io_s* handle = static_cast<audio_io_s*>(output);
1404
1405     try {
1406         if (handle == NULL || channel == NULL) {
1407             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1408                                    "Parameters are NULL output:%p, channel:%p", output, channel);
1409         }
1410
1411         assert(handle->audioIoHandle);
1412
1413         const CAudioInfo::EChannel srcChannel = handle->audioIoHandle->getAudioInfo().getChannel();
1414         audio_channel_e dstChannel = AUDIO_CHANNEL_MONO;
1415         __convert_audio_info_channel_2_channel(srcChannel, dstChannel);
1416
1417         *channel = dstChannel;
1418     } catch (CAudioError e) {
1419         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1420         return __convert_CAudioError(e);
1421     }
1422
1423     return AUDIO_IO_ERROR_NONE;
1424 }
1425
1426 int cpp_audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type) {
1427     audio_io_s* handle = static_cast<audio_io_s*>(output);
1428
1429     try {
1430         if (handle == NULL || type == NULL) {
1431             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1432                                    "Parameters are NULL output:%p, type:%p", output, type);
1433         }
1434
1435         assert(handle->audioIoHandle);
1436
1437         const CAudioInfo::ESampleType srcSampleType = handle->audioIoHandle->getAudioInfo().getSampleType();
1438         audio_sample_type_e     dstSampleType = AUDIO_SAMPLE_TYPE_U8;
1439         __convert_audio_info_sample_type_2_sample_type(srcSampleType, dstSampleType);
1440
1441         *type = dstSampleType;
1442     } catch (CAudioError e) {
1443         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1444         return __convert_CAudioError(e);
1445     }
1446
1447     return AUDIO_IO_ERROR_NONE;
1448 }
1449
1450 int cpp_audio_out_get_sound_type(audio_out_h output, sound_type_e *type) {
1451     audio_io_s* handle = static_cast<audio_io_s*>(output);
1452
1453     try {
1454         if (handle == NULL || type == NULL) {
1455             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1456                                    "Parameters are NULL output:%p, type:%p", output, type);
1457         }
1458
1459         assert(handle->audioIoHandle);
1460
1461         const CAudioInfo::EAudioType srcAudioType = handle->audioIoHandle->getAudioInfo().getAudioType();
1462         sound_type_e                 dstSoundType = SOUND_TYPE_MEDIA;
1463         __convert_audio_info_audio_type_2_sound_type(srcAudioType, dstSoundType);
1464
1465         *type = dstSoundType;
1466     } catch (CAudioError e) {
1467         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1468         return __convert_CAudioError(e);
1469     }
1470
1471     return AUDIO_IO_ERROR_NONE;
1472 }
1473
1474 int cpp_audio_out_set_interrupted_cb(audio_out_h output, audio_io_interrupted_cb callback, void *user_data) {
1475     audio_io_s* handle = static_cast<audio_io_s*>(output);
1476
1477     try {
1478         if (handle == NULL || callback == NULL) {
1479             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1480                                    "Parameters are NULL output:%p, callback:%p", output, callback);
1481         }
1482
1483         assert(handle->audioIoHandle);
1484
1485         handle->interrupt_callback.onInterrupt = callback;
1486         handle->interrupt_callback.user_data    = user_data;
1487
1488         CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
1489         cb.mUserData   = static_cast<void*>(handle);
1490         cb.onInterrupt = __interrupt_cb_internal;
1491
1492         handle->audioIoHandle->setInterruptCallback(cb);
1493     } catch (CAudioError e) {
1494         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1495         return __convert_CAudioError(e);
1496     }
1497
1498     return AUDIO_IO_ERROR_NONE;
1499 }
1500
1501 int cpp_audio_out_unset_interrupted_cb(audio_out_h output) {
1502     audio_io_s* handle = static_cast<audio_io_s*>(output);
1503
1504     try {
1505         if (handle == NULL) {
1506             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1507                                    "Parameters are NULL output:%p", output);
1508         }
1509
1510         assert(handle->audioIoHandle);
1511
1512         handle->interrupt_callback.onInterrupt = NULL;
1513         handle->interrupt_callback.user_data = NULL;
1514
1515         CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
1516         cb.mUserData = NULL;
1517         cb.onInterrupt = NULL;
1518
1519         handle->audioIoHandle->setInterruptCallback(cb);
1520     } catch (CAudioError e) {
1521         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1522         return __convert_CAudioError(e);
1523     }
1524
1525     return AUDIO_IO_ERROR_NONE;
1526 }
1527
1528 int cpp_audio_out_ignore_session(audio_out_h output) {
1529     audio_io_s* handle = static_cast<audio_io_s*>(output);
1530
1531     try {
1532         if (handle == NULL) {
1533             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1534                                    "Parameters are NULL output:%p", output);
1535         }
1536
1537         if (handle->stream_callback.onStream) {
1538             THROW_ERROR_MSG(CAudioError::EError::ERROR_INVALID_OPERATION,
1539                             "Not support ignore session in async mode");
1540         }
1541
1542         assert(handle->audioIoHandle);
1543
1544         handle->audioIoHandle->ignoreSession();
1545     } catch (CAudioError e) {
1546         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1547         return __convert_CAudioError(e);
1548     }
1549
1550     return AUDIO_IO_ERROR_NONE;
1551 }
1552
1553 int cpp_audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* user_data) {
1554     audio_io_s* handle = static_cast<audio_io_s*>(output);
1555
1556     try {
1557         if (handle == NULL || callback == NULL) {
1558             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1559                                    "Parameters are NULL output:%p, callback:%p", output, callback);
1560         }
1561
1562         assert(handle->audioIoHandle);
1563
1564         handle->stream_callback.onStream = callback;
1565         handle->stream_callback.user_data = user_data;
1566
1567         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
1568         cb.mUserData = static_cast<void*>(handle);
1569         cb.onStream  = __stream_cb_internal;
1570
1571         handle->audioIoHandle->setStreamCallback(cb);
1572     } catch (CAudioError e) {
1573         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1574         return __convert_CAudioError(e);
1575     }
1576
1577     return AUDIO_IO_ERROR_NONE;
1578 }
1579
1580 int cpp_audio_out_unset_stream_cb(audio_out_h output) {
1581     audio_io_s* handle = static_cast<audio_io_s*>(output);
1582
1583     try {
1584         if (handle == NULL) {
1585             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1586                                    "Parameters are NULL output:%p", output);
1587         }
1588
1589         assert(handle->audioIoHandle);
1590
1591         handle->stream_callback.onStream = NULL;
1592         handle->stream_callback.user_data = NULL;
1593
1594         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
1595         cb.mUserData = NULL;
1596         cb.onStream = NULL;
1597
1598         handle->audioIoHandle->setStreamCallback(cb);
1599     } catch (CAudioError e) {
1600         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1601         return __convert_CAudioError(e);
1602     }
1603
1604     return AUDIO_IO_ERROR_NONE;
1605 }
1606
1607 int cpp_audio_out_set_state_changed_cb(audio_out_h output, audio_in_state_changed_cb callback, void* user_data) {
1608     audio_io_s* handle = static_cast<audio_io_s*>(output);
1609
1610     try {
1611         if (handle == NULL || callback == NULL) {
1612             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1613                                    "Parameters are NULL output:%p, callback:%p", output, callback);
1614         }
1615
1616         assert(handle->audioIoHandle);
1617
1618         handle->state_changed_callback.onStateChanged = callback;
1619         handle->state_changed_callback.user_data = user_data;
1620
1621         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
1622         cb.mUserData = static_cast<void*>(handle);
1623         cb.onStateChanged = __state_changed_cb_internal;
1624
1625         handle->audioIoHandle->setStateChangedCallback(cb);
1626     } catch (CAudioError e) {
1627         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1628         return __convert_CAudioError(e);
1629     }
1630
1631     return AUDIO_IO_ERROR_NONE;
1632 }
1633
1634 int cpp_audio_out_unset_state_changed_cb(audio_out_h output) {
1635     audio_io_s* handle = static_cast<audio_io_s*>(output);
1636
1637     try {
1638         if (handle == NULL) {
1639             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1640                                    "Parameters are NULL output:%p", output);
1641         }
1642
1643         assert(handle->audioIoHandle);
1644
1645         handle->state_changed_callback.onStateChanged = NULL;
1646         handle->state_changed_callback.user_data = NULL;
1647
1648         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
1649         cb.mUserData = NULL;
1650         cb.onStateChanged = NULL;
1651
1652         handle->audioIoHandle->setStateChangedCallback(cb);
1653     } catch (CAudioError e) {
1654         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1655         return __convert_CAudioError(e);
1656     }
1657
1658     return AUDIO_IO_ERROR_NONE;
1659 }