audio-io fixed reference of CAudioInfo, check supported stream info
[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
406 int cpp_audio_in_create_loopback(int sample_rate, audio_channel_e channel, audio_sample_type_e type , audio_in_h* input) {
407     audio_io_s* handle = NULL;
408     try {
409         if (input == NULL) {
410             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
411         }
412
413         __check_audio_param(sample_rate, channel, type);
414
415         handle = new audio_io_s;
416         if (handle == NULL) {
417             THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation handle");
418         }
419
420         CAudioInfo audioInfo = __generate_audio_input_loopback_info(sample_rate, channel, type);
421
422         handle->audioIoHandle = new CAudioInput(audioInfo);
423         if (handle == NULL) {
424             THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation internal handle");
425         }
426
427         handle->audioIoHandle->initialize();
428
429         *input = handle;
430     } catch (CAudioError e) {
431         AUDIO_IO_LOGE("%s", e.getErrorMsg());
432
433         VALID_POINTER_START(handle)
434             SAFE_FINALIZE(handle->audioIoHandle);
435             SAFE_DELETE(handle->audioIoHandle);
436             SAFE_DELETE(handle);
437         VALID_POINTER_END
438
439         VALID_POINTER_START(input)
440             *input = NULL;
441         VALID_POINTER_END
442
443         return __convert_CAudioError(e);
444     }
445
446     return AUDIO_IO_ERROR_NONE;
447 }
448
449 int cpp_audio_in_destroy(audio_in_h input) {
450     audio_io_s* handle = static_cast<audio_io_s*>(input);
451
452     try {
453         if (handle == NULL) {
454             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
455         }
456
457         assert(handle->audioIoHandle);
458
459         SAFE_FINALIZE(handle->audioIoHandle);
460         SAFE_DELETE(handle->audioIoHandle);
461         SAFE_DELETE(handle);
462     } catch (CAudioError e) {
463         AUDIO_IO_LOGE("%s", e.getErrorMsg());
464         return __convert_CAudioError(e);
465     }
466
467     return AUDIO_IO_ERROR_NONE;
468 }
469
470 int cpp_audio_in_set_stream_info(audio_in_h input, sound_stream_info_h stream_info) {
471     audio_io_s* handle = static_cast<audio_io_s*>(input);
472
473     try {
474         if (handle == NULL || stream_info == NULL) {
475             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, stream_info:%p", input, stream_info);
476         }
477
478         assert(handle->audioIoHandle);
479
480         int errorCode = SOUND_MANAGER_ERROR_NONE;
481         CAudioInfo::EAudioType audioType = CAudioInfo::EAudioType::AUDIO_IN_TYPE_MEDIA;
482         char *type = NULL;
483         int index = -1;
484         bool avail = false;
485
486         if ((errorCode = sound_manager_is_available_stream_information(stream_info, NATIVE_API_AUDIO_IO, &avail)) != SOUND_MANAGER_ERROR_NONE) {
487             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info is invalid [ret:%d]", errorCode);
488         }
489
490         if (avail) {
491             if ((errorCode = sound_manager_get_type_from_stream_information (stream_info, &type)) != SOUND_MANAGER_ERROR_NONE) {
492                 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->stream_type is invalid [ret:%d]", errorCode);
493             }
494             handle->audioIoHandle->getAudioInfo().convertInputStreamType2AudioType(type, &audioType);
495             handle->audioIoHandle->getAudioInfo().setAudioType(audioType);
496
497             if ((errorCode = sound_manager_get_index_from_stream_information (stream_info, &index)) != SOUND_MANAGER_ERROR_NONE) {
498                 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->index is invalid [ret:%d]", errorCode);
499             }
500             handle->audioIoHandle->getAudioInfo().setAudioIndex(index);
501         } else {
502             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_NOT_SUPPORTED_TYPE, "Input stream is not supported");
503         }
504     } catch (CAudioError e) {
505         AUDIO_IO_LOGE("%s", e.getErrorMsg());
506         return __convert_CAudioError(e);
507     }
508
509     return AUDIO_IO_ERROR_NONE;
510 }
511
512 int cpp_audio_in_prepare(audio_in_h input) {
513     audio_io_s* handle = static_cast<audio_io_s*>(input);
514
515     try {
516         if (handle == NULL) {
517             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
518         }
519
520         assert(handle->audioIoHandle);
521
522         handle->audioIoHandle->prepare();
523     } catch (CAudioError e) {
524         AUDIO_IO_LOGE("%s", e.getErrorMsg());
525         return __convert_CAudioError(e);
526     }
527
528     return AUDIO_IO_ERROR_NONE;
529 }
530
531 int cpp_audio_in_unprepare(audio_in_h input) {
532     audio_io_s* handle = static_cast<audio_io_s*>(input);
533
534     try {
535         if (handle == NULL) {
536             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
537         }
538
539         assert(handle->audioIoHandle);
540
541         handle->audioIoHandle->unprepare();
542     } catch (CAudioError e) {
543         AUDIO_IO_LOGE("%s", e.getErrorMsg());
544         return __convert_CAudioError(e);
545     }
546
547     return AUDIO_IO_ERROR_NONE;
548 }
549
550 int cpp_audio_in_pause(audio_in_h input) {
551     audio_io_s* handle = static_cast<audio_io_s*>(input);
552
553     try {
554         if (handle == NULL) {
555             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
556         }
557
558         assert(handle->audioIoHandle);
559
560         handle->audioIoHandle->pause();
561     } catch (CAudioError e) {
562         AUDIO_IO_LOGE("%s", e.getErrorMsg());
563         return __convert_CAudioError(e);
564     }
565
566     return AUDIO_IO_ERROR_NONE;
567 }
568
569 int cpp_audio_in_resume(audio_in_h input) {
570     audio_io_s* handle = static_cast<audio_io_s*>(input);
571
572     try {
573         if (handle == NULL) {
574             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
575         }
576
577         assert(handle->audioIoHandle);
578
579         handle->audioIoHandle->resume();
580     } catch (CAudioError e) {
581         AUDIO_IO_LOGE("%s", e.getErrorMsg());
582         return __convert_CAudioError(e);
583     }
584
585     return AUDIO_IO_ERROR_NONE;
586 }
587
588 int cpp_audio_in_drain(audio_in_h input) {
589     audio_io_s* handle = static_cast<audio_io_s*>(input);
590
591     try {
592         if (handle == NULL) {
593             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
594         }
595
596         assert(handle->audioIoHandle);
597
598         handle->audioIoHandle->drain();
599     } catch (CAudioError e) {
600         AUDIO_IO_LOGE("%s", e.getErrorMsg());
601         return __convert_CAudioError(e);
602     }
603
604     return AUDIO_IO_ERROR_NONE;
605 }
606
607 int cpp_audio_in_flush(audio_in_h input) {
608     audio_io_s* handle = static_cast<audio_io_s*>(input);
609
610     try {
611         if (handle == NULL) {
612             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
613         }
614
615         assert(handle->audioIoHandle);
616
617         handle->audioIoHandle->flush();
618     } catch (CAudioError e) {
619         AUDIO_IO_LOGE("%s", e.getErrorMsg());
620         return __convert_CAudioError(e);
621     }
622
623     return AUDIO_IO_ERROR_NONE;
624 }
625
626 int cpp_audio_in_read(audio_in_h input, void *buffer, unsigned int length) {
627     audio_io_s* handle = static_cast<audio_io_s*>(input);
628     int ret = 0;
629
630     try {
631         if (handle == NULL || buffer == NULL) {
632             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, buffer:%p", input, buffer);
633         }
634
635         assert(handle->audioIoHandle);
636
637         CAudioInput* inputHandle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
638         size_t readn = inputHandle->read(buffer, static_cast<size_t>(length));
639         ret = static_cast<int>(readn);
640 #ifdef _AUDIO_IO_DEBUG_TIMING_
641         AUDIO_IO_LOGD("readn:%d", readn);
642 #endif
643     } catch (CAudioError e) {
644         AUDIO_IO_LOGE("%s", e.getErrorMsg());
645         return __convert_CAudioError(e);
646     }
647
648     return ret;
649 }
650
651 int cpp_audio_in_get_buffer_size(audio_in_h input, int *size) {
652     audio_io_s* handle = static_cast<audio_io_s*>(input);
653
654     try {
655         if (handle == NULL || size == NULL) {
656             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, size:%p", input, size);
657         }
658
659         assert(handle->audioIoHandle);
660
661         CAudioIO* inputHandle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
662         *size = inputHandle->getBufferSize();
663     } catch (CAudioError e) {
664         AUDIO_IO_LOGE("%s", e.getErrorMsg());
665         return __convert_CAudioError(e);
666     }
667
668     return AUDIO_IO_ERROR_NONE;
669 }
670
671 int cpp_audio_in_get_sample_rate(audio_in_h input, int *sample_rate) {
672     audio_io_s* handle = static_cast<audio_io_s*>(input);
673
674     try {
675         if (handle == NULL || sample_rate == NULL) {
676             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, sample_rate:%p", input, sample_rate);
677         }
678
679         assert(handle->audioIoHandle);
680         *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
681     } catch (CAudioError e) {
682         AUDIO_IO_LOGE("%s", e.getErrorMsg());
683         return __convert_CAudioError(e);
684     }
685
686     return AUDIO_IO_ERROR_NONE;
687 }
688
689 int cpp_audio_in_get_channel(audio_in_h input, audio_channel_e *channel) {
690     audio_io_s* handle = static_cast<audio_io_s*>(input);
691
692     try {
693         if (handle == NULL || channel == NULL) {
694             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, channel:%p", input, channel);
695         }
696
697         assert(handle->audioIoHandle);
698
699         const CAudioInfo::EChannel srcChannel = handle->audioIoHandle->getAudioInfo().getChannel();
700         audio_channel_e dstChannel = AUDIO_CHANNEL_MONO;
701         __convert_audio_info_channel_2_channel(srcChannel, dstChannel);
702
703         *channel = dstChannel;
704     } catch (CAudioError e) {
705         AUDIO_IO_LOGE("%s", e.getErrorMsg());
706         return __convert_CAudioError(e);
707     }
708
709     return AUDIO_IO_ERROR_NONE;
710 }
711
712 int cpp_audio_in_get_sample_type(audio_in_h input, audio_sample_type_e *type) {
713     audio_io_s* handle = static_cast<audio_io_s*>(input);
714
715     try {
716         if (handle == NULL || type == NULL) {
717             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, type:%p", input, type);
718         }
719
720         assert(handle->audioIoHandle);
721
722         const CAudioInfo::ESampleType srcSampleType = handle->audioIoHandle->getAudioInfo().getSampleType();
723         audio_sample_type_e     dstSampleType = AUDIO_SAMPLE_TYPE_U8;
724         __convert_audio_info_sample_type_2_sample_type(srcSampleType, dstSampleType);
725
726         *type = dstSampleType;
727     } catch (CAudioError e) {
728         AUDIO_IO_LOGE("%s", e.getErrorMsg());
729         return __convert_CAudioError(e);
730     }
731
732     return AUDIO_IO_ERROR_NONE;
733 }
734
735 static void __interrupt_cb_internal(IAudioSessionEventListener::EInterruptCode _code, void* user_data) {
736     audio_io_s* handle = static_cast<audio_io_s*>(user_data);
737     audio_io_interrupted_code_e code = __convert_interrupted_code(_code);
738
739     assert(handle);
740
741     if (handle->interrupt_callback.onInterrupt != NULL) {
742         handle->interrupt_callback.onInterrupt(code, handle->interrupt_callback.user_data);
743     }
744 }
745
746 int cpp_audio_in_set_interrupted_cb(audio_in_h input, audio_io_interrupted_cb callback, void *user_data) {
747     audio_io_s* handle = static_cast<audio_io_s*>(input);
748
749     try {
750         if (handle == NULL || callback == NULL) {
751             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, callback:%p", input, callback);
752         }
753
754         assert(handle->audioIoHandle);
755
756         handle->interrupt_callback.onInterrupt = callback;
757         handle->interrupt_callback.user_data    = user_data;
758
759         CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
760         cb.mUserData   = static_cast<void*>(handle);
761         cb.onInterrupt = __interrupt_cb_internal;
762
763         handle->audioIoHandle->setInterruptCallback(cb);
764     } catch (CAudioError e) {
765         AUDIO_IO_LOGE("%s", e.getErrorMsg());
766         return __convert_CAudioError(e);
767     }
768
769     return AUDIO_IO_ERROR_NONE;
770 }
771
772 int cpp_audio_in_unset_interrupted_cb(audio_in_h input) {
773     audio_io_s* handle = static_cast<audio_io_s*>(input);
774
775     try {
776         if (handle == NULL) {
777             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
778         }
779
780         assert(handle->audioIoHandle);
781
782         handle->interrupt_callback.onInterrupt = NULL;
783         handle->interrupt_callback.user_data    = NULL;
784
785         CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
786         cb.mUserData   = NULL;
787         cb.onInterrupt = NULL;
788
789         handle->audioIoHandle->setInterruptCallback(cb);
790     } catch (CAudioError e) {
791         AUDIO_IO_LOGE("%s", e.getErrorMsg());
792         return __convert_CAudioError(e);
793     }
794
795     return AUDIO_IO_ERROR_NONE;
796 }
797
798 int cpp_audio_in_ignore_session(audio_in_h input) {
799     audio_io_s* handle = static_cast<audio_io_s*>(input);
800
801     try {
802         if (handle == NULL) {
803             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
804         }
805
806         if (handle->stream_callback.onStream) {
807             THROW_ERROR_MSG(CAudioError::EError::ERROR_INVALID_OPERATION, "Not support ignore session in async mode");
808         }
809
810         assert(handle->audioIoHandle);
811
812         handle->audioIoHandle->ignoreSession();
813     } catch (CAudioError e) {
814         AUDIO_IO_LOGE("%s", e.getErrorMsg());
815         return __convert_CAudioError(e);
816     }
817
818     return AUDIO_IO_ERROR_NONE;
819 }
820
821 static void __stream_cb_internal(size_t nbytes, void *user_data) {
822     audio_io_s* audioIo = static_cast<audio_io_s*>(user_data);
823     assert(audioIo);
824
825     if (audioIo->stream_callback.onStream != NULL) {
826         audioIo->stream_callback.onStream(audioIo, nbytes, audioIo->stream_callback.user_data);
827     }
828 }
829
830 static void __state_changed_cb_internal(CAudioInfo::EAudioIOState state, CAudioInfo::EAudioIOState state_prev, bool by_policy, void *user_data) {
831     audio_io_s* audioIo = static_cast<audio_io_s*>(user_data);
832     assert(audioIo);
833
834     if (audioIo->state_changed_callback.onStateChanged != NULL) {
835         audioIo->state_changed_callback.onStateChanged(audioIo, __convert_state_type(state_prev), __convert_state_type(state), by_policy, audioIo->state_changed_callback.user_data);
836     }
837 }
838
839 int cpp_audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* user_data) {
840     audio_io_s* handle = static_cast<audio_io_s*>(input);
841
842     try {
843         if (handle == NULL || callback == NULL) {
844             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, callback:%p", input, callback);
845         }
846
847         assert(handle->audioIoHandle);
848
849         handle->stream_callback.onStream = callback;
850         handle->stream_callback.user_data = user_data;
851
852         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
853         cb.mUserData = static_cast<void*>(handle);
854         cb.onStream  = __stream_cb_internal;
855
856         handle->audioIoHandle->setStreamCallback(cb);
857     } catch (CAudioError e) {
858         AUDIO_IO_LOGE("%s", e.getErrorMsg());
859         return __convert_CAudioError(e);
860     }
861
862     return AUDIO_IO_ERROR_NONE;
863 }
864
865 int cpp_audio_in_unset_stream_cb(audio_in_h input) {
866     audio_io_s* handle = static_cast<audio_io_s*>(input);
867
868     try {
869         if (handle == NULL) {
870             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
871         }
872
873         assert(handle->audioIoHandle);
874
875         handle->stream_callback.onStream = NULL;
876         handle->stream_callback.user_data = NULL;
877
878         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
879         cb.mUserData = NULL;
880         cb.onStream  = NULL;
881
882         handle->audioIoHandle->setStreamCallback(cb);
883     } catch (CAudioError e) {
884         AUDIO_IO_LOGE("%s", e.getErrorMsg());
885         return __convert_CAudioError(e);
886     }
887
888     return AUDIO_IO_ERROR_NONE;
889 }
890
891 int cpp_audio_in_peek(audio_in_h input, const void **buffer, unsigned int *length) {
892     audio_io_s* handle = static_cast<audio_io_s*>(input);
893     size_t _length = 0;
894
895     try {
896         if (handle == NULL || buffer == NULL) {
897             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, buffer:%p", input, buffer);
898         }
899
900         CAudioInput* inputHandle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
901         assert(inputHandle);
902
903         inputHandle->peek(buffer, &_length);
904     } catch (CAudioError e) {
905         AUDIO_IO_LOGE("%s", e.getErrorMsg());
906         return __convert_CAudioError(e);
907     }
908
909     *length = (unsigned int)_length;
910
911     return AUDIO_IO_ERROR_NONE;
912 }
913
914 int cpp_audio_in_drop(audio_in_h input) {
915     audio_io_s* handle = static_cast<audio_io_s*>(input);
916
917     try {
918         if (handle == NULL) {
919             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
920         }
921
922         CAudioInput* inputHandle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
923         assert(inputHandle);
924
925         inputHandle->drop();
926     } catch (CAudioError e) {
927         AUDIO_IO_LOGE("%s", e.getErrorMsg());
928         return __convert_CAudioError(e);
929     }
930
931     return AUDIO_IO_ERROR_NONE;
932 }
933
934 int cpp_audio_in_set_state_changed_cb(audio_in_h input, audio_in_state_changed_cb callback, void* user_data) {
935     audio_io_s* handle = static_cast<audio_io_s*>(input);
936
937     try {
938         if (handle == NULL || callback == NULL) {
939             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, callback:%p", input, callback);
940         }
941
942         assert(handle->audioIoHandle);
943
944         handle->state_changed_callback.onStateChanged = callback;
945         handle->state_changed_callback.user_data = user_data;
946
947         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
948         cb.mUserData = static_cast<void*>(handle);
949         cb.onStateChanged = __state_changed_cb_internal;
950
951         handle->audioIoHandle->setStateChangedCallback(cb);
952     } catch (CAudioError e) {
953         AUDIO_IO_LOGE("%s", e.getErrorMsg());
954         return __convert_CAudioError(e);
955     }
956
957     return AUDIO_IO_ERROR_NONE;
958 }
959
960 int cpp_audio_in_unset_state_changed_cb(audio_in_h input) {
961     audio_io_s* handle = static_cast<audio_io_s*>(input);
962
963     try {
964         if (handle == NULL) {
965             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", input);
966         }
967
968         assert(handle->audioIoHandle);
969
970         handle->state_changed_callback.onStateChanged = NULL;
971         handle->state_changed_callback.user_data = NULL;
972
973         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
974         cb.mUserData = NULL;
975         cb.onStateChanged  = NULL;
976
977         handle->audioIoHandle->setStateChangedCallback(cb);
978     } catch (CAudioError e) {
979         AUDIO_IO_LOGE("%s", e.getErrorMsg());
980         return __convert_CAudioError(e);
981     }
982
983     return AUDIO_IO_ERROR_NONE;
984 }
985
986
987 /**
988  * Audio Out
989  */
990 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) {
991     audio_io_s* handle = NULL;
992     try {
993         if (output == NULL) {
994             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
995         }
996
997         __check_audio_param(sample_rate, channel, type, sound_type);
998
999         handle = new audio_io_s;
1000         if (handle == NULL) {
1001             THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation handle");
1002         }
1003
1004         CAudioInfo audioInfo = __generate_audio_output_info(sample_rate, channel, type, sound_type);
1005
1006         handle->audioIoHandle = new CAudioOutput(audioInfo);
1007         if (handle == NULL) {
1008             THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation internal handle");
1009         }
1010
1011         handle->audioIoHandle->initialize();
1012
1013         *output = handle;
1014     } catch (CAudioError e) {
1015         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1016
1017         VALID_POINTER_START(handle)
1018             SAFE_FINALIZE(handle->audioIoHandle);
1019             SAFE_DELETE(handle->audioIoHandle);
1020             SAFE_DELETE(handle);
1021         VALID_POINTER_END
1022
1023         VALID_POINTER_START(output)
1024             *output = NULL;
1025         VALID_POINTER_END
1026
1027         return __convert_CAudioError(e);
1028     }
1029
1030     return AUDIO_IO_ERROR_NONE;
1031 }
1032
1033 int cpp_audio_out_create_new(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_out_h *output) {
1034     audio_io_s* handle = NULL;
1035     try {
1036         if (output == NULL) {
1037             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
1038         }
1039
1040         __check_audio_param(sample_rate, channel, type, SOUND_TYPE_SYSTEM /*default check */);
1041
1042         handle = new audio_io_s;
1043         if (handle == NULL) {
1044             THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation handle");
1045         }
1046
1047         CAudioInfo audioInfo = __generate_audio_output_info(sample_rate, channel, type, SOUND_TYPE_MEDIA /* default sound_type */);
1048
1049         handle->audioIoHandle = new CAudioOutput(audioInfo);
1050         if (handle == NULL) {
1051             THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation internal handle");
1052         }
1053
1054         handle->audioIoHandle->initialize();
1055
1056         *output = handle;
1057     } catch (CAudioError e) {
1058         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1059
1060         VALID_POINTER_START(handle)
1061             SAFE_FINALIZE(handle->audioIoHandle);
1062             SAFE_DELETE(handle->audioIoHandle);
1063             SAFE_DELETE(handle);
1064         VALID_POINTER_END
1065
1066         VALID_POINTER_START(output)
1067             *output = NULL;
1068         VALID_POINTER_END
1069
1070         return __convert_CAudioError(e);
1071     }
1072
1073     return AUDIO_IO_ERROR_NONE;
1074 }
1075
1076 int cpp_audio_out_destroy(audio_out_h output) {
1077     audio_io_s* handle = static_cast<audio_io_s*>(output);
1078
1079     try {
1080         if (handle == NULL) {
1081             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
1082         }
1083
1084         assert(handle->audioIoHandle);
1085
1086         SAFE_FINALIZE(handle->audioIoHandle);
1087         SAFE_DELETE(handle->audioIoHandle);
1088         SAFE_DELETE(handle);
1089     } catch (CAudioError e) {
1090         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1091         return __convert_CAudioError(e);
1092     }
1093
1094     return AUDIO_IO_ERROR_NONE;
1095 }
1096
1097 int cpp_audio_out_set_stream_info(audio_out_h output, sound_stream_info_h stream_info) {
1098     audio_io_s* handle = static_cast<audio_io_s*>(output);
1099
1100     try {
1101         if (handle == NULL || stream_info == NULL) {
1102             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, stream_info:%p", output, stream_info);
1103         }
1104
1105         assert(handle->audioIoHandle);
1106
1107         int errorCode = SOUND_MANAGER_ERROR_NONE;
1108         CAudioInfo::EAudioType audioType = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA;
1109         char *type = NULL;
1110         int index = -1;
1111         bool avail = false;
1112
1113         if ((errorCode = sound_manager_is_available_stream_information(stream_info, NATIVE_API_AUDIO_IO, &avail)) != SOUND_MANAGER_ERROR_NONE) {
1114             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info is invalid [ret:%d]", errorCode);
1115         }
1116
1117         if (avail) {
1118             if ((errorCode = sound_manager_get_type_from_stream_information (stream_info, &type)) != SOUND_MANAGER_ERROR_NONE) {
1119                 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->stream_type is invalid [ret:%d]", errorCode);
1120             }
1121             handle->audioIoHandle->getAudioInfo().convertOutputStreamType2AudioType(type, &audioType);
1122             handle->audioIoHandle->getAudioInfo().setAudioType(audioType);
1123
1124             if ((errorCode = sound_manager_get_index_from_stream_information (stream_info, &index)) != SOUND_MANAGER_ERROR_NONE) {
1125                 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->index is invalid [ret:%d]", errorCode);
1126             }
1127             handle->audioIoHandle->getAudioInfo().setAudioIndex(index);
1128         } else {
1129             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_NOT_SUPPORTED_TYPE, "Output stream is not supported");
1130         }
1131     } catch (CAudioError e) {
1132         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1133         return __convert_CAudioError(e);
1134     }
1135
1136     return AUDIO_IO_ERROR_NONE;
1137 }
1138
1139 int cpp_audio_out_prepare(audio_out_h output) {
1140     audio_io_s* handle = static_cast<audio_io_s*>(output);
1141
1142     try {
1143         if (handle == NULL) {
1144             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
1145         }
1146
1147         assert(handle->audioIoHandle);
1148
1149         handle->audioIoHandle->prepare();
1150     } catch (CAudioError e) {
1151         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1152         return __convert_CAudioError(e);
1153     }
1154
1155     return AUDIO_IO_ERROR_NONE;
1156 }
1157
1158 int cpp_audio_out_unprepare(audio_out_h output) {
1159     audio_io_s* handle = static_cast<audio_io_s*>(output);
1160
1161     try {
1162         if (handle == NULL) {
1163             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
1164         }
1165
1166         assert(handle->audioIoHandle);
1167
1168         handle->audioIoHandle->unprepare();
1169     } catch (CAudioError e) {
1170         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1171         return __convert_CAudioError(e);
1172     }
1173
1174     return AUDIO_IO_ERROR_NONE;
1175 }
1176
1177 int cpp_audio_out_pause(audio_out_h output) {
1178     audio_io_s* handle = static_cast<audio_io_s*>(output);
1179
1180     try {
1181         if (handle == NULL) {
1182             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
1183         }
1184
1185         assert(handle->audioIoHandle);
1186
1187         handle->audioIoHandle->pause();
1188     } catch (CAudioError e) {
1189         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1190         return __convert_CAudioError(e);
1191     }
1192
1193     return AUDIO_IO_ERROR_NONE;
1194 }
1195
1196 int cpp_audio_out_resume(audio_out_h output) {
1197     audio_io_s* handle = static_cast<audio_io_s*>(output);
1198
1199     try {
1200         if (handle == NULL) {
1201             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
1202         }
1203
1204         assert(handle->audioIoHandle);
1205
1206         handle->audioIoHandle->resume();
1207     } catch (CAudioError e) {
1208         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1209         return __convert_CAudioError(e);
1210     }
1211
1212     return AUDIO_IO_ERROR_NONE;
1213 }
1214
1215 int cpp_audio_out_drain(audio_out_h output) {
1216     audio_io_s* handle = static_cast<audio_io_s*>(output);
1217
1218     try {
1219         if (handle == NULL) {
1220             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
1221         }
1222
1223         assert(handle->audioIoHandle);
1224
1225         handle->audioIoHandle->drain();
1226     } catch (CAudioError e) {
1227         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1228         return __convert_CAudioError(e);
1229     }
1230
1231     return AUDIO_IO_ERROR_NONE;
1232 }
1233
1234 int cpp_audio_out_flush(audio_out_h output) {
1235     audio_io_s* handle = static_cast<audio_io_s*>(output);
1236
1237     try {
1238         if (handle == NULL) {
1239             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
1240         }
1241
1242         assert(handle->audioIoHandle);
1243
1244         handle->audioIoHandle->flush();
1245     } catch (CAudioError e) {
1246         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1247         return __convert_CAudioError(e);
1248     }
1249
1250     return AUDIO_IO_ERROR_NONE;
1251 }
1252
1253 int cpp_audio_out_write(audio_out_h output, void *buffer, unsigned int length) {
1254     audio_io_s* handle = static_cast<audio_io_s*>(output);
1255     int ret = 0;
1256
1257     try {
1258         if (handle == NULL || buffer == NULL) {
1259             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p, buffer:%p", output, buffer);
1260         }
1261
1262         assert(handle->audioIoHandle);
1263
1264         CAudioOutput* outputHandle = dynamic_cast<CAudioOutput*>(handle->audioIoHandle);
1265         size_t writen = outputHandle->write(buffer, static_cast<size_t>(length));
1266         ret = static_cast<int>(writen);
1267 #ifdef _AUDIO_IO_DEBUG_TIMING_
1268         AUDIO_IO_LOGD("writen:%d", writen);
1269 #endif
1270     } catch (CAudioError e) {
1271         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1272         return __convert_CAudioError(e);
1273     }
1274
1275     return ret;
1276 }
1277
1278 int cpp_audio_out_get_buffer_size(audio_out_h output, int *size) {
1279     audio_io_s* handle = static_cast<audio_io_s*>(output);
1280
1281     try {
1282         if (handle == NULL || size == NULL) {
1283             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, size:%p", output, size);
1284         }
1285
1286         assert(handle->audioIoHandle);
1287
1288         CAudioOutput* outputHandle = dynamic_cast<CAudioOutput*>(handle->audioIoHandle);
1289         *size = outputHandle->getBufferSize();
1290     } catch (CAudioError e) {
1291         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1292         return __convert_CAudioError(e);
1293     }
1294
1295     return AUDIO_IO_ERROR_NONE;
1296 }
1297
1298 int cpp_audio_out_get_sample_rate(audio_out_h output, int *sample_rate) {
1299     audio_io_s* handle = static_cast<audio_io_s*>(output);
1300
1301     try {
1302         if (handle == NULL || sample_rate == NULL) {
1303             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, sample_rate:%p", output, sample_rate);
1304         }
1305
1306         assert(handle->audioIoHandle);
1307         *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
1308     } catch (CAudioError e) {
1309         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1310         return __convert_CAudioError(e);
1311     }
1312
1313     return AUDIO_IO_ERROR_NONE;
1314 }
1315
1316 int cpp_audio_out_get_channel(audio_out_h output, audio_channel_e *channel) {
1317     audio_io_s* handle = static_cast<audio_io_s*>(output);
1318
1319     try {
1320         if (handle == NULL || channel == NULL) {
1321             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, channel:%p", output, channel);
1322         }
1323
1324         assert(handle->audioIoHandle);
1325
1326         const CAudioInfo::EChannel srcChannel = handle->audioIoHandle->getAudioInfo().getChannel();
1327         audio_channel_e dstChannel = AUDIO_CHANNEL_MONO;
1328         __convert_audio_info_channel_2_channel(srcChannel, dstChannel);
1329
1330         *channel = dstChannel;
1331     } catch (CAudioError e) {
1332         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1333         return __convert_CAudioError(e);
1334     }
1335
1336     return AUDIO_IO_ERROR_NONE;
1337 }
1338
1339 int cpp_audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type) {
1340     audio_io_s* handle = static_cast<audio_io_s*>(output);
1341
1342     try {
1343         if (handle == NULL || type == NULL) {
1344             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, type:%p", output, type);
1345         }
1346
1347         assert(handle->audioIoHandle);
1348
1349         const CAudioInfo::ESampleType srcSampleType = handle->audioIoHandle->getAudioInfo().getSampleType();
1350         audio_sample_type_e     dstSampleType = AUDIO_SAMPLE_TYPE_U8;
1351         __convert_audio_info_sample_type_2_sample_type(srcSampleType, dstSampleType);
1352
1353         *type = dstSampleType;
1354     } catch (CAudioError e) {
1355         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1356         return __convert_CAudioError(e);
1357     }
1358
1359     return AUDIO_IO_ERROR_NONE;
1360 }
1361
1362 int cpp_audio_out_get_sound_type(audio_out_h output, sound_type_e *type) {
1363     audio_io_s* handle = static_cast<audio_io_s*>(output);
1364
1365     try {
1366         if (handle == NULL || type == NULL) {
1367             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, type:%p", output, type);
1368         }
1369
1370         assert(handle->audioIoHandle);
1371
1372         const CAudioInfo::EAudioType srcAudioType = handle->audioIoHandle->getAudioInfo().getAudioType();
1373         sound_type_e                 dstSoundType = SOUND_TYPE_MEDIA;
1374         __convert_audio_info_audio_type_2_sound_type(srcAudioType, dstSoundType);
1375
1376         *type = dstSoundType;
1377     } catch (CAudioError e) {
1378         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1379         return __convert_CAudioError(e);
1380     }
1381
1382     return AUDIO_IO_ERROR_NONE;
1383 }
1384
1385 int cpp_audio_out_set_interrupted_cb(audio_out_h output, audio_io_interrupted_cb callback, void *user_data) {
1386     audio_io_s* handle = static_cast<audio_io_s*>(output);
1387
1388     try {
1389         if (handle == NULL || callback == NULL) {
1390             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, callback:%p", output, callback);
1391         }
1392
1393         assert(handle->audioIoHandle);
1394
1395         handle->interrupt_callback.onInterrupt = callback;
1396         handle->interrupt_callback.user_data    = user_data;
1397
1398         CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
1399         cb.mUserData   = static_cast<void*>(handle);
1400         cb.onInterrupt = __interrupt_cb_internal;
1401
1402         handle->audioIoHandle->setInterruptCallback(cb);
1403     } catch (CAudioError e) {
1404         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1405         return __convert_CAudioError(e);
1406     }
1407
1408     return AUDIO_IO_ERROR_NONE;
1409 }
1410
1411 int cpp_audio_out_unset_interrupted_cb(audio_out_h output) {
1412     audio_io_s* handle = static_cast<audio_io_s*>(output);
1413
1414     try {
1415         if (handle == NULL) {
1416             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
1417         }
1418
1419         assert(handle->audioIoHandle);
1420
1421         handle->interrupt_callback.onInterrupt = NULL;
1422         handle->interrupt_callback.user_data    = NULL;
1423
1424         CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
1425         cb.mUserData   = NULL;
1426         cb.onInterrupt = NULL;
1427
1428         handle->audioIoHandle->setInterruptCallback(cb);
1429     } catch (CAudioError e) {
1430         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1431         return __convert_CAudioError(e);
1432     }
1433
1434     return AUDIO_IO_ERROR_NONE;
1435 }
1436
1437 int cpp_audio_out_ignore_session(audio_out_h output) {
1438     audio_io_s* handle = static_cast<audio_io_s*>(output);
1439
1440     try {
1441         if (handle == NULL) {
1442             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
1443         }
1444
1445         if (handle->stream_callback.onStream) {
1446             THROW_ERROR_MSG(CAudioError::EError::ERROR_INVALID_OPERATION, "Not support ignore session in async mode");
1447         }
1448
1449         assert(handle->audioIoHandle);
1450
1451         handle->audioIoHandle->ignoreSession();
1452     } catch (CAudioError e) {
1453         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1454         return __convert_CAudioError(e);
1455     }
1456
1457     return AUDIO_IO_ERROR_NONE;
1458 }
1459
1460 int cpp_audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* user_data) {
1461     audio_io_s* handle = static_cast<audio_io_s*>(output);
1462
1463     try {
1464         if (handle == NULL || callback == NULL) {
1465             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, callback:%p", output, callback);
1466         }
1467
1468         assert(handle->audioIoHandle);
1469
1470         handle->stream_callback.onStream = callback;
1471         handle->stream_callback.user_data = user_data;
1472
1473         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
1474         cb.mUserData = static_cast<void*>(handle);
1475         cb.onStream  = __stream_cb_internal;
1476
1477         handle->audioIoHandle->setStreamCallback(cb);
1478     } catch (CAudioError e) {
1479         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1480         return __convert_CAudioError(e);
1481     }
1482
1483     return AUDIO_IO_ERROR_NONE;
1484 }
1485
1486 int cpp_audio_out_unset_stream_cb(audio_out_h output) {
1487     audio_io_s* handle = static_cast<audio_io_s*>(output);
1488
1489     try {
1490         if (handle == NULL) {
1491             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
1492         }
1493
1494         assert(handle->audioIoHandle);
1495
1496         handle->stream_callback.onStream = NULL;
1497         handle->stream_callback.user_data = NULL;
1498
1499         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
1500         cb.mUserData = NULL;
1501         cb.onStream  = NULL;
1502
1503         handle->audioIoHandle->setStreamCallback(cb);
1504     } catch (CAudioError e) {
1505         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1506         return __convert_CAudioError(e);
1507     }
1508
1509     return AUDIO_IO_ERROR_NONE;
1510 }
1511
1512 int cpp_audio_out_set_state_changed_cb(audio_out_h output, audio_in_state_changed_cb callback, void* user_data) {
1513     audio_io_s* handle = static_cast<audio_io_s*>(output);
1514
1515     try {
1516         if (handle == NULL || callback == NULL) {
1517             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, callback:%p", output, callback);
1518         }
1519
1520         assert(handle->audioIoHandle);
1521
1522         handle->state_changed_callback.onStateChanged = callback;
1523         handle->state_changed_callback.user_data = user_data;
1524
1525         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
1526         cb.mUserData = static_cast<void*>(handle);
1527         cb.onStateChanged = __state_changed_cb_internal;
1528
1529         handle->audioIoHandle->setStateChangedCallback(cb);
1530     } catch (CAudioError e) {
1531         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1532         return __convert_CAudioError(e);
1533     }
1534
1535     return AUDIO_IO_ERROR_NONE;
1536 }
1537
1538 int cpp_audio_out_unset_state_changed_cb(audio_out_h output) {
1539     audio_io_s* handle = static_cast<audio_io_s*>(output);
1540
1541     try {
1542         if (handle == NULL) {
1543             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
1544         }
1545
1546         assert(handle->audioIoHandle);
1547
1548         handle->state_changed_callback.onStateChanged = NULL;
1549         handle->state_changed_callback.user_data = NULL;
1550
1551         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
1552         cb.mUserData = NULL;
1553         cb.onStateChanged  = NULL;
1554
1555         handle->audioIoHandle->setStateChangedCallback(cb);
1556     } catch (CAudioError e) {
1557         AUDIO_IO_LOGE("%s", e.getErrorMsg());
1558         return __convert_CAudioError(e);
1559     }
1560
1561     return AUDIO_IO_ERROR_NONE;
1562 }