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