diff options
Diffstat (limited to 'src/audio_io.c')
-rw-r--r-- | src/audio_io.c | 329 |
1 files changed, 329 insertions, 0 deletions
diff --git a/src/audio_io.c b/src/audio_io.c new file mode 100644 index 0000000..743d798 --- /dev/null +++ b/src/audio_io.c @@ -0,0 +1,329 @@ +/* +* 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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <mm.h> +#include <glib.h> +#include <audio_io_private.h> +#include <dlog.h> + +#ifdef LOG_TAG +#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" ) + +/* +* Internal Implementation +*/ +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; +} + +int _check_parameter(int sample_rate, audio_channel_e channel, audio_sample_type_e type) +{ + if(sample_rate<8000 || sample_rate > 44100) + { + LOGE("[%s] AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) : Invalid sample rate (8000~44100Hz) : %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; +} + +/* +* Public Implementation +*/ +int audio_in_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type , audio_in_h* input) +{ + AUDIO_IO_NULL_ARG_CHECK(input); + if(_check_parameter(sample_rate, channel, type)!=AUDIO_IO_ERROR_NONE) + return AUDIO_IO_ERROR_INVALID_PARAMETER; + + audio_in_s * 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; + } + int ret = mm_sound_pcm_capture_open( &handle->mm_handle,sample_rate, channel, type); + if( ret < 0) + { + return _convert_error_code(ret, (char*)__FUNCTION__); + } + else + { + *input = (audio_in_h)handle; + handle->_buffer_size= ret; + handle->_sample_rate= sample_rate; + handle->_channel= channel; + handle->_type= type; + return AUDIO_IO_ERROR_NONE; + } +} + +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_sound_pcm_capture_close(handle->mm_handle); + if (ret != MM_ERROR_NONE) + { + return _convert_error_code(ret, (char*)__FUNCTION__); + } + else + { + free(handle); + return AUDIO_IO_ERROR_NONE; + } +} + +int audio_in_read(audio_in_h input, void *buffer, unsigned int length ) +{ + AUDIO_IO_NULL_ARG_CHECK(input); + AUDIO_IO_NULL_ARG_CHECK(buffer); + audio_in_s * handle = (audio_in_s *) input; + int ret; + ret = mm_sound_pcm_capture_read(handle->mm_handle, (void*) buffer, length); + if(ret <0) + { + return _convert_error_code(ret, (char*)__FUNCTION__); + } + else + { + LOGI("[%s] %d bytes read" ,__FUNCTION__, ret); + return ret; + } +} + +int audio_in_get_buffer_size(audio_in_h input, int *size) +{ + AUDIO_IO_NULL_ARG_CHECK(input); + AUDIO_IO_NULL_ARG_CHECK(size); + audio_in_s * handle = (audio_in_s *) input; + *size = handle->_buffer_size; + return AUDIO_IO_ERROR_NONE; +} + +int audio_in_get_sample_rate(audio_in_h input, int *sample_rate) +{ + AUDIO_IO_NULL_ARG_CHECK(input); + AUDIO_IO_NULL_ARG_CHECK(sample_rate); + audio_in_s * handle = (audio_in_s *) input; + *sample_rate = handle->_sample_rate; + return AUDIO_IO_ERROR_NONE; +} + + +int audio_in_get_channel(audio_in_h input, audio_channel_e *channel) +{ + AUDIO_IO_NULL_ARG_CHECK(input); + AUDIO_IO_NULL_ARG_CHECK(channel); + audio_in_s * handle = (audio_in_s *) input; + *channel = handle->_channel; + return AUDIO_IO_ERROR_NONE; +} + +int audio_in_get_sample_type(audio_in_h input, audio_sample_type_e *type) +{ + AUDIO_IO_NULL_ARG_CHECK(input); + AUDIO_IO_NULL_ARG_CHECK(type); + audio_in_s * handle = (audio_in_s *) input; + *type = handle->_type; + return AUDIO_IO_ERROR_NONE; +} + +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) +{ + 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; + } + + audio_out_s * 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; + } + int ret = mm_sound_pcm_play_open(&handle->mm_handle,sample_rate, channel, type, sound_type); + if( ret < 0) + { + return _convert_error_code(ret, (char*)__FUNCTION__); + } + else + { + *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; + return AUDIO_IO_ERROR_NONE; + } +} + +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_sound_pcm_play_close(handle->mm_handle); + if (ret != MM_ERROR_NONE) + { + return _convert_error_code(ret, (char*)__FUNCTION__); + } + else + { + free(handle); + return AUDIO_IO_ERROR_NONE; + } +} + + +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; + ret = mm_sound_pcm_play_write(handle->mm_handle, (void*) buffer, length); + if(ret <0) + { + return _convert_error_code(ret, (char*)__FUNCTION__); + } + else + { + LOGI("[%s] %d bytes written" ,__FUNCTION__, ret); + return ret; + } +} + + +int audio_out_get_buffer_size(audio_out_h output, int *size) +{ + AUDIO_IO_NULL_ARG_CHECK(output); + AUDIO_IO_NULL_ARG_CHECK(size); + audio_out_s * handle = (audio_out_s *) output; + *size = handle->_buffer_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); + AUDIO_IO_NULL_ARG_CHECK(sample_rate); + audio_out_s * handle = (audio_out_s *) output; + *sample_rate = handle->_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); + AUDIO_IO_NULL_ARG_CHECK(channel); + audio_out_s * handle = (audio_out_s *) output; + *channel = handle->_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); + AUDIO_IO_NULL_ARG_CHECK(type); + audio_out_s * handle = (audio_out_s *) output; + *type = handle->_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); + AUDIO_IO_NULL_ARG_CHECK(type); + audio_out_s * handle = (audio_out_s *) output; + *type = handle->_sound_type; + return AUDIO_IO_ERROR_NONE; +} |