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