From: KimJeongYeon Date: Tue, 7 Jul 2015 04:33:07 +0000 (+0900) Subject: audio-io sync branch of tizen_2.4 X-Git-Tag: accepted/tizen/mobile/20150708.015308^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2f358b1f5748aa5f6f79b4fe1bbf4ce94b23254b;p=platform%2Fcore%2Fapi%2Faudio-io.git audio-io sync branch of tizen_2.4 [Version] 0.2.3 [Profile] Common [Issue Type] Add features [Dependency module] NA [Dependency commit] NA [Comment] Signed-off-by: KimJeongYeon Change-Id: Ic4a98fa254643c4662829c4a9c8969d3c5e006c0 --- diff --git a/include/audio_io.h b/include/audio_io.h index b797d2d..067cddc 100644 --- a/include/audio_io.h +++ b/include/audio_io.h @@ -11,7 +11,7 @@ * 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. +* limitations under the License. */ #ifndef __TIZEN_MEDIA_AUDIO_IO_H__ @@ -38,7 +38,7 @@ extern "C" /** * @brief The audio input handle. - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ typedef struct audio_in_s *audio_in_h; @@ -50,10 +50,10 @@ typedef struct audio_in_s *audio_in_h; * @addtogroup CAPI_MEDIA_AUDIO_OUT_MODULE * @{ */ - + /** * @brief The audio output handle. - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ typedef struct audio_out_s *audio_out_h; @@ -68,7 +68,7 @@ typedef struct audio_out_s *audio_out_h; /** * @brief Enumeration for audio sample type with bit depth. - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ typedef enum { @@ -78,7 +78,7 @@ typedef enum /** * @brief Enumeration for audio channel. - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ typedef enum { AUDIO_CHANNEL_MONO = 0x80, /**< 1 channel, mono */ @@ -87,7 +87,7 @@ typedef enum { /** * @brief Enumeration for audio input and output error. - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ typedef enum{ AUDIO_IO_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ @@ -104,7 +104,7 @@ typedef enum{ /** * @brief Enumeration for audio IO interrupted messages. - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ typedef enum { @@ -121,7 +121,7 @@ typedef enum /** * @brief Called when audio input or output is interrupted. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] error_code The interrupted error code * @param[in] user_data The user data passed from the callback registration function * @@ -148,7 +148,7 @@ typedef void (*audio_io_interrupted_cb)(audio_io_interrupted_code_e code, void * /** * @brief Called when audio input data is available in asynchronous(event) mode. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @remarks @a use audio_in_peek() to get audio in data inside callback, use audio_in_drop() after use of peeked data. * @@ -163,7 +163,7 @@ typedef void (*audio_in_stream_cb)(audio_in_h handle, size_t nbytes, void *userd /** * @brief Creates an audio device instance and returns an input handle to record PCM (pulse-code modulation) data. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @privlevel public * @privilege %http://tizen.org/privilege/recorder * @@ -171,10 +171,10 @@ typedef void (*audio_in_stream_cb)(audio_in_h handle, size_t nbytes, void *userd * * @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 is created on success + * @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 is created on success * @return @c 0 on success, * otherwise a negative error value * @retval #AUDIO_IO_ERROR_NONE Successful @@ -191,7 +191,7 @@ int audio_in_create(int sample_rate, audio_channel_e channel, audio_sample_type_ /** * @brief Creates an audio loopback device instance and returns an input handle to record PCM (pulse-code modulation) data. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @privlevel public * @privilege %http://tizen.org/privilege/recorder * @@ -199,10 +199,10 @@ int audio_in_create(int sample_rate, audio_channel_e channel, audio_sample_type_ * * @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 + * @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 @@ -219,7 +219,7 @@ int audio_in_create_loopback(int sample_rate, audio_channel_e channel, audio_sam /** * @brief Releases the audio input handle and all its resources associated with an audio stream. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] input The handle to the audio input to destroy * @return @c 0 on success, @@ -235,7 +235,7 @@ int audio_in_destroy(audio_in_h input); /** * @brief Prepares reading audio input by starting buffering of audio data from the device. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] input The handle to the audio input * @return @c 0 on success, @@ -251,7 +251,7 @@ int audio_in_prepare(audio_in_h input); /** * @brief Unprepares reading audio input by stopping buffering the audio data from the device. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] input The handle to the audio input * @return @c 0 on success, @@ -274,16 +274,13 @@ int audio_in_unprepare(audio_in_h input); * @retval #AUDIO_IO_ERROR_NONE Successful * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter * @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported - * @retval #AUDIO_IO_ERROR_INVALID_STATE Invalid state - * - * @pre The state should be #AUDIO_IO_STATE_RUNNING or #AUDIO_IO_STATE_PAUSED. */ int audio_in_flush(audio_in_h input); /** * @brief Reads audio data from the audio input buffer. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] input The handle to the audio input * @param[out] buffer The PCM buffer address @@ -302,7 +299,7 @@ int audio_in_read(audio_in_h input, void *buffer, unsigned int length); /** * @brief Gets the size to be allocated for the audio input buffer. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] input The handle to the audio input * @param[out] size The buffer size (in bytes, the maximum size is 1 MB) @@ -318,7 +315,7 @@ int audio_in_get_buffer_size(audio_in_h input, int *size); /** * @brief Gets the sample rate of the audio input data stream. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] input The handle to the audio input * @param[out] sample_rate The audio sample rate in Hertz (8000 ~ 48000) @@ -333,7 +330,7 @@ int audio_in_get_sample_rate(audio_in_h input, int *sample_rate); /** * @brief Gets the channel type of the audio input data stream. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @details The audio channel type defines whether the audio is mono or stereo. * @@ -350,7 +347,7 @@ int audio_in_get_channel(audio_in_h input, audio_channel_e *channel); /** * @brief Gets the sample audio format (8-bit or 16-bit) of the audio input data stream. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] input The handle to the audio input * @param[out] type The audio sample type @@ -365,7 +362,7 @@ int audio_in_get_sample_type(audio_in_h input, audio_sample_type_e *type); /** * @brief Registers a callback function to be invoked when the audio input handle is interrupted or the interrupt is completed. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] input The handle to the audio input * @param[in] callback The callback function to register @@ -386,7 +383,7 @@ int audio_in_set_interrupted_cb(audio_in_h input, audio_io_interrupted_cb callba /** * @brief Unregisters the callback function. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] input The handle to the audio input * @return @c 0 on success, @@ -403,7 +400,7 @@ int audio_in_unset_interrupted_cb(audio_in_h input); /** * @brief Ignores session for input. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] input The handle to the audio input * @return @c 0 on success, @@ -418,7 +415,7 @@ int audio_in_ignore_session(audio_in_h input); /** * @brief Sets an asynchronous(event) callback function to handle recording PCM (pulse-code modulation) data. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @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. @@ -447,7 +444,7 @@ int audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* /** * @brief Unregisters the callback function. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] input The handle to the audio input * @return @c 0 on success, @@ -464,7 +461,7 @@ int audio_in_unset_stream_cb(audio_in_h input); /** * @brief peek from audio in buffer * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @details This function works correctly only with read, write callback. Otherwise it won't operate as intended. * @@ -489,7 +486,7 @@ int audio_in_peek(audio_in_h input, const void **buffer, unsigned int *length); * * @details This function works correctly only with read, write callback. Otherwise it won't operate as intended. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @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. * @@ -522,7 +519,7 @@ int audio_in_drop(audio_in_h input); /** * @brief Called when audio out data can be written in asynchronous(event) mode. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @remarks @a use audio_out_write() to write pcm data inside this callback. * @param[in] handle The handle to the audio output @@ -536,7 +533,7 @@ typedef void (*audio_out_stream_cb)(audio_out_h handle, size_t nbytes, void *use /** * @brief Creates an audio device instance and returns an output handle to play PCM (pulse-code modulation) data. - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @details This function is used for audio output initialization. * @@ -562,7 +559,7 @@ int audio_out_create(int sample_rate, audio_channel_e channel, audio_sample_type /** * @brief Releases the audio output handle, along with all its resources. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] output The handle to the audio output to destroy * @return @c 0 on success, @@ -579,7 +576,7 @@ int audio_out_destroy(audio_out_h output); /** * @brief Prepares playing audio output, this must be called before audio_out_write(). * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] output The handle to the audio output * @return @c 0 on success, @@ -594,7 +591,7 @@ int audio_out_prepare(audio_out_h output); /** * @brief Unprepares playing audio output. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] output The handle to the audio output * @return @c 0 on success, @@ -618,9 +615,7 @@ int audio_out_unprepare(audio_out_h output); * otherwise a negative error value * @retval #AUDIO_IO_ERROR_NONE Successful * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #AUDIO_IO_ERROR_INVALID_STATE Invalid state * - * @pre The state should be #AUDIO_IO_STATE_RUNNING or #AUDIO_IO_STATE_PAUSED. * @see audio_out_flush() */ int audio_out_drain(audio_out_h output); @@ -635,9 +630,7 @@ int audio_out_drain(audio_out_h output); * otherwise a negative error value * @retval #AUDIO_IO_ERROR_NONE Successful * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #AUDIO_IO_ERROR_INVALID_STATE Invalid state * - * @pre The state should be #AUDIO_IO_STATE_RUNNING or #AUDIO_IO_STATE_PAUSED. * @see audio_out_drain() */ int audio_out_flush(audio_out_h output); @@ -645,7 +638,7 @@ int audio_out_flush(audio_out_h output); /** * @brief Starts writing the audio data to the device. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] output The handle to the audio output * @param[in,out] buffer The PCM buffer address @@ -661,7 +654,7 @@ int audio_out_write(audio_out_h output, void *buffer, unsigned int length); /** * @brief Gets the size to be allocated for the audio output buffer. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] output The handle to the audio output * @param[out] size The suggested buffer size (in bytes, the maximum size is 1 MB) @@ -677,7 +670,7 @@ int audio_out_get_buffer_size(audio_out_h output, int *size); /** * @brief Gets the sample rate of the audio output data stream. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] output The handle to the audio output * @param[out] sample_rate The audio sample rate in Hertz (8000 ~ 48000) @@ -692,7 +685,7 @@ int audio_out_get_sample_rate(audio_out_h output, int *sample_rate); * @brief Gets the channel type of the audio output data stream. * @details The audio channel type defines whether the audio is mono or stereo. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] output The handle to the audio output * @param[out] channel The audio channel type @@ -706,7 +699,7 @@ int audio_out_get_channel(audio_out_h output, audio_channel_e *channel); /** * @brief Gets the sample audio format (8-bit or 16-bit) of the audio output data stream. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] output The handle to the audio output * @param[out] type The audio sample type @@ -721,7 +714,7 @@ int audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type); /** * @brief Gets the sound type supported by the audio output device. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] output The handle to the audio output * @param[out] type The sound type @@ -735,11 +728,11 @@ int audio_out_get_sound_type(audio_out_h output, sound_type_e *type); /** * @brief Registers a callback function to be invoked when the audio output handle is interrupted or the interrupt is completed. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] output The handle to the audio output - * @param[in] callback The callback function to register - * @param[in] user_data The user data to be passed to the callback function + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, * otherwise a negative error value * @retval #AUDIO_IO_ERROR_NONE Successful @@ -755,7 +748,7 @@ int audio_out_set_interrupted_cb(audio_out_h output, audio_io_interrupted_cb cal /** * @brief Unregisters the callback function. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] output The handle to the audio output * @return @c 0 on success, @@ -771,7 +764,7 @@ int audio_out_unset_interrupted_cb(audio_out_h output); /** * @brief Ignores session for output. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] output The handle to the audio output * @return @c 0 on success, @@ -785,7 +778,7 @@ int audio_out_ignore_session(audio_out_h output); /** * @brief Sets an asynchronous(event) callback function to handle playing PCM (pulse-code modulation) data. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @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. @@ -812,7 +805,7 @@ int audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, vo /** * @brief Unregisters the callback function. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] output The handle to the audio output * @return 0 on success, otherwise a negative error value diff --git a/include/audio_io_private.h b/include/audio_io_private.h old mode 100755 new mode 100644 index 880734b..8ce9181 --- a/include/audio_io_private.h +++ b/include/audio_io_private.h @@ -11,14 +11,14 @@ * 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. +* limitations under the License. */ #ifndef __TIZEN_MEDIA_AUDIO_IO_PRIVATE_H__ -#define __TIZEN_MEDIA_AUDIO_IO_PRIVATE_H__ -#include +#define __TIZEN_MEDIA_AUDIO_IO_PRIVATE_H__ #include #include +#include "audio_io.h" /* * Internal Macros @@ -38,10 +38,10 @@ extern "C" { #endif - typedef struct _audio_in_s{ MMSoundPcmHandle_t mm_handle; - + int is_async; + int is_loopback; int _buffer_size; int _sample_rate; audio_channel_e _channel; @@ -54,11 +54,12 @@ typedef struct _audio_in_s{ typedef struct _audio_out_s{ MMSoundPcmHandle_t mm_handle; - + int is_async; + int is_loopback; int _buffer_size; int _sample_rate; audio_channel_e _channel; - audio_sample_type_e _type; + audio_sample_type_e _type; sound_type_e _sound_type; audio_io_interrupted_cb user_cb; void* user_data; @@ -71,7 +72,7 @@ int __check_parameter(int sample_rate, audio_channel_e channel, audio_sample_typ 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_create_private(int sample_rate, audio_channel_e channel, audio_sample_type_e type , int source_type, audio_in_h* input); int audio_in_set_callback_private(audio_in_h input, audio_in_stream_cb callback, void* userdata); diff --git a/packaging/capi-media-audio-io.spec b/packaging/capi-media-audio-io.spec index fe26901..f873d97 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.2 +Version: 0.2.3 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/audio_io.c b/src/audio_io.c index 6b29ada..54a7f1e 100644 --- a/src/audio_io.c +++ b/src/audio_io.c @@ -11,22 +11,22 @@ * 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. +* limitations under the License. */ #include #include #include #include -#include +#include "audio_io_private.h" #include #ifdef LOG_TAG #undef LOG_TAG #endif #define LOG_TAG "TIZEN_N_AUDIO_IO" -/* TODO : it will be added after updating libmm-sound */ -//#include + +#include /* * Internal Implementation */ @@ -39,12 +39,12 @@ /* Audio In */ int audio_in_create(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); + return audio_in_create_private (sample_rate, channel, type, SUPPORT_SOURCE_TYPE_DEFAULT, input); } 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); + return audio_in_create_private (sample_rate, channel, type, SUPPORT_SOURCE_TYPE_LOOPBACK, input); } int audio_in_destroy(audio_in_h input) @@ -53,7 +53,11 @@ int audio_in_destroy(audio_in_h input) audio_in_s *handle = (audio_in_s *) input; int ret = MM_ERROR_NONE; - ret = mm_sound_pcm_capture_close(handle->mm_handle); + if (handle->is_async) { + ret = mm_sound_pcm_capture_close_async(handle->mm_handle); + } else { + ret = mm_sound_pcm_capture_close(handle->mm_handle); + } if (ret != MM_ERROR_NONE) { free(handle); return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); @@ -70,7 +74,12 @@ int audio_in_prepare(audio_in_h input) audio_in_s *handle = (audio_in_s *) input; int ret = MM_ERROR_NONE; - ret = mm_sound_pcm_capture_start(handle->mm_handle); + if (handle->is_async) { + ret = mm_sound_pcm_capture_start_async(handle->mm_handle); + } else { + ret = mm_sound_pcm_capture_start(handle->mm_handle); + } + if (ret != MM_ERROR_NONE) { return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); } @@ -85,7 +94,11 @@ int audio_in_unprepare(audio_in_h input) audio_in_s *handle = (audio_in_s *) input; int ret = MM_ERROR_NONE; - ret = mm_sound_pcm_capture_stop(handle->mm_handle); + if (handle->is_async) { + ret = mm_sound_pcm_capture_stop_async(handle->mm_handle); + } else { + ret = mm_sound_pcm_capture_stop(handle->mm_handle); + } if (ret != MM_ERROR_NONE) { return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); } @@ -100,7 +113,11 @@ int audio_in_flush(audio_in_h input) audio_in_s *handle = (audio_in_s *) input; int ret = MM_ERROR_NONE; - ret = mm_sound_pcm_capture_flush(handle->mm_handle); + if (handle->is_async) { + ret = mm_sound_pcm_capture_flush_async(handle->mm_handle); + } else { + ret = mm_sound_pcm_capture_flush(handle->mm_handle); + } if (ret != MM_ERROR_NONE) { return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); } @@ -117,6 +134,11 @@ int audio_in_read(audio_in_h input, void *buffer, unsigned int length ) int ret = 0; int result = 0; + if (handle->is_async) { + LOGE ("audio_in_read doesn't operate in async mode!!!, use audio_in_peek/audio_in_drop instead"); + return AUDIO_IO_ERROR_INVALID_OPERATION; + } + ret = mm_sound_pcm_capture_read(handle->mm_handle, (void*) buffer, length); if (ret > 0) return ret; @@ -214,6 +236,11 @@ int audio_in_ignore_session(audio_in_h input) audio_in_s * handle = (audio_in_s *) input; int ret = 0; + if (handle->is_async) { + LOGE ("Not supported in async mode"); + return AUDIO_IO_ERROR_INVALID_OPERATION; + } + ret = mm_sound_pcm_capture_ignore_session(handle->mm_handle); if (ret != MM_ERROR_NONE) { return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); @@ -225,26 +252,74 @@ int audio_in_ignore_session(audio_in_h input) int audio_in_set_stream_cb(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; + AUDIO_IO_NULL_ARG_CHECK(input); + AUDIO_IO_NULL_ARG_CHECK(callback); + return audio_in_set_callback_private(input, callback, userdata); } int audio_in_unset_stream_cb(audio_in_h input) { -/* TODO : it will be added after updating libmm-sound */ - return AUDIO_IO_ERROR_NONE; + AUDIO_IO_NULL_ARG_CHECK(input); + return audio_in_set_callback_private(input, NULL, NULL); } 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; + AUDIO_IO_NULL_ARG_CHECK(input); + AUDIO_IO_NULL_ARG_CHECK(buffer); + audio_in_s *handle = (audio_in_s *) input; + int ret = 0; + int result = 0; + LOGE("handle->is_async : %d", handle->is_async); + if (!handle->is_async) { + LOGE ("audio_in_peek doesn't operate in poll mode!!!, use audio_in_read instead"); + return AUDIO_IO_ERROR_INVALID_OPERATION; + } + + LOGE("before mm_sound_pcm_capture_peek(handle[%p], buffer[%p], length[%d])", handle->mm_handle, buffer, length); + ret = mm_sound_pcm_capture_peek(handle->mm_handle, buffer, length); + LOGE("after mm_sound_pcm_capture_peek() ret[%d]", ret); + switch(ret) + { + case MM_ERROR_SOUND_INVALID_STATE: + result = AUDIO_IO_ERROR_INVALID_OPERATION; + LOGE("[%s] (0x%08x) : Not recording started yet.",(char*)__FUNCTION__, AUDIO_IO_ERROR_INVALID_OPERATION); + break; + default: + result = __convert_audio_io_error_code(ret, (char*)__FUNCTION__); + break; + } + return result; } int audio_in_drop(audio_in_h input) { -/* TODO : it will be added after updating libmm-sound */ - return AUDIO_IO_ERROR_NONE; + AUDIO_IO_NULL_ARG_CHECK(input); + audio_in_s *handle = (audio_in_s *) input; + int ret = 0; + int result = 0; + + if (!handle->is_async) { + LOGE ("audio_in_drop doesn't operate in poll mode!!!, use audio_in_read instead"); + return AUDIO_IO_ERROR_INVALID_OPERATION; + } + + ret = mm_sound_pcm_capture_drop(handle->mm_handle); + if (ret == MM_ERROR_NONE) { + return ret; + } + + switch(ret) + { + case MM_ERROR_SOUND_INVALID_STATE: + result = AUDIO_IO_ERROR_INVALID_OPERATION; + LOGE("[%s] (0x%08x) : Not recording started yet.",(char*)__FUNCTION__, AUDIO_IO_ERROR_INVALID_OPERATION); + break; + default: + result = __convert_audio_io_error_code(ret, (char*)__FUNCTION__); + break; + } + return result; } @@ -260,7 +335,11 @@ int audio_out_destroy(audio_out_h output) audio_out_s *handle = (audio_out_s *) output; int ret = MM_ERROR_NONE; - ret = mm_sound_pcm_play_close(handle->mm_handle); + if (handle->is_async) { + ret = mm_sound_pcm_play_close_async(handle->mm_handle); + } else { + ret = mm_sound_pcm_play_close(handle->mm_handle); + } if (ret != MM_ERROR_NONE) { free(handle); return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); @@ -277,7 +356,12 @@ int audio_out_prepare(audio_out_h output) audio_out_s *handle = (audio_out_s *) output; int ret = MM_ERROR_NONE; - ret = mm_sound_pcm_play_start(handle->mm_handle); + if (handle->is_async) { + ret = mm_sound_pcm_play_start_async(handle->mm_handle); + } else { + ret = mm_sound_pcm_play_start(handle->mm_handle); + } + if (ret != MM_ERROR_NONE) { return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); } @@ -292,7 +376,12 @@ int audio_out_unprepare(audio_out_h output) audio_out_s *handle = (audio_out_s *) output; int ret = MM_ERROR_NONE; - ret = mm_sound_pcm_play_stop(handle->mm_handle); + if (handle->is_async) { + ret = mm_sound_pcm_play_stop_async(handle->mm_handle); + } else { + ret = mm_sound_pcm_play_stop(handle->mm_handle); + } + if (ret != MM_ERROR_NONE) { return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); } @@ -307,7 +396,12 @@ int audio_out_drain(audio_out_h output) audio_out_s *handle = (audio_out_s *) output; int ret = MM_ERROR_NONE; - ret = mm_sound_pcm_play_drain(handle->mm_handle); + if (handle->is_async) { + ret = mm_sound_pcm_play_drain_async(handle->mm_handle); + } else { + ret = mm_sound_pcm_play_drain(handle->mm_handle); + } + if (ret != MM_ERROR_NONE) { return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); } @@ -322,7 +416,12 @@ int audio_out_flush(audio_out_h output) audio_out_s *handle = (audio_out_s *) output; int ret = MM_ERROR_NONE; - ret = mm_sound_pcm_play_flush(handle->mm_handle); + if (handle->is_async) { + ret = mm_sound_pcm_play_flush_async(handle->mm_handle); + } else { + ret = mm_sound_pcm_play_flush(handle->mm_handle); + } + if (ret != MM_ERROR_NONE) { return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); } @@ -338,11 +437,15 @@ int audio_out_write(audio_out_h output, void* buffer, unsigned int length) audio_out_s *handle = (audio_out_s *) output; int ret = MM_ERROR_NONE; - 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; + if (handle->is_async) { + ret = mm_sound_pcm_play_write_async(handle->mm_handle, (void*) buffer, length); + } else { + ret = mm_sound_pcm_play_write(handle->mm_handle, (void*) buffer, length); } + + if (ret > 0) + return ret; + switch(ret) { case MM_ERROR_SOUND_INVALID_STATE: @@ -356,7 +459,6 @@ int audio_out_write(audio_out_h output, void* buffer, unsigned int length) return ret; } - int audio_out_get_buffer_size(audio_out_h output, int *size) { AUDIO_IO_NULL_ARG_CHECK(output); @@ -369,7 +471,6 @@ int audio_out_get_buffer_size(audio_out_h output, int *size) return AUDIO_IO_ERROR_NONE; } - int audio_out_get_sample_rate(audio_out_h output, int *sample_rate) { AUDIO_IO_NULL_ARG_CHECK(output); @@ -382,7 +483,6 @@ int audio_out_get_sample_rate(audio_out_h output, int *sample_rate) return AUDIO_IO_ERROR_NONE; } - int audio_out_get_channel(audio_out_h output, audio_channel_e *channel) { AUDIO_IO_NULL_ARG_CHECK(output); @@ -395,7 +495,6 @@ int audio_out_get_channel(audio_out_h output, audio_channel_e *channel) return AUDIO_IO_ERROR_NONE; } - int audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type) { AUDIO_IO_NULL_ARG_CHECK(output); @@ -408,7 +507,6 @@ int audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type) return AUDIO_IO_ERROR_NONE; } - int audio_out_get_sound_type(audio_out_h output, sound_type_e *type) { AUDIO_IO_NULL_ARG_CHECK(output); @@ -452,6 +550,11 @@ int audio_out_ignore_session(audio_out_h output) audio_out_s *handle = (audio_out_s *) output; int ret = 0; + if (handle->is_async) { + LOGE ("Not supported in async mode"); + return AUDIO_IO_ERROR_INVALID_OPERATION; + } + ret = mm_sound_pcm_play_ignore_session(handle->mm_handle); if (ret != MM_ERROR_NONE) { return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); @@ -463,12 +566,13 @@ int audio_out_ignore_session(audio_out_h output) 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; + AUDIO_IO_NULL_ARG_CHECK(output); + AUDIO_IO_NULL_ARG_CHECK(callback); + return audio_out_set_callback_private(output, callback, userdata); } int audio_out_unset_stream_cb(audio_out_h output) { -/* TODO : it will be added after updating libmm-sound */ - return AUDIO_IO_ERROR_NONE; + AUDIO_IO_NULL_ARG_CHECK(output); + return audio_out_set_callback_private(output, NULL, NULL); } diff --git a/src/audio_io_private.c b/src/audio_io_private.c old mode 100755 new mode 100644 index 718f417..b56a6de --- a/src/audio_io_private.c +++ b/src/audio_io_private.c @@ -20,8 +20,8 @@ #include #include "audio_io_private.h" #include -/* TODO : it will be added after updating libmm-sound */ -//#include + +#include #ifdef LOG_TAG @@ -94,6 +94,7 @@ int __check_parameter(int sample_rate, audio_channel_e channel, audio_sample_typ return AUDIO_IO_ERROR_NONE; } +//LCOV_EXCL_START audio_io_interrupted_code_e __translate_interrupted_code (int code) { audio_io_interrupted_code_e e = AUDIO_IO_INTERRUPTED_COMPLETED; @@ -194,21 +195,58 @@ static int __mm_sound_pcm_playback_msg_cb (int message, void *param, void *user_ return 0; } +//LCOV_EXCL_STOP -/* 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_in_stream_cb (void* p, int nbytes, void* userdata) +{ + audio_in_s *handle = (audio_in_s *) userdata; -//static int __audio_out_stream_cb (void* p, int nbytes, void* userdata) -//{ + LOGI("<< p=%p, nbytes=%d, userdata=%p", p, nbytes, userdata); -// return 0; -//} + if (handle && handle->stream_cb) { + handle->stream_cb ((audio_in_h)handle, nbytes, handle->stream_userdata); + LOGI("<< handle->stream_cb(handle:%p, nbytes:%d, handle->stream_userdata:%p)", p, nbytes, userdata); + } else { + LOGI("No stream callback is set. Skip this"); + } + return 0; +} +static int __audio_out_stream_cb (void* p, int nbytes, void* userdata) +{ + audio_out_s *handle = (audio_out_s *) userdata; + bool is_started = false; + char * dummy = NULL; + + LOGI(">> p=%p, nbytes=%d, userdata=%p", p, nbytes, userdata); + + if (handle) { + mm_sound_pcm_is_started_async(handle->mm_handle, &is_started); + if (is_started) { + if (handle->stream_cb) { + handle->stream_cb ((audio_out_h)handle, nbytes, handle->stream_userdata); + } else { + LOGI("Started state but No stream callback is set. Skip this"); + } + } else { + LOGI("Not started....write dummy data"); + if ((dummy = (char*)malloc(nbytes)) != NULL) { + memset (dummy, 0, nbytes); + mm_sound_pcm_play_write_async(handle->mm_handle, (void*) dummy, nbytes); + free (dummy); + LOGI("write done!!!"); + } else { + LOGE("ERROR : AUDIO_IO_ERROR_OUT_OF_MEMORY(0x%08x)", AUDIO_IO_ERROR_OUT_OF_MEMORY); + } + } + } else { + LOGE("Handle is invalid..."); + } + + return 0; +} -int audio_in_create_private(int sample_rate, audio_channel_e channel, audio_sample_type_e type , audio_in_h* input) +int audio_in_create_private(int sample_rate, audio_channel_e channel, audio_sample_type_e type , int source_type, audio_in_h* input) { int ret = 0; audio_in_s *handle = NULL; @@ -227,12 +265,18 @@ int audio_in_create_private(int sample_rate, audio_channel_e channel, audio_samp /* Capture open */ - if ((ret = mm_sound_pcm_capture_open( &handle->mm_handle,sample_rate, channel, type)) < 0) { + if ((ret = mm_sound_pcm_capture_open_ex(&handle->mm_handle, sample_rate, channel, type, source_type)) < 0) { LOGE("mm_sound_pcm_capture_open_ex() failed [0x%x]", ret); goto ERROR; } LOGI("mm_sound_pcm_capture_open_ex() success"); + + if (source_type == SUPPORT_SOURCE_TYPE_LOOPBACK) + { + handle->is_loopback = 1; + } + handle->_buffer_size = ret; /* return by pcm_open */ handle->_sample_rate = sample_rate; handle->_channel = channel; @@ -258,7 +302,56 @@ ERROR: 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 */ + AUDIO_IO_NULL_ARG_CHECK(input); + + int ret = AUDIO_IO_ERROR_NONE; + int source_type = SUPPORT_SOURCE_TYPE_DEFAULT; + audio_in_s* handle = (audio_in_s*)input; + + // at first, release existing audio handle + if (handle->is_async) { + ret = mm_sound_pcm_capture_close_async(handle->mm_handle); + } else { + ret = mm_sound_pcm_capture_close(handle->mm_handle); + } + + if (ret != MM_ERROR_NONE) { + return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); + } + + // Initialize flags + handle->stream_cb = NULL; + handle->stream_userdata = NULL; + handle->is_async = 0; + + // Checks loopback type + if (handle->is_loopback == 1) { + source_type = SUPPORT_SOURCE_TYPE_LOOPBACK; + } + + /* Async (callback exists) or Sync (otherwise) */ + if (callback != NULL) { + handle->stream_cb = callback; + handle->stream_userdata = userdata; + handle->is_async = 1; + + /* Capture open */ + if ((ret = mm_sound_pcm_capture_open_async(&handle->mm_handle, handle->_sample_rate, handle->_channel, handle->_type, source_type, + (mm_sound_pcm_stream_cb_t)__audio_in_stream_cb, handle)) < 0) { + LOGE("mm_sound_pcm_capture_open_async() failed [0x%x]", ret); + return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); + } + LOGI("mm_sound_pcm_capture_open_async() success"); + } else { + /* Capture open */ + if ((ret = mm_sound_pcm_capture_open_ex(&handle->mm_handle, handle->_sample_rate, handle->_channel, handle->_type, source_type)) < 0) { + LOGE("mm_sound_pcm_capture_open_ex() failed [0x%x]", ret); + return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); + } + LOGI("mm_sound_pcm_capture_open_ex() success"); + } + + handle->_buffer_size = ret; /* return by pcm_open */ return AUDIO_IO_ERROR_NONE; } @@ -272,7 +365,7 @@ int audio_out_create_private(int sample_rate, audio_channel_e channel, audio_sam 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) { + if(sound_type < SOUND_TYPE_SYSTEM || sound_type > SOUND_TYPE_VOICE) { 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; @@ -319,7 +412,48 @@ ERROR: 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 */ + AUDIO_IO_NULL_ARG_CHECK(output); + + int ret = AUDIO_IO_ERROR_NONE; + audio_out_s* handle = (audio_out_s*)output; + + // at first, release existing mm handle + if (handle->is_async) { + ret = mm_sound_pcm_play_close_async(handle->mm_handle); + } else { + ret = mm_sound_pcm_play_close(handle->mm_handle); + } + + if (ret != MM_ERROR_NONE) { + return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); + } + + // Initialize flags + handle->stream_cb = NULL; + handle->stream_userdata = NULL; + handle->is_async = 0; + + /* Async (callback exists) or Sync (otherwise) */ + if (callback != NULL) { + handle->stream_cb = callback; + handle->stream_userdata = userdata; + handle->is_async = 1; + + /* Playback open */ + if ((ret = mm_sound_pcm_play_open_async(&handle->mm_handle, handle->_sample_rate, handle->_channel, handle->_type, handle->_sound_type, + (mm_sound_pcm_stream_cb_t)__audio_out_stream_cb, handle)) < 0) { + LOGE("mm_sound_pcm_play_open_async() failed [0x%x]", ret); + return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); + } + LOGI("mm_sound_pcm_play_open_async() success"); + } else { + if ((ret = mm_sound_pcm_play_open(&handle->mm_handle, handle->_sample_rate, handle->_channel, handle->_type, handle->_sound_type)) < 0) { + LOGE("mm_sound_pcm_play_open() failed [0x%x]", ret); + return __convert_audio_io_error_code(ret, (char*)__FUNCTION__); + } + LOGI("mm_sound_pcm_play_open() success"); + } + handle->_buffer_size = ret; /* return by pcm_open */ return AUDIO_IO_ERROR_NONE; }