From 16235a60fdaa7c9a533994e658abd4ed5c716394 Mon Sep 17 00:00:00 2001 From: "dh8210.kim" Date: Thu, 15 Jan 2015 11:51:39 +0900 Subject: [PATCH] audio-io : Change APIs based on Tizen 2.3 Change-Id: Ic90535a671f8853ab74c60e8e2da7fd2718b0447 Signed-off-by: dh8210.kim --- CMakeLists.txt | 2 +- doc/audio_io_doc.h | 93 ++++++++ include/audio_io.h | 198 +++++++++++++++-- include/audio_io_private.h | 34 +++ packaging/capi-media-audio-io.spec | 2 +- src/audio_io.c | 333 ++++++----------------------- src/audio_io_private.c | 325 ++++++++++++++++++++++++++++ test/CMakeLists.txt | 2 +- 8 files changed, 712 insertions(+), 277 deletions(-) create mode 100755 doc/audio_io_doc.h mode change 100644 => 100755 include/audio_io.h mode change 100644 => 100755 include/audio_io_private.h mode change 100644 => 100755 src/audio_io.c create mode 100755 src/audio_io_private.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 08a3278..f2a7e53 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ FOREACH(flag ${${fw_name}_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall") SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") IF("${ARCH}" STREQUAL "arm") diff --git a/doc/audio_io_doc.h b/doc/audio_io_doc.h new file mode 100755 index 0000000..4ca1422 --- /dev/null +++ b/doc/audio_io_doc.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __TIZEN_MEDIA_AUDIO_IO_DOC_H__ +#define __TIZEN_MEDIA_AUDIO_IO_DOC_H__ + + +/** + * @file audio_io_doc.h + * @brief This file contains high level documentation for the Audio I/O API. + * + */ + +/** + * @defgroup CAPI_MEDIA_AUDIO_IO_MODULE Audio I/O + * @ingroup CAPI_MEDIA_FRAMEWORK + */ + +/** + * @ingroup CAPI_MEDIA_FRAMEWORK + * @addtogroup CAPI_MEDIA_AUDIO_IO_MODULE + * @brief The @ref CAPI_MEDIA_AUDIO_IO_MODULE API provides functions for controlling audio devices. + * @section CAPI_MEDIA_AUDIO_IO_MODULE_HEADER Required Header + * \#include + * + * @section CAPI_MEDIA_AUDIO_IO_MODULE_OVERVIEW Overview + * The Audio I/O API provides a set of functions to directly manage the system audio devices. + * It gives easy access to the hardware layer of the sound card with a professional multichannel audio interface. + * It should be used for activities requiring raw audio data buffers(PCM format). + * + * Programming the interface requires first obtaining a handle to the device, via the audio_in_create() or audio_out_create() function. + * + * The input and output devices both have an available set of queries, to find the suggested buffer size, sampling rate, channel type, + * and sample type. For output, there is an additional query, to get the sound type (these types are defined in the @ref CAPI_MEDIA_SOUND_MANAGER_MODULE API). + * + * Reading and writing is done by allocating a buffer and passing the buffer to the input device + * via audio_in_start_recording(), audio_in_read(), or writing to the buffer and passing it to the output device via audio_out_write(). + * + */ + + /** + * @ingroup CAPI_MEDIA_AUDIO_IO_MODULE + * @defgroup CAPI_MEDIA_AUDIO_IN_MODULE Audio Input + * @brief The @ref CAPI_MEDIA_AUDIO_IN_MODULE API provides a set of functions to directly manage the system audio input devices. + * @section CAPI_MEDIA_AUDIO_IN_MODULE_HEADER Required Header + * \#include + * + * @section CAPI_MEDIA_AUDIO_IN_MODULE_OVERVIEW Overview + * The Audio Input API provides a set of functions to record audio data (PCM format) from audio devices. + * + * @section CAPI_MEDIA_AUDIO_IN_MODULE_FEATURE Related Features + * This API is related with the following features:\n + * - http://tizen.org/feature/microphone\n + * + * It is recommended to design feature related codes in your application for reliability.\n + * + * You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n + * + * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.\n + * + * More details on featuring your application can be found from Feature Element. + * + */ + + /** + * @ingroup CAPI_MEDIA_AUDIO_IO_MODULE + * @defgroup CAPI_MEDIA_AUDIO_OUT_MODULE Audio Output + * @brief The @ref CAPI_MEDIA_AUDIO_OUT_MODULE API provides a set of functions to directly manage the system audio output devices. + * @section CAPI_MEDIA_AUDIO_OUT_MODULE_HEADER Required Header + * \#include + * + * @section CAPI_MEDIA_AUDIO_OUT_MODULE_OVERVIEW Overview + * The Audio Output API provides a set of functions to play recorded audio data from Audio Input. + * + * + */ +#endif /* __TIZEN_MEDIA_AUDIO_IO_DOC_H__ */ + + diff --git a/include/audio_io.h b/include/audio_io.h old mode 100644 new mode 100755 index b9e7d6d..fbe5151 --- a/include/audio_io.h +++ b/include/audio_io.h @@ -90,6 +90,7 @@ typedef enum{ AUDIO_IO_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ AUDIO_IO_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ AUDIO_IO_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Invalid operation */ + AUDIO_IO_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Device open error by security */ AUDIO_IO_ERROR_DEVICE_NOT_OPENED = AUDIO_IO_ERROR_CLASS | 0x01, /**< Device open error */ AUDIO_IO_ERROR_DEVICE_NOT_CLOSED = AUDIO_IO_ERROR_CLASS | 0x02, /**< Device close error */ AUDIO_IO_ERROR_INVALID_BUFFER = AUDIO_IO_ERROR_CLASS | 0x03, /**< Invalid buffer pointer */ @@ -101,14 +102,14 @@ typedef enum{ */ typedef enum { - AUDIO_IO_INTERRUPTED_COMPLETED = 0, /**< Interrupt completed*/ - AUDIO_IO_INTERRUPTED_BY_MEDIA, /**< Interrupted by non-resumable media application*/ - AUDIO_IO_INTERRUPTED_BY_CALL, /**< Interrupted by incoming call*/ - AUDIO_IO_INTERRUPTED_BY_EARJACK_UNPLUG, /**< Interrupted by unplugging headphone*/ - AUDIO_IO_INTERRUPTED_BY_RESOURCE_CONFLICT, /**< Interrupted by resource conflict*/ - AUDIO_IO_INTERRUPTED_BY_ALARM, /**< Interrupted by alarm*/ - AUDIO_IO_INTERRUPTED_BY_EMERGENCY, /**< Interrupted by emergency*/ - AUDIO_IO_INTERRUPTED_BY_RESUMABLE_MEDIA, /**< Interrupted by resumable media application*/ + AUDIO_IO_INTERRUPTED_COMPLETED = 0, /**< Interrupt completed */ + AUDIO_IO_INTERRUPTED_BY_MEDIA, /**< Interrupted by a media application */ + AUDIO_IO_INTERRUPTED_BY_CALL, /**< Interrupted by an incoming call */ + AUDIO_IO_INTERRUPTED_BY_EARJACK_UNPLUG, /**< Interrupted by unplugging headphones */ + AUDIO_IO_INTERRUPTED_BY_RESOURCE_CONFLICT, /**< Interrupted by a resource conflict */ + AUDIO_IO_INTERRUPTED_BY_ALARM, /**< Interrupted by an alarm */ + AUDIO_IO_INTERRUPTED_BY_EMERGENCY, /**< Interrupted by an emergency */ + AUDIO_IO_INTERRUPTED_BY_NOTIFICATION, /**< Interrupted by a notification */ } audio_io_interrupted_code_e; /** @@ -136,6 +137,19 @@ typedef void (*audio_io_interrupted_cb)(audio_io_interrupted_code_e code, void * //AUDIO INPUT // +/** + * @brief Called when audio input data is available in asynchronous(event) mode. + * + * + * @remarks @a use audio_in_peek() to get audio in data inside callback, use audio_in_drop() after use of peeked data. + * + * @param[in] handle The handle to the audio input + * @param[in] nbytes The amount of available audio in data which can be peeked. + * @param[in] userdata The user data passed from the callback registration function + * + * @see audio_in_set_stream_cb() + */ +typedef void (*audio_in_stream_cb)(audio_in_h handle, size_t nbytes, void *userdata); /** * @brief Creates an audio device instance and returns an input handle to record PCM (pulse-code modulation) data @@ -151,6 +165,7 @@ typedef void (*audio_io_interrupted_cb)(audio_io_interrupted_code_e code, void * * @return 0 on success, otherwise a negative error value. * @retval #AUDIO_IO_ERROR_NONE Successful * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #AUDIO_IO_ERROR_PERMISSION_DENIED Permission denied * @retval #AUDIO_IO_ERROR_OUT_OF_MEMORY Out of memory * @retval #AUDIO_IO_ERROR_DEVICE_NOT_OPENED Device not opened * @retval #AUDIO_IO_ERROR_SOUND_POLICY Sound policy error @@ -158,7 +173,29 @@ typedef void (*audio_io_interrupted_cb)(audio_io_interrupted_code_e code, void * */ int audio_in_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type , audio_in_h *input); - +/** + * @brief Creates an audio loopback device instance and returns an input handle to record PCM (pulse-code modulation) data. + * + * + * @details This function is used for audio loopback input initialization. + * + * @remarks @a input must be released using audio_in_destroy(). + * + * @param[in] sample_rate The audio sample rate in 8000[Hz] ~ 48000[Hz] + * @param[in] channel The audio channel type, mono, or stereo + * @param[in] type The type of audio sample (8- or 16-bit) + * @param[out] input An audio input handle will be created, if successful + * @return @c 0 on success, + * otherwise a negative error value + * @retval #AUDIO_IO_ERROR_NONE Successful + * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #AUDIO_IO_ERROR_PERMISSION_DENIED Permission denied + * @retval #AUDIO_IO_ERROR_OUT_OF_MEMORY Out of memory + * @retval #AUDIO_IO_ERROR_DEVICE_NOT_OPENED Device not opened + * @retval #AUDIO_IO_ERROR_SOUND_POLICY Sound policy error + * @see audio_in_destroy() + */ +int audio_in_create_loopback(int sample_rate, audio_channel_e channel, audio_sample_type_e type , audio_in_h* input); /** * @brief Releases the audio input handle and all its resources associated with an audio stream @@ -311,6 +348,89 @@ int audio_in_unset_interrupted_cb(audio_in_h input); */ int audio_in_ignore_session(audio_in_h input); +/** + * @brief Sets an asynchronous(event) callback function to handle recording PCM (pulse-code modulation) data. + * + * + * @details @a callback will be called when you can read a PCM data. + * It might cause dead lock if change the state of audio handle in callback. + * (ex: audio_in_destroy, audio_in_prepare, audio_in_unprepare) + * Recommend to use as a VOIP only. + * Recommend not to hold callback too long.(it affects latency) + * + * @remarks @a input must be created using audio_in_create(). + * + * @param[in] input An audio input handle + * @param[in] callback notify stream callback when user can read data (#audio_in_stream_cb) + * @param[in] userdata user data to be retrieved when callback is called + * @return @c 0 on success, + * otherwise a negative error value + * @retval #AUDIO_IO_ERROR_NONE Successful + * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #AUDIO_IO_ERROR_OUT_OF_MEMORY Out of memory + * @retval #AUDIO_IO_ERROR_DEVICE_NOT_OPENED Device not opened + * @retval #AUDIO_IO_ERROR_SOUND_POLICY Sound policy error + * + * @see audio_out_set_stream_cb() + */ +int audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* userdata); + +/** + * @brief Unregisters the callback function. + * + * + * @param[in] input The handle to the audio input + * @return @c 0 on success, + * otherwise a negative error value + * @retval #AUDIO_IO_ERROR_NONE Successful + * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #AUDIO_IO_ERROR_INVALID_OPERATION Invalid operation + * + * @see audio_in_set_interrupted_cb() + */ +int audio_in_unset_stream_cb(audio_in_h input); + +/** + * @brief peek from audio in buffer + * + * + * @details This function works correctly only with read, write callback. Otherwise it won't operate as intended. + * + * @remarks @a Works only in asynchronous(event) mode. This will just retrieve buffer pointer from audio in buffer. Drop after use. + * + * @param[in] input The handle to the audio input + * @param[out] buffer start buffer pointer of peeked audio in data + * @param[in,out] length amount of audio in data to be peeked + * @return @c 0 on success, + * otherwise a negative error value + * @retval #AUDIO_IO_ERROR_NONE Successful + * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #AUDIO_IO_ERROR_INVALID_OPERATION Invalid operation + * + * @see audio_in_drop() + */ +int audio_in_peek(audio_in_h input, const void **buffer, unsigned int *length); + +/** + * @brief drop peeked audio buffer. + * + * @details This function works correctly only with read, write callback. Otherwise it won't operate as intended. + * + * + * @remarks @a Works only in asynchronous(event) mode. This will remove audio in data from actual stream buffer. Use this if peeked data is not needed anymore. + * + * @param[in] input The handle to the audio input + * @return 0 on success, otherwise a negative error value + * @retval #AUDIO_IO_ERROR_NONE Successful + * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #AUDIO_IO_ERROR_INVALID_OPERATION Invalid operation + * + * @see audio_in_peek() + */ +int audio_in_drop(audio_in_h input); + + + // // AUDIO OUTPUT // @@ -325,9 +445,25 @@ int audio_in_ignore_session(audio_in_h input); */ /** - * @brief Creates an audio device instance and returns an output handle to play PCM (pulse-code modulation) data - * @details This function is used for audio output initialization. - * @remarks @a output must be released audio_out_destroy() by you. + * @brief Called when audio out data can be written in asynchronous(event) mode. + * + * + * @remarks @a use audio_out_write() to write pcm data inside this callback. + * @param[in] handle The handle to the audio output + * @param[in] nbytes The amount of audio in data which can be written. + * @param[in] userdata The user data passed from the callback registration function + * + * @see audio_out_set_stream_cb() + */ +typedef void (*audio_out_stream_cb)(audio_out_h handle, size_t nbytes, void *userdata); + +/** + * @brief Creates an audio device instance and returns an output handle to play PCM (pulse-code modulation) data. + + * + * @details This function is used for audio output initialization. + * + * @remarks @a output must be released by audio_out_destroy(). * * @param[in] sample_rate The audio sample rate in 8000[Hz] ~ 48000[Hz] * @param[in] channel The audio channel type, mono, or stereo @@ -511,7 +647,45 @@ int audio_out_unset_interrupted_cb(audio_out_h output); */ int audio_out_ignore_session(audio_out_h output); +/** + * @brief Sets an asynchronous(event) callback function to handle playing PCM (pulse-code modulation) data. + * + * + * @details @a callback will be called when you can write a PCM data. + * It might cause dead lock if change the state of audio handle in callback. + * (ex: audio_in_destroy, audio_in_prepare, audio_in_unprepare) + * Recommend to use as a VOIP only. + * Recommend not to hold callback too long.(it affects latency) + * + * @remarks @a output must be created using audio_out_create(). + * + * @param[in] output An audio output handle + * @param[in] callback notify stream callback when user can write data (#audio_out_stream_cb) + * @param[in] userdata user data to be retrieved when callback is called + * @return 0 on success, otherwise a negative error value + * @retval #AUDIO_IO_ERROR_NONE Successful + * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #AUDIO_IO_ERROR_OUT_OF_MEMORY Out of memory + * @retval #AUDIO_IO_ERROR_DEVICE_NOT_OPENED Device not opened + * @retval #AUDIO_IO_ERROR_SOUND_POLICY Sound policy error + * + * @see audio_in_set_stream_cb() + */ +int audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* userdata); +/** + * @brief Unregisters the callback function. + * + * + * @param[in] output The handle to the audio output + * @return 0 on success, otherwise a negative error value + * @retval #AUDIO_IO_ERROR_NONE Successful + * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #AUDIO_IO_ERROR_INVALID_OPERATION Invalid operation + * + * @see audio_out_set_stream_cb() + */ +int audio_out_unset_stream_cb(audio_out_h output); /** * @} */ diff --git a/include/audio_io_private.h b/include/audio_io_private.h old mode 100644 new mode 100755 index d124cea..880734b --- a/include/audio_io_private.h +++ b/include/audio_io_private.h @@ -20,6 +20,20 @@ #include #include +/* +* Internal Macros +*/ + +#define AUDIO_IO_INTERRUPTED_BY_RESUMABLE_MEDIA (AUDIO_IO_INTERRUPTED_BY_NOTIFICATION + 1) +#define AUDIO_IO_INTERRUPTED_BY_RESUMABLE_CANCELED (AUDIO_IO_INTERRUPTED_BY_NOTIFICATION + 2) + +#define AUDIO_IO_CHECK_CONDITION(condition,error,msg) \ + if(condition) {} else \ + { LOGE("[%s] %s(0x%08x)",__FUNCTION__, msg,error); return error;}; \ + +#define AUDIO_IO_NULL_ARG_CHECK(arg) \ + AUDIO_IO_CHECK_CONDITION(arg != NULL, AUDIO_IO_ERROR_INVALID_PARAMETER, "AUDIO_IO_ERROR_INVALID_PARAMETER" ) + #ifdef __cplusplus extern "C" { #endif @@ -27,16 +41,20 @@ extern "C" { typedef struct _audio_in_s{ MMSoundPcmHandle_t mm_handle; + int _buffer_size; int _sample_rate; audio_channel_e _channel; audio_sample_type_e _type; audio_io_interrupted_cb user_cb; void* user_data; + audio_in_stream_cb stream_cb; + void* stream_userdata; } audio_in_s; typedef struct _audio_out_s{ MMSoundPcmHandle_t mm_handle; + int _buffer_size; int _sample_rate; audio_channel_e _channel; @@ -44,8 +62,24 @@ typedef struct _audio_out_s{ sound_type_e _sound_type; audio_io_interrupted_cb user_cb; void* user_data; + audio_out_stream_cb stream_cb; + void* stream_userdata; } audio_out_s; +int __convert_audio_io_error_code(int code, char *func_name); +int __check_parameter(int sample_rate, audio_channel_e channel, audio_sample_type_e type); +int __mm_sound_pcm_capture_msg_cb (int message, void *param, void *user_param); +audio_io_interrupted_code_e __translate_interrupted_code (int code); + +int audio_in_create_private(int sample_rate, audio_channel_e channel, audio_sample_type_e type , audio_in_h* input); + +int audio_in_set_callback_private(audio_in_h input, audio_in_stream_cb callback, void* userdata); + +int audio_out_create_private(int sample_rate, audio_channel_e channel, audio_sample_type_e type, sound_type_e sound_type, audio_out_h* output); + +int audio_out_set_callback_private(audio_out_h output, audio_out_stream_cb callback, void* userdata); + + #ifdef __cplusplus } #endif diff --git a/packaging/capi-media-audio-io.spec b/packaging/capi-media-audio-io.spec index fbc170e..92118a3 100644 --- a/packaging/capi-media-audio-io.spec +++ b/packaging/capi-media-audio-io.spec @@ -1,6 +1,6 @@ Name: capi-media-audio-io Summary: An Audio Input & Audio Output library in Tizen Native API -Version: 0.2.0 +Version: 0.2.1 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/audio_io.c b/src/audio_io.c old mode 100644 new mode 100755 index 76304d9..8ed0cee --- a/src/audio_io.c +++ b/src/audio_io.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -26,170 +25,11 @@ #undef LOG_TAG #endif #define LOG_TAG "TIZEN_N_AUDIO_IO" - -/* -* Internal Macros -*/ -#define AUDIO_IO_CHECK_CONDITION(condition,error,msg) \ - if(condition) {} else \ - { LOGE("[%s] %s(0x%08x)",__FUNCTION__, msg,error); return error;}; \ - -#define AUDIO_IO_NULL_ARG_CHECK(arg) \ - AUDIO_IO_CHECK_CONDITION(arg != NULL, AUDIO_IO_ERROR_INVALID_PARAMETER, "AUDIO_IO_ERROR_INVALID_PARAMETER" ) - +/* TODO : it will be added after updating libmm-sound */ +//#include /* * Internal Implementation */ -static int __convert_error_code(int code, char *func_name) -{ - int ret = AUDIO_IO_ERROR_NONE; - char* msg = "AUDIO_IO_ERROR_NONE"; - - switch(code) - { - case MM_ERROR_NONE: - ret = AUDIO_IO_ERROR_NONE; - msg = "AUDIO_IO_ERROR_NONE"; - break; - case MM_ERROR_INVALID_ARGUMENT: - case MM_ERROR_SOUND_DEVICE_INVALID_SAMPLERATE: - case MM_ERROR_SOUND_DEVICE_INVALID_CHANNEL: - case MM_ERROR_SOUND_DEVICE_INVALID_FORMAT: - ret = AUDIO_IO_ERROR_INVALID_PARAMETER; - msg = "AUDIO_IO_ERROR_INVALID_PARAMETER"; - break; - case MM_ERROR_SOUND_DEVICE_NOT_OPENED: - ret = AUDIO_IO_ERROR_DEVICE_NOT_OPENED; - msg = "AUDIO_IO_ERROR_DEVICE_NOT_OPENED"; - break; - case MM_ERROR_SOUND_INTERNAL: - ret = AUDIO_IO_ERROR_DEVICE_NOT_CLOSED; - msg = "AUDIO_IO_ERROR_DEVICE_NOT_CLOSED"; - break; - case MM_ERROR_SOUND_INVALID_POINTER: - ret = AUDIO_IO_ERROR_INVALID_BUFFER; - msg = "AUDIO_IO_ERROR_INVALID_BUFFER"; - break; - case MM_ERROR_POLICY_BLOCKED: - case MM_ERROR_POLICY_INTERRUPTED: - case MM_ERROR_POLICY_INTERNAL: - case MM_ERROR_POLICY_DUPLICATED: - ret = AUDIO_IO_ERROR_SOUND_POLICY; - msg = "AUDIO_IO_ERROR_SOUND_POLICY"; - break; - } - LOGE("[%s] %s(0x%08x) : core fw error(0x%x)",func_name,msg, ret, code); - return ret; -} - -static int __check_parameter(int sample_rate, audio_channel_e channel, audio_sample_type_e type) -{ - if(sample_rate<8000 || sample_rate > 48000) { - LOGE("[%s] AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) : Invalid sample rate (8000~48000Hz) : %d",__FUNCTION__, AUDIO_IO_ERROR_INVALID_PARAMETER,sample_rate); - return AUDIO_IO_ERROR_INVALID_PARAMETER; - } - if (channel < AUDIO_CHANNEL_MONO || channel > AUDIO_CHANNEL_STEREO) { - LOGE("[%s] AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) : Invalid audio channel : %d",__FUNCTION__, AUDIO_IO_ERROR_INVALID_PARAMETER,channel); - return AUDIO_IO_ERROR_INVALID_PARAMETER; - } - if (type < AUDIO_SAMPLE_TYPE_U8 || type > AUDIO_SAMPLE_TYPE_S16_LE) { - LOGE("[%s] AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) : Invalid sample typel : %d",__FUNCTION__, AUDIO_IO_ERROR_INVALID_PARAMETER,type); - return AUDIO_IO_ERROR_INVALID_PARAMETER; - } - return AUDIO_IO_ERROR_NONE; -} - - -static audio_io_interrupted_code_e __translate_interrupted_code (int code) -{ - audio_io_interrupted_code_e e = AUDIO_IO_INTERRUPTED_COMPLETED; - - switch(code) - { - case MM_MSG_CODE_INTERRUPTED_BY_ALARM_END: - case MM_MSG_CODE_INTERRUPTED_BY_EMERGENCY_END: - e = AUDIO_IO_INTERRUPTED_COMPLETED; - break; - - case MM_MSG_CODE_INTERRUPTED_BY_MEDIA: - case MM_MSG_CODE_INTERRUPTED_BY_OTHER_PLAYER_APP: - e = AUDIO_IO_INTERRUPTED_BY_MEDIA; - break; - - case MM_MSG_CODE_INTERRUPTED_BY_CALL_START: - e = AUDIO_IO_INTERRUPTED_BY_CALL; - break; - - case MM_MSG_CODE_INTERRUPTED_BY_EARJACK_UNPLUG: - e = AUDIO_IO_INTERRUPTED_BY_EARJACK_UNPLUG; - break; - - case MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT: - e = AUDIO_IO_INTERRUPTED_BY_RESOURCE_CONFLICT; - break; - - case MM_MSG_CODE_INTERRUPTED_BY_ALARM_START: - e = AUDIO_IO_INTERRUPTED_BY_ALARM; - break; - - case MM_MSG_CODE_INTERRUPTED_BY_EMERGENCY_START: - e = AUDIO_IO_INTERRUPTED_BY_EMERGENCY; - break; - - case MM_MSG_CODE_INTERRUPTED_BY_RESUMABLE_MEDIA: - e = AUDIO_IO_INTERRUPTED_BY_RESUMABLE_MEDIA; - break; - } - - return e; -} - -static int __mm_sound_pcm_capture_msg_cb (int message, void *param, void *user_param) -{ - audio_io_interrupted_code_e e = AUDIO_IO_INTERRUPTED_COMPLETED; - audio_in_s *handle = (audio_in_s *) user_param; - MMMessageParamType *msg = (MMMessageParamType*)param; - - LOGI("[%s] Got message type : 0x%x with code : %d" ,__FUNCTION__, message, msg->code); - - if (handle->user_cb == NULL) { - LOGI("[%s] No interrupt callback is set. Skip this" ,__FUNCTION__); - return 0; - } - - if (message == MM_MESSAGE_SOUND_PCM_INTERRUPTED) { - e = __translate_interrupted_code (msg->code); - } else if (message == MM_MESSAGE_SOUND_PCM_CAPTURE_RESTRICTED) { - /* TODO : handling restricted code is needed */ - /* e = _translate_restricted_code (msg->code); */ - } - - handle->user_cb (e, handle->user_data); - - return 0; -} - -static int __mm_sound_pcm_playback_msg_cb (int message, void *param, void *user_param) -{ - audio_io_interrupted_code_e e = AUDIO_IO_INTERRUPTED_COMPLETED; - audio_out_s *handle = (audio_out_s *) user_param; - MMMessageParamType *msg = (MMMessageParamType*)param; - - LOGI("[%s] Got message type : 0x%x with code : %d" ,__FUNCTION__, message, msg->code); - - if (handle->user_cb == NULL) { - LOGI("[%s] No interrupt callback is set. Skip this" ,__FUNCTION__); - return 0; - } - - if (message == MM_MESSAGE_SOUND_PCM_INTERRUPTED) { - e = __translate_interrupted_code (msg->code); - } - - handle->user_cb (e, handle->user_data); - - return 0; -} /* @@ -199,55 +39,24 @@ static int __mm_sound_pcm_playback_msg_cb (int message, void *param, void *user_ /* Audio In */ int audio_in_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type , audio_in_h* input) { - int ret = 0; - audio_in_s *handle = NULL; - - /* input condition check */ - AUDIO_IO_NULL_ARG_CHECK(input); - if(__check_parameter(sample_rate, channel, type) != AUDIO_IO_ERROR_NONE) - return AUDIO_IO_ERROR_INVALID_PARAMETER; - - /* Create Handle */ - handle = (audio_in_s*)malloc( sizeof(audio_in_s)); - if (handle != NULL) { - memset(handle, 0, sizeof(audio_in_s)); - } else { - LOGE("[%s] ERROR : AUDIO_IO_ERROR_OUT_OF_MEMORY(0x%08x)" ,__FUNCTION__, AUDIO_IO_ERROR_OUT_OF_MEMORY ); - return AUDIO_IO_ERROR_OUT_OF_MEMORY; - } - - ret = mm_sound_pcm_capture_open( &handle->mm_handle,sample_rate, channel, type); - if( ret < 0) { - free (handle); - return __convert_error_code(ret, (char*)__FUNCTION__); - } - LOGI("[%s] mm_sound_pcm_capture_open() success",__FUNCTION__); - - /* Fill information */ - *input = (audio_in_h)handle; - handle->_buffer_size= ret; - handle->_sample_rate= sample_rate; - handle->_channel= channel; - handle->_type= type; - - /* Set message interrupt callback */ - ret = mm_sound_pcm_set_message_callback(handle->mm_handle, __mm_sound_pcm_capture_msg_cb, handle); - if( ret < 0) { - return __convert_error_code(ret, (char*)__FUNCTION__); - } - LOGI("[%s] mm_sound_pcm_set_message_callback() success",__FUNCTION__); + return audio_in_create_private (sample_rate, channel, type, input); +} - return AUDIO_IO_ERROR_NONE; +int audio_in_create_loopback(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_in_h* input) +{ + return audio_in_create_private (sample_rate, channel, type, input); } int audio_in_destroy(audio_in_h input) { AUDIO_IO_NULL_ARG_CHECK(input); audio_in_s *handle = (audio_in_s *) input; + int ret = MM_ERROR_NONE; - int ret = mm_sound_pcm_capture_close(handle->mm_handle); + ret = mm_sound_pcm_capture_close(handle->mm_handle); if (ret != MM_ERROR_NONE) { - return __convert_error_code(ret, (char*)__FUNCTION__); + free(handle); + return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); } free(handle); @@ -259,10 +68,11 @@ int audio_in_prepare(audio_in_h input) { AUDIO_IO_NULL_ARG_CHECK(input); audio_in_s *handle = (audio_in_s *) input; + int ret = MM_ERROR_NONE; - int ret = mm_sound_pcm_capture_start(handle->mm_handle); + ret = mm_sound_pcm_capture_start(handle->mm_handle); if (ret != MM_ERROR_NONE) { - return __convert_error_code(ret, (char*)__FUNCTION__); + return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); } LOGI("[%s] mm_sound_pcm_capture_start() success",__FUNCTION__); @@ -273,10 +83,11 @@ int audio_in_unprepare(audio_in_h input) { AUDIO_IO_NULL_ARG_CHECK(input); audio_in_s *handle = (audio_in_s *) input; + int ret = MM_ERROR_NONE; - int ret = mm_sound_pcm_capture_stop(handle->mm_handle); + ret = mm_sound_pcm_capture_stop(handle->mm_handle); if (ret != MM_ERROR_NONE) { - return __convert_error_code(ret, (char*)__FUNCTION__); + return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); } LOGI("[%s] mm_sound_pcm_capture_stop() success",__FUNCTION__); @@ -292,10 +103,8 @@ int audio_in_read(audio_in_h input, void *buffer, unsigned int length ) int result = 0; ret = mm_sound_pcm_capture_read(handle->mm_handle, (void*) buffer, length); - if (ret > 0) { - LOGI("[%s] (%d/%d) bytes read" ,__FUNCTION__, ret, length); + if (ret > 0) return ret; - } switch(ret) { @@ -304,7 +113,7 @@ int audio_in_read(audio_in_h input, void *buffer, unsigned int length ) LOGE("[%s] (0x%08x) : Not recording started yet.",(char*)__FUNCTION__, AUDIO_IO_ERROR_INVALID_OPERATION); break; default: - result = __convert_error_code(ret, (char*)__FUNCTION__); + result = __convert_audio_io_error_code(ret, (char*)__FUNCTION__); break; } return result; @@ -392,69 +201,54 @@ int audio_in_ignore_session(audio_in_h input) ret = mm_sound_pcm_capture_ignore_session(handle->mm_handle); if (ret != MM_ERROR_NONE) { - return __convert_error_code(ret, (char*)__FUNCTION__); + return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); } LOGI("[%s] mm_sound_pcm_capture_ignore_session() success",__FUNCTION__); return AUDIO_IO_ERROR_NONE; } -/* Audio Out */ -int audio_out_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, sound_type_e sound_type, audio_out_h* output) +int audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* userdata) { - audio_out_s *handle = NULL; - int ret = 0; +/* TODO : it will be added after updating libmm-sound */ + return AUDIO_IO_ERROR_NONE; +} - /* input condition check */ - AUDIO_IO_NULL_ARG_CHECK(output); - if(__check_parameter(sample_rate, channel, type)!=AUDIO_IO_ERROR_NONE) - return AUDIO_IO_ERROR_INVALID_PARAMETER; - if(sound_type < SOUND_TYPE_SYSTEM || sound_type > SOUND_TYPE_CALL) { - LOGE("[%s] ERROR : AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) : Invalid sample sound type : %d" ,__FUNCTION__,AUDIO_IO_ERROR_INVALID_PARAMETER,sound_type ); - return AUDIO_IO_ERROR_INVALID_PARAMETER; - } - - /* Create Handle */ - handle = (audio_out_s*)malloc( sizeof(audio_out_s)); - if (handle != NULL) { - memset(handle, 0 , sizeof(audio_out_s)); - } else { - LOGE("[%s] ERROR : AUDIO_IO_ERROR_OUT_OF_MEMORY(0x%08x)" ,__FUNCTION__,AUDIO_IO_ERROR_OUT_OF_MEMORY ); - return AUDIO_IO_ERROR_OUT_OF_MEMORY; - } - ret = mm_sound_pcm_play_open(&handle->mm_handle,sample_rate, channel, type, sound_type); - if( ret < 0) { - free (handle); - return __convert_error_code(ret, (char*)__FUNCTION__); - } - LOGI("[%s] mm_sound_pcm_play_open() success",__FUNCTION__); - - /* Fill information */ - *output = (audio_out_h)handle; - handle->_buffer_size = ret; - handle->_sample_rate = sample_rate; - handle->_channel = channel; - handle->_type = type; - handle->_sound_type = sound_type; - - /* Set message interrupt callback */ - ret = mm_sound_pcm_set_message_callback(handle->mm_handle, __mm_sound_pcm_playback_msg_cb, handle); - if( ret < 0) { - return __convert_error_code(ret, (char*)__FUNCTION__); - } - LOGI("[%s] mm_sound_pcm_set_message_callback() success",__FUNCTION__); +int audio_in_unset_stream_cb(audio_in_h input) +{ +/* TODO : it will be added after updating libmm-sound */ + return AUDIO_IO_ERROR_NONE; +} + +int audio_in_peek(audio_in_h input, const void **buffer, unsigned int *length) +{ +/* TODO : it will be added after updating libmm-sound */ + return AUDIO_IO_ERROR_NONE; +} +int audio_in_drop(audio_in_h input) +{ +/* TODO : it will be added after updating libmm-sound */ return AUDIO_IO_ERROR_NONE; } + +/* Audio Out */ +int audio_out_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, sound_type_e sound_type, audio_out_h* output) +{ + return audio_out_create_private(sample_rate, channel, type, sound_type, output); +} + int audio_out_destroy(audio_out_h output) { AUDIO_IO_NULL_ARG_CHECK(output); audio_out_s *handle = (audio_out_s *) output; + int ret = MM_ERROR_NONE; - int ret = mm_sound_pcm_play_close(handle->mm_handle); + ret = mm_sound_pcm_play_close(handle->mm_handle); if (ret != MM_ERROR_NONE) { - return __convert_error_code(ret, (char*)__FUNCTION__); + free(handle); + return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); } free(handle); @@ -466,10 +260,11 @@ int audio_out_prepare(audio_out_h output) { AUDIO_IO_NULL_ARG_CHECK(output); audio_out_s *handle = (audio_out_s *) output; + int ret = MM_ERROR_NONE; - int ret = mm_sound_pcm_play_start(handle->mm_handle); + ret = mm_sound_pcm_play_start(handle->mm_handle); if (ret != MM_ERROR_NONE) { - return __convert_error_code(ret, (char*)__FUNCTION__); + return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); } LOGI("[%s] mm_sound_pcm_play_start() success",__FUNCTION__); @@ -480,10 +275,11 @@ int audio_out_unprepare(audio_out_h output) { AUDIO_IO_NULL_ARG_CHECK(output); audio_out_s *handle = (audio_out_s *) output; + int ret = MM_ERROR_NONE; - int ret = mm_sound_pcm_play_stop(handle->mm_handle); + ret = mm_sound_pcm_play_stop(handle->mm_handle); if (ret != MM_ERROR_NONE) { - return __convert_error_code(ret, (char*)__FUNCTION__); + return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); } LOGI("[%s] mm_sound_pcm_play_stop() success",__FUNCTION__); @@ -495,8 +291,9 @@ int audio_out_write(audio_out_h output, void* buffer, unsigned int length) AUDIO_IO_NULL_ARG_CHECK(output); AUDIO_IO_NULL_ARG_CHECK(buffer); audio_out_s *handle = (audio_out_s *) output; + int ret = MM_ERROR_NONE; - int ret = mm_sound_pcm_play_write(handle->mm_handle, (void*) buffer, length); + ret = mm_sound_pcm_play_write(handle->mm_handle, (void*) buffer, length); if (ret > 0) { LOGI("[%s] (%d/%d) bytes written" ,__FUNCTION__, ret, length); return ret; @@ -508,7 +305,7 @@ int audio_out_write(audio_out_h output, void* buffer, unsigned int length) LOGE("[%s] (0x%08x) : Not playing started yet.",(char*)__FUNCTION__, AUDIO_IO_ERROR_INVALID_OPERATION); break; default: - ret = __convert_error_code(ret, (char*)__FUNCTION__); + ret = __convert_audio_io_error_code(ret, (char*)__FUNCTION__); break; } return ret; @@ -612,9 +409,21 @@ int audio_out_ignore_session(audio_out_h output) ret = mm_sound_pcm_play_ignore_session(handle->mm_handle); if (ret != MM_ERROR_NONE) { - return __convert_error_code(ret, (char*)__FUNCTION__); + return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); } LOGI("[%s] mm_sound_pcm_play_ignore_session() success",__FUNCTION__); return AUDIO_IO_ERROR_NONE; } + +int audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* userdata) +{ +/* TODO : it will be added after updating libmm-sound */ + return AUDIO_IO_ERROR_NONE; +} + +int audio_out_unset_stream_cb(audio_out_h output) +{ +/* TODO : it will be added after updating libmm-sound */ + return AUDIO_IO_ERROR_NONE; +} diff --git a/src/audio_io_private.c b/src/audio_io_private.c new file mode 100755 index 0000000..718f417 --- /dev/null +++ b/src/audio_io_private.c @@ -0,0 +1,325 @@ +/* +* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include +#include +#include +#include +#include "audio_io_private.h" +#include +/* TODO : it will be added after updating libmm-sound */ +//#include + + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "TIZEN_N_AUDIO_IO" +/* +* Internal Implementation +*/ +int __convert_audio_io_error_code(int code, char *func_name) +{ + int ret = AUDIO_IO_ERROR_INVALID_OPERATION; + char* msg = "AUDIO_IO_ERROR_INVALID_OPERATION"; + + switch(code) + { + case MM_ERROR_NONE: + ret = AUDIO_IO_ERROR_NONE; + msg = "AUDIO_IO_ERROR_NONE"; + break; + case MM_ERROR_INVALID_ARGUMENT: + case MM_ERROR_SOUND_DEVICE_INVALID_SAMPLERATE: + case MM_ERROR_SOUND_DEVICE_INVALID_CHANNEL: + case MM_ERROR_SOUND_DEVICE_INVALID_FORMAT: + ret = AUDIO_IO_ERROR_INVALID_PARAMETER; + msg = "AUDIO_IO_ERROR_INVALID_PARAMETER"; + break; + case MM_ERROR_SOUND_DEVICE_NOT_OPENED: + ret = AUDIO_IO_ERROR_DEVICE_NOT_OPENED; + msg = "AUDIO_IO_ERROR_DEVICE_NOT_OPENED"; + break; + case MM_ERROR_SOUND_PERMISSION_DENIED: + ret = AUDIO_IO_ERROR_PERMISSION_DENIED; + msg = "AUDIO_IO_ERROR_PERMISSION_DENIED"; + break; + case MM_ERROR_SOUND_INTERNAL: + ret = AUDIO_IO_ERROR_INVALID_OPERATION; + msg = "AUDIO_IO_ERROR_INVALID_OPERATION"; + break; + case MM_ERROR_SOUND_INVALID_POINTER: + ret = AUDIO_IO_ERROR_INVALID_BUFFER; + msg = "AUDIO_IO_ERROR_INVALID_BUFFER"; + break; + case MM_ERROR_POLICY_BLOCKED: + case MM_ERROR_POLICY_INTERRUPTED: + case MM_ERROR_POLICY_INTERNAL: + case MM_ERROR_POLICY_DUPLICATED: + ret = AUDIO_IO_ERROR_SOUND_POLICY; + msg = "AUDIO_IO_ERROR_SOUND_POLICY"; + break; + } + LOGE("[%s] %s(0x%08x) : core fw error(0x%x)",func_name,msg, ret, code); + return ret; +} + +int __check_parameter(int sample_rate, audio_channel_e channel, audio_sample_type_e type) +{ + if(sample_rate<8000 || sample_rate > 48000) { + LOGE("[%s] AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) : Invalid sample rate (8000~48000Hz) : %d",__FUNCTION__, AUDIO_IO_ERROR_INVALID_PARAMETER,sample_rate); + return AUDIO_IO_ERROR_INVALID_PARAMETER; + } + if (channel < AUDIO_CHANNEL_MONO || channel > AUDIO_CHANNEL_STEREO) { + LOGE("[%s] AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) : Invalid audio channel : %d",__FUNCTION__, AUDIO_IO_ERROR_INVALID_PARAMETER,channel); + return AUDIO_IO_ERROR_INVALID_PARAMETER; + } + if (type < AUDIO_SAMPLE_TYPE_U8 || type > AUDIO_SAMPLE_TYPE_S16_LE) { + LOGE("[%s] AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) : Invalid sample typel : %d",__FUNCTION__, AUDIO_IO_ERROR_INVALID_PARAMETER,type); + return AUDIO_IO_ERROR_INVALID_PARAMETER; + } + return AUDIO_IO_ERROR_NONE; +} + +audio_io_interrupted_code_e __translate_interrupted_code (int code) +{ + audio_io_interrupted_code_e e = AUDIO_IO_INTERRUPTED_COMPLETED; + + switch(code) + { + case MM_MSG_CODE_INTERRUPTED_BY_CALL_END: + case MM_MSG_CODE_INTERRUPTED_BY_ALARM_END: + case MM_MSG_CODE_INTERRUPTED_BY_EMERGENCY_END: + case MM_MSG_CODE_INTERRUPTED_BY_NOTIFICATION_END: + e = AUDIO_IO_INTERRUPTED_COMPLETED; + break; + + case MM_MSG_CODE_INTERRUPTED_BY_MEDIA: + case MM_MSG_CODE_INTERRUPTED_BY_OTHER_PLAYER_APP: + e = AUDIO_IO_INTERRUPTED_BY_MEDIA; + break; + + case MM_MSG_CODE_INTERRUPTED_BY_CALL_START: + e = AUDIO_IO_INTERRUPTED_BY_CALL; + break; + + case MM_MSG_CODE_INTERRUPTED_BY_EARJACK_UNPLUG: + e = AUDIO_IO_INTERRUPTED_BY_EARJACK_UNPLUG; + break; + + case MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT: + e = AUDIO_IO_INTERRUPTED_BY_RESOURCE_CONFLICT; + break; + + case MM_MSG_CODE_INTERRUPTED_BY_ALARM_START: + e = AUDIO_IO_INTERRUPTED_BY_ALARM; + break; + + case MM_MSG_CODE_INTERRUPTED_BY_NOTIFICATION_START: + e = AUDIO_IO_INTERRUPTED_BY_NOTIFICATION; + break; + + case MM_MSG_CODE_INTERRUPTED_BY_EMERGENCY_START: + e = AUDIO_IO_INTERRUPTED_BY_EMERGENCY; + break; + + case MM_MSG_CODE_INTERRUPTED_BY_RESUMABLE_MEDIA: + e = AUDIO_IO_INTERRUPTED_BY_RESUMABLE_MEDIA; + break; + + case MM_MSG_CODE_INTERRUPTED_BY_RESUMABLE_CANCELED: + e = AUDIO_IO_INTERRUPTED_BY_RESUMABLE_CANCELED; + break; + } + + return e; +} + +int __mm_sound_pcm_capture_msg_cb (int message, void *param, void *user_param) +{ + audio_io_interrupted_code_e e = AUDIO_IO_INTERRUPTED_COMPLETED; + audio_in_s *handle = (audio_in_s *) user_param; + MMMessageParamType *msg = (MMMessageParamType*)param; + + LOGI("[%s] Got message type : 0x%x with code : %d" ,__FUNCTION__, message, msg->code); + + if (handle->user_cb == NULL) { + LOGI("[%s] No interrupt callback is set. Skip this" ,__FUNCTION__); + return 0; + } + + if (message == MM_MESSAGE_SOUND_PCM_INTERRUPTED) { + e = __translate_interrupted_code (msg->code); + } else if (message == MM_MESSAGE_SOUND_PCM_CAPTURE_RESTRICTED) { + /* TODO : handling restricted code is needed */ + /* e = _translate_restricted_code (msg->code); */ + } + + handle->user_cb (e, handle->user_data); + + return 0; +} + +static int __mm_sound_pcm_playback_msg_cb (int message, void *param, void *user_param) +{ + audio_io_interrupted_code_e e = AUDIO_IO_INTERRUPTED_COMPLETED; + audio_out_s *handle = (audio_out_s *) user_param; + MMMessageParamType *msg = (MMMessageParamType*)param; + + LOGI("[%s] Got message type : 0x%x with code : %d" ,__FUNCTION__, message, msg->code); + + if (handle->user_cb == NULL) { + LOGI("[%s] No interrupt callback is set. Skip this" ,__FUNCTION__); + return 0; + } + + if (message == MM_MESSAGE_SOUND_PCM_INTERRUPTED) { + e = __translate_interrupted_code (msg->code); + } + + handle->user_cb (e, handle->user_data); + + return 0; +} + +/* TODO : it will be added after updating libmm-sound */ +//static int __audio_in_stream_cb (void* p, int nbytes, void* userdata) +//{ +// return 0; +//} + +//static int __audio_out_stream_cb (void* p, int nbytes, void* userdata) +//{ + +// return 0; +//} + + +int audio_in_create_private(int sample_rate, audio_channel_e channel, audio_sample_type_e type , audio_in_h* input) +{ + int ret = 0; + audio_in_s *handle = NULL; + + /* input condition check */ + AUDIO_IO_NULL_ARG_CHECK(input); + if(__check_parameter(sample_rate, channel, type) != AUDIO_IO_ERROR_NONE) + return AUDIO_IO_ERROR_INVALID_PARAMETER; + + /* Create Handle & Fill information */ + if ((handle = (audio_in_s*)malloc( sizeof(audio_in_s))) == NULL) { + LOGE("ERROR : AUDIO_IO_ERROR_OUT_OF_MEMORY(0x%08x)", AUDIO_IO_ERROR_OUT_OF_MEMORY); + return AUDIO_IO_ERROR_OUT_OF_MEMORY; + } + memset(handle, 0, sizeof(audio_in_s)); + + + /* Capture open */ + if ((ret = mm_sound_pcm_capture_open( &handle->mm_handle,sample_rate, channel, type)) < 0) { + LOGE("mm_sound_pcm_capture_open_ex() failed [0x%x]", ret); + goto ERROR; + } + LOGI("mm_sound_pcm_capture_open_ex() success"); + + handle->_buffer_size = ret; /* return by pcm_open */ + handle->_sample_rate = sample_rate; + handle->_channel = channel; + handle->_type = type; + + /* Set message interrupt callback */ + if ((ret = mm_sound_pcm_set_message_callback(handle->mm_handle, __mm_sound_pcm_capture_msg_cb, handle)) < 0) { + LOGE("mm_sound_pcm_set_message_callback() failed [0x%x]", ret); + goto ERROR; + } + LOGI("mm_sound_pcm_set_message_callback() success"); + + /* Handle assign */ + *input = (audio_in_h)handle; + + return AUDIO_IO_ERROR_NONE; + +ERROR: + if (handle) + free (handle); + return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); +} + +int audio_in_set_callback_private(audio_in_h input, audio_in_stream_cb callback, void* userdata) +{ +/* TODO : it will be added after updating libmm-sound */ + + return AUDIO_IO_ERROR_NONE; +} + +int audio_out_create_private(int sample_rate, audio_channel_e channel, audio_sample_type_e type, sound_type_e sound_type, audio_out_h* output) +{ + audio_out_s *handle = NULL; + int ret = 0; + + /* input condition check */ + AUDIO_IO_NULL_ARG_CHECK(output); + if(__check_parameter(sample_rate, channel, type)!=AUDIO_IO_ERROR_NONE) + return AUDIO_IO_ERROR_INVALID_PARAMETER; + if(sound_type < SOUND_TYPE_SYSTEM || sound_type > SOUND_TYPE_CALL) { + LOGE("ERROR : AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) : Invalid sample sound type : %d", + AUDIO_IO_ERROR_INVALID_PARAMETER,sound_type ); + return AUDIO_IO_ERROR_INVALID_PARAMETER; + } + + /* Create Handle & Fill information */ + if ((handle = (audio_out_s*)malloc( sizeof(audio_out_s))) == NULL) { + LOGE("ERROR : AUDIO_IO_ERROR_OUT_OF_MEMORY(0x%08x)", AUDIO_IO_ERROR_OUT_OF_MEMORY); + return AUDIO_IO_ERROR_OUT_OF_MEMORY; + } + memset(handle, 0 , sizeof(audio_out_s)); + + + if ((ret = mm_sound_pcm_play_open(&handle->mm_handle,sample_rate, channel, type, sound_type)) < 0) { + LOGE("mm_sound_pcm_play_open() failed [0x%x]", ret); + goto ERROR; + } + LOGI("mm_sound_pcm_play_open() success"); + + + handle->_buffer_size = ret; /* return by pcm_open */ + handle->_sample_rate = sample_rate; + handle->_channel = channel; + handle->_type = type; + handle->_sound_type = sound_type; + + /* Set message interrupt callback */ + if ((ret = mm_sound_pcm_set_message_callback(handle->mm_handle, __mm_sound_pcm_playback_msg_cb, handle)) < 0) { + LOGE("mm_sound_pcm_set_message_callback() failed [0x%x]", ret); + goto ERROR; + } + LOGI("mm_sound_pcm_set_message_callback() success"); + + /* Handle assign */ + *output = (audio_out_h)handle; + + return AUDIO_IO_ERROR_NONE; + +ERROR: + if (handle) + free (handle); + return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); +} + +int audio_out_set_callback_private(audio_out_h output, audio_out_stream_cb callback, void* userdata) +{ +/* TODO : it will be added after updating libmm-sound */ + + return AUDIO_IO_ERROR_NONE; +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 795370d..0d11160 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,7 +6,7 @@ FOREACH(flag ${${fw_test}_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -Werror") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall") aux_source_directory(. sources) FOREACH(src ${sources}) -- 2.34.1