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