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