8df8dde4e0f7f82ee23563fa7b52aeee35fbcc8e
[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_drain(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->drain();
544     } catch (CAudioError& e) {
545         AUDIO_IO_LOGE("%s", e.getErrorMsg());
546         return __convert_CAudioError(e);
547     }
548
549     AUDIO_IO_LOGD("[%p] drained", handle);
550
551     return AUDIO_IO_ERROR_NONE;
552 }
553
554 int cpp_audio_in_flush(audio_in_h input) {
555     audio_io_s* handle = static_cast<audio_io_s*>(input);
556
557     try {
558         if (handle == NULL)
559             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
560                                    "Parameters are NULL input:%p", input);
561         assert(handle->audioIoHandle);
562         AUDIO_IO_LOGD("[%p]", handle);
563
564         handle->audioIoHandle->flush();
565     } catch (CAudioError& e) {
566         AUDIO_IO_LOGE("%s", e.getErrorMsg());
567         return __convert_CAudioError(e);
568     }
569
570     AUDIO_IO_LOGD("[%p] flushed", handle);
571
572     return AUDIO_IO_ERROR_NONE;
573 }
574
575 int cpp_audio_in_read(audio_in_h input, void *buffer, unsigned int length) {
576     audio_io_s* handle = static_cast<audio_io_s*>(input);
577     int ret = 0;
578
579     try {
580         if (handle == NULL || buffer == NULL)
581             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
582                                    "Parameters are NULL input:%p, buffer:%p", input, buffer);
583         assert(handle->audioIoHandle);
584
585         CAudioInput* inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
586         if (inputHandle == NULL) {
587             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
588         }
589
590         size_t readn = inputHandle->read(buffer, static_cast<size_t>(length));
591         ret = static_cast<int>(readn);
592 #ifdef _AUDIO_IO_DEBUG_TIMING_
593         AUDIO_IO_LOGD("readn:%d", readn);
594 #endif
595     } catch (CAudioError& e) {
596         AUDIO_IO_LOGE("%s", e.getErrorMsg());
597         return __convert_CAudioError(e);
598     }
599
600     return ret;
601 }
602
603 int cpp_audio_in_get_buffer_size(audio_in_h input, int *size) {
604     audio_io_s* handle = static_cast<audio_io_s*>(input);
605
606     try {
607         if (handle == NULL || size == NULL)
608             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
609                                    "Parameters are NULL input:%p, size:%p", input, size);
610         assert(handle->audioIoHandle);
611
612         CAudioIO* inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
613         if (inputHandle == NULL) {
614             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
615         }
616         *size = inputHandle->getBufferSize();
617     } catch (CAudioError& e) {
618         AUDIO_IO_LOGE("%s", e.getErrorMsg());
619         return __convert_CAudioError(e);
620     }
621
622     return AUDIO_IO_ERROR_NONE;
623 }
624
625 int cpp_audio_in_get_sample_rate(audio_in_h input, int *sample_rate) {
626     audio_io_s* handle = static_cast<audio_io_s*>(input);
627
628     try {
629         if (handle == NULL || sample_rate == NULL)
630             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
631                                    "Parameters are NULL input:%p, sample_rate:%p", input, sample_rate);
632         assert(handle->audioIoHandle);
633
634         *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
635     } catch (CAudioError& e) {
636         AUDIO_IO_LOGE("%s", e.getErrorMsg());
637         return __convert_CAudioError(e);
638     }
639
640     return AUDIO_IO_ERROR_NONE;
641 }
642
643 int cpp_audio_in_get_channel(audio_in_h input, audio_channel_e *channel) {
644     audio_io_s* handle = static_cast<audio_io_s*>(input);
645
646     try {
647         if (handle == NULL || channel == NULL)
648             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
649                                    "Parameters are NULL input:%p, channel:%p", input, channel);
650         assert(handle->audioIoHandle);
651
652         const CAudioInfo::EChannel srcChannel = handle->audioIoHandle->getAudioInfo().getChannel();
653         audio_channel_e dstChannel = AUDIO_CHANNEL_MONO;
654         __convert_audio_info_channel_2_channel(srcChannel, dstChannel);
655
656         *channel = dstChannel;
657     } catch (CAudioError& e) {
658         AUDIO_IO_LOGE("%s", e.getErrorMsg());
659         return __convert_CAudioError(e);
660     }
661
662     return AUDIO_IO_ERROR_NONE;
663 }
664
665 int cpp_audio_in_get_sample_type(audio_in_h input, audio_sample_type_e *type) {
666     audio_io_s* handle = static_cast<audio_io_s*>(input);
667
668     try {
669         if (handle == NULL || type == NULL)
670             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
671                                    "Parameters are NULL input:%p, type:%p", input, type);
672         assert(handle->audioIoHandle);
673
674         const CAudioInfo::ESampleType srcSampleType = handle->audioIoHandle->getAudioInfo().getSampleType();
675         audio_sample_type_e dstSampleType = AUDIO_SAMPLE_TYPE_U8;
676         __convert_audio_info_sample_type_2_sample_type(srcSampleType, dstSampleType);
677
678         *type = dstSampleType;
679     } catch (CAudioError& e) {
680         AUDIO_IO_LOGE("%s", e.getErrorMsg());
681         return __convert_CAudioError(e);
682     }
683
684     return AUDIO_IO_ERROR_NONE;
685 }
686
687 static void __stream_cb_internal(size_t nbytes, void *user_data) {
688     audio_io_s* audioIo = static_cast<audio_io_s*>(user_data);
689     assert(audioIo);
690
691     if (audioIo->stream_callback.onStream)
692         audioIo->stream_callback.onStream(audioIo, nbytes, audioIo->stream_callback.user_data);
693 }
694
695 static void __state_changed_cb_internal(CAudioInfo::EAudioIOState state,
696                                         CAudioInfo::EAudioIOState state_prev,
697                                         bool by_policy,
698                                         void *user_data) {
699     audio_io_s* audioIo = static_cast<audio_io_s*>(user_data);
700     assert(audioIo);
701
702     if (audioIo->state_changed_callback.onStateChanged)
703         audioIo->state_changed_callback.onStateChanged(audioIo, __convert_state_type(state_prev),
704                                                        __convert_state_type(state), by_policy,
705                                                        audioIo->state_changed_callback.user_data);
706 }
707
708 int cpp_audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* user_data) {
709     audio_io_s* handle = static_cast<audio_io_s*>(input);
710
711     try {
712         if (handle == NULL || callback == NULL)
713             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
714                                    "Parameters are NULL input:%p, callback:%p", input, callback);
715         assert(handle->audioIoHandle);
716         AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
717
718         handle->stream_callback.onStream = callback;
719         handle->stream_callback.user_data = user_data;
720
721         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
722         cb.mUserData = static_cast<void*>(handle);
723         cb.onStream  = __stream_cb_internal;
724
725         handle->audioIoHandle->setStreamCallback(cb);
726     } catch (CAudioError& e) {
727         AUDIO_IO_LOGE("%s", e.getErrorMsg());
728         return __convert_CAudioError(e);
729     }
730
731     AUDIO_IO_LOGD("[%p] done", handle);
732
733     return AUDIO_IO_ERROR_NONE;
734 }
735
736 int cpp_audio_in_unset_stream_cb(audio_in_h input) {
737     audio_io_s* handle = static_cast<audio_io_s*>(input);
738
739     try {
740         if (handle == NULL)
741             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
742                                    "Parameters are NULL input:%p", input);
743         assert(handle->audioIoHandle);
744         AUDIO_IO_LOGD("[%p]", handle);
745
746         handle->stream_callback.onStream = NULL;
747         handle->stream_callback.user_data = NULL;
748
749         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
750         cb.mUserData = NULL;
751         cb.onStream  = NULL;
752
753         handle->audioIoHandle->setStreamCallback(cb);
754     } catch (CAudioError& e) {
755         AUDIO_IO_LOGE("%s", e.getErrorMsg());
756         return __convert_CAudioError(e);
757     }
758
759     AUDIO_IO_LOGD("[%p] done", handle);
760
761     return AUDIO_IO_ERROR_NONE;
762 }
763
764 int cpp_audio_in_peek(audio_in_h input, const void **buffer, unsigned int *length) {
765     audio_io_s* handle = static_cast<audio_io_s*>(input);
766     size_t _length = 0;
767
768     try {
769         if (handle == NULL || buffer == NULL)
770             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
771                                    "Parameters are NULL input:%p, buffer:%p", input, buffer);
772
773         CAudioInput* inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
774         if (inputHandle == NULL)
775             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
776
777         inputHandle->peek(buffer, &_length);
778     } catch (CAudioError& e) {
779         AUDIO_IO_LOGE("%s", e.getErrorMsg());
780         return __convert_CAudioError(e);
781     }
782
783     *length = (unsigned int)_length;
784
785     return AUDIO_IO_ERROR_NONE;
786 }
787
788 int cpp_audio_in_drop(audio_in_h input) {
789     audio_io_s* handle = static_cast<audio_io_s*>(input);
790
791     try {
792         if (handle == NULL)
793             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
794                                    "Parameters are NULL input:%p", input);
795
796         CAudioInput* inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
797         if (inputHandle == NULL)
798             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
799
800         inputHandle->drop();
801     } catch (CAudioError& e) {
802         AUDIO_IO_LOGE("%s", e.getErrorMsg());
803         return __convert_CAudioError(e);
804     }
805
806     return AUDIO_IO_ERROR_NONE;
807 }
808
809 int cpp_audio_in_set_state_changed_cb(audio_in_h input, audio_in_state_changed_cb callback, void* user_data) {
810     audio_io_s* handle = static_cast<audio_io_s*>(input);
811
812     try {
813         if (handle == NULL || callback == NULL)
814             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
815                                    "Parameters are NULL input:%p, callback:%p", input, callback);
816         assert(handle->audioIoHandle);
817         AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
818
819         handle->state_changed_callback.onStateChanged = callback;
820         handle->state_changed_callback.user_data = user_data;
821
822         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
823         cb.mUserData = static_cast<void*>(handle);
824         cb.onStateChanged = __state_changed_cb_internal;
825
826         handle->audioIoHandle->setStateChangedCallback(cb);
827     } catch (CAudioError& e) {
828         AUDIO_IO_LOGE("%s", e.getErrorMsg());
829         return __convert_CAudioError(e);
830     }
831
832     AUDIO_IO_LOGD("[%p] done", handle);
833
834     return AUDIO_IO_ERROR_NONE;
835 }
836
837 int cpp_audio_in_unset_state_changed_cb(audio_in_h input) {
838     audio_io_s* handle = static_cast<audio_io_s*>(input);
839
840     try {
841         if (handle == NULL)
842             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
843                                    "Parameters are NULL output:%p", input);
844         assert(handle->audioIoHandle);
845         AUDIO_IO_LOGD("[%p]", handle);
846
847         handle->state_changed_callback.onStateChanged = NULL;
848         handle->state_changed_callback.user_data = NULL;
849
850         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
851         cb.mUserData = NULL;
852         cb.onStateChanged  = NULL;
853
854         handle->audioIoHandle->setStateChangedCallback(cb);
855     } catch (CAudioError& e) {
856         AUDIO_IO_LOGE("%s", e.getErrorMsg());
857         return __convert_CAudioError(e);
858     }
859
860     AUDIO_IO_LOGD("[%p] done", handle);
861
862     return AUDIO_IO_ERROR_NONE;
863 }
864
865
866 /**
867  * Audio Out
868  */
869 int cpp_audio_out_create_new(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_out_h *output) {
870     audio_io_s* handle = NULL;
871     try {
872         if (output == NULL)
873             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
874                                    "Parameters are NULL output:%p", output);
875
876         __check_audio_param(sample_rate, channel, type, SOUND_TYPE_SYSTEM /*default check */);
877
878         AUDIO_IO_LOGD("samplerate:[%d] channel:[0x%x] sample_type:[0x%x]", sample_rate, channel, type);
879         CAudioInfo audioInfo = __generate_audio_output_info(sample_rate, channel, type, SOUND_TYPE_MEDIA);
880
881         handle = new audio_io_s;
882         handle->audioIoHandle = new CAudioOutput(audioInfo);
883         handle->audioIoHandle->initialize();
884
885         AUDIO_IO_LOGD("[%p] created", handle);
886         *output = handle;
887     } catch (CAudioError& e) {
888         AUDIO_IO_LOGE("%s", e.getErrorMsg());
889         __handle_safe_free(handle, (void *)output, true);
890         return __convert_CAudioError(e);
891     } catch (const std::bad_alloc&) {
892         CAudioError e = CAudioError::EError::ERROR_OUT_OF_MEMORY;
893         AUDIO_IO_LOGE("Failed to allocate handle");
894         __handle_safe_free(handle, (void *)output, true);
895         return __convert_CAudioError(e);
896     }
897
898     return AUDIO_IO_ERROR_NONE;
899 }
900
901 int cpp_audio_out_destroy(audio_out_h output) {
902     audio_io_s* handle = static_cast<audio_io_s*>(output);
903
904     try {
905         if (handle == NULL)
906             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
907                                    "Parameter is NULL output:%p", output);
908         assert(handle->audioIoHandle);
909         AUDIO_IO_LOGD("[%p]", handle);
910
911         /* Internal unprepare for backward compatibility */
912         handle->audioIoHandle->unprepare();
913
914         SAFE_FINALIZE(handle->audioIoHandle);
915         SAFE_DELETE(handle->audioIoHandle);
916         SAFE_DELETE(handle);
917     } catch (CAudioError& e) {
918         AUDIO_IO_LOGE("%s", e.getErrorMsg());
919         return __convert_CAudioError(e);
920     }
921
922     AUDIO_IO_LOGD("destroyed");
923
924     return AUDIO_IO_ERROR_NONE;
925 }
926
927 int cpp_audio_out_set_sound_stream_info(audio_out_h output, sound_stream_info_h stream_info) {
928     audio_io_s* handle = static_cast<audio_io_s*>(output);
929
930     try {
931         if (handle == NULL || stream_info == NULL)
932             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
933                                    "Parameters are NULL output:%p, stream_info:%p", output, stream_info);
934         assert(handle->audioIoHandle);
935         AUDIO_IO_LOGD("[%p], stream_info:[%p]", handle, stream_info);
936
937         handle->audioIoHandle->setStreamInfo(stream_info);
938     } catch (CAudioError& e) {
939         AUDIO_IO_LOGE("%s", e.getErrorMsg());
940         return __convert_CAudioError(e);
941     }
942
943     AUDIO_IO_LOGD("[%p] done", handle);
944
945     return AUDIO_IO_ERROR_NONE;
946 }
947
948 int cpp_audio_out_prepare(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->prepare();
959     } catch (CAudioError& e) {
960         AUDIO_IO_LOGE("%s", e.getErrorMsg());
961         return __convert_CAudioError(e);
962     }
963
964     AUDIO_IO_LOGD("[%p] prepared", handle);
965
966     return AUDIO_IO_ERROR_NONE;
967 }
968
969 int cpp_audio_out_unprepare(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->unprepare();
980     } catch (CAudioError& e) {
981         AUDIO_IO_LOGE("%s", e.getErrorMsg());
982         return __convert_CAudioError(e);
983     }
984
985     AUDIO_IO_LOGD("[%p] unprepared", handle);
986
987     return AUDIO_IO_ERROR_NONE;
988 }
989
990 int cpp_audio_out_pause(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->pause();
1001     } catch (CAudioError& e) {
1002         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1003         return __convert_CAudioError(e);
1004     }
1005
1006     AUDIO_IO_LOGD("[%p] paused", handle);
1007
1008     return AUDIO_IO_ERROR_NONE;
1009 }
1010
1011 int cpp_audio_out_resume(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->resume();
1022     } catch (CAudioError& e) {
1023         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1024         return __convert_CAudioError(e);
1025     }
1026
1027     AUDIO_IO_LOGD("[%p] resumed", handle);
1028
1029     return AUDIO_IO_ERROR_NONE;
1030 }
1031
1032 int cpp_audio_out_drain(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->drain();
1043     } catch (CAudioError& e) {
1044         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1045         return __convert_CAudioError(e);
1046     }
1047
1048     AUDIO_IO_LOGD("[%p] drained", handle);
1049
1050     return AUDIO_IO_ERROR_NONE;
1051 }
1052
1053 int cpp_audio_out_flush(audio_out_h output) {
1054     audio_io_s* handle = static_cast<audio_io_s*>(output);
1055
1056     try {
1057         if (handle == NULL)
1058             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1059                                    "Parameter is NULL output:%p", output);
1060         assert(handle->audioIoHandle);
1061         AUDIO_IO_LOGD("[%p]", handle);
1062
1063         handle->audioIoHandle->flush();
1064     } catch (CAudioError& e) {
1065         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1066         return __convert_CAudioError(e);
1067     }
1068
1069     AUDIO_IO_LOGD("[%p] flushed", handle);
1070
1071     return AUDIO_IO_ERROR_NONE;
1072 }
1073
1074 int cpp_audio_out_write(audio_out_h output, void *buffer, unsigned int length) {
1075     audio_io_s* handle = static_cast<audio_io_s*>(output);
1076     int ret = 0;
1077
1078     try {
1079         if (handle == NULL || buffer == NULL)
1080             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1081                                    "Parameter is NULL output:%p, buffer:%p", output, buffer);
1082         assert(handle->audioIoHandle);
1083
1084         CAudioOutput* outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
1085         if (outputHandle == NULL)
1086             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1087
1088         size_t written = outputHandle->write(buffer, static_cast<size_t>(length));
1089         ret = static_cast<int>(written);
1090 #ifdef _AUDIO_IO_DEBUG_TIMING_
1091         AUDIO_IO_LOGD("written:%d", written);
1092 #endif
1093     } catch (CAudioError& e) {
1094         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1095         return __convert_CAudioError(e);
1096     }
1097
1098     return ret;
1099 }
1100
1101 int cpp_audio_out_get_buffer_size(audio_out_h output, int *size) {
1102     audio_io_s* handle = static_cast<audio_io_s*>(output);
1103
1104     try {
1105         if (handle == NULL || size == NULL)
1106             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1107                                    "Parameters are NULL output:%p, size:%p", output, size);
1108         assert(handle->audioIoHandle);
1109
1110         CAudioOutput* outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
1111         if (outputHandle == NULL)
1112             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1113
1114         *size = outputHandle->getBufferSize();
1115     } catch (CAudioError& e) {
1116         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1117         return __convert_CAudioError(e);
1118     }
1119
1120     return AUDIO_IO_ERROR_NONE;
1121 }
1122
1123 int cpp_audio_out_get_sample_rate(audio_out_h output, int *sample_rate) {
1124     audio_io_s* handle = static_cast<audio_io_s*>(output);
1125
1126     try {
1127         if (handle == NULL || sample_rate == NULL)
1128             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1129                                    "Parameters are NULL output:%p, sample_rate:%p", output, sample_rate);
1130         assert(handle->audioIoHandle);
1131
1132         *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
1133     } catch (CAudioError& e) {
1134         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1135         return __convert_CAudioError(e);
1136     }
1137
1138     return AUDIO_IO_ERROR_NONE;
1139 }
1140
1141 int cpp_audio_out_get_channel(audio_out_h output, audio_channel_e *channel) {
1142     audio_io_s* handle = static_cast<audio_io_s*>(output);
1143
1144     try {
1145         if (handle == NULL || channel == NULL)
1146             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1147                                    "Parameters are NULL output:%p, channel:%p", output, channel);
1148         assert(handle->audioIoHandle);
1149
1150         const CAudioInfo::EChannel srcChannel = handle->audioIoHandle->getAudioInfo().getChannel();
1151         audio_channel_e dstChannel = AUDIO_CHANNEL_MONO;
1152         __convert_audio_info_channel_2_channel(srcChannel, dstChannel);
1153
1154         *channel = dstChannel;
1155     } catch (CAudioError& e) {
1156         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1157         return __convert_CAudioError(e);
1158     }
1159
1160     return AUDIO_IO_ERROR_NONE;
1161 }
1162
1163 int cpp_audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type) {
1164     audio_io_s* handle = static_cast<audio_io_s*>(output);
1165
1166     try {
1167         if (handle == NULL || type == NULL)
1168             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1169                                    "Parameters are NULL output:%p, type:%p", output, type);
1170         assert(handle->audioIoHandle);
1171
1172         const CAudioInfo::ESampleType srcSampleType = handle->audioIoHandle->getAudioInfo().getSampleType();
1173         audio_sample_type_e dstSampleType = AUDIO_SAMPLE_TYPE_U8;
1174         __convert_audio_info_sample_type_2_sample_type(srcSampleType, dstSampleType);
1175
1176         *type = dstSampleType;
1177     } catch (CAudioError& e) {
1178         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1179         return __convert_CAudioError(e);
1180     }
1181
1182     return AUDIO_IO_ERROR_NONE;
1183 }
1184
1185 int cpp_audio_out_get_sound_type(audio_out_h output, sound_type_e *type) {
1186     audio_io_s* handle = static_cast<audio_io_s*>(output);
1187
1188     try {
1189         if (handle == NULL || type == NULL)
1190             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1191                                    "Parameters are NULL output:%p, type:%p", output, type);
1192         assert(handle->audioIoHandle);
1193
1194         const CAudioInfo::EAudioType srcAudioType = handle->audioIoHandle->getAudioInfo().getAudioType();
1195         sound_type_e dstSoundType = SOUND_TYPE_MEDIA;
1196         __convert_audio_info_audio_type_2_sound_type(srcAudioType, dstSoundType);
1197
1198         *type = dstSoundType;
1199     } catch (CAudioError& e) {
1200         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1201         return __convert_CAudioError(e);
1202     }
1203
1204     return AUDIO_IO_ERROR_NONE;
1205 }
1206
1207 int cpp_audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* user_data) {
1208     audio_io_s* handle = static_cast<audio_io_s*>(output);
1209
1210     try {
1211         if (handle == NULL || callback == NULL)
1212             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1213                                    "Parameters are NULL output:%p, callback:%p", output, callback);
1214         assert(handle->audioIoHandle);
1215         AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
1216
1217         handle->stream_callback.onStream = callback;
1218         handle->stream_callback.user_data = user_data;
1219
1220         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
1221         cb.mUserData = static_cast<void*>(handle);
1222         cb.onStream = __stream_cb_internal;
1223
1224         handle->audioIoHandle->setStreamCallback(cb);
1225     } catch (CAudioError& e) {
1226         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1227         return __convert_CAudioError(e);
1228     }
1229
1230     AUDIO_IO_LOGD("[%p] done", handle);
1231
1232     return AUDIO_IO_ERROR_NONE;
1233 }
1234
1235 int cpp_audio_out_unset_stream_cb(audio_out_h output) {
1236     audio_io_s* handle = static_cast<audio_io_s*>(output);
1237
1238     try {
1239         if (handle == NULL)
1240             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1241                                    "Parameters are NULL output:%p", output);
1242         assert(handle->audioIoHandle);
1243         AUDIO_IO_LOGD("[%p]", handle);
1244
1245         handle->stream_callback.onStream = NULL;
1246         handle->stream_callback.user_data = NULL;
1247
1248         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
1249         cb.mUserData = NULL;
1250         cb.onStream = NULL;
1251
1252         handle->audioIoHandle->setStreamCallback(cb);
1253     } catch (CAudioError& e) {
1254         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1255         return __convert_CAudioError(e);
1256     }
1257
1258     AUDIO_IO_LOGD("[%p] done", handle);
1259
1260     return AUDIO_IO_ERROR_NONE;
1261 }
1262
1263 int cpp_audio_out_set_state_changed_cb(audio_out_h output, audio_in_state_changed_cb callback, void* user_data) {
1264     audio_io_s* handle = static_cast<audio_io_s*>(output);
1265
1266     try {
1267         if (handle == NULL || callback == NULL)
1268             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1269                                    "Parameters are NULL output:%p, callback:%p", output, callback);
1270         assert(handle->audioIoHandle);
1271         AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
1272
1273         handle->state_changed_callback.onStateChanged = callback;
1274         handle->state_changed_callback.user_data = user_data;
1275
1276         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
1277         cb.mUserData = static_cast<void*>(handle);
1278         cb.onStateChanged = __state_changed_cb_internal;
1279
1280         handle->audioIoHandle->setStateChangedCallback(cb);
1281     } catch (CAudioError& e) {
1282         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1283         return __convert_CAudioError(e);
1284     }
1285
1286     AUDIO_IO_LOGD("[%p] done", handle);
1287
1288     return AUDIO_IO_ERROR_NONE;
1289 }
1290
1291 int cpp_audio_out_unset_state_changed_cb(audio_out_h output) {
1292     audio_io_s* handle = static_cast<audio_io_s*>(output);
1293
1294     try {
1295         if (handle == NULL)
1296             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1297                                    "Parameters are NULL output:%p", output);
1298         assert(handle->audioIoHandle);
1299         AUDIO_IO_LOGD("[%p]", handle);
1300
1301         handle->state_changed_callback.onStateChanged = NULL;
1302         handle->state_changed_callback.user_data = NULL;
1303
1304         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
1305         cb.mUserData = NULL;
1306         cb.onStateChanged = NULL;
1307
1308         handle->audioIoHandle->setStateChangedCallback(cb);
1309     } catch (CAudioError& e) {
1310         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1311         return __convert_CAudioError(e);
1312     }
1313
1314     AUDIO_IO_LOGD("[%p] done", handle);
1315
1316     return AUDIO_IO_ERROR_NONE;
1317 }