Add session mutex lock
[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 <sound_manager_internal.h>
22 #include "audio_io.h"
23 #include "CAudioIODef.h"
24
25 #include <system_info.h>
26
27 #define FEATURE_MICROPHONE          "http://tizen.org/feature/microphone"
28
29 using namespace std;
30 using namespace tizen_media_audio;
31
32
33 /**
34  * Defines Structures
35  * type : struct
36  * Name : audio_io_interrupted_cb_s
37  * Declaration : Keeps user callback pointer and user data for delivering an interrupt event
38  */
39 typedef struct audio_io_interrupted_cb_s {
40     void* user_data;
41     audio_io_interrupted_cb onInterrupt;
42
43     audio_io_interrupted_cb_s() : user_data(NULL), onInterrupt(NULL)
44     {/* Empty Body */}
45 }   audio_io_interrupted_cb_s;
46
47 /**
48  * Defines Structures
49  * type : struct
50  * Name : audio_io_stream_cb_s
51  * Declaration : Keeps user callback pointer and user data for delivering an stream event
52  */
53 typedef struct audio_io_stream_cb_s {
54     void* user_data;
55     audio_in_stream_cb onStream;
56
57     audio_io_stream_cb_s() : user_data(NULL), onStream(NULL)
58     {/* Empty Body */}
59 }   audio_io_stream_cb_s;
60
61 /**
62  * Defines Structures
63  * type : struct
64  * Name : audio_io_state_changed_cb_s
65  * Declaration : Keeps user callback pointer and user data for delivering an state changed event
66  */
67 typedef struct audio_io_state_changed_cb_s {
68     void* user_data;
69     audio_in_state_changed_cb onStateChanged;
70
71     audio_io_state_changed_cb_s() : user_data(NULL), onStateChanged(NULL)
72     {/* Empty Body */}
73 }   audio_io_state_changed_cb_s;
74
75 /**
76  * Defines Structures
77  * type : struct
78  * Name : audio_io_s
79  * Declaration : An handle of AudioIO
80  * The handle has two struct for user callback
81  * And the handle has a pointer of private audioIO object
82  * The CAudioIO is a abstract class object about Input and Output
83  */
84 typedef struct audio_io_s {
85     CAudioIO* audioIoHandle;
86     audio_io_interrupted_cb_s interrupt_callback;
87     audio_io_stream_cb_s stream_callback;
88     audio_io_state_changed_cb_s state_changed_callback;
89
90     audio_io_s() : audioIoHandle(NULL)
91     {/* Empty Body */}
92 }   audio_io_s;
93
94
95 /**
96  * Internal functions
97  */
98 static audio_io_error_e __convert_CAudioError(CAudioError& error) {
99     audio_io_error_e ret = AUDIO_IO_ERROR_NONE;
100     CAudioError::EError err = error.getError();
101
102     switch (err) {
103     case CAudioError::EError::ERROR_NONE:
104         ret = AUDIO_IO_ERROR_NONE;
105         break;
106     case CAudioError::EError::ERROR_INVALID_ARGUMENT:
107     case CAudioError::EError::ERROR_INVALID_HANDLE:
108     case CAudioError::EError::ERROR_INVALID_SAMPLERATE:
109     case CAudioError::EError::ERROR_INVALID_CHANNEL:
110     case CAudioError::EError::ERROR_INVALID_FORMAT:
111         ret = AUDIO_IO_ERROR_INVALID_PARAMETER;
112         break;
113     case CAudioError::EError::ERROR_DEVICE_NOT_OPENED:
114         ret = AUDIO_IO_ERROR_DEVICE_NOT_OPENED;
115         break;
116     case CAudioError::EError::ERROR_DEVICE_NOT_CLOSED:
117         ret = AUDIO_IO_ERROR_DEVICE_NOT_CLOSED;
118         break;
119     case CAudioError::EError::ERROR_PERMISSION_DENIED:
120         ret = AUDIO_IO_ERROR_PERMISSION_DENIED;
121         break;
122     case CAudioError::EError::ERROR_DEVICE_POLICY_RESTRICTION:
123         ret = AUDIO_IO_ERROR_DEVICE_POLICY_RESTRICTION;
124         break;
125     case CAudioError::EError::ERROR_NOT_SUPPORTED:
126         ret = AUDIO_IO_ERROR_NOT_SUPPORTED;
127         break;
128     case CAudioError::EError::ERROR_NOT_SUPPORTED_TYPE:
129         ret = AUDIO_IO_ERROR_NOT_SUPPORTED_TYPE;
130         break;
131     case CAudioError::EError::ERROR_MAX:
132     case CAudioError::EError::ERROR_INTERNAL_OPERATION:
133     case CAudioError::EError::ERROR_NOT_INITIALIZED:
134     case CAudioError::EError::ERROR_FAILED_OPERATION:
135     case CAudioError::EError::ERROR_INVALID_OPERATION:
136         ret = AUDIO_IO_ERROR_INVALID_OPERATION;
137         break;
138     case CAudioError::EError::ERROR_INVALID_STATE:
139         ret = AUDIO_IO_ERROR_INVALID_STATE;
140         break;
141     case CAudioError::EError::ERROR_OUT_OF_MEMORY:
142     case CAudioError::EError::ERROR_INVALID_POINTER:
143         ret = AUDIO_IO_ERROR_INVALID_BUFFER;
144         break;
145     case CAudioError::EError::ERROR_POLICY_BLOCKED:
146     case CAudioError::EError::ERROR_POLICY_INTERRUPTED:
147     case CAudioError::EError::ERROR_POLICY_DUPLICATED:
148         ret = AUDIO_IO_ERROR_SOUND_POLICY;
149         break;
150     }
151
152     return ret;
153 }
154
155 static void __convert_channel_2_audio_info_channel(const audio_channel_e& src_channel,
156                                                    CAudioInfo::EChannel& dst_channel) {
157     switch (src_channel) {
158     case AUDIO_CHANNEL_MONO:
159         dst_channel = CAudioInfo::EChannel::CHANNEL_MONO;
160         break;
161     case AUDIO_CHANNEL_STEREO:
162         dst_channel = CAudioInfo::EChannel::CHANNEL_STEREO;
163         break;
164     default:
165         dst_channel = CAudioInfo::EChannel::CHANNEL_MONO;
166         break;
167     }
168 }
169
170 static void __convert_audio_info_channel_2_channel(const CAudioInfo::EChannel& src_channel,
171                                                    audio_channel_e& dst_channel) {
172     switch (src_channel) {
173     case CAudioInfo::EChannel::CHANNEL_MONO:
174         dst_channel = AUDIO_CHANNEL_MONO;
175         break;
176     case CAudioInfo::EChannel::CHANNEL_STEREO:
177         dst_channel = AUDIO_CHANNEL_STEREO;
178         break;
179     default:
180         dst_channel = AUDIO_CHANNEL_MONO;
181         break;
182     }
183 }
184
185 static void __convert_sample_type_2_audio_info_sample_type(const audio_sample_type_e& src_type,
186                                                            CAudioInfo::ESampleType& dst_type) {
187     switch (src_type) {
188     case AUDIO_SAMPLE_TYPE_U8:
189         dst_type = CAudioInfo::ESampleType::SAMPLE_TYPE_U8;
190         break;
191     case AUDIO_SAMPLE_TYPE_S16_LE:
192         dst_type = CAudioInfo::ESampleType::SAMPLE_TYPE_S16_LE;
193         break;
194     default:
195         dst_type = CAudioInfo::ESampleType::SAMPLE_TYPE_U8;
196         break;
197     }
198 }
199
200 static void __convert_audio_info_sample_type_2_sample_type(const CAudioInfo::ESampleType& src_type,
201                                                            audio_sample_type_e& dst_type) {
202     switch (src_type) {
203     case CAudioInfo::ESampleType::SAMPLE_TYPE_U8:
204         dst_type = AUDIO_SAMPLE_TYPE_U8;
205         break;
206     case CAudioInfo::ESampleType::SAMPLE_TYPE_S16_LE:
207         dst_type = AUDIO_SAMPLE_TYPE_S16_LE;
208         break;
209     default:
210         dst_type = AUDIO_SAMPLE_TYPE_U8;
211         break;
212     }
213 }
214
215 static void __convert_sound_type_2_audio_info_audio_type(const sound_type_e& src_type,
216                                                          CAudioInfo::EAudioType& dst_type) {
217     switch (src_type) {
218     case SOUND_TYPE_SYSTEM:
219         dst_type = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_SYSTEM;
220         break;
221     case SOUND_TYPE_NOTIFICATION:
222         dst_type = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_NOTIFICATION;
223         break;
224     case SOUND_TYPE_ALARM:
225         dst_type = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_ALARM;
226         break;
227     case SOUND_TYPE_RINGTONE:
228         dst_type = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_RINGTONE_VOIP;
229         break;
230     case SOUND_TYPE_MEDIA:
231         dst_type = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA;
232         break;
233     case SOUND_TYPE_CALL:
234         dst_type = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_SYSTEM;
235         break;
236     case SOUND_TYPE_VOIP:
237         dst_type = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOIP;
238         break;
239     case SOUND_TYPE_VOICE:
240         dst_type = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOICE_INFORMATION;
241         break;
242     default:
243         dst_type = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA;
244         break;
245     }
246 }
247
248 static void __convert_audio_info_audio_type_2_sound_type(const CAudioInfo::EAudioType& src_type,
249                                                          sound_type_e& dst_type) {
250     switch (src_type) {
251     case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA:
252         dst_type = SOUND_TYPE_MEDIA;
253         break;
254     case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_SYSTEM:
255         dst_type = SOUND_TYPE_SYSTEM;
256         break;
257     case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_ALARM:
258         dst_type = SOUND_TYPE_ALARM;
259         break;
260     case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_NOTIFICATION:
261     case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_EMERGENCY:
262         dst_type = SOUND_TYPE_NOTIFICATION;
263         break;
264     case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOICE_INFORMATION:
265         dst_type = SOUND_TYPE_VOICE;
266         break;
267     case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_RINGTONE_VOIP:
268         dst_type = SOUND_TYPE_RINGTONE;
269         break;
270     case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOIP:
271         dst_type = SOUND_TYPE_VOIP;
272         break;
273     default:
274         dst_type = SOUND_TYPE_MEDIA;
275         break;
276     }
277 }
278
279 static audio_io_state_e __convert_state_type(const CAudioInfo::EAudioIOState src_state) {
280     audio_io_state_e dst_state;
281
282     switch (src_state) {
283     case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE:
284         dst_state = AUDIO_IO_STATE_IDLE;
285         break;
286     case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_IDLE:
287         dst_state = AUDIO_IO_STATE_IDLE;
288         break;
289     case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_RUNNING:
290         dst_state = AUDIO_IO_STATE_RUNNING;
291         break;
292     case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_PAUSED:
293         dst_state = AUDIO_IO_STATE_PAUSED;
294         break;
295     default:
296         dst_state = AUDIO_IO_STATE_IDLE;
297         break;
298     }
299     return dst_state;
300 }
301
302 static void __check_audio_param(int sample_rate, audio_channel_e channel, audio_sample_type_e type) {
303     if (sample_rate < 0)
304         THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid sample rate :%d", sample_rate);
305
306     if (channel != AUDIO_CHANNEL_MONO && channel != AUDIO_CHANNEL_STEREO)
307         THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid channel :%d", channel);
308
309     if (type != AUDIO_SAMPLE_TYPE_U8 && type != AUDIO_SAMPLE_TYPE_S16_LE)
310         THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid sample type :%d", type);
311 }
312
313 static void __check_audio_param(int sample_rate, audio_channel_e channel, audio_sample_type_e type, sound_type_e sound_type) {
314     __check_audio_param(sample_rate, channel, type);
315
316     if (sound_type < SOUND_TYPE_SYSTEM || sound_type > SOUND_TYPE_VOICE)
317         THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid sound type : %d", sound_type);
318 }
319
320 static CAudioInfo __generate_audio_input_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type) {
321     CAudioInfo::EChannel dstChannel;
322     CAudioInfo::ESampleType dstSampleType;
323     CAudioInfo::EAudioType dstAudioType = CAudioInfo::EAudioType::AUDIO_IN_TYPE_MEDIA;
324
325     __convert_channel_2_audio_info_channel(channel, dstChannel);
326     __convert_sample_type_2_audio_info_sample_type(sample_type, dstSampleType);
327
328     return CAudioInfo(sampleRate, dstChannel, dstSampleType, dstAudioType, -1);
329 }
330
331 static CAudioInfo __generate_audio_input_loopback_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type) {
332     CAudioInfo::EChannel dstChannel;
333     CAudioInfo::ESampleType dstSampleType;
334     CAudioInfo::EAudioType dstAudioType = CAudioInfo::EAudioType::AUDIO_IN_TYPE_LOOPBACK;
335
336     __convert_channel_2_audio_info_channel(channel, dstChannel);
337     __convert_sample_type_2_audio_info_sample_type(sample_type, dstSampleType);
338
339     return CAudioInfo(sampleRate, dstChannel, dstSampleType, dstAudioType, -1);
340 }
341
342 static CAudioInfo __generate_audio_output_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type, sound_type_e sound_type) {
343     CAudioInfo::EChannel dstChannel;
344     CAudioInfo::ESampleType dstSampleType;
345     CAudioInfo::EAudioType dstAudioType;
346
347     __convert_channel_2_audio_info_channel(channel, dstChannel);
348     __convert_sample_type_2_audio_info_sample_type(sample_type, dstSampleType);
349     __convert_sound_type_2_audio_info_audio_type(sound_type, dstAudioType);
350
351     return CAudioInfo(sampleRate, dstChannel, dstSampleType, dstAudioType, -1);
352 }
353
354 static audio_io_interrupted_code_e __convert_interrupted_code(IAudioSessionEventListener::EInterruptCode code) {
355     switch (code) {
356     case IAudioSessionEventListener::EInterruptCode::INTERRUPT_COMPLETED:
357         return AUDIO_IO_INTERRUPTED_COMPLETED;
358     case IAudioSessionEventListener::EInterruptCode::INTERRUPT_BY_CALL:
359         return AUDIO_IO_INTERRUPTED_BY_CALL;
360     case IAudioSessionEventListener::EInterruptCode::INTERRUPT_BY_EARJACK_UNPLUG:
361         return AUDIO_IO_INTERRUPTED_BY_EARJACK_UNPLUG;
362     case IAudioSessionEventListener::EInterruptCode::INTERRUPT_BY_RESOURCE_CONFLICT:
363         return AUDIO_IO_INTERRUPTED_BY_RESOURCE_CONFLICT;
364     case IAudioSessionEventListener::EInterruptCode::INTERRUPT_BY_ALARM:
365         return AUDIO_IO_INTERRUPTED_BY_ALARM;
366     case IAudioSessionEventListener::EInterruptCode::INTERRUPT_BY_EMERGENCY:
367         return AUDIO_IO_INTERRUPTED_BY_EMERGENCY;
368     case IAudioSessionEventListener::EInterruptCode::INTERRUPT_BY_NOTIFICATION:
369         return AUDIO_IO_INTERRUPTED_BY_NOTIFICATION;
370     case IAudioSessionEventListener::EInterruptCode::INTERRUPT_BY_MEDIA:
371     case IAudioSessionEventListener::EInterruptCode::INTERRUPT_MAX:
372     default:
373         return AUDIO_IO_INTERRUPTED_BY_MEDIA;
374     }
375 }
376
377 static void __handle_safe_free(audio_io_s* handle, void *obj, bool is_output) {
378     VALID_POINTER_START(handle)
379         SAFE_FINALIZE(handle->audioIoHandle);
380         SAFE_DELETE(handle->audioIoHandle);
381         SAFE_DELETE(handle);
382     VALID_POINTER_END
383
384     VALID_POINTER_START(obj)
385         if (is_output)
386             *(audio_out_h *)obj = NULL;
387         else
388             *(audio_in_h *)obj = NULL;
389     VALID_POINTER_END
390 }
391
392 /**
393  * Implements CAPI functions
394  */
395 int cpp_audio_in_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_in_h *input) {
396     audio_io_s* handle = NULL;
397     bool mic_enable = false;
398     int ret = 0;
399     try {
400         if (input == NULL) {
401             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
402                                   "Parameters are NULL input:%p", input);
403         }
404
405         __check_audio_param(sample_rate, channel, type);
406
407         AUDIO_IO_LOGD("samplerate:[%d] channel:[0x%x] sample_type:[0x%x]", sample_rate, channel, type);
408
409         /* If MIC is not supported, return NOT_SUPPORTED error */
410         ret = system_info_get_platform_bool(FEATURE_MICROPHONE, &mic_enable);
411         AUDIO_IO_LOGD("system_info_platform [%s]=[%d], ret[%d]", FEATURE_MICROPHONE, mic_enable, ret);
412         if (ret != SYSTEM_INFO_ERROR_NONE || !mic_enable) {
413             THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "System doesn't support microphone!");
414         }
415
416         CAudioInfo audioInfo = __generate_audio_input_info(sample_rate, channel, type);
417
418         handle = new audio_io_s;
419         handle->audioIoHandle = new CAudioInput(audioInfo);
420         handle->audioIoHandle->initialize();
421
422         AUDIO_IO_LOGD("[%p] created", handle);
423         *input = handle;
424     } catch (CAudioError& e) {
425         AUDIO_IO_LOGE("%s", e.getErrorMsg());
426         __handle_safe_free(handle, (void *)input, false);
427         return __convert_CAudioError(e);
428     } catch (const std::bad_alloc&) {
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     }
434
435     return AUDIO_IO_ERROR_NONE;
436 }
437
438 int cpp_audio_in_create_loopback(int sample_rate, audio_channel_e channel, audio_sample_type_e type , audio_in_h* input) {
439     audio_io_s* handle = NULL;
440     try {
441         if (input == NULL)
442             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
443                                   "Parameters are NULL input:%p", input);
444
445         __check_audio_param(sample_rate, channel, type);
446         CAudioInfo audioInfo = __generate_audio_input_loopback_info(sample_rate, channel, type);
447
448         handle = new audio_io_s;
449         handle->audioIoHandle = new CAudioInput(audioInfo);
450         handle->audioIoHandle->initialize();
451
452         *input = handle;
453     } catch (CAudioError& e) {
454         AUDIO_IO_LOGE("%s", e.getErrorMsg());
455         __handle_safe_free(handle, (void *)input, false);
456         return __convert_CAudioError(e);
457     } catch (const std::bad_alloc&) {
458         CAudioError e = CAudioError::EError::ERROR_OUT_OF_MEMORY;
459         AUDIO_IO_LOGE("Failed to allocate handle");
460         __handle_safe_free(handle, (void *)input, false);
461         return __convert_CAudioError(e);
462     }
463
464     return AUDIO_IO_ERROR_NONE;
465 }
466
467 int cpp_audio_in_destroy(audio_in_h input) {
468     audio_io_s* handle = static_cast<audio_io_s*>(input);
469
470     try {
471         if (handle == NULL)
472             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
473                                   "Parameters are NULL input:%p", input);
474         assert(handle->audioIoHandle);
475         AUDIO_IO_LOGD("[%p]", handle);
476
477         /* Internal unprepare for backward compatibility */
478         handle->audioIoHandle->unprepare();
479
480         SAFE_FINALIZE(handle->audioIoHandle);
481         SAFE_DELETE(handle->audioIoHandle);
482         SAFE_DELETE(handle);
483     } catch (CAudioError& e) {
484         AUDIO_IO_LOGE("%s", e.getErrorMsg());
485         return __convert_CAudioError(e);
486     }
487
488     AUDIO_IO_LOGD("destroyed");
489
490     return AUDIO_IO_ERROR_NONE;
491 }
492
493 int cpp_audio_in_set_sound_stream_info(audio_in_h input, sound_stream_info_h stream_info) {
494     audio_io_s* handle = static_cast<audio_io_s*>(input);
495
496     try {
497         if (handle == NULL || stream_info == NULL)
498             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
499                                    "Parameters are NULL input:%p, stream_info:%p", input, stream_info);
500         assert(handle->audioIoHandle);
501         AUDIO_IO_LOGD("[%p], stream_info:[%p]", handle, stream_info);
502
503         handle->audioIoHandle->setStreamInfo(stream_info);
504     } catch (CAudioError& e) {
505         AUDIO_IO_LOGE("%s", e.getErrorMsg());
506         return __convert_CAudioError(e);
507     }
508
509     AUDIO_IO_LOGD("[%p] done", handle);
510
511     return AUDIO_IO_ERROR_NONE;
512 }
513
514 int cpp_audio_in_prepare(audio_in_h input) {
515     audio_io_s* handle = static_cast<audio_io_s*>(input);
516
517     try {
518         if (handle == NULL)
519             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
520                                    "Parameters are NULL input:%p", input);
521         assert(handle->audioIoHandle);
522         AUDIO_IO_LOGD("[%p]", handle);
523
524         handle->audioIoHandle->prepare();
525     } catch (CAudioError& e) {
526         AUDIO_IO_LOGE("%s", e.getErrorMsg());
527         return __convert_CAudioError(e);
528     }
529
530     AUDIO_IO_LOGD("[%p] prepared", handle);
531
532     return AUDIO_IO_ERROR_NONE;
533 }
534
535 int cpp_audio_in_unprepare(audio_in_h input) {
536     audio_io_s* handle = static_cast<audio_io_s*>(input);
537
538     try {
539         if (handle == NULL)
540             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
541                                    "Parameters are NULL input:%p", input);
542         assert(handle->audioIoHandle);
543         AUDIO_IO_LOGD("[%p]", handle);
544
545         handle->audioIoHandle->unprepare();
546     } catch (CAudioError& e) {
547         AUDIO_IO_LOGE("%s", e.getErrorMsg());
548         return __convert_CAudioError(e);
549     }
550
551     AUDIO_IO_LOGD("[%p] unprepared", handle);
552
553     return AUDIO_IO_ERROR_NONE;
554 }
555
556 int cpp_audio_in_pause(audio_in_h input) {
557     audio_io_s* handle = static_cast<audio_io_s*>(input);
558
559     try {
560         if (handle == NULL)
561             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
562                                    "Parameters are NULL input:%p", input);
563         assert(handle->audioIoHandle);
564         AUDIO_IO_LOGD("[%p]", handle);
565
566         handle->audioIoHandle->pause();
567     } catch (CAudioError& e) {
568         AUDIO_IO_LOGE("%s", e.getErrorMsg());
569         return __convert_CAudioError(e);
570     }
571
572     AUDIO_IO_LOGD("[%p] paused", handle);
573
574     return AUDIO_IO_ERROR_NONE;
575 }
576
577 int cpp_audio_in_resume(audio_in_h input) {
578     audio_io_s* handle = static_cast<audio_io_s*>(input);
579
580     try {
581         if (handle == NULL)
582             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
583                                    "Parameters are NULL input:%p", input);
584         assert(handle->audioIoHandle);
585         AUDIO_IO_LOGD("[%p]", handle);
586
587         handle->audioIoHandle->resume();
588     } catch (CAudioError& e) {
589         AUDIO_IO_LOGE("%s", e.getErrorMsg());
590         return __convert_CAudioError(e);
591     }
592
593     AUDIO_IO_LOGD("[%p] resumed", handle);
594
595     return AUDIO_IO_ERROR_NONE;
596 }
597
598 int cpp_audio_in_drain(audio_in_h input) {
599     audio_io_s* handle = static_cast<audio_io_s*>(input);
600
601     try {
602         if (handle == NULL)
603             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
604                                    "Parameters are NULL input:%p", input);
605         assert(handle->audioIoHandle);
606         AUDIO_IO_LOGD("[%p]", handle);
607
608         handle->audioIoHandle->drain();
609     } catch (CAudioError& e) {
610         AUDIO_IO_LOGE("%s", e.getErrorMsg());
611         return __convert_CAudioError(e);
612     }
613
614     AUDIO_IO_LOGD("[%p] drained", handle);
615
616     return AUDIO_IO_ERROR_NONE;
617 }
618
619 int cpp_audio_in_flush(audio_in_h input) {
620     audio_io_s* handle = static_cast<audio_io_s*>(input);
621
622     try {
623         if (handle == NULL)
624             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
625                                    "Parameters are NULL input:%p", input);
626         assert(handle->audioIoHandle);
627         AUDIO_IO_LOGD("[%p]", handle);
628
629         handle->audioIoHandle->flush();
630     } catch (CAudioError& e) {
631         AUDIO_IO_LOGE("%s", e.getErrorMsg());
632         return __convert_CAudioError(e);
633     }
634
635     AUDIO_IO_LOGD("[%p] flushed", handle);
636
637     return AUDIO_IO_ERROR_NONE;
638 }
639
640 int cpp_audio_in_read(audio_in_h input, void *buffer, unsigned int length) {
641     audio_io_s* handle = static_cast<audio_io_s*>(input);
642     int ret = 0;
643
644     try {
645         if (handle == NULL || buffer == NULL)
646             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
647                                    "Parameters are NULL input:%p, buffer:%p", input, buffer);
648         assert(handle->audioIoHandle);
649
650         CAudioInput* inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
651         if (inputHandle == NULL) {
652             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
653         }
654
655         size_t readn = inputHandle->read(buffer, static_cast<size_t>(length));
656         ret = static_cast<int>(readn);
657 #ifdef _AUDIO_IO_DEBUG_TIMING_
658         AUDIO_IO_LOGD("readn:%d", readn);
659 #endif
660     } catch (CAudioError& e) {
661         AUDIO_IO_LOGE("%s", e.getErrorMsg());
662         return __convert_CAudioError(e);
663     }
664
665     return ret;
666 }
667
668 int cpp_audio_in_get_buffer_size(audio_in_h input, int *size) {
669     audio_io_s* handle = static_cast<audio_io_s*>(input);
670
671     try {
672         if (handle == NULL || size == NULL)
673             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
674                                    "Parameters are NULL input:%p, size:%p", input, size);
675         assert(handle->audioIoHandle);
676
677         CAudioIO* inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
678         if (inputHandle == NULL) {
679             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
680         }
681         *size = inputHandle->getBufferSize();
682     } catch (CAudioError& e) {
683         AUDIO_IO_LOGE("%s", e.getErrorMsg());
684         return __convert_CAudioError(e);
685     }
686
687     return AUDIO_IO_ERROR_NONE;
688 }
689
690 int cpp_audio_in_get_sample_rate(audio_in_h input, int *sample_rate) {
691     audio_io_s* handle = static_cast<audio_io_s*>(input);
692
693     try {
694         if (handle == NULL || sample_rate == NULL)
695             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
696                                    "Parameters are NULL input:%p, sample_rate:%p", input, sample_rate);
697         assert(handle->audioIoHandle);
698
699         *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
700     } catch (CAudioError& e) {
701         AUDIO_IO_LOGE("%s", e.getErrorMsg());
702         return __convert_CAudioError(e);
703     }
704
705     return AUDIO_IO_ERROR_NONE;
706 }
707
708 int cpp_audio_in_get_channel(audio_in_h input, audio_channel_e *channel) {
709     audio_io_s* handle = static_cast<audio_io_s*>(input);
710
711     try {
712         if (handle == NULL || channel == NULL)
713             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
714                                    "Parameters are NULL input:%p, channel:%p", input, channel);
715         assert(handle->audioIoHandle);
716
717         const CAudioInfo::EChannel srcChannel = handle->audioIoHandle->getAudioInfo().getChannel();
718         audio_channel_e dstChannel = AUDIO_CHANNEL_MONO;
719         __convert_audio_info_channel_2_channel(srcChannel, dstChannel);
720
721         *channel = dstChannel;
722     } catch (CAudioError& e) {
723         AUDIO_IO_LOGE("%s", e.getErrorMsg());
724         return __convert_CAudioError(e);
725     }
726
727     return AUDIO_IO_ERROR_NONE;
728 }
729
730 int cpp_audio_in_get_sample_type(audio_in_h input, audio_sample_type_e *type) {
731     audio_io_s* handle = static_cast<audio_io_s*>(input);
732
733     try {
734         if (handle == NULL || type == NULL)
735             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
736                                    "Parameters are NULL input:%p, type:%p", input, type);
737         assert(handle->audioIoHandle);
738
739         const CAudioInfo::ESampleType srcSampleType = handle->audioIoHandle->getAudioInfo().getSampleType();
740         audio_sample_type_e dstSampleType = AUDIO_SAMPLE_TYPE_U8;
741         __convert_audio_info_sample_type_2_sample_type(srcSampleType, dstSampleType);
742
743         *type = dstSampleType;
744     } catch (CAudioError& e) {
745         AUDIO_IO_LOGE("%s", e.getErrorMsg());
746         return __convert_CAudioError(e);
747     }
748
749     return AUDIO_IO_ERROR_NONE;
750 }
751
752 static void __interrupt_cb_internal(IAudioSessionEventListener::EInterruptCode _code, void* user_data) {
753     audio_io_s* handle = static_cast<audio_io_s*>(user_data);
754     audio_io_interrupted_code_e code = __convert_interrupted_code(_code);
755
756     assert(handle);
757
758     AUDIO_IO_LOGD("Calling interrupted callback for handle:[%p] code:[%d]", handle, code);
759
760     if (handle->interrupt_callback.onInterrupt)
761         handle->interrupt_callback.onInterrupt(code, handle->interrupt_callback.user_data);
762 }
763
764 int cpp_audio_in_set_interrupted_cb(audio_in_h input, audio_io_interrupted_cb callback, void *user_data) {
765     audio_io_s* handle = static_cast<audio_io_s*>(input);
766
767     try {
768         if (handle == NULL || callback == NULL)
769             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
770                                    "Parameters are NULL input:%p, callback:%p", input, callback);
771         assert(handle->audioIoHandle);
772         AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
773
774         handle->interrupt_callback.onInterrupt = callback;
775         handle->interrupt_callback.user_data = user_data;
776
777         CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
778         cb.mUserData = static_cast<void*>(handle);
779         cb.onInterrupt = __interrupt_cb_internal;
780
781         handle->audioIoHandle->setInterruptCallback(cb);
782     } catch (CAudioError& e) {
783         AUDIO_IO_LOGE("%s", e.getErrorMsg());
784         return __convert_CAudioError(e);
785     }
786
787     AUDIO_IO_LOGD("[%p] done", handle);
788
789     return AUDIO_IO_ERROR_NONE;
790 }
791
792 int cpp_audio_in_unset_interrupted_cb(audio_in_h input) {
793     audio_io_s* handle = static_cast<audio_io_s*>(input);
794
795     try {
796         if (handle == NULL)
797             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
798                                    "Parameters are NULL input:%p", input);
799         assert(handle->audioIoHandle);
800         AUDIO_IO_LOGD("[%p]", handle);
801
802         handle->interrupt_callback.onInterrupt = NULL;
803         handle->interrupt_callback.user_data    = NULL;
804
805         CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
806         cb.mUserData = NULL;
807         cb.onInterrupt = NULL;
808
809         handle->audioIoHandle->setInterruptCallback(cb);
810     } catch (CAudioError& e) {
811         AUDIO_IO_LOGE("%s", e.getErrorMsg());
812         return __convert_CAudioError(e);
813     }
814
815     AUDIO_IO_LOGD("[%p] done", handle);
816
817     return AUDIO_IO_ERROR_NONE;
818 }
819
820 int cpp_audio_in_ignore_session(audio_in_h input) {
821     audio_io_s* handle = static_cast<audio_io_s*>(input);
822
823     try {
824         if (handle == NULL)
825             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
826                                    "Parameters are NULL input:%p", input);
827         if (handle->stream_callback.onStream)
828             THROW_ERROR_MSG(CAudioError::EError::ERROR_INVALID_OPERATION,
829                             "Not support ignore session in async mode");
830         assert(handle->audioIoHandle);
831         AUDIO_IO_LOGD("[%p]", handle);
832
833         handle->audioIoHandle->ignoreSession();
834     } catch (CAudioError& e) {
835         AUDIO_IO_LOGE("%s", e.getErrorMsg());
836         return __convert_CAudioError(e);
837     }
838
839     AUDIO_IO_LOGD("[%p] done", handle);
840
841     return AUDIO_IO_ERROR_NONE;
842 }
843
844 static void __stream_cb_internal(size_t nbytes, void *user_data) {
845     audio_io_s* audioIo = static_cast<audio_io_s*>(user_data);
846     assert(audioIo);
847
848     if (audioIo->stream_callback.onStream)
849         audioIo->stream_callback.onStream(audioIo, nbytes, audioIo->stream_callback.user_data);
850 }
851
852 static void __state_changed_cb_internal(CAudioInfo::EAudioIOState state,
853                                         CAudioInfo::EAudioIOState state_prev,
854                                         bool by_policy,
855                                         void *user_data) {
856     audio_io_s* audioIo = static_cast<audio_io_s*>(user_data);
857     assert(audioIo);
858
859     if (audioIo->state_changed_callback.onStateChanged)
860         audioIo->state_changed_callback.onStateChanged(audioIo, __convert_state_type(state_prev),
861                                                        __convert_state_type(state), by_policy,
862                                                        audioIo->state_changed_callback.user_data);
863 }
864
865 int cpp_audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* user_data) {
866     audio_io_s* handle = static_cast<audio_io_s*>(input);
867
868     try {
869         if (handle == NULL || callback == NULL)
870             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
871                                    "Parameters are NULL input:%p, callback:%p", input, callback);
872         assert(handle->audioIoHandle);
873         AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
874
875         handle->stream_callback.onStream = callback;
876         handle->stream_callback.user_data = user_data;
877
878         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
879         cb.mUserData = static_cast<void*>(handle);
880         cb.onStream  = __stream_cb_internal;
881
882         handle->audioIoHandle->setStreamCallback(cb);
883     } catch (CAudioError& e) {
884         AUDIO_IO_LOGE("%s", e.getErrorMsg());
885         return __convert_CAudioError(e);
886     }
887
888     AUDIO_IO_LOGD("[%p] done", handle);
889
890     return AUDIO_IO_ERROR_NONE;
891 }
892
893 int cpp_audio_in_unset_stream_cb(audio_in_h input) {
894     audio_io_s* handle = static_cast<audio_io_s*>(input);
895
896     try {
897         if (handle == NULL)
898             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
899                                    "Parameters are NULL input:%p", input);
900         assert(handle->audioIoHandle);
901         AUDIO_IO_LOGD("[%p]", handle);
902
903         handle->stream_callback.onStream = NULL;
904         handle->stream_callback.user_data = NULL;
905
906         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
907         cb.mUserData = NULL;
908         cb.onStream  = NULL;
909
910         handle->audioIoHandle->setStreamCallback(cb);
911     } catch (CAudioError& e) {
912         AUDIO_IO_LOGE("%s", e.getErrorMsg());
913         return __convert_CAudioError(e);
914     }
915
916     AUDIO_IO_LOGD("[%p] done", handle);
917
918     return AUDIO_IO_ERROR_NONE;
919 }
920
921 int cpp_audio_in_peek(audio_in_h input, const void **buffer, unsigned int *length) {
922     audio_io_s* handle = static_cast<audio_io_s*>(input);
923     size_t _length = 0;
924
925     try {
926         if (handle == NULL || buffer == NULL)
927             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
928                                    "Parameters are NULL input:%p, buffer:%p", input, buffer);
929
930         CAudioInput* inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
931         if (inputHandle == NULL)
932             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
933
934         inputHandle->peek(buffer, &_length);
935     } catch (CAudioError& e) {
936         AUDIO_IO_LOGE("%s", e.getErrorMsg());
937         return __convert_CAudioError(e);
938     }
939
940     *length = (unsigned int)_length;
941
942     return AUDIO_IO_ERROR_NONE;
943 }
944
945 int cpp_audio_in_drop(audio_in_h input) {
946     audio_io_s* handle = static_cast<audio_io_s*>(input);
947
948     try {
949         if (handle == NULL)
950             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
951                                    "Parameters are NULL input:%p", input);
952
953         CAudioInput* inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
954         if (inputHandle == NULL)
955             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
956
957         inputHandle->drop();
958     } catch (CAudioError& e) {
959         AUDIO_IO_LOGE("%s", e.getErrorMsg());
960         return __convert_CAudioError(e);
961     }
962
963     return AUDIO_IO_ERROR_NONE;
964 }
965
966 int cpp_audio_in_set_state_changed_cb(audio_in_h input, audio_in_state_changed_cb callback, void* user_data) {
967     audio_io_s* handle = static_cast<audio_io_s*>(input);
968
969     try {
970         if (handle == NULL || callback == NULL)
971             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
972                                    "Parameters are NULL input:%p, callback:%p", input, callback);
973         assert(handle->audioIoHandle);
974         AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
975
976         handle->state_changed_callback.onStateChanged = callback;
977         handle->state_changed_callback.user_data = user_data;
978
979         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
980         cb.mUserData = static_cast<void*>(handle);
981         cb.onStateChanged = __state_changed_cb_internal;
982
983         handle->audioIoHandle->setStateChangedCallback(cb);
984     } catch (CAudioError& e) {
985         AUDIO_IO_LOGE("%s", e.getErrorMsg());
986         return __convert_CAudioError(e);
987     }
988
989     AUDIO_IO_LOGD("[%p] done", handle);
990
991     return AUDIO_IO_ERROR_NONE;
992 }
993
994 int cpp_audio_in_unset_state_changed_cb(audio_in_h input) {
995     audio_io_s* handle = static_cast<audio_io_s*>(input);
996
997     try {
998         if (handle == NULL)
999             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1000                                    "Parameters are NULL output:%p", input);
1001         assert(handle->audioIoHandle);
1002         AUDIO_IO_LOGD("[%p]", handle);
1003
1004         handle->state_changed_callback.onStateChanged = NULL;
1005         handle->state_changed_callback.user_data = NULL;
1006
1007         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
1008         cb.mUserData = NULL;
1009         cb.onStateChanged  = NULL;
1010
1011         handle->audioIoHandle->setStateChangedCallback(cb);
1012     } catch (CAudioError& e) {
1013         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1014         return __convert_CAudioError(e);
1015     }
1016
1017     AUDIO_IO_LOGD("[%p] done", handle);
1018
1019     return AUDIO_IO_ERROR_NONE;
1020 }
1021
1022
1023 /**
1024  * Audio Out
1025  */
1026 int cpp_audio_out_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, sound_type_e sound_type, audio_out_h *output) {
1027     audio_io_s* handle = NULL;
1028     try {
1029         if (output == NULL)
1030             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1031                                    "Parameters are NULL output:%p", output);
1032
1033         __check_audio_param(sample_rate, channel, type, sound_type);
1034
1035         AUDIO_IO_LOGD("samplerate:[%d] channel:[0x%x] sample_type:[0x%x] sound_type:[%d]", sample_rate, channel, type, sound_type);
1036         CAudioInfo audioInfo = __generate_audio_output_info(sample_rate, channel, type, sound_type);
1037
1038         handle = new audio_io_s;
1039         handle->audioIoHandle = new CAudioOutput(audioInfo);
1040         handle->audioIoHandle->initialize();
1041
1042         AUDIO_IO_LOGD("[%p] created", handle);
1043         *output = handle;
1044     } catch (CAudioError& e) {
1045         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1046         __handle_safe_free(handle, (void *)output, true);
1047         return __convert_CAudioError(e);
1048     } catch (const std::bad_alloc&) {
1049         CAudioError e = CAudioError::EError::ERROR_OUT_OF_MEMORY;
1050         AUDIO_IO_LOGE("Failed to allocate handle");
1051         __handle_safe_free(handle, (void *)output, true);
1052         return __convert_CAudioError(e);
1053     }
1054
1055     return AUDIO_IO_ERROR_NONE;
1056 }
1057
1058 int cpp_audio_out_create_new(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_out_h *output) {
1059     audio_io_s* handle = NULL;
1060     try {
1061         if (output == NULL)
1062             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1063                                    "Parameters are NULL output:%p", output);
1064
1065         __check_audio_param(sample_rate, channel, type, SOUND_TYPE_SYSTEM /*default check */);
1066
1067         AUDIO_IO_LOGD("samplerate:[%d] channel:[0x%x] sample_type:[0x%x]", sample_rate, channel, type);
1068         CAudioInfo audioInfo = __generate_audio_output_info(sample_rate, channel, type, SOUND_TYPE_MEDIA);
1069
1070         handle = new audio_io_s;
1071         handle->audioIoHandle = new CAudioOutput(audioInfo);
1072         handle->audioIoHandle->initialize();
1073
1074         AUDIO_IO_LOGD("[%p] created", handle);
1075         *output = handle;
1076     } catch (CAudioError& e) {
1077         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1078         __handle_safe_free(handle, (void *)output, true);
1079         return __convert_CAudioError(e);
1080     } catch (const std::bad_alloc&) {
1081         CAudioError e = CAudioError::EError::ERROR_OUT_OF_MEMORY;
1082         AUDIO_IO_LOGE("Failed to allocate handle");
1083         __handle_safe_free(handle, (void *)output, true);
1084         return __convert_CAudioError(e);
1085     }
1086
1087     return AUDIO_IO_ERROR_NONE;
1088 }
1089
1090 int cpp_audio_out_destroy(audio_out_h output) {
1091     audio_io_s* handle = static_cast<audio_io_s*>(output);
1092
1093     try {
1094         if (handle == NULL)
1095             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1096                                    "Parameter is NULL output:%p", output);
1097         assert(handle->audioIoHandle);
1098         AUDIO_IO_LOGD("[%p]", handle);
1099
1100         /* Internal unprepare for backward compatibility */
1101         handle->audioIoHandle->unprepare();
1102
1103         SAFE_FINALIZE(handle->audioIoHandle);
1104         SAFE_DELETE(handle->audioIoHandle);
1105         SAFE_DELETE(handle);
1106     } catch (CAudioError& e) {
1107         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1108         return __convert_CAudioError(e);
1109     }
1110
1111     AUDIO_IO_LOGD("destroyed");
1112
1113     return AUDIO_IO_ERROR_NONE;
1114 }
1115
1116 int cpp_audio_out_set_sound_stream_info(audio_out_h output, sound_stream_info_h stream_info) {
1117     audio_io_s* handle = static_cast<audio_io_s*>(output);
1118
1119     try {
1120         if (handle == NULL || stream_info == NULL)
1121             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1122                                    "Parameters are NULL output:%p, stream_info:%p", output, stream_info);
1123         assert(handle->audioIoHandle);
1124         AUDIO_IO_LOGD("[%p], stream_info:[%p]", handle, stream_info);
1125
1126         handle->audioIoHandle->setStreamInfo(stream_info);
1127     } catch (CAudioError& e) {
1128         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1129         return __convert_CAudioError(e);
1130     }
1131
1132     AUDIO_IO_LOGD("[%p] done", handle);
1133
1134     return AUDIO_IO_ERROR_NONE;
1135 }
1136
1137 int cpp_audio_out_prepare(audio_out_h output) {
1138     audio_io_s* handle = static_cast<audio_io_s*>(output);
1139
1140     try {
1141         if (handle == NULL)
1142             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1143                                    "Parameter is NULL output:%p", output);
1144         assert(handle->audioIoHandle);
1145         AUDIO_IO_LOGD("[%p]", handle);
1146
1147         handle->audioIoHandle->prepare();
1148     } catch (CAudioError& e) {
1149         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1150         return __convert_CAudioError(e);
1151     }
1152
1153     AUDIO_IO_LOGD("[%p] prepared", handle);
1154
1155     return AUDIO_IO_ERROR_NONE;
1156 }
1157
1158 int cpp_audio_out_unprepare(audio_out_h output) {
1159     audio_io_s* handle = static_cast<audio_io_s*>(output);
1160
1161     try {
1162         if (handle == NULL)
1163             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1164                                    "Parameter is NULL output:%p", output);
1165         assert(handle->audioIoHandle);
1166         AUDIO_IO_LOGD("[%p]", handle);
1167
1168         handle->audioIoHandle->unprepare();
1169     } catch (CAudioError& e) {
1170         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1171         return __convert_CAudioError(e);
1172     }
1173
1174     AUDIO_IO_LOGD("[%p] unprepared", handle);
1175
1176     return AUDIO_IO_ERROR_NONE;
1177 }
1178
1179 int cpp_audio_out_pause(audio_out_h output) {
1180     audio_io_s* handle = static_cast<audio_io_s*>(output);
1181
1182     try {
1183         if (handle == NULL)
1184             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1185                                    "Parameter is NULL output:%p", output);
1186         assert(handle->audioIoHandle);
1187         AUDIO_IO_LOGD("[%p]", handle);
1188
1189         handle->audioIoHandle->pause();
1190     } catch (CAudioError& e) {
1191         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1192         return __convert_CAudioError(e);
1193     }
1194
1195     AUDIO_IO_LOGD("[%p] paused", handle);
1196
1197     return AUDIO_IO_ERROR_NONE;
1198 }
1199
1200 int cpp_audio_out_resume(audio_out_h output) {
1201     audio_io_s* handle = static_cast<audio_io_s*>(output);
1202
1203     try {
1204         if (handle == NULL)
1205             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1206                                    "Parameter is NULL output:%p", output);
1207         assert(handle->audioIoHandle);
1208         AUDIO_IO_LOGD("[%p]", handle);
1209
1210         handle->audioIoHandle->resume();
1211     } catch (CAudioError& e) {
1212         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1213         return __convert_CAudioError(e);
1214     }
1215
1216     AUDIO_IO_LOGD("[%p] resumed", handle);
1217
1218     return AUDIO_IO_ERROR_NONE;
1219 }
1220
1221 int cpp_audio_out_drain(audio_out_h output) {
1222     audio_io_s* handle = static_cast<audio_io_s*>(output);
1223
1224     try {
1225         if (handle == NULL)
1226             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1227                                    "Parameter is NULL output:%p", output);
1228         assert(handle->audioIoHandle);
1229         AUDIO_IO_LOGD("[%p]", handle);
1230
1231         handle->audioIoHandle->drain();
1232     } catch (CAudioError& e) {
1233         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1234         return __convert_CAudioError(e);
1235     }
1236
1237     AUDIO_IO_LOGD("[%p] drained", handle);
1238
1239     return AUDIO_IO_ERROR_NONE;
1240 }
1241
1242 int cpp_audio_out_flush(audio_out_h output) {
1243     audio_io_s* handle = static_cast<audio_io_s*>(output);
1244
1245     try {
1246         if (handle == NULL)
1247             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1248                                    "Parameter is NULL output:%p", output);
1249         assert(handle->audioIoHandle);
1250         AUDIO_IO_LOGD("[%p]", handle);
1251
1252         handle->audioIoHandle->flush();
1253     } catch (CAudioError& e) {
1254         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1255         return __convert_CAudioError(e);
1256     }
1257
1258     AUDIO_IO_LOGD("[%p] flushed", handle);
1259
1260     return AUDIO_IO_ERROR_NONE;
1261 }
1262
1263 int cpp_audio_out_write(audio_out_h output, void *buffer, unsigned int length) {
1264     audio_io_s* handle = static_cast<audio_io_s*>(output);
1265     int ret = 0;
1266
1267     try {
1268         if (handle == NULL || buffer == NULL)
1269             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1270                                    "Parameter is NULL output:%p, buffer:%p", output, buffer);
1271         assert(handle->audioIoHandle);
1272
1273         CAudioOutput* outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
1274         if (outputHandle == NULL)
1275             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1276
1277         size_t written = outputHandle->write(buffer, static_cast<size_t>(length));
1278         ret = static_cast<int>(written);
1279 #ifdef _AUDIO_IO_DEBUG_TIMING_
1280         AUDIO_IO_LOGD("written:%d", written);
1281 #endif
1282     } catch (CAudioError& e) {
1283         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1284         return __convert_CAudioError(e);
1285     }
1286
1287     return ret;
1288 }
1289
1290 int cpp_audio_out_get_buffer_size(audio_out_h output, int *size) {
1291     audio_io_s* handle = static_cast<audio_io_s*>(output);
1292
1293     try {
1294         if (handle == NULL || size == NULL)
1295             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1296                                    "Parameters are NULL output:%p, size:%p", output, size);
1297         assert(handle->audioIoHandle);
1298
1299         CAudioOutput* outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
1300         if (outputHandle == NULL)
1301             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1302
1303         *size = outputHandle->getBufferSize();
1304     } catch (CAudioError& e) {
1305         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1306         return __convert_CAudioError(e);
1307     }
1308
1309     return AUDIO_IO_ERROR_NONE;
1310 }
1311
1312 int cpp_audio_out_get_sample_rate(audio_out_h output, int *sample_rate) {
1313     audio_io_s* handle = static_cast<audio_io_s*>(output);
1314
1315     try {
1316         if (handle == NULL || sample_rate == NULL)
1317             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1318                                    "Parameters are NULL output:%p, sample_rate:%p", output, sample_rate);
1319         assert(handle->audioIoHandle);
1320
1321         *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
1322     } catch (CAudioError& e) {
1323         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1324         return __convert_CAudioError(e);
1325     }
1326
1327     return AUDIO_IO_ERROR_NONE;
1328 }
1329
1330 int cpp_audio_out_get_channel(audio_out_h output, audio_channel_e *channel) {
1331     audio_io_s* handle = static_cast<audio_io_s*>(output);
1332
1333     try {
1334         if (handle == NULL || channel == NULL)
1335             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1336                                    "Parameters are NULL output:%p, channel:%p", output, channel);
1337         assert(handle->audioIoHandle);
1338
1339         const CAudioInfo::EChannel srcChannel = handle->audioIoHandle->getAudioInfo().getChannel();
1340         audio_channel_e dstChannel = AUDIO_CHANNEL_MONO;
1341         __convert_audio_info_channel_2_channel(srcChannel, dstChannel);
1342
1343         *channel = dstChannel;
1344     } catch (CAudioError& e) {
1345         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1346         return __convert_CAudioError(e);
1347     }
1348
1349     return AUDIO_IO_ERROR_NONE;
1350 }
1351
1352 int cpp_audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type) {
1353     audio_io_s* handle = static_cast<audio_io_s*>(output);
1354
1355     try {
1356         if (handle == NULL || type == NULL)
1357             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1358                                    "Parameters are NULL output:%p, type:%p", output, type);
1359         assert(handle->audioIoHandle);
1360
1361         const CAudioInfo::ESampleType srcSampleType = handle->audioIoHandle->getAudioInfo().getSampleType();
1362         audio_sample_type_e dstSampleType = AUDIO_SAMPLE_TYPE_U8;
1363         __convert_audio_info_sample_type_2_sample_type(srcSampleType, dstSampleType);
1364
1365         *type = dstSampleType;
1366     } catch (CAudioError& e) {
1367         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1368         return __convert_CAudioError(e);
1369     }
1370
1371     return AUDIO_IO_ERROR_NONE;
1372 }
1373
1374 int cpp_audio_out_get_sound_type(audio_out_h output, sound_type_e *type) {
1375     audio_io_s* handle = static_cast<audio_io_s*>(output);
1376
1377     try {
1378         if (handle == NULL || type == NULL)
1379             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1380                                    "Parameters are NULL output:%p, type:%p", output, type);
1381         assert(handle->audioIoHandle);
1382
1383         const CAudioInfo::EAudioType srcAudioType = handle->audioIoHandle->getAudioInfo().getAudioType();
1384         sound_type_e dstSoundType = SOUND_TYPE_MEDIA;
1385         __convert_audio_info_audio_type_2_sound_type(srcAudioType, dstSoundType);
1386
1387         *type = dstSoundType;
1388     } catch (CAudioError& e) {
1389         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1390         return __convert_CAudioError(e);
1391     }
1392
1393     return AUDIO_IO_ERROR_NONE;
1394 }
1395
1396 int cpp_audio_out_set_interrupted_cb(audio_out_h output, audio_io_interrupted_cb callback, void *user_data) {
1397     audio_io_s* handle = static_cast<audio_io_s*>(output);
1398
1399     try {
1400         if (handle == NULL || callback == NULL)
1401             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1402                                    "Parameters are NULL output:%p, callback:%p", output, callback);
1403         assert(handle->audioIoHandle);
1404         AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
1405
1406         handle->interrupt_callback.onInterrupt = callback;
1407         handle->interrupt_callback.user_data    = user_data;
1408
1409         CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
1410         cb.mUserData = static_cast<void*>(handle);
1411         cb.onInterrupt = __interrupt_cb_internal;
1412
1413         handle->audioIoHandle->setInterruptCallback(cb);
1414     } catch (CAudioError& e) {
1415         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1416         return __convert_CAudioError(e);
1417     }
1418
1419     AUDIO_IO_LOGD("[%p] done", handle);
1420
1421     return AUDIO_IO_ERROR_NONE;
1422 }
1423
1424 int cpp_audio_out_unset_interrupted_cb(audio_out_h output) {
1425     audio_io_s* handle = static_cast<audio_io_s*>(output);
1426
1427     try {
1428         if (handle == NULL)
1429             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1430                                    "Parameters are NULL output:%p", output);
1431         assert(handle->audioIoHandle);
1432         AUDIO_IO_LOGD("[%p]", handle);
1433
1434         handle->interrupt_callback.onInterrupt = NULL;
1435         handle->interrupt_callback.user_data = NULL;
1436
1437         CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
1438         cb.mUserData = NULL;
1439         cb.onInterrupt = NULL;
1440
1441         handle->audioIoHandle->setInterruptCallback(cb);
1442     } catch (CAudioError& e) {
1443         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1444         return __convert_CAudioError(e);
1445     }
1446
1447     AUDIO_IO_LOGD("[%p] done", handle);
1448
1449     return AUDIO_IO_ERROR_NONE;
1450 }
1451
1452 int cpp_audio_out_ignore_session(audio_out_h output) {
1453     audio_io_s* handle = static_cast<audio_io_s*>(output);
1454
1455     try {
1456         if (handle == NULL)
1457             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1458                                    "Parameters are NULL output:%p", output);
1459         if (handle->stream_callback.onStream)
1460             THROW_ERROR_MSG(CAudioError::EError::ERROR_INVALID_OPERATION,
1461                             "Not support ignore session in async mode");
1462         assert(handle->audioIoHandle);
1463         AUDIO_IO_LOGD("[%p]", handle);
1464
1465         handle->audioIoHandle->ignoreSession();
1466     } catch (CAudioError& e) {
1467         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1468         return __convert_CAudioError(e);
1469     }
1470
1471     AUDIO_IO_LOGD("[%p] done", handle);
1472
1473     return AUDIO_IO_ERROR_NONE;
1474 }
1475
1476 int cpp_audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* user_data) {
1477     audio_io_s* handle = static_cast<audio_io_s*>(output);
1478
1479     try {
1480         if (handle == NULL || callback == NULL)
1481             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1482                                    "Parameters are NULL output:%p, callback:%p", output, callback);
1483         assert(handle->audioIoHandle);
1484         AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
1485
1486         handle->stream_callback.onStream = callback;
1487         handle->stream_callback.user_data = user_data;
1488
1489         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
1490         cb.mUserData = static_cast<void*>(handle);
1491         cb.onStream = __stream_cb_internal;
1492
1493         handle->audioIoHandle->setStreamCallback(cb);
1494     } catch (CAudioError& e) {
1495         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1496         return __convert_CAudioError(e);
1497     }
1498
1499     AUDIO_IO_LOGD("[%p] done", handle);
1500
1501     return AUDIO_IO_ERROR_NONE;
1502 }
1503
1504 int cpp_audio_out_unset_stream_cb(audio_out_h output) {
1505     audio_io_s* handle = static_cast<audio_io_s*>(output);
1506
1507     try {
1508         if (handle == NULL)
1509             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1510                                    "Parameters are NULL output:%p", output);
1511         assert(handle->audioIoHandle);
1512         AUDIO_IO_LOGD("[%p]", handle);
1513
1514         handle->stream_callback.onStream = NULL;
1515         handle->stream_callback.user_data = NULL;
1516
1517         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
1518         cb.mUserData = NULL;
1519         cb.onStream = NULL;
1520
1521         handle->audioIoHandle->setStreamCallback(cb);
1522     } catch (CAudioError& e) {
1523         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1524         return __convert_CAudioError(e);
1525     }
1526
1527     AUDIO_IO_LOGD("[%p] done", handle);
1528
1529     return AUDIO_IO_ERROR_NONE;
1530 }
1531
1532 int cpp_audio_out_set_state_changed_cb(audio_out_h output, audio_in_state_changed_cb callback, void* user_data) {
1533     audio_io_s* handle = static_cast<audio_io_s*>(output);
1534
1535     try {
1536         if (handle == NULL || callback == NULL)
1537             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1538                                    "Parameters are NULL output:%p, callback:%p", output, callback);
1539         assert(handle->audioIoHandle);
1540         AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
1541
1542         handle->state_changed_callback.onStateChanged = callback;
1543         handle->state_changed_callback.user_data = user_data;
1544
1545         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
1546         cb.mUserData = static_cast<void*>(handle);
1547         cb.onStateChanged = __state_changed_cb_internal;
1548
1549         handle->audioIoHandle->setStateChangedCallback(cb);
1550     } catch (CAudioError& e) {
1551         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1552         return __convert_CAudioError(e);
1553     }
1554
1555     AUDIO_IO_LOGD("[%p] done", handle);
1556
1557     return AUDIO_IO_ERROR_NONE;
1558 }
1559
1560 int cpp_audio_out_unset_state_changed_cb(audio_out_h output) {
1561     audio_io_s* handle = static_cast<audio_io_s*>(output);
1562
1563     try {
1564         if (handle == NULL)
1565             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1566                                    "Parameters are NULL output:%p", output);
1567         assert(handle->audioIoHandle);
1568         AUDIO_IO_LOGD("[%p]", handle);
1569
1570         handle->state_changed_callback.onStateChanged = NULL;
1571         handle->state_changed_callback.user_data = NULL;
1572
1573         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
1574         cb.mUserData = NULL;
1575         cb.onStateChanged = NULL;
1576
1577         handle->audioIoHandle->setStateChangedCallback(cb);
1578     } catch (CAudioError& e) {
1579         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1580         return __convert_CAudioError(e);
1581     }
1582
1583     AUDIO_IO_LOGD("[%p] done", handle);
1584
1585     return AUDIO_IO_ERROR_NONE;
1586 }