Fix invalid format string
[platform/core/api/audio-io.git] / src / cpp / cpp_audio_io.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 #include <new>
19
20 #include "cpp_audio_io.h"
21 #include "audio_io.h"
22 #include "CAudioIODef.h"
23
24 #include <system_info.h>
25
26 #define FEATURE_MICROPHONE          "http://tizen.org/feature/microphone"
27
28 using namespace std;
29 using namespace tizen_media_audio;
30
31 /**
32  * Defines Structures
33  * type : struct
34  * Name : audio_io_stream_cb_s
35  * Declaration : Keeps user callback pointer and user data for delivering an stream event
36  */
37 typedef struct audio_io_stream_cb_s {
38     void* user_data;
39     audio_in_stream_cb onStream;
40
41     audio_io_stream_cb_s() : user_data(NULL), onStream(NULL)
42     {/* Empty Body */}
43 }   audio_io_stream_cb_s;
44
45 /**
46  * Defines Structures
47  * type : struct
48  * Name : audio_io_state_changed_cb_s
49  * Declaration : Keeps user callback pointer and user data for delivering an state changed event
50  */
51 typedef struct audio_io_state_changed_cb_s {
52     void* user_data;
53     audio_in_state_changed_cb onStateChanged;
54
55     audio_io_state_changed_cb_s() : user_data(NULL), onStateChanged(NULL)
56     {/* Empty Body */}
57 }   audio_io_state_changed_cb_s;
58
59 /**
60  * Defines Structures
61  * type : struct
62  * Name : audio_io_s
63  * Declaration : An handle of AudioIO
64  * The handle has two struct for user callback
65  * And the handle has a pointer of private audioIO object
66  * The CAudioIO is a abstract class object about Input and Output
67  */
68 typedef struct audio_io_s {
69     CAudioIO* audioIoHandle;
70     audio_io_stream_cb_s stream_callback;
71     audio_io_state_changed_cb_s state_changed_callback;
72
73     audio_io_s() : audioIoHandle(NULL)
74     {/* Empty Body */}
75 }   audio_io_s;
76
77
78 /**
79  * Internal functions
80  */
81 static audio_io_error_e __convert_CAudioError(CAudioError& error) {
82     audio_io_error_e ret = AUDIO_IO_ERROR_NONE;
83     CAudioError::EError err = error.getError();
84
85     switch (err) {
86     case CAudioError::EError::ERROR_NONE:
87         ret = AUDIO_IO_ERROR_NONE;
88         break;
89     case CAudioError::EError::ERROR_INVALID_ARGUMENT:
90     case CAudioError::EError::ERROR_INVALID_HANDLE:
91     case CAudioError::EError::ERROR_INVALID_SAMPLERATE:
92     case CAudioError::EError::ERROR_INVALID_CHANNEL:
93     case CAudioError::EError::ERROR_INVALID_FORMAT:
94         ret = AUDIO_IO_ERROR_INVALID_PARAMETER;
95         break;
96     case CAudioError::EError::ERROR_DEVICE_NOT_OPENED:
97         ret = AUDIO_IO_ERROR_DEVICE_NOT_OPENED;
98         break;
99     case CAudioError::EError::ERROR_DEVICE_NOT_CLOSED:
100         ret = AUDIO_IO_ERROR_DEVICE_NOT_CLOSED;
101         break;
102     case CAudioError::EError::ERROR_PERMISSION_DENIED:
103         ret = AUDIO_IO_ERROR_PERMISSION_DENIED;
104         break;
105     case CAudioError::EError::ERROR_DEVICE_POLICY_RESTRICTION:
106         ret = AUDIO_IO_ERROR_DEVICE_POLICY_RESTRICTION;
107         break;
108     case CAudioError::EError::ERROR_NOT_SUPPORTED:
109         ret = AUDIO_IO_ERROR_NOT_SUPPORTED;
110         break;
111     case CAudioError::EError::ERROR_NOT_SUPPORTED_TYPE:
112         ret = AUDIO_IO_ERROR_NOT_SUPPORTED_TYPE;
113         break;
114     case CAudioError::EError::ERROR_MAX:
115     case CAudioError::EError::ERROR_INTERNAL_OPERATION:
116     case CAudioError::EError::ERROR_NOT_INITIALIZED:
117     case CAudioError::EError::ERROR_FAILED_OPERATION:
118     case CAudioError::EError::ERROR_INVALID_OPERATION:
119         ret = AUDIO_IO_ERROR_INVALID_OPERATION;
120         break;
121     case CAudioError::EError::ERROR_INVALID_STATE:
122         ret = AUDIO_IO_ERROR_INVALID_STATE;
123         break;
124     case CAudioError::EError::ERROR_OUT_OF_MEMORY:
125     case CAudioError::EError::ERROR_INVALID_POINTER:
126         ret = AUDIO_IO_ERROR_INVALID_BUFFER;
127         break;
128     case CAudioError::EError::ERROR_POLICY_BLOCKED:
129     case CAudioError::EError::ERROR_POLICY_INTERRUPTED:
130     case CAudioError::EError::ERROR_POLICY_DUPLICATED:
131         ret = AUDIO_IO_ERROR_SOUND_POLICY;
132         break;
133     }
134
135     return ret;
136 }
137
138 static void __convert_channel_2_audio_info_channel(const audio_channel_e& src_channel,
139                                                    CAudioInfo::EChannel& dst_channel) {
140     switch (src_channel) {
141     case AUDIO_CHANNEL_MONO:
142         dst_channel = CAudioInfo::EChannel::CHANNEL_MONO;
143         break;
144     case AUDIO_CHANNEL_STEREO:
145         dst_channel = CAudioInfo::EChannel::CHANNEL_STEREO;
146         break;
147     default:
148         dst_channel = CAudioInfo::EChannel::CHANNEL_MONO;
149         break;
150     }
151 }
152
153 static void __convert_audio_info_channel_2_channel(const CAudioInfo::EChannel& src_channel,
154                                                    audio_channel_e& dst_channel) {
155     switch (src_channel) {
156     case CAudioInfo::EChannel::CHANNEL_MONO:
157         dst_channel = AUDIO_CHANNEL_MONO;
158         break;
159     case CAudioInfo::EChannel::CHANNEL_STEREO:
160         dst_channel = AUDIO_CHANNEL_STEREO;
161         break;
162     default:
163         dst_channel = AUDIO_CHANNEL_MONO;
164         break;
165     }
166 }
167
168 static void __convert_sample_type_2_audio_info_sample_type(const audio_sample_type_e& src_type,
169                                                            CAudioInfo::ESampleType& dst_type) {
170     switch (src_type) {
171     case AUDIO_SAMPLE_TYPE_U8:
172         dst_type = CAudioInfo::ESampleType::SAMPLE_TYPE_U8;
173         break;
174     case AUDIO_SAMPLE_TYPE_S16_LE:
175         dst_type = CAudioInfo::ESampleType::SAMPLE_TYPE_S16_LE;
176         break;
177     case AUDIO_SAMPLE_TYPE_S24_LE:
178         dst_type = CAudioInfo::ESampleType::SAMPLE_TYPE_S24_LE;
179         break;
180     case AUDIO_SAMPLE_TYPE_S24_32_LE:
181         dst_type = CAudioInfo::ESampleType::SAMPLE_TYPE_S24_32_LE;
182         break;
183     default:
184         dst_type = CAudioInfo::ESampleType::SAMPLE_TYPE_U8;
185         break;
186     }
187 }
188
189 static void __convert_audio_info_sample_type_2_sample_type(const CAudioInfo::ESampleType& src_type,
190                                                            audio_sample_type_e& dst_type) {
191     switch (src_type) {
192     case CAudioInfo::ESampleType::SAMPLE_TYPE_U8:
193         dst_type = AUDIO_SAMPLE_TYPE_U8;
194         break;
195     case CAudioInfo::ESampleType::SAMPLE_TYPE_S16_LE:
196         dst_type = AUDIO_SAMPLE_TYPE_S16_LE;
197         break;
198     case CAudioInfo::ESampleType::SAMPLE_TYPE_S24_LE:
199         dst_type = AUDIO_SAMPLE_TYPE_S24_LE;
200         break;
201     case CAudioInfo::ESampleType::SAMPLE_TYPE_S24_32_LE:
202         dst_type = AUDIO_SAMPLE_TYPE_S24_32_LE;
203         break;
204     default:
205         dst_type = AUDIO_SAMPLE_TYPE_U8;
206         break;
207     }
208 }
209
210 static void __convert_sound_type_2_audio_info_audio_type(const sound_type_e& src_type,
211                                                          CAudioInfo::EAudioType& dst_type) {
212     switch (src_type) {
213     case SOUND_TYPE_SYSTEM:
214         dst_type = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_SYSTEM;
215         break;
216     case SOUND_TYPE_NOTIFICATION:
217         dst_type = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_NOTIFICATION;
218         break;
219     case SOUND_TYPE_ALARM:
220         dst_type = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_ALARM;
221         break;
222     case SOUND_TYPE_RINGTONE:
223         dst_type = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_RINGTONE_VOIP;
224         break;
225     case SOUND_TYPE_MEDIA:
226         dst_type = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA;
227         break;
228     case SOUND_TYPE_CALL:
229         dst_type = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_SYSTEM;
230         break;
231     case SOUND_TYPE_VOIP:
232         dst_type = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOIP;
233         break;
234     case SOUND_TYPE_VOICE:
235         dst_type = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOICE_INFORMATION;
236         break;
237     default:
238         dst_type = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA;
239         break;
240     }
241 }
242
243 static void __convert_audio_info_audio_type_2_sound_type(const CAudioInfo::EAudioType& src_type,
244                                                          sound_type_e& dst_type) {
245     switch (src_type) {
246     case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA:
247         dst_type = SOUND_TYPE_MEDIA;
248         break;
249     case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_SYSTEM:
250         dst_type = SOUND_TYPE_SYSTEM;
251         break;
252     case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_ALARM:
253         dst_type = SOUND_TYPE_ALARM;
254         break;
255     case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_NOTIFICATION:
256     case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_EMERGENCY:
257         dst_type = SOUND_TYPE_NOTIFICATION;
258         break;
259     case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOICE_INFORMATION:
260         dst_type = SOUND_TYPE_VOICE;
261         break;
262     case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_RINGTONE_VOIP:
263         dst_type = SOUND_TYPE_RINGTONE;
264         break;
265     case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOIP:
266         dst_type = SOUND_TYPE_VOIP;
267         break;
268     default:
269         dst_type = SOUND_TYPE_MEDIA;
270         break;
271     }
272 }
273
274 static audio_io_state_e __convert_state_type(const CAudioInfo::EAudioIOState src_state) {
275     audio_io_state_e dst_state;
276
277     switch (src_state) {
278     case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE:
279         dst_state = AUDIO_IO_STATE_IDLE;
280         break;
281     case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_IDLE:
282         dst_state = AUDIO_IO_STATE_IDLE;
283         break;
284     case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_RUNNING:
285         dst_state = AUDIO_IO_STATE_RUNNING;
286         break;
287     case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_PAUSED:
288         dst_state = AUDIO_IO_STATE_PAUSED;
289         break;
290     default:
291         dst_state = AUDIO_IO_STATE_IDLE;
292         break;
293     }
294     return dst_state;
295 }
296
297 static void __check_audio_param(int sample_rate, audio_channel_e channel, audio_sample_type_e type) {
298     if (sample_rate < 0)
299         THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid sample rate :%d", sample_rate);
300
301     if (channel != AUDIO_CHANNEL_MONO && channel != AUDIO_CHANNEL_STEREO)
302         THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid channel :%d", channel);
303
304     if (type != AUDIO_SAMPLE_TYPE_U8 &&
305         type != AUDIO_SAMPLE_TYPE_S16_LE &&
306         type != AUDIO_SAMPLE_TYPE_S24_LE &&
307         type != AUDIO_SAMPLE_TYPE_S24_32_LE)
308         THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid sample type :%d", type);
309 }
310
311 static void __check_audio_param(int sample_rate, audio_channel_e channel, audio_sample_type_e type, sound_type_e sound_type) {
312     __check_audio_param(sample_rate, channel, type);
313
314     if (sound_type < SOUND_TYPE_SYSTEM || sound_type > SOUND_TYPE_VOICE)
315         THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid sound type : %d", sound_type);
316 }
317
318 static CAudioInfo __generate_audio_input_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type) {
319     CAudioInfo::EChannel dstChannel;
320     CAudioInfo::ESampleType dstSampleType;
321     CAudioInfo::EAudioType dstAudioType = CAudioInfo::EAudioType::AUDIO_IN_TYPE_MEDIA;
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) {
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 void __handle_safe_free(audio_io_s* handle, void *obj, bool is_output) {
342     VALID_POINTER_START(handle)
343         SAFE_FINALIZE(handle->audioIoHandle);
344         SAFE_DELETE(handle->audioIoHandle);
345         SAFE_DELETE(handle);
346     VALID_POINTER_END
347
348     VALID_POINTER_START(obj)
349         if (is_output)
350             *(audio_out_h *)obj = NULL;
351         else
352             *(audio_in_h *)obj = NULL;
353     VALID_POINTER_END
354 }
355
356 /**
357  * Implements CAPI functions
358  */
359 int cpp_audio_in_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_in_h *input) {
360     audio_io_s* handle = NULL;
361     bool mic_enable = false;
362     int ret = 0;
363     try {
364         if (input == NULL) {
365             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
366                                   "Parameters are NULL input:%p", input);
367         }
368
369         __check_audio_param(sample_rate, channel, type);
370
371         AUDIO_IO_LOGD("samplerate:[%d] channel:[0x%x] sample_type:[0x%x]", sample_rate, channel, type);
372
373         /* If MIC is not supported, return NOT_SUPPORTED error */
374         ret = system_info_get_platform_bool(FEATURE_MICROPHONE, &mic_enable);
375         AUDIO_IO_LOGD("system_info_platform [%s]=[%d], ret[%d]", FEATURE_MICROPHONE, mic_enable, ret);
376         if (ret != SYSTEM_INFO_ERROR_NONE || !mic_enable) {
377             THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "System doesn't support microphone!");
378         }
379
380         CAudioInfo audioInfo = __generate_audio_input_info(sample_rate, channel, type);
381
382         handle = new audio_io_s;
383         handle->audioIoHandle = new CAudioInput(audioInfo);
384         handle->audioIoHandle->initialize();
385
386         AUDIO_IO_LOGD("[%p] created", handle);
387         *input = handle;
388     } catch (CAudioError& e) {
389         AUDIO_IO_LOGE("%s", e.getErrorMsg());
390         __handle_safe_free(handle, (void *)input, false);
391         return __convert_CAudioError(e);
392     } catch (const std::bad_alloc&) {
393         CAudioError e = CAudioError::EError::ERROR_OUT_OF_MEMORY;
394         AUDIO_IO_LOGE("Failed to allocate handle");
395         __handle_safe_free(handle, (void *)input, false);
396         return __convert_CAudioError(e);
397     }
398
399     return AUDIO_IO_ERROR_NONE;
400 }
401
402 int cpp_audio_in_destroy(audio_in_h input) {
403     audio_io_s* handle = static_cast<audio_io_s*>(input);
404
405     try {
406         if (handle == NULL)
407             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
408                                   "Parameters are NULL input:%p", input);
409         assert(handle->audioIoHandle);
410         AUDIO_IO_LOGD("[%p]", handle);
411
412         /* Internal unprepare for backward compatibility */
413         handle->audioIoHandle->unprepare();
414
415         SAFE_FINALIZE(handle->audioIoHandle);
416         SAFE_DELETE(handle->audioIoHandle);
417         SAFE_DELETE(handle);
418     } catch (CAudioError& e) {
419         AUDIO_IO_LOGE("%s", e.getErrorMsg());
420         return __convert_CAudioError(e);
421     }
422
423     AUDIO_IO_LOGD("destroyed");
424
425     return AUDIO_IO_ERROR_NONE;
426 }
427
428 int cpp_audio_in_set_sound_stream_info(audio_in_h input, sound_stream_info_h stream_info) {
429     audio_io_s* handle = static_cast<audio_io_s*>(input);
430
431     try {
432         if (handle == NULL || stream_info == NULL)
433             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
434                                    "Parameters are NULL input:%p, stream_info:%p", input, stream_info);
435         assert(handle->audioIoHandle);
436         AUDIO_IO_LOGD("[%p], stream_info:[%p]", handle, stream_info);
437
438         handle->audioIoHandle->setStreamInfo(stream_info);
439     } catch (CAudioError& e) {
440         AUDIO_IO_LOGE("%s", e.getErrorMsg());
441         return __convert_CAudioError(e);
442     }
443
444     AUDIO_IO_LOGD("[%p] done", handle);
445
446     return AUDIO_IO_ERROR_NONE;
447 }
448
449 int cpp_audio_in_prepare(audio_in_h input) {
450     audio_io_s* handle = static_cast<audio_io_s*>(input);
451
452     try {
453         if (handle == NULL)
454             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
455                                    "Parameters are NULL input:%p", input);
456         assert(handle->audioIoHandle);
457         AUDIO_IO_LOGD("[%p]", handle);
458
459         handle->audioIoHandle->prepare();
460     } catch (CAudioError& e) {
461         AUDIO_IO_LOGE("%s", e.getErrorMsg());
462         return __convert_CAudioError(e);
463     }
464
465     AUDIO_IO_LOGD("[%p] prepared", handle);
466
467     return AUDIO_IO_ERROR_NONE;
468 }
469
470 int cpp_audio_in_unprepare(audio_in_h input) {
471     audio_io_s* handle = static_cast<audio_io_s*>(input);
472
473     try {
474         if (handle == NULL)
475             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
476                                    "Parameters are NULL input:%p", input);
477         assert(handle->audioIoHandle);
478         AUDIO_IO_LOGD("[%p]", handle);
479
480         handle->audioIoHandle->unprepare();
481     } catch (CAudioError& e) {
482         AUDIO_IO_LOGE("%s", e.getErrorMsg());
483         return __convert_CAudioError(e);
484     }
485
486     AUDIO_IO_LOGD("[%p] unprepared", handle);
487
488     return AUDIO_IO_ERROR_NONE;
489 }
490
491 int cpp_audio_in_pause(audio_in_h input) {
492     audio_io_s* handle = static_cast<audio_io_s*>(input);
493
494     try {
495         if (handle == NULL)
496             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
497                                    "Parameters are NULL input:%p", input);
498         assert(handle->audioIoHandle);
499         AUDIO_IO_LOGD("[%p]", handle);
500
501         handle->audioIoHandle->pause();
502     } catch (CAudioError& e) {
503         AUDIO_IO_LOGE("%s", e.getErrorMsg());
504         return __convert_CAudioError(e);
505     }
506
507     AUDIO_IO_LOGD("[%p] paused", handle);
508
509     return AUDIO_IO_ERROR_NONE;
510 }
511
512 int cpp_audio_in_resume(audio_in_h input) {
513     audio_io_s* handle = static_cast<audio_io_s*>(input);
514
515     try {
516         if (handle == NULL)
517             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
518                                    "Parameters are NULL input:%p", input);
519         assert(handle->audioIoHandle);
520         AUDIO_IO_LOGD("[%p]", handle);
521
522         handle->audioIoHandle->resume();
523     } catch (CAudioError& e) {
524         AUDIO_IO_LOGE("%s", e.getErrorMsg());
525         return __convert_CAudioError(e);
526     }
527
528     AUDIO_IO_LOGD("[%p] resumed", handle);
529
530     return AUDIO_IO_ERROR_NONE;
531 }
532
533 int cpp_audio_in_flush(audio_in_h input) {
534     audio_io_s* handle = static_cast<audio_io_s*>(input);
535
536     try {
537         if (handle == NULL)
538             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
539                                    "Parameters are NULL input:%p", input);
540         assert(handle->audioIoHandle);
541         AUDIO_IO_LOGD("[%p]", handle);
542
543         handle->audioIoHandle->flush();
544     } catch (CAudioError& e) {
545         AUDIO_IO_LOGE("%s", e.getErrorMsg());
546         return __convert_CAudioError(e);
547     }
548
549     AUDIO_IO_LOGD("[%p] flushed", handle);
550
551     return AUDIO_IO_ERROR_NONE;
552 }
553
554 int cpp_audio_in_read(audio_in_h input, void *buffer, unsigned int length) {
555     audio_io_s* handle = static_cast<audio_io_s*>(input);
556     int ret = 0;
557
558     try {
559         if (handle == NULL || buffer == NULL)
560             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
561                                    "Parameters are NULL input:%p, buffer:%p", input, buffer);
562         assert(handle->audioIoHandle);
563
564         CAudioInput* inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
565         if (inputHandle == NULL) {
566             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
567         }
568
569         size_t readn = inputHandle->read(buffer, static_cast<size_t>(length));
570         ret = static_cast<int>(readn);
571 #ifdef _AUDIO_IO_DEBUG_TIMING_
572         AUDIO_IO_LOGD("readn:%zu", readn);
573 #endif
574     } catch (CAudioError& e) {
575         AUDIO_IO_LOGE("%s", e.getErrorMsg());
576         return __convert_CAudioError(e);
577     }
578
579     return ret;
580 }
581
582 int cpp_audio_in_get_buffer_size(audio_in_h input, int *size) {
583     audio_io_s* handle = static_cast<audio_io_s*>(input);
584
585     try {
586         if (handle == NULL || size == NULL)
587             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
588                                    "Parameters are NULL input:%p, size:%p", input, size);
589         assert(handle->audioIoHandle);
590
591         CAudioIO* inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
592         if (inputHandle == NULL) {
593             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
594         }
595         *size = inputHandle->getBufferSize();
596     } catch (CAudioError& e) {
597         AUDIO_IO_LOGE("%s", e.getErrorMsg());
598         return __convert_CAudioError(e);
599     }
600
601     return AUDIO_IO_ERROR_NONE;
602 }
603
604 int cpp_audio_in_get_sample_rate(audio_in_h input, int *sample_rate) {
605     audio_io_s* handle = static_cast<audio_io_s*>(input);
606
607     try {
608         if (handle == NULL || sample_rate == NULL)
609             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
610                                    "Parameters are NULL input:%p, sample_rate:%p", input, sample_rate);
611         assert(handle->audioIoHandle);
612
613         *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
614     } catch (CAudioError& e) {
615         AUDIO_IO_LOGE("%s", e.getErrorMsg());
616         return __convert_CAudioError(e);
617     }
618
619     return AUDIO_IO_ERROR_NONE;
620 }
621
622 int cpp_audio_in_get_channel(audio_in_h input, audio_channel_e *channel) {
623     audio_io_s* handle = static_cast<audio_io_s*>(input);
624
625     try {
626         if (handle == NULL || channel == NULL)
627             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
628                                    "Parameters are NULL input:%p, channel:%p", input, channel);
629         assert(handle->audioIoHandle);
630
631         const CAudioInfo::EChannel srcChannel = handle->audioIoHandle->getAudioInfo().getChannel();
632         audio_channel_e dstChannel = AUDIO_CHANNEL_MONO;
633         __convert_audio_info_channel_2_channel(srcChannel, dstChannel);
634
635         *channel = dstChannel;
636     } catch (CAudioError& e) {
637         AUDIO_IO_LOGE("%s", e.getErrorMsg());
638         return __convert_CAudioError(e);
639     }
640
641     return AUDIO_IO_ERROR_NONE;
642 }
643
644 int cpp_audio_in_get_sample_type(audio_in_h input, audio_sample_type_e *type) {
645     audio_io_s* handle = static_cast<audio_io_s*>(input);
646
647     try {
648         if (handle == NULL || type == NULL)
649             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
650                                    "Parameters are NULL input:%p, type:%p", input, type);
651         assert(handle->audioIoHandle);
652
653         const CAudioInfo::ESampleType srcSampleType = handle->audioIoHandle->getAudioInfo().getSampleType();
654         audio_sample_type_e dstSampleType = AUDIO_SAMPLE_TYPE_U8;
655         __convert_audio_info_sample_type_2_sample_type(srcSampleType, dstSampleType);
656
657         *type = dstSampleType;
658     } catch (CAudioError& e) {
659         AUDIO_IO_LOGE("%s", e.getErrorMsg());
660         return __convert_CAudioError(e);
661     }
662
663     return AUDIO_IO_ERROR_NONE;
664 }
665
666 static void __stream_cb_internal(size_t nbytes, void *user_data) {
667     audio_io_s* audioIo = static_cast<audio_io_s*>(user_data);
668     assert(audioIo);
669
670     if (audioIo->stream_callback.onStream)
671         audioIo->stream_callback.onStream(audioIo, nbytes, audioIo->stream_callback.user_data);
672 }
673
674 static void __state_changed_cb_internal(CAudioInfo::EAudioIOState state,
675                                         CAudioInfo::EAudioIOState state_prev,
676                                         bool by_policy,
677                                         void *user_data) {
678     audio_io_s* audioIo = static_cast<audio_io_s*>(user_data);
679     assert(audioIo);
680
681     if (audioIo->state_changed_callback.onStateChanged)
682         audioIo->state_changed_callback.onStateChanged(audioIo, __convert_state_type(state_prev),
683                                                        __convert_state_type(state), by_policy,
684                                                        audioIo->state_changed_callback.user_data);
685 }
686
687 int cpp_audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* user_data) {
688     audio_io_s* handle = static_cast<audio_io_s*>(input);
689
690     try {
691         if (handle == NULL || callback == NULL)
692             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
693                                    "Parameters are NULL input:%p, callback:%p", input, callback);
694         assert(handle->audioIoHandle);
695         AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
696
697         handle->stream_callback.onStream = callback;
698         handle->stream_callback.user_data = user_data;
699
700         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
701         cb.mUserData = static_cast<void*>(handle);
702         cb.onStream  = __stream_cb_internal;
703
704         handle->audioIoHandle->setStreamCallback(cb);
705     } catch (CAudioError& e) {
706         AUDIO_IO_LOGE("%s", e.getErrorMsg());
707         return __convert_CAudioError(e);
708     }
709
710     AUDIO_IO_LOGD("[%p] done", handle);
711
712     return AUDIO_IO_ERROR_NONE;
713 }
714
715 int cpp_audio_in_unset_stream_cb(audio_in_h input) {
716     audio_io_s* handle = static_cast<audio_io_s*>(input);
717
718     try {
719         if (handle == NULL)
720             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
721                                    "Parameters are NULL input:%p", input);
722         assert(handle->audioIoHandle);
723         AUDIO_IO_LOGD("[%p]", handle);
724
725         handle->stream_callback.onStream = NULL;
726         handle->stream_callback.user_data = NULL;
727
728         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
729         cb.mUserData = NULL;
730         cb.onStream  = NULL;
731
732         handle->audioIoHandle->setStreamCallback(cb);
733     } catch (CAudioError& e) {
734         AUDIO_IO_LOGE("%s", e.getErrorMsg());
735         return __convert_CAudioError(e);
736     }
737
738     AUDIO_IO_LOGD("[%p] done", handle);
739
740     return AUDIO_IO_ERROR_NONE;
741 }
742
743 int cpp_audio_in_peek(audio_in_h input, const void **buffer, unsigned int *length) {
744     audio_io_s* handle = static_cast<audio_io_s*>(input);
745     size_t _length = 0;
746
747     try {
748         if (handle == NULL || buffer == NULL)
749             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
750                                    "Parameters are NULL input:%p, buffer:%p", input, buffer);
751
752         CAudioInput* inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
753         if (inputHandle == NULL)
754             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
755
756         inputHandle->peek(buffer, &_length);
757     } catch (CAudioError& e) {
758         AUDIO_IO_LOGE("%s", e.getErrorMsg());
759         return __convert_CAudioError(e);
760     }
761
762     *length = (unsigned int)_length;
763
764     return AUDIO_IO_ERROR_NONE;
765 }
766
767 int cpp_audio_in_drop(audio_in_h input) {
768     audio_io_s* handle = static_cast<audio_io_s*>(input);
769
770     try {
771         if (handle == NULL)
772             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
773                                    "Parameters are NULL input:%p", input);
774
775         CAudioInput* inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
776         if (inputHandle == NULL)
777             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
778
779         inputHandle->drop();
780     } catch (CAudioError& e) {
781         AUDIO_IO_LOGE("%s", e.getErrorMsg());
782         return __convert_CAudioError(e);
783     }
784
785     return AUDIO_IO_ERROR_NONE;
786 }
787
788 int cpp_audio_in_set_state_changed_cb(audio_in_h input, audio_in_state_changed_cb callback, void* user_data) {
789     audio_io_s* handle = static_cast<audio_io_s*>(input);
790
791     try {
792         if (handle == NULL || callback == NULL)
793             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
794                                    "Parameters are NULL input:%p, callback:%p", input, callback);
795         assert(handle->audioIoHandle);
796         AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
797
798         handle->state_changed_callback.onStateChanged = callback;
799         handle->state_changed_callback.user_data = user_data;
800
801         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
802         cb.mUserData = static_cast<void*>(handle);
803         cb.onStateChanged = __state_changed_cb_internal;
804
805         handle->audioIoHandle->setStateChangedCallback(cb);
806     } catch (CAudioError& e) {
807         AUDIO_IO_LOGE("%s", e.getErrorMsg());
808         return __convert_CAudioError(e);
809     }
810
811     AUDIO_IO_LOGD("[%p] done", handle);
812
813     return AUDIO_IO_ERROR_NONE;
814 }
815
816 int cpp_audio_in_unset_state_changed_cb(audio_in_h input) {
817     audio_io_s* handle = static_cast<audio_io_s*>(input);
818
819     try {
820         if (handle == NULL)
821             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
822                                    "Parameters are NULL output:%p", input);
823         assert(handle->audioIoHandle);
824         AUDIO_IO_LOGD("[%p]", handle);
825
826         handle->state_changed_callback.onStateChanged = NULL;
827         handle->state_changed_callback.user_data = NULL;
828
829         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
830         cb.mUserData = NULL;
831         cb.onStateChanged  = NULL;
832
833         handle->audioIoHandle->setStateChangedCallback(cb);
834     } catch (CAudioError& e) {
835         AUDIO_IO_LOGE("%s", e.getErrorMsg());
836         return __convert_CAudioError(e);
837     }
838
839     AUDIO_IO_LOGD("[%p] done", handle);
840
841     return AUDIO_IO_ERROR_NONE;
842 }
843
844
845 /**
846  * Audio Out
847  */
848 int cpp_audio_out_create_new(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_out_h *output) {
849     audio_io_s* handle = NULL;
850     try {
851         if (output == NULL)
852             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
853                                    "Parameters are NULL output:%p", output);
854
855         __check_audio_param(sample_rate, channel, type, SOUND_TYPE_SYSTEM /*default check */);
856
857         AUDIO_IO_LOGD("samplerate:[%d] channel:[0x%x] sample_type:[0x%x]", sample_rate, channel, type);
858         CAudioInfo audioInfo = __generate_audio_output_info(sample_rate, channel, type, SOUND_TYPE_MEDIA);
859
860         handle = new audio_io_s;
861         handle->audioIoHandle = new CAudioOutput(audioInfo);
862         handle->audioIoHandle->initialize();
863
864         AUDIO_IO_LOGD("[%p] created", handle);
865         *output = handle;
866     } catch (CAudioError& e) {
867         AUDIO_IO_LOGE("%s", e.getErrorMsg());
868         __handle_safe_free(handle, (void *)output, true);
869         return __convert_CAudioError(e);
870     } catch (const std::bad_alloc&) {
871         CAudioError e = CAudioError::EError::ERROR_OUT_OF_MEMORY;
872         AUDIO_IO_LOGE("Failed to allocate handle");
873         __handle_safe_free(handle, (void *)output, true);
874         return __convert_CAudioError(e);
875     }
876
877     return AUDIO_IO_ERROR_NONE;
878 }
879
880 int cpp_audio_out_destroy(audio_out_h output) {
881     audio_io_s* handle = static_cast<audio_io_s*>(output);
882
883     try {
884         if (handle == NULL)
885             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
886                                    "Parameter is NULL output:%p", output);
887         assert(handle->audioIoHandle);
888         AUDIO_IO_LOGD("[%p]", handle);
889
890         /* Internal unprepare for backward compatibility */
891         handle->audioIoHandle->unprepare();
892
893         SAFE_FINALIZE(handle->audioIoHandle);
894         SAFE_DELETE(handle->audioIoHandle);
895         SAFE_DELETE(handle);
896     } catch (CAudioError& e) {
897         AUDIO_IO_LOGE("%s", e.getErrorMsg());
898         return __convert_CAudioError(e);
899     }
900
901     AUDIO_IO_LOGD("destroyed");
902
903     return AUDIO_IO_ERROR_NONE;
904 }
905
906 int cpp_audio_out_set_sound_stream_info(audio_out_h output, sound_stream_info_h stream_info) {
907     audio_io_s* handle = static_cast<audio_io_s*>(output);
908
909     try {
910         if (handle == NULL || stream_info == NULL)
911             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
912                                    "Parameters are NULL output:%p, stream_info:%p", output, stream_info);
913         assert(handle->audioIoHandle);
914         AUDIO_IO_LOGD("[%p], stream_info:[%p]", handle, stream_info);
915
916         handle->audioIoHandle->setStreamInfo(stream_info);
917     } catch (CAudioError& e) {
918         AUDIO_IO_LOGE("%s", e.getErrorMsg());
919         return __convert_CAudioError(e);
920     }
921
922     AUDIO_IO_LOGD("[%p] done", handle);
923
924     return AUDIO_IO_ERROR_NONE;
925 }
926
927 int cpp_audio_out_prepare(audio_out_h output) {
928     audio_io_s* handle = static_cast<audio_io_s*>(output);
929
930     try {
931         if (handle == NULL)
932             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
933                                    "Parameter is NULL output:%p", output);
934         assert(handle->audioIoHandle);
935         AUDIO_IO_LOGD("[%p]", handle);
936
937         handle->audioIoHandle->prepare();
938     } catch (CAudioError& e) {
939         AUDIO_IO_LOGE("%s", e.getErrorMsg());
940         return __convert_CAudioError(e);
941     }
942
943     AUDIO_IO_LOGD("[%p] prepared", handle);
944
945     return AUDIO_IO_ERROR_NONE;
946 }
947
948 int cpp_audio_out_unprepare(audio_out_h output) {
949     audio_io_s* handle = static_cast<audio_io_s*>(output);
950
951     try {
952         if (handle == NULL)
953             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
954                                    "Parameter is NULL output:%p", output);
955         assert(handle->audioIoHandle);
956         AUDIO_IO_LOGD("[%p]", handle);
957
958         handle->audioIoHandle->unprepare();
959     } catch (CAudioError& e) {
960         AUDIO_IO_LOGE("%s", e.getErrorMsg());
961         return __convert_CAudioError(e);
962     }
963
964     AUDIO_IO_LOGD("[%p] unprepared", handle);
965
966     return AUDIO_IO_ERROR_NONE;
967 }
968
969 int cpp_audio_out_pause(audio_out_h output) {
970     audio_io_s* handle = static_cast<audio_io_s*>(output);
971
972     try {
973         if (handle == NULL)
974             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
975                                    "Parameter is NULL output:%p", output);
976         assert(handle->audioIoHandle);
977         AUDIO_IO_LOGD("[%p]", handle);
978
979         handle->audioIoHandle->pause();
980     } catch (CAudioError& e) {
981         AUDIO_IO_LOGE("%s", e.getErrorMsg());
982         return __convert_CAudioError(e);
983     }
984
985     AUDIO_IO_LOGD("[%p] paused", handle);
986
987     return AUDIO_IO_ERROR_NONE;
988 }
989
990 int cpp_audio_out_resume(audio_out_h output) {
991     audio_io_s* handle = static_cast<audio_io_s*>(output);
992
993     try {
994         if (handle == NULL)
995             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
996                                    "Parameter is NULL output:%p", output);
997         assert(handle->audioIoHandle);
998         AUDIO_IO_LOGD("[%p]", handle);
999
1000         handle->audioIoHandle->resume();
1001     } catch (CAudioError& e) {
1002         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1003         return __convert_CAudioError(e);
1004     }
1005
1006     AUDIO_IO_LOGD("[%p] resumed", handle);
1007
1008     return AUDIO_IO_ERROR_NONE;
1009 }
1010
1011 int cpp_audio_out_drain(audio_out_h output) {
1012     audio_io_s* handle = static_cast<audio_io_s*>(output);
1013
1014     try {
1015         if (handle == NULL)
1016             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1017                                    "Parameter is NULL output:%p", output);
1018         assert(handle->audioIoHandle);
1019         AUDIO_IO_LOGD("[%p]", handle);
1020
1021         handle->audioIoHandle->drain();
1022     } catch (CAudioError& e) {
1023         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1024         return __convert_CAudioError(e);
1025     }
1026
1027     AUDIO_IO_LOGD("[%p] drained", handle);
1028
1029     return AUDIO_IO_ERROR_NONE;
1030 }
1031
1032 int cpp_audio_out_flush(audio_out_h output) {
1033     audio_io_s* handle = static_cast<audio_io_s*>(output);
1034
1035     try {
1036         if (handle == NULL)
1037             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1038                                    "Parameter is NULL output:%p", output);
1039         assert(handle->audioIoHandle);
1040         AUDIO_IO_LOGD("[%p]", handle);
1041
1042         handle->audioIoHandle->flush();
1043     } catch (CAudioError& e) {
1044         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1045         return __convert_CAudioError(e);
1046     }
1047
1048     AUDIO_IO_LOGD("[%p] flushed", handle);
1049
1050     return AUDIO_IO_ERROR_NONE;
1051 }
1052
1053 int cpp_audio_out_write(audio_out_h output, void *buffer, unsigned int length) {
1054     audio_io_s* handle = static_cast<audio_io_s*>(output);
1055     int ret = 0;
1056
1057     try {
1058         if (handle == NULL || buffer == NULL)
1059             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1060                                    "Parameter is NULL output:%p, buffer:%p", output, buffer);
1061         assert(handle->audioIoHandle);
1062
1063         CAudioOutput* outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
1064         if (outputHandle == NULL)
1065             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1066
1067         size_t written = outputHandle->write(buffer, static_cast<size_t>(length));
1068         ret = static_cast<int>(written);
1069 #ifdef _AUDIO_IO_DEBUG_TIMING_
1070         AUDIO_IO_LOGD("written:%zu", written);
1071 #endif
1072     } catch (CAudioError& e) {
1073         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1074         return __convert_CAudioError(e);
1075     }
1076
1077     return ret;
1078 }
1079
1080 int cpp_audio_out_get_buffer_size(audio_out_h output, int *size) {
1081     audio_io_s* handle = static_cast<audio_io_s*>(output);
1082
1083     try {
1084         if (handle == NULL || size == NULL)
1085             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1086                                    "Parameters are NULL output:%p, size:%p", output, size);
1087         assert(handle->audioIoHandle);
1088
1089         CAudioOutput* outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
1090         if (outputHandle == NULL)
1091             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1092
1093         *size = outputHandle->getBufferSize();
1094     } catch (CAudioError& e) {
1095         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1096         return __convert_CAudioError(e);
1097     }
1098
1099     return AUDIO_IO_ERROR_NONE;
1100 }
1101
1102 int cpp_audio_out_get_sample_rate(audio_out_h output, int *sample_rate) {
1103     audio_io_s* handle = static_cast<audio_io_s*>(output);
1104
1105     try {
1106         if (handle == NULL || sample_rate == NULL)
1107             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1108                                    "Parameters are NULL output:%p, sample_rate:%p", output, sample_rate);
1109         assert(handle->audioIoHandle);
1110
1111         *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
1112     } catch (CAudioError& e) {
1113         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1114         return __convert_CAudioError(e);
1115     }
1116
1117     return AUDIO_IO_ERROR_NONE;
1118 }
1119
1120 int cpp_audio_out_get_channel(audio_out_h output, audio_channel_e *channel) {
1121     audio_io_s* handle = static_cast<audio_io_s*>(output);
1122
1123     try {
1124         if (handle == NULL || channel == NULL)
1125             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1126                                    "Parameters are NULL output:%p, channel:%p", output, channel);
1127         assert(handle->audioIoHandle);
1128
1129         const CAudioInfo::EChannel srcChannel = handle->audioIoHandle->getAudioInfo().getChannel();
1130         audio_channel_e dstChannel = AUDIO_CHANNEL_MONO;
1131         __convert_audio_info_channel_2_channel(srcChannel, dstChannel);
1132
1133         *channel = dstChannel;
1134     } catch (CAudioError& e) {
1135         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1136         return __convert_CAudioError(e);
1137     }
1138
1139     return AUDIO_IO_ERROR_NONE;
1140 }
1141
1142 int cpp_audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type) {
1143     audio_io_s* handle = static_cast<audio_io_s*>(output);
1144
1145     try {
1146         if (handle == NULL || type == NULL)
1147             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1148                                    "Parameters are NULL output:%p, type:%p", output, type);
1149         assert(handle->audioIoHandle);
1150
1151         const CAudioInfo::ESampleType srcSampleType = handle->audioIoHandle->getAudioInfo().getSampleType();
1152         audio_sample_type_e dstSampleType = AUDIO_SAMPLE_TYPE_U8;
1153         __convert_audio_info_sample_type_2_sample_type(srcSampleType, dstSampleType);
1154
1155         *type = dstSampleType;
1156     } catch (CAudioError& e) {
1157         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1158         return __convert_CAudioError(e);
1159     }
1160
1161     return AUDIO_IO_ERROR_NONE;
1162 }
1163
1164 int cpp_audio_out_get_sound_type(audio_out_h output, sound_type_e *type) {
1165     audio_io_s* handle = static_cast<audio_io_s*>(output);
1166
1167     try {
1168         if (handle == NULL || type == NULL)
1169             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1170                                    "Parameters are NULL output:%p, type:%p", output, type);
1171         assert(handle->audioIoHandle);
1172
1173         const CAudioInfo::EAudioType srcAudioType = handle->audioIoHandle->getAudioInfo().getAudioType();
1174         sound_type_e dstSoundType = SOUND_TYPE_MEDIA;
1175         __convert_audio_info_audio_type_2_sound_type(srcAudioType, dstSoundType);
1176
1177         *type = dstSoundType;
1178     } catch (CAudioError& e) {
1179         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1180         return __convert_CAudioError(e);
1181     }
1182
1183     return AUDIO_IO_ERROR_NONE;
1184 }
1185
1186 int cpp_audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* user_data) {
1187     audio_io_s* handle = static_cast<audio_io_s*>(output);
1188
1189     try {
1190         if (handle == NULL || callback == NULL)
1191             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1192                                    "Parameters are NULL output:%p, callback:%p", output, callback);
1193         assert(handle->audioIoHandle);
1194         AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
1195
1196         handle->stream_callback.onStream = callback;
1197         handle->stream_callback.user_data = user_data;
1198
1199         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
1200         cb.mUserData = static_cast<void*>(handle);
1201         cb.onStream = __stream_cb_internal;
1202
1203         handle->audioIoHandle->setStreamCallback(cb);
1204     } catch (CAudioError& e) {
1205         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1206         return __convert_CAudioError(e);
1207     }
1208
1209     AUDIO_IO_LOGD("[%p] done", handle);
1210
1211     return AUDIO_IO_ERROR_NONE;
1212 }
1213
1214 int cpp_audio_out_unset_stream_cb(audio_out_h output) {
1215     audio_io_s* handle = static_cast<audio_io_s*>(output);
1216
1217     try {
1218         if (handle == NULL)
1219             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1220                                    "Parameters are NULL output:%p", output);
1221         assert(handle->audioIoHandle);
1222         AUDIO_IO_LOGD("[%p]", handle);
1223
1224         handle->stream_callback.onStream = NULL;
1225         handle->stream_callback.user_data = NULL;
1226
1227         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
1228         cb.mUserData = NULL;
1229         cb.onStream = NULL;
1230
1231         handle->audioIoHandle->setStreamCallback(cb);
1232     } catch (CAudioError& e) {
1233         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1234         return __convert_CAudioError(e);
1235     }
1236
1237     AUDIO_IO_LOGD("[%p] done", handle);
1238
1239     return AUDIO_IO_ERROR_NONE;
1240 }
1241
1242 int cpp_audio_out_set_state_changed_cb(audio_out_h output, audio_in_state_changed_cb callback, void* user_data) {
1243     audio_io_s* handle = static_cast<audio_io_s*>(output);
1244
1245     try {
1246         if (handle == NULL || callback == NULL)
1247             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1248                                    "Parameters are NULL output:%p, callback:%p", output, callback);
1249         assert(handle->audioIoHandle);
1250         AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
1251
1252         handle->state_changed_callback.onStateChanged = callback;
1253         handle->state_changed_callback.user_data = user_data;
1254
1255         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
1256         cb.mUserData = static_cast<void*>(handle);
1257         cb.onStateChanged = __state_changed_cb_internal;
1258
1259         handle->audioIoHandle->setStateChangedCallback(cb);
1260     } catch (CAudioError& e) {
1261         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1262         return __convert_CAudioError(e);
1263     }
1264
1265     AUDIO_IO_LOGD("[%p] done", handle);
1266
1267     return AUDIO_IO_ERROR_NONE;
1268 }
1269
1270 int cpp_audio_out_unset_state_changed_cb(audio_out_h output) {
1271     audio_io_s* handle = static_cast<audio_io_s*>(output);
1272
1273     try {
1274         if (handle == NULL)
1275             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1276                                    "Parameters are NULL output:%p", output);
1277         assert(handle->audioIoHandle);
1278         AUDIO_IO_LOGD("[%p]", handle);
1279
1280         handle->state_changed_callback.onStateChanged = NULL;
1281         handle->state_changed_callback.user_data = NULL;
1282
1283         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
1284         cb.mUserData = NULL;
1285         cb.onStateChanged = NULL;
1286
1287         handle->audioIoHandle->setStateChangedCallback(cb);
1288     } catch (CAudioError& e) {
1289         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1290         return __convert_CAudioError(e);
1291     }
1292
1293     AUDIO_IO_LOGD("[%p] done", handle);
1294
1295     return AUDIO_IO_ERROR_NONE;
1296 }