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