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