* 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__
/**
* @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;
* @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;
/**
* @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
{
/**
* @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 */
/**
* @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 */
/**
* @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
{
/**
* @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
*
/**
* @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.
*
/**
* @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
*
*
* @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
/**
* @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
*
*
* @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
/**
* @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,
/**
* @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,
/**
* @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,
* @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
/**
* @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)
/**
* @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)
/**
* @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.
*
/**
* @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
/**
* @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
/**
* @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,
/**
* @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,
/**
* @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.
/**
* @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,
/**
* @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.
*
*
* @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.
*
/**
* @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
/**
* @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.
*
/**
* @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,
/**
* @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,
/**
* @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,
* 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);
* 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);
/**
* @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
/**
* @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)
/**
* @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)
* @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
/**
* @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
/**
* @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
/**
* @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
/**
* @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,
/**
* @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,
/**
* @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.
/**
* @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
* 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 <audio_io.h>
+#define __TIZEN_MEDIA_AUDIO_IO_PRIVATE_H__
#include <sound_manager.h>
#include <mm_sound.h>
+#include "audio_io.h"
/*
* Internal Macros
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;
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;
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);
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
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mm.h>
-#include <audio_io_private.h>
+#include "audio_io_private.h"
#include <dlog.h>
#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "TIZEN_N_AUDIO_IO"
-/* TODO : it will be added after updating libmm-sound */
-//#include <mm_sound_pcm_async.h>
+
+#include <mm_sound_pcm_async.h>
/*
* Internal Implementation
*/
/* 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)
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__);
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__);
}
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__);
}
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__);
}
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;
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__);
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;
}
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__);
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__);
}
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__);
}
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__);
}
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__);
}
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:
return ret;
}
-
int audio_out_get_buffer_size(audio_out_h output, int *size)
{
AUDIO_IO_NULL_ARG_CHECK(output);
return AUDIO_IO_ERROR_NONE;
}
-
int audio_out_get_sample_rate(audio_out_h output, int *sample_rate)
{
AUDIO_IO_NULL_ARG_CHECK(output);
return AUDIO_IO_ERROR_NONE;
}
-
int audio_out_get_channel(audio_out_h output, audio_channel_e *channel)
{
AUDIO_IO_NULL_ARG_CHECK(output);
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);
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);
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__);
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);
}
#include <mm.h>
#include "audio_io_private.h"
#include <dlog.h>
-/* TODO : it will be added after updating libmm-sound */
-//#include <mm_sound_pcm_async.h>
+
+#include <mm_sound_pcm_async.h>
#ifdef LOG_TAG
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;
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;
/* 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;
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;
}
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;
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;
}