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