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