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