Support 24bit sample format and up-to 192kHz sample rate
[platform/core/api/audio-io.git] / src / cpp / cpp_audio_io.cpp
index 936873f..8df8dde 100644 (file)
  */
 
 
+#include <new>
+
 #include "cpp_audio_io.h"
-#include <sound_manager_internal.h>
 #include "audio_io.h"
 #include "CAudioIODef.h"
 
+#include <system_info.h>
+
+#define FEATURE_MICROPHONE          "http://tizen.org/feature/microphone"
 
 using namespace std;
 using namespace tizen_media_audio;
 
-
-/**
- * Defines Structures
- * type : struct
- * Name : audio_io_interrupted_cb_s
- * Declaration : Keeps user callback pointer and user data for delivering an interrupt event
- */
-typedef struct audio_io_interrupted_cb_s {
-    void* user_data;
-    audio_io_interrupted_cb onInterrupt;
-
-    audio_io_interrupted_cb_s() : user_data(NULL), onInterrupt(NULL)
-    {/* Empty Body */}
-}   audio_io_interrupted_cb_s;
-
 /**
  * Defines Structures
  * type : struct
@@ -77,10 +66,9 @@ typedef struct audio_io_state_changed_cb_s {
  * The CAudioIO is a abstract class object about Input and Output
  */
 typedef struct audio_io_s {
-    CAudioIO*                    audioIoHandle;
-    audio_io_interrupted_cb_s    interrupt_callback;
-    audio_io_stream_cb_s         stream_callback;
-    audio_io_state_changed_cb_s  state_changed_callback;
+    CAudioIO* audioIoHandle;
+    audio_io_stream_cb_s stream_callback;
+    audio_io_state_changed_cb_s state_changed_callback;
 
     audio_io_s() : audioIoHandle(NULL)
     {/* Empty Body */}
@@ -91,7 +79,7 @@ typedef struct audio_io_s {
  * Internal functions
  */
 static audio_io_error_e __convert_CAudioError(CAudioError& error) {
-    audio_io_error_e    ret = AUDIO_IO_ERROR_NONE;
+    audio_io_error_e ret = AUDIO_IO_ERROR_NONE;
     CAudioError::EError err = error.getError();
 
     switch (err) {
@@ -130,6 +118,9 @@ static audio_io_error_e __convert_CAudioError(CAudioError& error) {
     case CAudioError::EError::ERROR_INVALID_OPERATION:
         ret = AUDIO_IO_ERROR_INVALID_OPERATION;
         break;
+    case CAudioError::EError::ERROR_INVALID_STATE:
+        ret = AUDIO_IO_ERROR_INVALID_STATE;
+        break;
     case CAudioError::EError::ERROR_OUT_OF_MEMORY:
     case CAudioError::EError::ERROR_INVALID_POINTER:
         ret = AUDIO_IO_ERROR_INVALID_BUFFER;
@@ -144,7 +135,8 @@ static audio_io_error_e __convert_CAudioError(CAudioError& error) {
     return ret;
 }
 
-static void __convert_channel_2_audio_info_channel(const audio_channel_e& src_channel, CAudioInfo::EChannel& dst_channel) {
+static void __convert_channel_2_audio_info_channel(const audio_channel_e& src_channel,
+                                                   CAudioInfo::EChannel& dst_channel) {
     switch (src_channel) {
     case AUDIO_CHANNEL_MONO:
         dst_channel = CAudioInfo::EChannel::CHANNEL_MONO;
@@ -154,10 +146,12 @@ static void __convert_channel_2_audio_info_channel(const audio_channel_e& src_ch
         break;
     default:
         dst_channel = CAudioInfo::EChannel::CHANNEL_MONO;
+        break;
     }
 }
 
-static void __convert_audio_info_channel_2_channel(const CAudioInfo::EChannel& src_channel, audio_channel_e& dst_channel) {
+static void __convert_audio_info_channel_2_channel(const CAudioInfo::EChannel& src_channel,
+                                                   audio_channel_e& dst_channel) {
     switch (src_channel) {
     case CAudioInfo::EChannel::CHANNEL_MONO:
         dst_channel = AUDIO_CHANNEL_MONO;
@@ -167,10 +161,12 @@ static void __convert_audio_info_channel_2_channel(const CAudioInfo::EChannel& s
         break;
     default:
         dst_channel = AUDIO_CHANNEL_MONO;
+        break;
     }
 }
 
-static void __convert_sample_type_2_audio_info_sample_type(const audio_sample_type_e& src_type, CAudioInfo::ESampleType& dst_type) {
+static void __convert_sample_type_2_audio_info_sample_type(const audio_sample_type_e& src_type,
+                                                           CAudioInfo::ESampleType& dst_type) {
     switch (src_type) {
     case AUDIO_SAMPLE_TYPE_U8:
         dst_type = CAudioInfo::ESampleType::SAMPLE_TYPE_U8;
@@ -178,12 +174,20 @@ static void __convert_sample_type_2_audio_info_sample_type(const audio_sample_ty
     case AUDIO_SAMPLE_TYPE_S16_LE:
         dst_type = CAudioInfo::ESampleType::SAMPLE_TYPE_S16_LE;
         break;
+    case AUDIO_SAMPLE_TYPE_S24_LE:
+        dst_type = CAudioInfo::ESampleType::SAMPLE_TYPE_S24_LE;
+        break;
+    case AUDIO_SAMPLE_TYPE_S24_32_LE:
+        dst_type = CAudioInfo::ESampleType::SAMPLE_TYPE_S24_32_LE;
+        break;
     default:
         dst_type = CAudioInfo::ESampleType::SAMPLE_TYPE_U8;
+        break;
     }
 }
 
-static void __convert_audio_info_sample_type_2_sample_type(const CAudioInfo::ESampleType& src_type, audio_sample_type_e& dst_type) {
+static void __convert_audio_info_sample_type_2_sample_type(const CAudioInfo::ESampleType& src_type,
+                                                           audio_sample_type_e& dst_type) {
     switch (src_type) {
     case CAudioInfo::ESampleType::SAMPLE_TYPE_U8:
         dst_type = AUDIO_SAMPLE_TYPE_U8;
@@ -191,12 +195,20 @@ static void __convert_audio_info_sample_type_2_sample_type(const CAudioInfo::ESa
     case CAudioInfo::ESampleType::SAMPLE_TYPE_S16_LE:
         dst_type = AUDIO_SAMPLE_TYPE_S16_LE;
         break;
+    case CAudioInfo::ESampleType::SAMPLE_TYPE_S24_LE:
+        dst_type = AUDIO_SAMPLE_TYPE_S24_LE;
+        break;
+    case CAudioInfo::ESampleType::SAMPLE_TYPE_S24_32_LE:
+        dst_type = AUDIO_SAMPLE_TYPE_S24_32_LE;
+        break;
     default:
         dst_type = AUDIO_SAMPLE_TYPE_U8;
+        break;
     }
 }
 
-static void __convert_sound_type_2_audio_info_audio_type(const sound_type_e& src_type, CAudioInfo::EAudioType& dst_type) {
+static void __convert_sound_type_2_audio_info_audio_type(const sound_type_e& src_type,
+                                                         CAudioInfo::EAudioType& dst_type) {
     switch (src_type) {
     case SOUND_TYPE_SYSTEM:
         dst_type = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_SYSTEM;
@@ -228,7 +240,8 @@ static void __convert_sound_type_2_audio_info_audio_type(const sound_type_e& src
     }
 }
 
-static void __convert_audio_info_audio_type_2_sound_type(const CAudioInfo::EAudioType& src_type, sound_type_e& dst_type) {
+static void __convert_audio_info_audio_type_2_sound_type(const CAudioInfo::EAudioType& src_type,
+                                                         sound_type_e& dst_type) {
     switch (src_type) {
     case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA:
         dst_type = SOUND_TYPE_MEDIA;
@@ -260,6 +273,7 @@ static void __convert_audio_info_audio_type_2_sound_type(const CAudioInfo::EAudi
 
 static audio_io_state_e __convert_state_type(const CAudioInfo::EAudioIOState src_state) {
     audio_io_state_e dst_state;
+
     switch (src_state) {
     case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE:
         dst_state = AUDIO_IO_STATE_IDLE;
@@ -275,36 +289,36 @@ static audio_io_state_e __convert_state_type(const CAudioInfo::EAudioIOState src
         break;
     default:
         dst_state = AUDIO_IO_STATE_IDLE;
+        break;
     }
     return dst_state;
 }
 
-static void __check_audio_param(int sample_rate, audio_channel_e channel, audio_sample_type_e type) throw(CAudioError) {
-    if (sample_rate < 0) {
+static void __check_audio_param(int sample_rate, audio_channel_e channel, audio_sample_type_e type) {
+    if (sample_rate < 0)
         THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid sample rate :%d", sample_rate);
-    }
 
-    if (channel != AUDIO_CHANNEL_MONO && channel != AUDIO_CHANNEL_STEREO) {
+    if (channel != AUDIO_CHANNEL_MONO && channel != AUDIO_CHANNEL_STEREO)
         THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid channel :%d", channel);
-    }
 
-    if (type != AUDIO_SAMPLE_TYPE_U8 && type != AUDIO_SAMPLE_TYPE_S16_LE) {
+    if (type != AUDIO_SAMPLE_TYPE_U8 &&
+        type != AUDIO_SAMPLE_TYPE_S16_LE &&
+        type != AUDIO_SAMPLE_TYPE_S24_LE &&
+        type != AUDIO_SAMPLE_TYPE_S24_32_LE)
         THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid sample type :%d", type);
-    }
 }
 
-static void __check_audio_param(int sample_rate, audio_channel_e channel, audio_sample_type_e type, sound_type_e sound_type) throw(CAudioError) {
+static void __check_audio_param(int sample_rate, audio_channel_e channel, audio_sample_type_e type, sound_type_e sound_type) {
     __check_audio_param(sample_rate, channel, type);
 
-    if (sound_type < SOUND_TYPE_SYSTEM || sound_type > SOUND_TYPE_VOICE) {
+    if (sound_type < SOUND_TYPE_SYSTEM || sound_type > SOUND_TYPE_VOICE)
         THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid sound type : %d", sound_type);
-    }
 }
 
-static CAudioInfo __generate_audio_input_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type) throw(CAudioError) {
-    CAudioInfo::EChannel     dstChannel;
+static CAudioInfo __generate_audio_input_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type) {
+    CAudioInfo::EChannel dstChannel;
     CAudioInfo::ESampleType dstSampleType;
-    CAudioInfo::EAudioType  dstAudioType = CAudioInfo::EAudioType::AUDIO_IN_TYPE_MEDIA;
+    CAudioInfo::EAudioType dstAudioType = CAudioInfo::EAudioType::AUDIO_IN_TYPE_MEDIA;
 
     __convert_channel_2_audio_info_channel(channel, dstChannel);
     __convert_sample_type_2_audio_info_sample_type(sample_type, dstSampleType);
@@ -312,21 +326,10 @@ static CAudioInfo __generate_audio_input_info(int sampleRate, audio_channel_e ch
     return CAudioInfo(sampleRate, dstChannel, dstSampleType, dstAudioType, -1);
 }
 
-static CAudioInfo __generate_audio_input_loopback_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type) throw(CAudioError) {
-    CAudioInfo::EChannel     dstChannel;
+static CAudioInfo __generate_audio_output_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type, sound_type_e sound_type) {
+    CAudioInfo::EChannel dstChannel;
     CAudioInfo::ESampleType dstSampleType;
-    CAudioInfo::EAudioType  dstAudioType = CAudioInfo::EAudioType::AUDIO_IN_TYPE_LOOPBACK;
-
-    __convert_channel_2_audio_info_channel(channel, dstChannel);
-    __convert_sample_type_2_audio_info_sample_type(sample_type, dstSampleType);
-
-    return CAudioInfo(sampleRate, dstChannel, dstSampleType, dstAudioType, -1);
-}
-
-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) {
-    CAudioInfo::EChannel     dstChannel;
-    CAudioInfo::ESampleType dstSampleType;
-    CAudioInfo::EAudioType  dstAudioType;
+    CAudioInfo::EAudioType dstAudioType;
 
     __convert_channel_2_audio_info_channel(channel, dstChannel);
     __convert_sample_type_2_audio_info_sample_type(sample_type, dstSampleType);
@@ -335,27 +338,19 @@ static CAudioInfo __generate_audio_output_info(int sampleRate, audio_channel_e c
     return CAudioInfo(sampleRate, dstChannel, dstSampleType, dstAudioType, -1);
 }
 
-static audio_io_interrupted_code_e __convert_interrupted_code(IAudioSessionEventListener::EInterruptCode code) {
-    switch (code) {
-    case IAudioSessionEventListener::EInterruptCode::INTERRUPT_COMPLETED:
-        return AUDIO_IO_INTERRUPTED_COMPLETED;
-    case IAudioSessionEventListener::EInterruptCode::INTERRUPT_BY_CALL:
-        return AUDIO_IO_INTERRUPTED_BY_CALL;
-    case IAudioSessionEventListener::EInterruptCode::INTERRUPT_BY_EARJACK_UNPLUG:
-        return AUDIO_IO_INTERRUPTED_BY_EARJACK_UNPLUG;
-    case IAudioSessionEventListener::EInterruptCode::INTERRUPT_BY_RESOURCE_CONFLICT:
-        return AUDIO_IO_INTERRUPTED_BY_RESOURCE_CONFLICT;
-    case IAudioSessionEventListener::EInterruptCode::INTERRUPT_BY_ALARM:
-        return AUDIO_IO_INTERRUPTED_BY_ALARM;
-    case IAudioSessionEventListener::EInterruptCode::INTERRUPT_BY_EMERGENCY:
-        return AUDIO_IO_INTERRUPTED_BY_EMERGENCY;
-    case IAudioSessionEventListener::EInterruptCode::INTERRUPT_BY_NOTIFICATION:
-        return AUDIO_IO_INTERRUPTED_BY_NOTIFICATION;
-    case IAudioSessionEventListener::EInterruptCode::INTERRUPT_BY_MEDIA:
-    case IAudioSessionEventListener::EInterruptCode::INTERRUPT_MAX:
-    default:
-        return AUDIO_IO_INTERRUPTED_BY_MEDIA;
-    }
+static void __handle_safe_free(audio_io_s* handle, void *obj, bool is_output) {
+    VALID_POINTER_START(handle)
+        SAFE_FINALIZE(handle->audioIoHandle);
+        SAFE_DELETE(handle->audioIoHandle);
+        SAFE_DELETE(handle);
+    VALID_POINTER_END
+
+    VALID_POINTER_START(obj)
+        if (is_output)
+            *(audio_out_h *)obj = NULL;
+        else
+            *(audio_in_h *)obj = NULL;
+    VALID_POINTER_END
 }
 
 /**
@@ -363,84 +358,41 @@ static audio_io_interrupted_code_e __convert_interrupted_code(IAudioSessionEvent
  */
 int cpp_audio_in_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_in_h *input) {
     audio_io_s* handle = NULL;
+    bool mic_enable = false;
+    int ret = 0;
     try {
         if (input == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                  "Parameters are NULL input:%p", input);
         }
 
         __check_audio_param(sample_rate, channel, type);
 
-        handle = new audio_io_s;
-        if (handle == NULL) {
-            THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation handle");
-        }
-
-        CAudioInfo audioInfo = __generate_audio_input_info(sample_rate, channel, type);
-
-        handle->audioIoHandle = new CAudioInput(audioInfo);
-        if (handle == NULL) {
-            THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation internal handle");
-        }
-
-        handle->audioIoHandle->initialize();
-
-        *input = handle;
-    } catch (CAudioError e) {
-        AUDIO_IO_LOGE("%s", e.getErrorMsg());
+        AUDIO_IO_LOGD("samplerate:[%d] channel:[0x%x] sample_type:[0x%x]", sample_rate, channel, type);
 
-        VALID_POINTER_START(handle)
-            SAFE_FINALIZE(handle->audioIoHandle);
-            SAFE_DELETE(handle->audioIoHandle);
-            SAFE_DELETE(handle);
-        VALID_POINTER_END
-
-        VALID_POINTER_START(input)
-            *input = NULL;
-        VALID_POINTER_END
-
-        return __convert_CAudioError(e);
-    }
-
-    return AUDIO_IO_ERROR_NONE;
-}
-
-int cpp_audio_in_create_loopback(int sample_rate, audio_channel_e channel, audio_sample_type_e type , audio_in_h* input) {
-    audio_io_s* handle = NULL;
-    try {
-        if (input == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
+        /* If MIC is not supported, return NOT_SUPPORTED error */
+        ret = system_info_get_platform_bool(FEATURE_MICROPHONE, &mic_enable);
+        AUDIO_IO_LOGD("system_info_platform [%s]=[%d], ret[%d]", FEATURE_MICROPHONE, mic_enable, ret);
+        if (ret != SYSTEM_INFO_ERROR_NONE || !mic_enable) {
+            THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "System doesn't support microphone!");
         }
 
-        __check_audio_param(sample_rate, channel, type);
+        CAudioInfo audioInfo = __generate_audio_input_info(sample_rate, channel, type);
 
         handle = new audio_io_s;
-        if (handle == NULL) {
-            THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation handle");
-        }
-
-        CAudioInfo audioInfo = __generate_audio_input_loopback_info(sample_rate, channel, type);
-
         handle->audioIoHandle = new CAudioInput(audioInfo);
-        if (handle == NULL) {
-            THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation internal handle");
-        }
-
         handle->audioIoHandle->initialize();
 
+        AUDIO_IO_LOGD("[%p] created", handle);
         *input = handle;
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
-
-        VALID_POINTER_START(handle)
-            SAFE_FINALIZE(handle->audioIoHandle);
-            SAFE_DELETE(handle->audioIoHandle);
-            SAFE_DELETE(handle);
-        VALID_POINTER_END
-
-        VALID_POINTER_START(input)
-            *input = NULL;
-        VALID_POINTER_END
-
+        __handle_safe_free(handle, (void *)input, false);
+        return __convert_CAudioError(e);
+    } catch (const std::bad_alloc&) {
+        CAudioError e = CAudioError::EError::ERROR_OUT_OF_MEMORY;
+        AUDIO_IO_LOGE("Failed to allocate handle");
+        __handle_safe_free(handle, (void *)input, false);
         return __convert_CAudioError(e);
     }
 
@@ -451,62 +403,46 @@ int cpp_audio_in_destroy(audio_in_h input) {
     audio_io_s* handle = static_cast<audio_io_s*>(input);
 
     try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
-        }
-
+        if (handle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                  "Parameters are NULL input:%p", input);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p]", handle);
+
+        /* Internal unprepare for backward compatibility */
+        handle->audioIoHandle->unprepare();
 
         SAFE_FINALIZE(handle->audioIoHandle);
         SAFE_DELETE(handle->audioIoHandle);
         SAFE_DELETE(handle);
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("destroyed");
+
     return AUDIO_IO_ERROR_NONE;
 }
 
-int cpp_audio_in_set_stream_info(audio_in_h input, sound_stream_info_h stream_info) {
+int cpp_audio_in_set_sound_stream_info(audio_in_h input, sound_stream_info_h stream_info) {
     audio_io_s* handle = static_cast<audio_io_s*>(input);
 
     try {
-        if (handle == NULL || stream_info == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, stream_info:%p", input, stream_info);
-        }
-
+        if (handle == NULL || stream_info == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL input:%p, stream_info:%p", input, stream_info);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p], stream_info:[%p]", handle, stream_info);
 
-        int errorCode = SOUND_MANAGER_ERROR_NONE;
-        CAudioInfo::EAudioType audioType = CAudioInfo::EAudioType::AUDIO_IN_TYPE_MEDIA;
-        char *type = NULL;
-        int index = -1;
-        bool avail = false;
-
-        if ((errorCode = sound_manager_is_available_stream_information(stream_info, NATIVE_API_AUDIO_IO, &avail)) != SOUND_MANAGER_ERROR_NONE) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info is invalid [ret:%d]", errorCode);
-        }
-
-        if (avail) {
-            if ((errorCode = sound_manager_get_type_from_stream_information(stream_info, &type)) != SOUND_MANAGER_ERROR_NONE) {
-                THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->stream_type is invalid [ret:%d]", errorCode);
-            }
-            handle->audioIoHandle->getAudioInfo().convertInputStreamType2AudioType(type, &audioType);
-            handle->audioIoHandle->getAudioInfo().setAudioType(audioType);
-
-            if ((errorCode = sound_manager_get_index_from_stream_information(stream_info, &index)) != SOUND_MANAGER_ERROR_NONE) {
-                THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->index is invalid [ret:%d]", errorCode);
-            }
-            handle->audioIoHandle->getAudioInfo().setAudioIndex(index);
-        } else {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_NOT_SUPPORTED_TYPE, "Input stream is not supported");
-        }
-    } catch (CAudioError e) {
+        handle->audioIoHandle->setStreamInfo(stream_info);
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] done", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -514,18 +450,20 @@ int cpp_audio_in_prepare(audio_in_h input) {
     audio_io_s* handle = static_cast<audio_io_s*>(input);
 
     try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
-        }
-
+        if (handle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL input:%p", input);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p]", handle);
 
         handle->audioIoHandle->prepare();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] prepared", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -533,18 +471,20 @@ int cpp_audio_in_unprepare(audio_in_h input) {
     audio_io_s* handle = static_cast<audio_io_s*>(input);
 
     try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
-        }
-
+        if (handle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL input:%p", input);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p]", handle);
 
         handle->audioIoHandle->unprepare();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] unprepared", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -552,18 +492,20 @@ int cpp_audio_in_pause(audio_in_h input) {
     audio_io_s* handle = static_cast<audio_io_s*>(input);
 
     try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
-        }
-
+        if (handle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL input:%p", input);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p]", handle);
 
         handle->audioIoHandle->pause();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] paused", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -571,18 +513,20 @@ int cpp_audio_in_resume(audio_in_h input) {
     audio_io_s* handle = static_cast<audio_io_s*>(input);
 
     try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
-        }
-
+        if (handle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL input:%p", input);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p]", handle);
 
         handle->audioIoHandle->resume();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] resumed", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -590,18 +534,20 @@ int cpp_audio_in_drain(audio_in_h input) {
     audio_io_s* handle = static_cast<audio_io_s*>(input);
 
     try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
-        }
-
+        if (handle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL input:%p", input);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p]", handle);
 
         handle->audioIoHandle->drain();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] drained", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -609,18 +555,20 @@ int cpp_audio_in_flush(audio_in_h input) {
     audio_io_s* handle = static_cast<audio_io_s*>(input);
 
     try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
-        }
-
+        if (handle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL input:%p", input);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p]", handle);
 
         handle->audioIoHandle->flush();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] flushed", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -629,22 +577,22 @@ int cpp_audio_in_read(audio_in_h input, void *buffer, unsigned int length) {
     int ret = 0;
 
     try {
-        if (handle == NULL || buffer == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, buffer:%p", input, buffer);
-        }
-
+        if (handle == NULL || buffer == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL input:%p, buffer:%p", input, buffer);
         assert(handle->audioIoHandle);
 
-        CAudioInput* inputHandle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
+        CAudioInput* inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
         if (inputHandle == NULL) {
             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
         }
+
         size_t readn = inputHandle->read(buffer, static_cast<size_t>(length));
         ret = static_cast<int>(readn);
 #ifdef _AUDIO_IO_DEBUG_TIMING_
         AUDIO_IO_LOGD("readn:%d", readn);
 #endif
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
@@ -656,18 +604,17 @@ int cpp_audio_in_get_buffer_size(audio_in_h input, int *size) {
     audio_io_s* handle = static_cast<audio_io_s*>(input);
 
     try {
-        if (handle == NULL || size == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, size:%p", input, size);
-        }
-
+        if (handle == NULL || size == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL input:%p, size:%p", input, size);
         assert(handle->audioIoHandle);
 
-        CAudioIO* inputHandle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
+        CAudioIO* inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
         if (inputHandle == NULL) {
             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
         }
         *size = inputHandle->getBufferSize();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
@@ -679,13 +626,13 @@ int cpp_audio_in_get_sample_rate(audio_in_h input, int *sample_rate) {
     audio_io_s* handle = static_cast<audio_io_s*>(input);
 
     try {
-        if (handle == NULL || sample_rate == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, sample_rate:%p", input, sample_rate);
-        }
-
+        if (handle == NULL || sample_rate == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL input:%p, sample_rate:%p", input, sample_rate);
         assert(handle->audioIoHandle);
+
         *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
@@ -697,10 +644,9 @@ int cpp_audio_in_get_channel(audio_in_h input, audio_channel_e *channel) {
     audio_io_s* handle = static_cast<audio_io_s*>(input);
 
     try {
-        if (handle == NULL || channel == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, channel:%p", input, channel);
-        }
-
+        if (handle == NULL || channel == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL input:%p, channel:%p", input, channel);
         assert(handle->audioIoHandle);
 
         const CAudioInfo::EChannel srcChannel = handle->audioIoHandle->getAudioInfo().getChannel();
@@ -708,7 +654,7 @@ int cpp_audio_in_get_channel(audio_in_h input, audio_channel_e *channel) {
         __convert_audio_info_channel_2_channel(srcChannel, dstChannel);
 
         *channel = dstChannel;
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
@@ -720,104 +666,17 @@ int cpp_audio_in_get_sample_type(audio_in_h input, audio_sample_type_e *type) {
     audio_io_s* handle = static_cast<audio_io_s*>(input);
 
     try {
-        if (handle == NULL || type == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, type:%p", input, type);
-        }
-
+        if (handle == NULL || type == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL input:%p, type:%p", input, type);
         assert(handle->audioIoHandle);
 
         const CAudioInfo::ESampleType srcSampleType = handle->audioIoHandle->getAudioInfo().getSampleType();
-        audio_sample_type_e     dstSampleType = AUDIO_SAMPLE_TYPE_U8;
+        audio_sample_type_e dstSampleType = AUDIO_SAMPLE_TYPE_U8;
         __convert_audio_info_sample_type_2_sample_type(srcSampleType, dstSampleType);
 
         *type = dstSampleType;
-    } catch (CAudioError e) {
-        AUDIO_IO_LOGE("%s", e.getErrorMsg());
-        return __convert_CAudioError(e);
-    }
-
-    return AUDIO_IO_ERROR_NONE;
-}
-
-static void __interrupt_cb_internal(IAudioSessionEventListener::EInterruptCode _code, void* user_data) {
-    audio_io_s* handle = static_cast<audio_io_s*>(user_data);
-    audio_io_interrupted_code_e code = __convert_interrupted_code(_code);
-
-    assert(handle);
-
-    if (handle->interrupt_callback.onInterrupt != NULL) {
-        handle->interrupt_callback.onInterrupt(code, handle->interrupt_callback.user_data);
-    }
-}
-
-int cpp_audio_in_set_interrupted_cb(audio_in_h input, audio_io_interrupted_cb callback, void *user_data) {
-    audio_io_s* handle = static_cast<audio_io_s*>(input);
-
-    try {
-        if (handle == NULL || callback == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, callback:%p", input, callback);
-        }
-
-        assert(handle->audioIoHandle);
-
-        handle->interrupt_callback.onInterrupt = callback;
-        handle->interrupt_callback.user_data    = user_data;
-
-        CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
-        cb.mUserData   = static_cast<void*>(handle);
-        cb.onInterrupt = __interrupt_cb_internal;
-
-        handle->audioIoHandle->setInterruptCallback(cb);
-    } catch (CAudioError e) {
-        AUDIO_IO_LOGE("%s", e.getErrorMsg());
-        return __convert_CAudioError(e);
-    }
-
-    return AUDIO_IO_ERROR_NONE;
-}
-
-int cpp_audio_in_unset_interrupted_cb(audio_in_h input) {
-    audio_io_s* handle = static_cast<audio_io_s*>(input);
-
-    try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
-        }
-
-        assert(handle->audioIoHandle);
-
-        handle->interrupt_callback.onInterrupt = NULL;
-        handle->interrupt_callback.user_data    = NULL;
-
-        CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
-        cb.mUserData   = NULL;
-        cb.onInterrupt = NULL;
-
-        handle->audioIoHandle->setInterruptCallback(cb);
-    } catch (CAudioError e) {
-        AUDIO_IO_LOGE("%s", e.getErrorMsg());
-        return __convert_CAudioError(e);
-    }
-
-    return AUDIO_IO_ERROR_NONE;
-}
-
-int cpp_audio_in_ignore_session(audio_in_h input) {
-    audio_io_s* handle = static_cast<audio_io_s*>(input);
-
-    try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
-        }
-
-        if (handle->stream_callback.onStream) {
-            THROW_ERROR_MSG(CAudioError::EError::ERROR_INVALID_OPERATION, "Not support ignore session in async mode");
-        }
-
-        assert(handle->audioIoHandle);
-
-        handle->audioIoHandle->ignoreSession();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
@@ -829,29 +688,32 @@ static void __stream_cb_internal(size_t nbytes, void *user_data) {
     audio_io_s* audioIo = static_cast<audio_io_s*>(user_data);
     assert(audioIo);
 
-    if (audioIo->stream_callback.onStream != NULL) {
+    if (audioIo->stream_callback.onStream)
         audioIo->stream_callback.onStream(audioIo, nbytes, audioIo->stream_callback.user_data);
-    }
 }
 
-static void __state_changed_cb_internal(CAudioInfo::EAudioIOState state, CAudioInfo::EAudioIOState state_prev, bool by_policy, void *user_data) {
+static void __state_changed_cb_internal(CAudioInfo::EAudioIOState state,
+                                        CAudioInfo::EAudioIOState state_prev,
+                                        bool by_policy,
+                                        void *user_data) {
     audio_io_s* audioIo = static_cast<audio_io_s*>(user_data);
     assert(audioIo);
 
-    if (audioIo->state_changed_callback.onStateChanged != NULL) {
-        audioIo->state_changed_callback.onStateChanged(audioIo, __convert_state_type(state_prev), __convert_state_type(state), by_policy, audioIo->state_changed_callback.user_data);
-    }
+    if (audioIo->state_changed_callback.onStateChanged)
+        audioIo->state_changed_callback.onStateChanged(audioIo, __convert_state_type(state_prev),
+                                                       __convert_state_type(state), by_policy,
+                                                       audioIo->state_changed_callback.user_data);
 }
 
 int cpp_audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* user_data) {
     audio_io_s* handle = static_cast<audio_io_s*>(input);
 
     try {
-        if (handle == NULL || callback == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, callback:%p", input, callback);
-        }
-
+        if (handle == NULL || callback == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL input:%p, callback:%p", input, callback);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
 
         handle->stream_callback.onStream = callback;
         handle->stream_callback.user_data = user_data;
@@ -861,11 +723,13 @@ int cpp_audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, vo
         cb.onStream  = __stream_cb_internal;
 
         handle->audioIoHandle->setStreamCallback(cb);
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] done", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -873,11 +737,11 @@ int cpp_audio_in_unset_stream_cb(audio_in_h input) {
     audio_io_s* handle = static_cast<audio_io_s*>(input);
 
     try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
-        }
-
+        if (handle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL input:%p", input);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p]", handle);
 
         handle->stream_callback.onStream = NULL;
         handle->stream_callback.user_data = NULL;
@@ -887,11 +751,13 @@ int cpp_audio_in_unset_stream_cb(audio_in_h input) {
         cb.onStream  = NULL;
 
         handle->audioIoHandle->setStreamCallback(cb);
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] done", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -900,15 +766,16 @@ int cpp_audio_in_peek(audio_in_h input, const void **buffer, unsigned int *lengt
     size_t _length = 0;
 
     try {
-        if (handle == NULL || buffer == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, buffer:%p", input, buffer);
-        }
+        if (handle == NULL || buffer == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL input:%p, buffer:%p", input, buffer);
 
-        CAudioInput* inputHandle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
-        assert(inputHandle);
+        CAudioInput* inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
+        if (inputHandle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
 
         inputHandle->peek(buffer, &_length);
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
@@ -922,15 +789,16 @@ int cpp_audio_in_drop(audio_in_h input) {
     audio_io_s* handle = static_cast<audio_io_s*>(input);
 
     try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
-        }
+        if (handle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL input:%p", input);
 
-        CAudioInput* inputHandle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
-        assert(inputHandle);
+        CAudioInput* inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
+        if (inputHandle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
 
         inputHandle->drop();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
@@ -942,11 +810,11 @@ int cpp_audio_in_set_state_changed_cb(audio_in_h input, audio_in_state_changed_c
     audio_io_s* handle = static_cast<audio_io_s*>(input);
 
     try {
-        if (handle == NULL || callback == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, callback:%p", input, callback);
-        }
-
+        if (handle == NULL || callback == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL input:%p, callback:%p", input, callback);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
 
         handle->state_changed_callback.onStateChanged = callback;
         handle->state_changed_callback.user_data = user_data;
@@ -956,11 +824,13 @@ int cpp_audio_in_set_state_changed_cb(audio_in_h input, audio_in_state_changed_c
         cb.onStateChanged = __state_changed_cb_internal;
 
         handle->audioIoHandle->setStateChangedCallback(cb);
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] done", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -968,11 +838,11 @@ int cpp_audio_in_unset_state_changed_cb(audio_in_h input) {
     audio_io_s* handle = static_cast<audio_io_s*>(input);
 
     try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", input);
-        }
-
+        if (handle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL output:%p", input);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p]", handle);
 
         handle->state_changed_callback.onStateChanged = NULL;
         handle->state_changed_callback.user_data = NULL;
@@ -982,11 +852,13 @@ int cpp_audio_in_unset_state_changed_cb(audio_in_h input) {
         cb.onStateChanged  = NULL;
 
         handle->audioIoHandle->setStateChangedCallback(cb);
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] done", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -994,86 +866,32 @@ int cpp_audio_in_unset_state_changed_cb(audio_in_h input) {
 /**
  * Audio Out
  */
-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) {
-    audio_io_s* handle = NULL;
-    try {
-        if (output == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
-        }
-
-        __check_audio_param(sample_rate, channel, type, sound_type);
-
-        handle = new audio_io_s;
-        if (handle == NULL) {
-            THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation handle");
-        }
-
-        CAudioInfo audioInfo = __generate_audio_output_info(sample_rate, channel, type, sound_type);
-
-        handle->audioIoHandle = new CAudioOutput(audioInfo);
-        if (handle == NULL) {
-            THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation internal handle");
-        }
-
-        handle->audioIoHandle->initialize();
-
-        *output = handle;
-    } catch (CAudioError e) {
-        AUDIO_IO_LOGE("%s", e.getErrorMsg());
-
-        VALID_POINTER_START(handle)
-            SAFE_FINALIZE(handle->audioIoHandle);
-            SAFE_DELETE(handle->audioIoHandle);
-            SAFE_DELETE(handle);
-        VALID_POINTER_END
-
-        VALID_POINTER_START(output)
-            *output = NULL;
-        VALID_POINTER_END
-
-        return __convert_CAudioError(e);
-    }
-
-    return AUDIO_IO_ERROR_NONE;
-}
-
 int cpp_audio_out_create_new(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_out_h *output) {
     audio_io_s* handle = NULL;
     try {
-        if (output == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
-        }
+        if (output == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL output:%p", output);
 
         __check_audio_param(sample_rate, channel, type, SOUND_TYPE_SYSTEM /*default check */);
 
-        handle = new audio_io_s;
-        if (handle == NULL) {
-            THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation handle");
-        }
-
-        CAudioInfo audioInfo = __generate_audio_output_info(sample_rate, channel, type, SOUND_TYPE_MEDIA /* default sound_type */);
+        AUDIO_IO_LOGD("samplerate:[%d] channel:[0x%x] sample_type:[0x%x]", sample_rate, channel, type);
+        CAudioInfo audioInfo = __generate_audio_output_info(sample_rate, channel, type, SOUND_TYPE_MEDIA);
 
+        handle = new audio_io_s;
         handle->audioIoHandle = new CAudioOutput(audioInfo);
-        if (handle == NULL) {
-            THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed allocation internal handle");
-        }
-
         handle->audioIoHandle->initialize();
 
+        AUDIO_IO_LOGD("[%p] created", handle);
         *output = handle;
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
-
-        VALID_POINTER_START(handle)
-            SAFE_FINALIZE(handle->audioIoHandle);
-            SAFE_DELETE(handle->audioIoHandle);
-            SAFE_DELETE(handle);
-        VALID_POINTER_END
-
-        VALID_POINTER_START(output)
-            *output = NULL;
-        VALID_POINTER_END
-
+        __handle_safe_free(handle, (void *)output, true);
+        return __convert_CAudioError(e);
+    } catch (const std::bad_alloc&) {
+        CAudioError e = CAudioError::EError::ERROR_OUT_OF_MEMORY;
+        AUDIO_IO_LOGE("Failed to allocate handle");
+        __handle_safe_free(handle, (void *)output, true);
         return __convert_CAudioError(e);
     }
 
@@ -1084,62 +902,46 @@ int cpp_audio_out_destroy(audio_out_h output) {
     audio_io_s* handle = static_cast<audio_io_s*>(output);
 
     try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
-        }
-
+        if (handle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameter is NULL output:%p", output);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p]", handle);
+
+        /* Internal unprepare for backward compatibility */
+        handle->audioIoHandle->unprepare();
 
         SAFE_FINALIZE(handle->audioIoHandle);
         SAFE_DELETE(handle->audioIoHandle);
         SAFE_DELETE(handle);
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("destroyed");
+
     return AUDIO_IO_ERROR_NONE;
 }
 
-int cpp_audio_out_set_stream_info(audio_out_h output, sound_stream_info_h stream_info) {
+int cpp_audio_out_set_sound_stream_info(audio_out_h output, sound_stream_info_h stream_info) {
     audio_io_s* handle = static_cast<audio_io_s*>(output);
 
     try {
-        if (handle == NULL || stream_info == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, stream_info:%p", output, stream_info);
-        }
-
+        if (handle == NULL || stream_info == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL output:%p, stream_info:%p", output, stream_info);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p], stream_info:[%p]", handle, stream_info);
 
-        int errorCode = SOUND_MANAGER_ERROR_NONE;
-        CAudioInfo::EAudioType audioType = CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA;
-        char *type = NULL;
-        int index = -1;
-        bool avail = false;
-
-        if ((errorCode = sound_manager_is_available_stream_information(stream_info, NATIVE_API_AUDIO_IO, &avail)) != SOUND_MANAGER_ERROR_NONE) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info is invalid [ret:%d]", errorCode);
-        }
-
-        if (avail) {
-            if ((errorCode = sound_manager_get_type_from_stream_information(stream_info, &type)) != SOUND_MANAGER_ERROR_NONE) {
-                THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->stream_type is invalid [ret:%d]", errorCode);
-            }
-            handle->audioIoHandle->getAudioInfo().convertOutputStreamType2AudioType(type, &audioType);
-            handle->audioIoHandle->getAudioInfo().setAudioType(audioType);
-
-            if ((errorCode = sound_manager_get_index_from_stream_information(stream_info, &index)) != SOUND_MANAGER_ERROR_NONE) {
-                THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->index is invalid [ret:%d]", errorCode);
-            }
-            handle->audioIoHandle->getAudioInfo().setAudioIndex(index);
-        } else {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_NOT_SUPPORTED_TYPE, "Output stream is not supported");
-        }
-    } catch (CAudioError e) {
+        handle->audioIoHandle->setStreamInfo(stream_info);
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] done", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -1147,18 +949,20 @@ int cpp_audio_out_prepare(audio_out_h output) {
     audio_io_s* handle = static_cast<audio_io_s*>(output);
 
     try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
-        }
-
+        if (handle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameter is NULL output:%p", output);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p]", handle);
 
         handle->audioIoHandle->prepare();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] prepared", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -1166,18 +970,20 @@ int cpp_audio_out_unprepare(audio_out_h output) {
     audio_io_s* handle = static_cast<audio_io_s*>(output);
 
     try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
-        }
-
+        if (handle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameter is NULL output:%p", output);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p]", handle);
 
         handle->audioIoHandle->unprepare();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] unprepared", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -1185,18 +991,20 @@ int cpp_audio_out_pause(audio_out_h output) {
     audio_io_s* handle = static_cast<audio_io_s*>(output);
 
     try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
-        }
-
+        if (handle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameter is NULL output:%p", output);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p]", handle);
 
         handle->audioIoHandle->pause();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] paused", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -1204,18 +1012,20 @@ int cpp_audio_out_resume(audio_out_h output) {
     audio_io_s* handle = static_cast<audio_io_s*>(output);
 
     try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
-        }
-
+        if (handle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameter is NULL output:%p", output);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p]", handle);
 
         handle->audioIoHandle->resume();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] resumed", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -1223,18 +1033,20 @@ int cpp_audio_out_drain(audio_out_h output) {
     audio_io_s* handle = static_cast<audio_io_s*>(output);
 
     try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
-        }
-
+        if (handle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameter is NULL output:%p", output);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p]", handle);
 
         handle->audioIoHandle->drain();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] drained", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -1242,18 +1054,20 @@ int cpp_audio_out_flush(audio_out_h output) {
     audio_io_s* handle = static_cast<audio_io_s*>(output);
 
     try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
-        }
-
+        if (handle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameter is NULL output:%p", output);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p]", handle);
 
         handle->audioIoHandle->flush();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] flushed", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -1262,22 +1076,21 @@ int cpp_audio_out_write(audio_out_h output, void *buffer, unsigned int length) {
     int ret = 0;
 
     try {
-        if (handle == NULL || buffer == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p, buffer:%p", output, buffer);
-        }
-
+        if (handle == NULL || buffer == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameter is NULL output:%p, buffer:%p", output, buffer);
         assert(handle->audioIoHandle);
 
-        CAudioOutput* outputHandle = dynamic_cast<CAudioOutput*>(handle->audioIoHandle);
-        if (outputHandle == NULL) {
+        CAudioOutput* outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
+        if (outputHandle == NULL)
             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
-        }
-        size_t writen = outputHandle->write(buffer, static_cast<size_t>(length));
-        ret = static_cast<int>(writen);
+
+        size_t written = outputHandle->write(buffer, static_cast<size_t>(length));
+        ret = static_cast<int>(written);
 #ifdef _AUDIO_IO_DEBUG_TIMING_
-        AUDIO_IO_LOGD("writen:%d", writen);
+        AUDIO_IO_LOGD("written:%d", written);
 #endif
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
@@ -1289,18 +1102,17 @@ int cpp_audio_out_get_buffer_size(audio_out_h output, int *size) {
     audio_io_s* handle = static_cast<audio_io_s*>(output);
 
     try {
-        if (handle == NULL || size == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, size:%p", output, size);
-        }
-
+        if (handle == NULL || size == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL output:%p, size:%p", output, size);
         assert(handle->audioIoHandle);
 
-        CAudioOutput* outputHandle = dynamic_cast<CAudioOutput*>(handle->audioIoHandle);
-        if (outputHandle == NULL) {
+        CAudioOutput* outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
+        if (outputHandle == NULL)
             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
-        }
+
         *size = outputHandle->getBufferSize();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
@@ -1312,13 +1124,13 @@ int cpp_audio_out_get_sample_rate(audio_out_h output, int *sample_rate) {
     audio_io_s* handle = static_cast<audio_io_s*>(output);
 
     try {
-        if (handle == NULL || sample_rate == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, sample_rate:%p", output, sample_rate);
-        }
-
+        if (handle == NULL || sample_rate == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL output:%p, sample_rate:%p", output, sample_rate);
         assert(handle->audioIoHandle);
+
         *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
@@ -1330,10 +1142,9 @@ int cpp_audio_out_get_channel(audio_out_h output, audio_channel_e *channel) {
     audio_io_s* handle = static_cast<audio_io_s*>(output);
 
     try {
-        if (handle == NULL || channel == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, channel:%p", output, channel);
-        }
-
+        if (handle == NULL || channel == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL output:%p, channel:%p", output, channel);
         assert(handle->audioIoHandle);
 
         const CAudioInfo::EChannel srcChannel = handle->audioIoHandle->getAudioInfo().getChannel();
@@ -1341,7 +1152,7 @@ int cpp_audio_out_get_channel(audio_out_h output, audio_channel_e *channel) {
         __convert_audio_info_channel_2_channel(srcChannel, dstChannel);
 
         *channel = dstChannel;
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
@@ -1353,18 +1164,17 @@ int cpp_audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type)
     audio_io_s* handle = static_cast<audio_io_s*>(output);
 
     try {
-        if (handle == NULL || type == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, type:%p", output, type);
-        }
-
+        if (handle == NULL || type == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL output:%p, type:%p", output, type);
         assert(handle->audioIoHandle);
 
         const CAudioInfo::ESampleType srcSampleType = handle->audioIoHandle->getAudioInfo().getSampleType();
-        audio_sample_type_e     dstSampleType = AUDIO_SAMPLE_TYPE_U8;
+        audio_sample_type_e dstSampleType = AUDIO_SAMPLE_TYPE_U8;
         __convert_audio_info_sample_type_2_sample_type(srcSampleType, dstSampleType);
 
         *type = dstSampleType;
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
@@ -1376,93 +1186,17 @@ int cpp_audio_out_get_sound_type(audio_out_h output, sound_type_e *type) {
     audio_io_s* handle = static_cast<audio_io_s*>(output);
 
     try {
-        if (handle == NULL || type == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, type:%p", output, type);
-        }
-
+        if (handle == NULL || type == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL output:%p, type:%p", output, type);
         assert(handle->audioIoHandle);
 
         const CAudioInfo::EAudioType srcAudioType = handle->audioIoHandle->getAudioInfo().getAudioType();
-        sound_type_e                 dstSoundType = SOUND_TYPE_MEDIA;
+        sound_type_e dstSoundType = SOUND_TYPE_MEDIA;
         __convert_audio_info_audio_type_2_sound_type(srcAudioType, dstSoundType);
 
         *type = dstSoundType;
-    } catch (CAudioError e) {
-        AUDIO_IO_LOGE("%s", e.getErrorMsg());
-        return __convert_CAudioError(e);
-    }
-
-    return AUDIO_IO_ERROR_NONE;
-}
-
-int cpp_audio_out_set_interrupted_cb(audio_out_h output, audio_io_interrupted_cb callback, void *user_data) {
-    audio_io_s* handle = static_cast<audio_io_s*>(output);
-
-    try {
-        if (handle == NULL || callback == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, callback:%p", output, callback);
-        }
-
-        assert(handle->audioIoHandle);
-
-        handle->interrupt_callback.onInterrupt = callback;
-        handle->interrupt_callback.user_data    = user_data;
-
-        CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
-        cb.mUserData   = static_cast<void*>(handle);
-        cb.onInterrupt = __interrupt_cb_internal;
-
-        handle->audioIoHandle->setInterruptCallback(cb);
-    } catch (CAudioError e) {
-        AUDIO_IO_LOGE("%s", e.getErrorMsg());
-        return __convert_CAudioError(e);
-    }
-
-    return AUDIO_IO_ERROR_NONE;
-}
-
-int cpp_audio_out_unset_interrupted_cb(audio_out_h output) {
-    audio_io_s* handle = static_cast<audio_io_s*>(output);
-
-    try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
-        }
-
-        assert(handle->audioIoHandle);
-
-        handle->interrupt_callback.onInterrupt = NULL;
-        handle->interrupt_callback.user_data    = NULL;
-
-        CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
-        cb.mUserData   = NULL;
-        cb.onInterrupt = NULL;
-
-        handle->audioIoHandle->setInterruptCallback(cb);
-    } catch (CAudioError e) {
-        AUDIO_IO_LOGE("%s", e.getErrorMsg());
-        return __convert_CAudioError(e);
-    }
-
-    return AUDIO_IO_ERROR_NONE;
-}
-
-int cpp_audio_out_ignore_session(audio_out_h output) {
-    audio_io_s* handle = static_cast<audio_io_s*>(output);
-
-    try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
-        }
-
-        if (handle->stream_callback.onStream) {
-            THROW_ERROR_MSG(CAudioError::EError::ERROR_INVALID_OPERATION, "Not support ignore session in async mode");
-        }
-
-        assert(handle->audioIoHandle);
-
-        handle->audioIoHandle->ignoreSession();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
@@ -1474,25 +1208,27 @@ int cpp_audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback
     audio_io_s* handle = static_cast<audio_io_s*>(output);
 
     try {
-        if (handle == NULL || callback == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, callback:%p", output, callback);
-        }
-
+        if (handle == NULL || callback == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL output:%p, callback:%p", output, callback);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
 
         handle->stream_callback.onStream = callback;
         handle->stream_callback.user_data = user_data;
 
         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
         cb.mUserData = static_cast<void*>(handle);
-        cb.onStream  = __stream_cb_internal;
+        cb.onStream = __stream_cb_internal;
 
         handle->audioIoHandle->setStreamCallback(cb);
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] done", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -1500,25 +1236,27 @@ int cpp_audio_out_unset_stream_cb(audio_out_h output) {
     audio_io_s* handle = static_cast<audio_io_s*>(output);
 
     try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
-        }
-
+        if (handle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL output:%p", output);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p]", handle);
 
         handle->stream_callback.onStream = NULL;
         handle->stream_callback.user_data = NULL;
 
         CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
         cb.mUserData = NULL;
-        cb.onStream  = NULL;
+        cb.onStream = NULL;
 
         handle->audioIoHandle->setStreamCallback(cb);
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] done", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -1526,11 +1264,11 @@ int cpp_audio_out_set_state_changed_cb(audio_out_h output, audio_in_state_change
     audio_io_s* handle = static_cast<audio_io_s*>(output);
 
     try {
-        if (handle == NULL || callback == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, callback:%p", output, callback);
-        }
-
+        if (handle == NULL || callback == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL output:%p, callback:%p", output, callback);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
 
         handle->state_changed_callback.onStateChanged = callback;
         handle->state_changed_callback.user_data = user_data;
@@ -1540,11 +1278,13 @@ int cpp_audio_out_set_state_changed_cb(audio_out_h output, audio_in_state_change
         cb.onStateChanged = __state_changed_cb_internal;
 
         handle->audioIoHandle->setStateChangedCallback(cb);
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] done", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }
 
@@ -1552,24 +1292,26 @@ int cpp_audio_out_unset_state_changed_cb(audio_out_h output) {
     audio_io_s* handle = static_cast<audio_io_s*>(output);
 
     try {
-        if (handle == NULL) {
-            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
-        }
-
+        if (handle == NULL)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL output:%p", output);
         assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p]", handle);
 
         handle->state_changed_callback.onStateChanged = NULL;
         handle->state_changed_callback.user_data = NULL;
 
         CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
         cb.mUserData = NULL;
-        cb.onStateChanged  = NULL;
+        cb.onStateChanged = NULL;
 
         handle->audioIoHandle->setStateChangedCallback(cb);
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
         return __convert_CAudioError(e);
     }
 
+    AUDIO_IO_LOGD("[%p] done", handle);
+
     return AUDIO_IO_ERROR_NONE;
 }