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