diff options
author | Sangchul Lee <sc11.lee@samsung.com> | 2016-05-30 10:54:56 +0900 |
---|---|---|
committer | Sangchul Lee <sc11.lee@samsung.com> | 2016-05-30 10:55:41 +0900 |
commit | 6e6425fcd1d064604db43cf21d6c3a2c9032a018 (patch) | |
tree | 7e9326087f40c511e9841eb7c423fefdee720771 | |
parent | f8d6e723269939482f162fedf6da3598f7a0a664 (diff) | |
download | audio-hal-wm1831-6e6425fcd1d064604db43cf21d6c3a2c9032a018.tar.gz audio-hal-wm1831-6e6425fcd1d064604db43cf21d6c3a2c9032a018.tar.bz2 audio-hal-wm1831-6e6425fcd1d064604db43cf21d6c3a2c9032a018.zip |
Restructure filessubmit/tizen/20160608.045525accepted/tizen/wearable/20160608.084418accepted/tizen/tv/20160608.084413accepted/tizen/mobile/20160608.084452accepted/tizen/ivi/20160608.084430accepted/tizen/common/20160608.160248
- add tizen-audio-impl.h and tizen-audio-impl-xxx.c for implemetation layer that could be code variation as per HW
- rename files
- remove unused functions
- rename functions according to rules("__" prefix for static functions)
[Version] 0.1.5
[Profile] Common
[Issue Type] Refactoring
Change-Id: I563e4bda0fa198b193fa0833f7b410b6cda6c80b
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
-rw-r--r-- | Makefile.am | 10 | ||||
-rw-r--r-- | packaging/audio-hal-wm1831.spec | 2 | ||||
-rw-r--r-- | tizen-audio-impl-ctrl.c | 251 | ||||
-rw-r--r-- | tizen-audio-impl-pcm.c (renamed from tizen-audio-device.c) | 507 | ||||
-rw-r--r-- | tizen-audio-impl-ucm.c (renamed from tizen-audio-ucm.c) | 154 | ||||
-rw-r--r-- | tizen-audio-impl.h | 57 | ||||
-rw-r--r-- | tizen-audio-internal.h | 86 | ||||
-rw-r--r-- | tizen-audio-pcm.c | 203 | ||||
-rw-r--r-- | tizen-audio-routing.c | 335 | ||||
-rw-r--r-- | tizen-audio-stream.c | 230 | ||||
-rw-r--r-- | tizen-audio-util.c | 433 | ||||
-rw-r--r-- | tizen-audio-volume.c | 2 | ||||
-rw-r--r-- | tizen-audio.c | 201 | ||||
-rw-r--r-- | tizen-audio.h | 6 |
14 files changed, 1240 insertions, 1237 deletions
diff --git a/Makefile.am b/Makefile.am index 1145f10..2543080 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,10 +1,14 @@ lib_LTLIBRARIES = libtizen-audio.la libtizen_audio_la_SOURCES = tizen-audio.c \ - tizen-audio-device.c \ tizen-audio-volume.c \ - tizen-audio-ucm.c \ - tizen-audio-util.c + tizen-audio-routing.c \ + tizen-audio-stream.c \ + tizen-audio-pcm.c \ + tizen-audio-util.c \ + tizen-audio-impl-pcm.c \ + tizen-audio-impl-ucm.c \ + tizen-audio-impl-ctrl.c libtizen_audio_la_LDFLAGS = $(AM_LDFLAGS) -disable-static -avoid-version if USE_TINYALSA libtizen_audio_la_LIBADD = $(AM_LDADD) $(ASOUNDLIB_LIBS) $(TINYALSA_LIBS) $(VCONF_LIBS) $(DLOG_LIBS) $(INIPARSER_LIBS) diff --git a/packaging/audio-hal-wm1831.spec b/packaging/audio-hal-wm1831.spec index 7c13d8e..34dbde3 100644 --- a/packaging/audio-hal-wm1831.spec +++ b/packaging/audio-hal-wm1831.spec @@ -1,6 +1,6 @@ Name: audio-hal-wm1831 Summary: TIZEN Audio HAL for WM1831 -Version: 0.1.4 +Version: 0.1.5 Release: 0 Group: System/Libraries License: Apache-2.0 diff --git a/tizen-audio-impl-ctrl.c b/tizen-audio-impl-ctrl.c new file mode 100644 index 0000000..253eaab --- /dev/null +++ b/tizen-audio-impl-ctrl.c @@ -0,0 +1,251 @@ +/* + * audio-hal + * + * Copyright (c) 2016 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. + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pthread.h> + +#include "tizen-audio-internal.h" + +#ifdef __MIXER_PARAM_DUMP +static void __dump_mixer_param(char *dump, long *param, int size) +{ + int i, len; + + for (i = 0; i < size; i++) { + len = sprintf(dump, "%ld", *param); + if (len > 0) + dump += len; + if (i != size -1) { + *dump++ = ','; + } + + param++; + } + *dump = '\0'; +} +#endif + +audio_return_t _control_init(audio_hal_t *ah) +{ + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + + pthread_mutex_init(&(ah->mixer.mutex), NULL); + return AUDIO_RET_OK; +} + +audio_return_t _control_deinit(audio_hal_t *ah) +{ + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + + pthread_mutex_destroy(&(ah->mixer.mutex)); + return AUDIO_RET_OK; +} + +audio_return_t _mixer_control_set_param(audio_hal_t *ah, const char* ctl_name, snd_ctl_elem_value_t* param, int size) +{ + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + + /* TODO. */ + return AUDIO_RET_OK; +} + +audio_return_t _mixer_control_get_value(audio_hal_t *ah, const char *ctl_name, int *val) +{ + snd_ctl_t *handle; + snd_ctl_elem_value_t *control; + snd_ctl_elem_id_t *id; + snd_ctl_elem_info_t *info; + snd_ctl_elem_type_t type; + + int ret = 0, count = 0, i = 0; + + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + + pthread_mutex_lock(&(ah->mixer.mutex)); + + ret = snd_ctl_open(&handle, ALSA_DEFAULT_CARD, 0); + if (ret < 0) { + AUDIO_LOG_ERROR("snd_ctl_open error, %s\n", snd_strerror(ret)); + pthread_mutex_unlock(&(ah->mixer.mutex)); + return AUDIO_ERR_IOCTL; + } + + // Get Element Info + + snd_ctl_elem_id_alloca(&id); + snd_ctl_elem_info_alloca(&info); + snd_ctl_elem_value_alloca(&control); + + snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); + snd_ctl_elem_id_set_name(id, ctl_name); + + snd_ctl_elem_info_set_id(info, id); + if (snd_ctl_elem_info(handle, info) < 0) { + AUDIO_LOG_ERROR("Cannot find control element: %s\n", ctl_name); + goto close; + } + snd_ctl_elem_info_get_id(info, id); + + type = snd_ctl_elem_info_get_type(info); + count = snd_ctl_elem_info_get_count(info); + + snd_ctl_elem_value_set_id(control, id); + + if (snd_ctl_elem_read(handle, control) < 0) { + AUDIO_LOG_ERROR("snd_ctl_elem_read failed \n"); + goto close; +} + + switch (type) { + case SND_CTL_ELEM_TYPE_BOOLEAN: + *val = snd_ctl_elem_value_get_boolean(control, i); + break; + case SND_CTL_ELEM_TYPE_INTEGER: + for (i = 0; i < count; i++) + *val = snd_ctl_elem_value_get_integer(control, i); + break; + case SND_CTL_ELEM_TYPE_ENUMERATED: + for (i = 0; i < count; i++) + *val = snd_ctl_elem_value_get_enumerated(control, i); + break; + default: + AUDIO_LOG_WARN("unsupported control element type\n"); + goto close; + } + + snd_ctl_close(handle); + +#ifdef AUDIO_DEBUG + AUDIO_LOG_INFO("get mixer(%s) = %d success", ctl_name, *val); +#endif + + pthread_mutex_unlock(&(ah->mixer.mutex)); + return AUDIO_RET_OK; + +close: + AUDIO_LOG_ERROR("Error\n"); + snd_ctl_close(handle); + pthread_mutex_unlock(&(ah->mixer.mutex)); + return AUDIO_ERR_UNDEFINED; +} + +audio_return_t _mixer_control_set_value(audio_hal_t *ah, const char *ctl_name, int val) +{ + snd_ctl_t *handle; + snd_ctl_elem_value_t *control; + snd_ctl_elem_id_t *id; + snd_ctl_elem_info_t *info; + snd_ctl_elem_type_t type; + int ret = 0, count = 0, i = 0; + + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(ctl_name, AUDIO_ERR_PARAMETER); + + pthread_mutex_lock(&(ah->mixer.mutex)); + + ret = snd_ctl_open(&handle, ALSA_DEFAULT_CARD, 0); + if (ret < 0) { + AUDIO_LOG_ERROR("snd_ctl_open error, card: %s: %s", ALSA_DEFAULT_CARD, snd_strerror(ret)); + pthread_mutex_unlock(&(ah->mixer.mutex)); + return AUDIO_ERR_IOCTL; + } + + // Get Element Info + + snd_ctl_elem_id_alloca(&id); + snd_ctl_elem_info_alloca(&info); + snd_ctl_elem_value_alloca(&control); + + snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); + snd_ctl_elem_id_set_name(id, ctl_name); + + snd_ctl_elem_info_set_id(info, id); + if (snd_ctl_elem_info(handle, info) < 0) { + AUDIO_LOG_ERROR("Cannot find control element: %s", ctl_name); + goto close; + } + snd_ctl_elem_info_get_id(info, id); + + type = snd_ctl_elem_info_get_type(info); + count = snd_ctl_elem_info_get_count(info); + + snd_ctl_elem_value_set_id(control, id); + + snd_ctl_elem_read(handle, control); + + switch (type) { + case SND_CTL_ELEM_TYPE_BOOLEAN: + for (i = 0; i < count; i++) + snd_ctl_elem_value_set_boolean(control, i, val); + break; + case SND_CTL_ELEM_TYPE_INTEGER: + for (i = 0; i < count; i++) + snd_ctl_elem_value_set_integer(control, i, val); + break; + case SND_CTL_ELEM_TYPE_ENUMERATED: + for (i = 0; i < count; i++) + snd_ctl_elem_value_set_enumerated(control, i, val); + break; + + default: + AUDIO_LOG_WARN("unsupported control element type"); + goto close; + } + + snd_ctl_elem_write(handle, control); + + snd_ctl_close(handle); + + AUDIO_LOG_INFO("set mixer(%s) = %d success", ctl_name, val); + + pthread_mutex_unlock(&(ah->mixer.mutex)); + return AUDIO_RET_OK; + +close: + AUDIO_LOG_ERROR("Error"); + snd_ctl_close(handle); + pthread_mutex_unlock(&(ah->mixer.mutex)); + return AUDIO_ERR_UNDEFINED; +} + +audio_return_t _mixer_control_set_value_string(audio_hal_t *ah, const char* ctl_name, const char* value) +{ + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(ctl_name, AUDIO_ERR_PARAMETER); + + /* TODO. */ + return AUDIO_RET_OK; +} + + +audio_return_t _mixer_control_get_element(audio_hal_t *ah, const char *ctl_name, snd_hctl_elem_t **elem) +{ + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(ctl_name, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(elem, AUDIO_ERR_PARAMETER); + + /* TODO. */ + return AUDIO_RET_OK; +}
\ No newline at end of file diff --git a/tizen-audio-device.c b/tizen-audio-impl-pcm.c index 6f3bbb7..926de2c 100644 --- a/tizen-audio-device.c +++ b/tizen-audio-impl-pcm.c @@ -1,7 +1,7 @@ /* * audio-hal * - * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2016 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. @@ -27,326 +27,40 @@ #include <stdbool.h> #include "tizen-audio-internal.h" +#include "tizen-audio-impl.h" -#ifndef __USE_TINYALSA__ +#ifdef __USE_TINYALSA__ +/* Convert pcm format from pulse to alsa */ +static const uint32_t g_format_convert_table[] = { + [AUDIO_SAMPLE_U8] = PCM_FORMAT_S8, + [AUDIO_SAMPLE_S16LE] = PCM_FORMAT_S16_LE, + [AUDIO_SAMPLE_S32LE] = PCM_FORMAT_S32_LE, + [AUDIO_SAMPLE_S24_32LE] = PCM_FORMAT_S24_LE +}; +#else /* alsa-lib */ /* FIXME : To avoid build warning... */ int _snd_pcm_poll_descriptor(snd_pcm_t *pcm); -#endif -/* #define DEBUG_TIMING */ - -static device_type_t outDeviceTypes[] = { - { AUDIO_DEVICE_OUT_SPEAKER, "Speaker" }, - { AUDIO_DEVICE_OUT_JACK, "Headphones" }, - { AUDIO_DEVICE_OUT_BT_SCO, "Bluetooth" }, - { AUDIO_DEVICE_OUT_AUX, "Line" }, - { AUDIO_DEVICE_OUT_HDMI, "HDMI" }, - { 0, 0 }, -}; - -static device_type_t inDeviceTypes[] = { - { AUDIO_DEVICE_IN_MAIN_MIC, "MainMic" }, - { AUDIO_DEVICE_IN_JACK, "HeadsetMic" }, - { AUDIO_DEVICE_IN_BT_SCO, "BT Mic" }, - { 0, 0 }, -}; - -static const char* mode_to_verb_str[] = { - AUDIO_USE_CASE_VERB_HIFI, +/* Convert pcm format from pulse to alsa */ +static const uint32_t g_format_convert_table[] = { + [AUDIO_SAMPLE_U8] = SND_PCM_FORMAT_U8, + [AUDIO_SAMPLE_ALAW] = SND_PCM_FORMAT_A_LAW, + [AUDIO_SAMPLE_ULAW] = SND_PCM_FORMAT_MU_LAW, + [AUDIO_SAMPLE_S16LE] = SND_PCM_FORMAT_S16_LE, + [AUDIO_SAMPLE_S16BE] = SND_PCM_FORMAT_S16_BE, + [AUDIO_SAMPLE_FLOAT32LE] = SND_PCM_FORMAT_FLOAT_LE, + [AUDIO_SAMPLE_FLOAT32BE] = SND_PCM_FORMAT_FLOAT_BE, + [AUDIO_SAMPLE_S32LE] = SND_PCM_FORMAT_S32_LE, + [AUDIO_SAMPLE_S32BE] = SND_PCM_FORMAT_S32_BE, + [AUDIO_SAMPLE_S24LE] = SND_PCM_FORMAT_S24_3LE, + [AUDIO_SAMPLE_S24BE] = SND_PCM_FORMAT_S24_3BE, + [AUDIO_SAMPLE_S24_32LE] = SND_PCM_FORMAT_S24_LE, + [AUDIO_SAMPLE_S24_32BE] = SND_PCM_FORMAT_S24_BE }; +#endif -static uint32_t convert_device_string_to_enum(const char* device_str, uint32_t direction) -{ - uint32_t device = 0; - - if (!strncmp(device_str, "builtin-speaker", MAX_NAME_LEN)) { - device = AUDIO_DEVICE_OUT_SPEAKER; - } else if (!strncmp(device_str, "builtin-receiver", MAX_NAME_LEN)) { - device = AUDIO_DEVICE_OUT_RECEIVER; - } else if ((!strncmp(device_str, "audio-jack", MAX_NAME_LEN)) && (direction == AUDIO_DIRECTION_OUT)) { - device = AUDIO_DEVICE_OUT_JACK; - } else if ((!strncmp(device_str, "bt", MAX_NAME_LEN)) && (direction == AUDIO_DIRECTION_OUT)) { - device = AUDIO_DEVICE_OUT_BT_SCO; - } else if (!strncmp(device_str, "aux", MAX_NAME_LEN)) { - device = AUDIO_DEVICE_OUT_AUX; - } else if (!strncmp(device_str, "hdmi", MAX_NAME_LEN)) { - device = AUDIO_DEVICE_OUT_HDMI; - } else if ((!strncmp(device_str, "builtin-mic", MAX_NAME_LEN))) { - device = AUDIO_DEVICE_IN_MAIN_MIC; - } else if ((!strncmp(device_str, "audio-jack", MAX_NAME_LEN)) && (direction == AUDIO_DIRECTION_IN)) { - device = AUDIO_DEVICE_IN_JACK; - } else if ((!strncmp(device_str, "bt", MAX_NAME_LEN)) && (direction == AUDIO_DIRECTION_IN)) { - device = AUDIO_DEVICE_IN_BT_SCO; - } else { - device = AUDIO_DEVICE_NONE; - } - AUDIO_LOG_INFO("device type(%s), enum(0x%x)", device_str, device); - return device; -} - -static audio_return_t set_devices(audio_hal_t *ah, const char *verb, device_info_t *devices, uint32_t num_of_devices) -{ - audio_return_t audio_ret = AUDIO_RET_OK; - uint32_t new_device = 0; - const char *active_devices[MAX_DEVICES] = {NULL,}; - int i = 0, j = 0, dev_idx = 0; - - AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(devices, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(num_of_devices, AUDIO_ERR_PARAMETER); - - if (num_of_devices > MAX_DEVICES) { - num_of_devices = MAX_DEVICES; - AUDIO_LOG_ERROR("error: num_of_devices"); - return AUDIO_ERR_PARAMETER; - } - - if (devices[0].direction == AUDIO_DIRECTION_OUT) { - ah->device.active_out &= 0x0; - if (ah->device.active_in) { - /* check the active in devices */ - for (j = 0; j < inDeviceTypes[j].type; j++) { - if (((ah->device.active_in & (~AUDIO_DEVICE_IN)) & inDeviceTypes[j].type)) - active_devices[dev_idx++] = inDeviceTypes[j].name; - } - } - } else if (devices[0].direction == AUDIO_DIRECTION_IN) { - ah->device.active_in &= 0x0; - if (ah->device.active_out) { - /* check the active out devices */ - for (j = 0; j < outDeviceTypes[j].type; j++) { - if (ah->device.active_out & outDeviceTypes[j].type) - active_devices[dev_idx++] = outDeviceTypes[j].name; - } - } - } - - for (i = 0; i < num_of_devices; i++) { - new_device = convert_device_string_to_enum(devices[i].type, devices[i].direction); - if (new_device & AUDIO_DEVICE_IN) { - for (j = 0; j < inDeviceTypes[j].type; j++) { - if (new_device == inDeviceTypes[j].type) { - active_devices[dev_idx++] = inDeviceTypes[j].name; - ah->device.active_in |= new_device; - } - } - } else { - for (j = 0; j < outDeviceTypes[j].type; j++) { - if (new_device == outDeviceTypes[j].type) { - active_devices[dev_idx++] = outDeviceTypes[j].name; - ah->device.active_out |= new_device; - } - } - } - } - - if (active_devices[0] == NULL) { - AUDIO_LOG_ERROR("Failed to set device: active device is NULL"); - return AUDIO_ERR_PARAMETER; - } - - audio_ret = _audio_ucm_set_devices(ah, verb, active_devices); - if (audio_ret) - AUDIO_LOG_ERROR("Failed to set device: error = %d", audio_ret); - - return audio_ret; -} - -audio_return_t _audio_device_init(audio_hal_t *ah) -{ - AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - - ah->device.active_in = 0x0; - ah->device.active_out = 0x0; - ah->device.pcm_in = NULL; - ah->device.pcm_out = NULL; - ah->device.mode = VERB_NORMAL; - pthread_mutex_init(&ah->device.pcm_lock, NULL); - ah->device.pcm_count = 0; - - return AUDIO_RET_OK; -} - -audio_return_t _audio_device_deinit(audio_hal_t *ah) -{ - AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - - return AUDIO_RET_OK; -} - -static audio_return_t _update_route_ap_playback_capture(audio_hal_t *ah, audio_route_info_t *route_info) -{ - audio_return_t audio_ret = AUDIO_RET_OK; - device_info_t *devices = NULL; - const char *verb = mode_to_verb_str[VERB_NORMAL]; - - AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(route_info, AUDIO_ERR_PARAMETER); - - devices = route_info->device_infos; - - /* To Do: Set modifiers */ - /* int mod_idx = 0; */ - /* const char *modifiers[MAX_MODIFIERS] = {NULL,}; */ - - AUDIO_LOG_INFO("update_route_ap_playback_capture++ "); - - audio_ret = set_devices(ah, verb, devices, route_info->num_of_devices); - if (audio_ret) { - AUDIO_LOG_ERROR("Failed to set devices: error = 0x%x", audio_ret); - return audio_ret; - } - ah->device.mode = VERB_NORMAL; - - /* To Do: Set modifiers */ - /* - if (!strncmp("voice_recognition", route_info->role, MAX_NAME_LEN)) { - modifiers[mod_idx++] = AUDIO_USE_CASE_MODIFIER_VOICESEARCH; - } else if ((!strncmp("alarm", route_info->role, MAX_NAME_LEN))||(!strncmp("notifiication", route_info->role, MAX_NAME_LEN))) { - if (ah->device.active_out &= AUDIO_DEVICE_OUT_JACK) - modifiers[mod_idx++] = AUDIO_USE_CASE_MODIFIER_DUAL_MEDIA; - else - modifiers[mod_idx++] = AUDIO_USE_CASE_MODIFIER_MEDIA; - } else { - if (ah->device.active_in) - modifiers[mod_idx++] = AUDIO_USE_CASE_MODIFIER_CAMCORDING; - else - modifiers[mod_idx++] = AUDIO_USE_CASE_MODIFIER_MEDIA; - } - audio_ret = _audio_ucm_set_modifiers (ah, verb, modifiers); - */ - - return audio_ret; -} - -static audio_return_t _update_route_voip(audio_hal_t *ah, device_info_t *devices, int32_t num_of_devices) -{ - audio_return_t audio_ret = AUDIO_RET_OK; - const char *verb = mode_to_verb_str[VERB_NORMAL]; - - AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(devices, AUDIO_ERR_PARAMETER); - - AUDIO_LOG_INFO("update_route_voip++"); - - audio_ret = set_devices(ah, verb, devices, num_of_devices); - if (audio_ret) { - AUDIO_LOG_ERROR("Failed to set devices: error = 0x%x", audio_ret); - return audio_ret; - } - /* FIXME. If necessary, set VERB_VOIP */ - ah->device.mode = VERB_NORMAL; - - /* TO DO: Set modifiers */ - return audio_ret; -} - -static audio_return_t _update_route_reset(audio_hal_t *ah, uint32_t direction) -{ - audio_return_t audio_ret = AUDIO_RET_OK; - const char *active_devices[MAX_DEVICES] = {NULL,}; - int i = 0, dev_idx = 0; - - /* FIXME: If you need to reset, set verb inactive */ - /* const char *verb = NULL; */ - /* verb = AUDIO_USE_CASE_VERB_INACTIVE; */ - - AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - - AUDIO_LOG_INFO("update_route_reset++, direction(0x%x)", direction); - - if (direction == AUDIO_DIRECTION_OUT) { - ah->device.active_out &= 0x0; - if (ah->device.active_in) { - /* check the active in devices */ - for (i = 0; i < inDeviceTypes[i].type; i++) { - if (((ah->device.active_in & (~AUDIO_DEVICE_IN)) & inDeviceTypes[i].type)) { - active_devices[dev_idx++] = inDeviceTypes[i].name; - AUDIO_LOG_INFO("added for in : %s", inDeviceTypes[i].name); - } - } - } - } else { - ah->device.active_in &= 0x0; - if (ah->device.active_out) { - /* check the active out devices */ - for (i = 0; i < outDeviceTypes[i].type; i++) { - if (ah->device.active_out & outDeviceTypes[i].type) { - active_devices[dev_idx++] = outDeviceTypes[i].name; - AUDIO_LOG_INFO("added for out : %s", outDeviceTypes[i].name); - } - } - } - } - - if (active_devices[0] == NULL) { - AUDIO_LOG_DEBUG("active device is NULL, no need to update."); - return AUDIO_RET_OK; - } - - audio_ret = _audio_ucm_set_devices(ah, mode_to_verb_str[ah->device.mode], active_devices); - if (audio_ret) - AUDIO_LOG_ERROR("Failed to set device: error = %d", audio_ret); - - return audio_ret; -} - -audio_return_t audio_update_route(void *audio_handle, audio_route_info_t *info) -{ - audio_return_t audio_ret = AUDIO_RET_OK; - audio_hal_t *ah = (audio_hal_t *)audio_handle; - device_info_t *devices = NULL; - - AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(info, AUDIO_ERR_PARAMETER); - - AUDIO_LOG_INFO("role:%s", info->role); - - devices = info->device_infos; - - if (!strncmp("voip", info->role, MAX_NAME_LEN)) { - audio_ret = _update_route_voip(ah, devices, info->num_of_devices); - if (AUDIO_IS_ERROR(audio_ret)) { - AUDIO_LOG_WARN("set voip route return 0x%x", audio_ret); - } - } else if (!strncmp("reset", info->role, MAX_NAME_LEN)) { - audio_ret = _update_route_reset(ah, devices->direction); - if (AUDIO_IS_ERROR(audio_ret)) { - AUDIO_LOG_WARN("set reset return 0x%x", audio_ret); - } - } else { - /* need to prepare for "alarm","notification","emergency","voice-information","voice-recognition","ringtone" */ - audio_ret = _update_route_ap_playback_capture(ah, info); - if (AUDIO_IS_ERROR(audio_ret)) { - AUDIO_LOG_WARN("set playback route return 0x%x", audio_ret); - } - } - return audio_ret; -} - -audio_return_t audio_notify_stream_connection_changed(void *audio_handle, audio_stream_info_t *info, uint32_t is_connected) -{ - audio_return_t audio_ret = AUDIO_RET_OK; - audio_hal_t *ah = (audio_hal_t *)audio_handle; - - AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(info, AUDIO_ERR_PARAMETER); - - AUDIO_LOG_INFO("role:%s, direction:%u, idx:%u, is_connected:%d", info->role, info->direction, info->idx, is_connected); - - return audio_ret; -} - -audio_return_t audio_update_route_option(void *audio_handle, audio_route_option_t *option) +static uint32_t __convert_format(audio_sample_format_t format) { - audio_return_t audio_ret = AUDIO_RET_OK; - audio_hal_t *ah = (audio_hal_t *)audio_handle; - - AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(option, AUDIO_ERR_PARAMETER); - - AUDIO_LOG_INFO("role:%s, name:%s, value:%d", option->role, option->name, option->value); - - return audio_ret; + return g_format_convert_table[format]; } #ifdef __USE_TINYALSA__ @@ -380,24 +94,39 @@ static struct pcm *__tinyalsa_open_device(audio_pcm_sample_spec_t *ss, size_t pe return pcm; } + +static int __tinyalsa_pcm_recover(struct pcm *pcm, int err) +{ + if (err > 0) + err = -err; + if (err == -EINTR) /* nothing to do, continue */ + return 0; + if (err == -EPIPE) { + AUDIO_LOG_INFO("XRUN occurred"); + err = pcm_prepare(pcm); + if (err < 0) { + AUDIO_LOG_ERROR("Could not recover from XRUN occurred, prepare failed : %d", err); + return err; + } + return 0; + } + if (err == -ESTRPIPE) { + /* tinyalsa does not support pcm resume, dont't care suspend case */ + AUDIO_LOG_ERROR("Could not recover from suspend : %d", err); + return err; + } + return err; +} #endif -audio_return_t audio_pcm_open(void *audio_handle, void **pcm_handle, uint32_t direction, void *sample_spec, uint32_t period_size, uint32_t periods) +audio_return_t _pcm_open(void **pcm_handle, uint32_t direction, void *sample_spec, uint32_t period_size, uint32_t periods) { #ifdef __USE_TINYALSA__ - audio_hal_t *ah; audio_pcm_sample_spec_t *ss; int err; - AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(sample_spec, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL((period_size > 0), AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL((periods > 0), AUDIO_ERR_PARAMETER); - - ah = (audio_hal_t *)audio_handle; ss = (audio_pcm_sample_spec_t *)sample_spec; - ss->format = _convert_format((audio_sample_format_t)ss->format); + ss->format = __convert_format((audio_sample_format_t)ss->format); *pcm_handle = __tinyalsa_open_device(ss, (size_t)period_size, (size_t)periods, direction); if (*pcm_handle == NULL) { @@ -409,20 +138,10 @@ audio_return_t audio_pcm_open(void *audio_handle, void **pcm_handle, uint32_t di AUDIO_LOG_ERROR("Error prepare PCM device : %d", err); } - ah->device.pcm_count++; - AUDIO_LOG_INFO("Opening PCM handle 0x%x", *pcm_handle); #else /* alsa-lib */ - audio_hal_t *ah; int err, mode; char *device_name = NULL; - AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(sample_spec, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL((period_size > 0), AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL((periods > 0), AUDIO_ERR_PARAMETER); - - ah = (audio_hal_t *)audio_handle; mode = SND_PCM_NONBLOCK | SND_PCM_NO_AUTO_RESAMPLE | SND_PCM_NO_AUTO_CHANNELS | SND_PCM_NO_AUTO_FORMAT; if (direction == AUDIO_DIRECTION_OUT) @@ -439,25 +158,21 @@ audio_return_t audio_pcm_open(void *audio_handle, void **pcm_handle, uint32_t di return AUDIO_ERR_RESOURCE; } - if ((err = audio_pcm_set_params(audio_handle, *pcm_handle, direction, sample_spec, period_size, periods)) != AUDIO_RET_OK) { + if ((err = _pcm_set_params(*pcm_handle, direction, sample_spec, period_size, periods)) != AUDIO_RET_OK) { AUDIO_LOG_ERROR("Failed to set pcm parameters : %d", err); return err; } - ah->device.pcm_count++; - AUDIO_LOG_INFO("Opening PCM handle 0x%x, PCM device %s", *pcm_handle, device_name); + AUDIO_LOG_INFO("PCM device %s", device_name); #endif return AUDIO_RET_OK; } -audio_return_t audio_pcm_start(void *audio_handle, void *pcm_handle) +audio_return_t _pcm_start(void *pcm_handle) { int err; - AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); - #ifdef __USE_TINYALSA__ if ((err = pcm_start(pcm_handle)) < 0) { AUDIO_LOG_ERROR("Error starting PCM handle : %d", err); @@ -474,13 +189,10 @@ audio_return_t audio_pcm_start(void *audio_handle, void *pcm_handle) return AUDIO_RET_OK; } -audio_return_t audio_pcm_stop(void *audio_handle, void *pcm_handle) +audio_return_t _pcm_stop(void *pcm_handle) { int err; - AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); - #ifdef __USE_TINYALSA__ if ((err = pcm_stop(pcm_handle)) < 0) { AUDIO_LOG_ERROR("Error stopping PCM handle : %d", err); @@ -497,14 +209,10 @@ audio_return_t audio_pcm_stop(void *audio_handle, void *pcm_handle) return AUDIO_RET_OK; } -audio_return_t audio_pcm_close(void *audio_handle, void *pcm_handle) +audio_return_t _pcm_close(void *pcm_handle) { - audio_hal_t *ah = (audio_hal_t *)audio_handle; int err; - AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); - AUDIO_LOG_INFO("Try to close PCM handle 0x%x", pcm_handle); #ifdef __USE_TINYALSA__ @@ -519,24 +227,16 @@ audio_return_t audio_pcm_close(void *audio_handle, void *pcm_handle) } #endif - pcm_handle = NULL; - ah->device.pcm_count--; - AUDIO_LOG_INFO("PCM handle close success (count:%d)", ah->device.pcm_count); - return AUDIO_RET_OK; } -audio_return_t audio_pcm_avail(void *audio_handle, void *pcm_handle, uint32_t *avail) +audio_return_t _pcm_avail(void *pcm_handle, uint32_t *avail) { #ifdef __USE_TINYALSA__ struct timespec tspec; unsigned int frames_avail = 0; int err; - AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(avail, AUDIO_ERR_PARAMETER); - err = pcm_get_htimestamp(pcm_handle, &frames_avail, &tspec); if (err < 0) { AUDIO_LOG_ERROR("Could not get avail and timespec at PCM handle 0x%x : %d", pcm_handle, err); @@ -551,10 +251,6 @@ audio_return_t audio_pcm_avail(void *audio_handle, void *pcm_handle, uint32_t *a #else /* alsa-lib */ snd_pcm_sframes_t frames_avail; - AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(avail, AUDIO_ERR_PARAMETER); - if ((frames_avail = snd_pcm_avail(pcm_handle)) < 0) { AUDIO_LOG_ERROR("Could not get avail at PCM handle 0x%x : %d", pcm_handle, frames_avail); return AUDIO_ERR_IOCTL; @@ -570,14 +266,11 @@ audio_return_t audio_pcm_avail(void *audio_handle, void *pcm_handle, uint32_t *a return AUDIO_RET_OK; } -audio_return_t audio_pcm_write(void *audio_handle, void *pcm_handle, const void *buffer, uint32_t frames) +audio_return_t _pcm_write(void *pcm_handle, const void *buffer, uint32_t frames) { #ifdef __USE_TINYALSA__ int err; - AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); - err = pcm_write(pcm_handle, buffer, pcm_frames_to_bytes(pcm_handle, (unsigned int)frames)); if (err < 0) { AUDIO_LOG_ERROR("Failed to write pcm : %d", err); @@ -585,7 +278,7 @@ audio_return_t audio_pcm_write(void *audio_handle, void *pcm_handle, const void } #ifdef DEBUG_TIMING - AUDIO_LOG_DEBUG("audio_pcm_write = %d", frames); + AUDIO_LOG_DEBUG("_pcm_write = %d", frames); #endif #else /* alsa-lib */ snd_pcm_sframes_t frames_written; @@ -599,21 +292,18 @@ audio_return_t audio_pcm_write(void *audio_handle, void *pcm_handle, const void } #ifdef DEBUG_TIMING - AUDIO_LOG_DEBUG("audio_pcm_write = (%d / %d)", frames_written, frames); + AUDIO_LOG_DEBUG("_pcm_write = (%d / %d)", frames_written, frames); #endif #endif return AUDIO_RET_OK; } -audio_return_t audio_pcm_read(void *audio_handle, void *pcm_handle, void *buffer, uint32_t frames) +audio_return_t _pcm_read(void *pcm_handle, void *buffer, uint32_t frames) { #ifdef __USE_TINYALSA__ int err; - AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); - err = pcm_read(pcm_handle, buffer, pcm_frames_to_bytes(pcm_handle, (unsigned int)frames)); if (err < 0) { AUDIO_LOG_ERROR("Failed to read pcm : %d", err); @@ -626,9 +316,6 @@ audio_return_t audio_pcm_read(void *audio_handle, void *pcm_handle, void *buffer #else /* alsa-lib */ snd_pcm_sframes_t frames_read; - AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); - frames_read = snd_pcm_readi(pcm_handle, buffer, (snd_pcm_uframes_t)frames); if (frames_read < 0) { AUDIO_LOG_ERROR("Failed to read pcm : %d", frames_read); @@ -636,18 +323,15 @@ audio_return_t audio_pcm_read(void *audio_handle, void *pcm_handle, void *buffer } #ifdef DEBUG_TIMING - AUDIO_LOG_DEBUG("audio_pcm_read = (%d / %d)", frames_read, frames); + AUDIO_LOG_DEBUG("_pcm_read = (%d / %d)", frames_read, frames); #endif #endif return AUDIO_RET_OK; } -audio_return_t audio_pcm_get_fd(void *audio_handle, void *pcm_handle, int *fd) +audio_return_t _pcm_get_fd(void *pcm_handle, int *fd) { - AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(fd, AUDIO_ERR_PARAMETER); /* we use an internal API of the (tiny)alsa library, so it causes warning message during compile */ #ifdef __USE_TINYALSA__ *fd = _pcm_poll_descriptor((struct pcm *)pcm_handle); @@ -657,36 +341,10 @@ audio_return_t audio_pcm_get_fd(void *audio_handle, void *pcm_handle, int *fd) return AUDIO_RET_OK; } -#ifdef __USE_TINYALSA__ -static int __tinyalsa_pcm_recover(struct pcm *pcm, int err) -{ - if (err > 0) - err = -err; - if (err == -EINTR) /* nothing to do, continue */ - return 0; - if (err == -EPIPE) { - AUDIO_LOG_INFO("XRUN occurred"); - err = pcm_prepare(pcm); - if (err < 0) { - AUDIO_LOG_ERROR("Could not recover from XRUN occurred, prepare failed : %d", err); - return err; - } - return 0; - } - if (err == -ESTRPIPE) { - /* tinyalsa does not support pcm resume, dont't care suspend case */ - AUDIO_LOG_ERROR("Could not recover from suspend : %d", err); - return err; - } - return err; -} -#endif - -audio_return_t audio_pcm_recover(void *audio_handle, void *pcm_handle, int revents) +audio_return_t _pcm_recover(void *pcm_handle, int revents) { int state, err; - AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); if (revents & POLLERR) @@ -759,11 +417,11 @@ audio_return_t audio_pcm_recover(void *audio_handle, void *pcm_handle, int reven } #endif - AUDIO_LOG_DEBUG("audio_pcm_recover"); + AUDIO_LOG_DEBUG("_pcm_recover"); return AUDIO_RET_OK; } -audio_return_t audio_pcm_get_params(void *audio_handle, void *pcm_handle, uint32_t direction, void **sample_spec, uint32_t *period_size, uint32_t *periods) +audio_return_t _pcm_get_params(void *pcm_handle, uint32_t direction, void **sample_spec, uint32_t *period_size, uint32_t *periods) { #ifdef __USE_TINYALSA__ audio_pcm_sample_spec_t *ss; @@ -771,11 +429,6 @@ audio_return_t audio_pcm_get_params(void *audio_handle, void *pcm_handle, uint32 unsigned int _start_threshold, _stop_threshold, _silence_threshold; struct pcm_config *config; - AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(sample_spec, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(period_size, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(periods, AUDIO_ERR_PARAMETER); ss = (audio_pcm_sample_spec_t *)*sample_spec; /* we use an internal API of the tiny alsa library, so it causes warning message during compile */ @@ -791,7 +444,7 @@ audio_return_t audio_pcm_get_params(void *audio_handle, void *pcm_handle, uint32 _stop_threshold = config->stop_threshold; _silence_threshold = config->silence_threshold; - AUDIO_LOG_DEBUG("audio_pcm_get_params (handle 0x%x, format %d, rate %d, channels %d, period_size %d, periods %d, buffer_size %d)", pcm_handle, config->format, config->rate, config->channels, config->period_size, config->period_count, _buffer_size); + AUDIO_LOG_DEBUG("_pcm_get_params (handle 0x%x, format %d, rate %d, channels %d, period_size %d, periods %d, buffer_size %d)", pcm_handle, config->format, config->rate, config->channels, config->period_size, config->period_count, _buffer_size); #else /* alsa-lib */ int err; audio_pcm_sample_spec_t *ss; @@ -804,11 +457,6 @@ audio_return_t audio_pcm_get_params(void *audio_handle, void *pcm_handle, uint32 snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; - AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(sample_spec, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(period_size, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(periods, AUDIO_ERR_PARAMETER); ss = (audio_pcm_sample_spec_t *)*sample_spec; snd_pcm_hw_params_alloca(&hwparams); @@ -847,17 +495,17 @@ audio_return_t audio_pcm_get_params(void *audio_handle, void *pcm_handle, uint32 AUDIO_LOG_ERROR("snd_pcm_sw_params_get_{start_threshold|stop_threshold|silence_threshold|avail_min}() failed : %s", err); } - AUDIO_LOG_DEBUG("audio_pcm_get_params (handle 0x%x, format %d, rate %d, channels %d, period_size %d, periods %d, buffer_size %d)", pcm_handle, _format, _rate, _channels, _period_size, _periods, _buffer_size); + AUDIO_LOG_DEBUG("_pcm_get_params (handle 0x%x, format %d, rate %d, channels %d, period_size %d, periods %d, buffer_size %d)", pcm_handle, _format, _rate, _channels, _period_size, _periods, _buffer_size); #endif return AUDIO_RET_OK; } -audio_return_t audio_pcm_set_params(void *audio_handle, void *pcm_handle, uint32_t direction, void *sample_spec, uint32_t period_size, uint32_t periods) +audio_return_t _pcm_set_params(void *pcm_handle, uint32_t direction, void *sample_spec, uint32_t period_size, uint32_t periods) { #ifdef __USE_TINYALSA__ /* Parameters are only acceptable in pcm_open() function */ - AUDIO_LOG_DEBUG("audio_pcm_set_params"); + AUDIO_LOG_DEBUG("_pcm_set_params"); #else /* alsa-lib */ int err; audio_pcm_sample_spec_t ss; @@ -865,11 +513,6 @@ audio_return_t audio_pcm_set_params(void *audio_handle, void *pcm_handle, uint32 snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; - AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(sample_spec, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(period_size, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(periods, AUDIO_ERR_PARAMETER); ss = *(audio_pcm_sample_spec_t *)sample_spec; snd_pcm_hw_params_alloca(&hwparams); @@ -891,7 +534,7 @@ audio_return_t audio_pcm_set_params(void *audio_handle, void *pcm_handle, uint32 return AUDIO_ERR_PARAMETER; } - ss.format = _convert_format((audio_sample_format_t)ss.format); + ss.format = __convert_format((audio_sample_format_t)ss.format); if ((err = snd_pcm_hw_params_set_format(pcm_handle, hwparams, ss.format)) < 0) { AUDIO_LOG_ERROR("snd_pcm_hw_params_set_format() failed : %d", err); return AUDIO_ERR_PARAMETER; @@ -965,7 +608,7 @@ audio_return_t audio_pcm_set_params(void *audio_handle, void *pcm_handle, uint32 return AUDIO_ERR_IOCTL; } - AUDIO_LOG_DEBUG("audio_pcm_set_params (handle 0x%x, format %d, rate %d, channels %d, period_size %d, periods %d, buffer_size %d)", pcm_handle, ss.format, ss.rate, ss.channels, period_size, periods, _buffer_size); + AUDIO_LOG_DEBUG("_pcm_set_params (handle 0x%x, format %d, rate %d, channels %d, period_size %d, periods %d, buffer_size %d)", pcm_handle, ss.format, ss.rate, ss.channels, period_size, periods, _buffer_size); #endif return AUDIO_RET_OK; diff --git a/tizen-audio-ucm.c b/tizen-audio-impl-ucm.c index 2bc1aa4..2c42613 100644 --- a/tizen-audio-ucm.c +++ b/tizen-audio-impl-ucm.c @@ -1,7 +1,7 @@ /* * audio-hal * - * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2016 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. @@ -41,98 +41,6 @@ #define UCM_PREFIX_REQUESTED "> UCM requested" #define UCM_PREFIX_CHANGED "<<< UCM changed" -audio_return_t _audio_ucm_init(audio_hal_t *ah) -{ - AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - - snd_use_case_mgr_open(&ah->ucm.uc_mgr, ALSA_DEFAULT_CARD); - - if (!ah->ucm.uc_mgr) { - AUDIO_LOG_ERROR("uc_mgr open failed"); - return AUDIO_ERR_RESOURCE; - } - return AUDIO_RET_OK; -} - -audio_return_t _audio_ucm_deinit(audio_hal_t *ah) -{ - AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(ah->ucm.uc_mgr, AUDIO_ERR_PARAMETER); - - snd_use_case_mgr_close(ah->ucm.uc_mgr); - ah->ucm.uc_mgr = NULL; - - return AUDIO_RET_OK; -} - -void _audio_ucm_get_device_name(audio_hal_t *ah, const char *use_case, audio_direction_t direction, const char **value) -{ - char identifier[70] = { 0, }; - - AUDIO_RETURN_IF_FAIL(ah); - AUDIO_RETURN_IF_FAIL(ah->ucm.uc_mgr); - - snprintf(identifier, sizeof(identifier), "%sPCM//%s", - (direction == AUDIO_DIRECTION_IN) ? "Capture" : "Playback", use_case); - - snd_use_case_get(ah->ucm.uc_mgr, identifier, value); -} - -static inline void __add_ucm_device_info(audio_hal_t *ah, const char *use_case, audio_direction_t direction, audio_device_info_t *device_info_list, int *device_info_count) -{ - audio_device_info_t *device_info; - const char *device_name = NULL; - char *needle = NULL; - - AUDIO_RETURN_IF_FAIL(ah); - AUDIO_RETURN_IF_FAIL(ah->ucm.uc_mgr); - AUDIO_RETURN_IF_FAIL(device_info_list); - AUDIO_RETURN_IF_FAIL(device_info_count); - - _audio_ucm_get_device_name(ah, use_case, direction, &device_name); - if (device_name) { - device_info = &device_info_list[(*device_info_count)++]; - - memset(device_info, 0x00, sizeof(audio_device_info_t)); - device_info->api = AUDIO_DEVICE_API_ALSA; - device_info->direction = direction; - needle = strstr(&device_name[3], ","); - if (needle) { - device_info->alsa.device_idx = *(needle+1) - '0'; - device_info->alsa.card_name = strndup(&device_name[3], needle - (device_name+3)); - device_info->alsa.card_idx = snd_card_get_index(device_info->alsa.card_name); - AUDIO_LOG_DEBUG("Card name: %s", device_info->alsa.card_name); - } - - free((void *)device_name); - } -} - -int _audio_ucm_fill_device_info_list(audio_hal_t *ah, audio_device_info_t *device_info_list, const char *verb) -{ - int device_info_count = 0; - const char *curr_verb = NULL; - - AUDIO_RETURN_VAL_IF_FAIL(ah, device_info_count); - AUDIO_RETURN_VAL_IF_FAIL(ah->ucm.uc_mgr, device_info_count); - AUDIO_RETURN_VAL_IF_FAIL(device_info_list, device_info_count); - - if (!verb) { - snd_use_case_get(ah->ucm.uc_mgr, "_verb", &curr_verb); - verb = curr_verb; - } - - if (verb) { - __add_ucm_device_info(ah, verb, AUDIO_DIRECTION_IN, device_info_list, &device_info_count); - __add_ucm_device_info(ah, verb, AUDIO_DIRECTION_OUT, device_info_list, &device_info_count); - - if (curr_verb) - free((void *)curr_verb); - } - - return device_info_count; -} - #define DUMP_LEN 512 static void __dump_use_case(const char* prefix, const char *verb, const char *devices[], int dev_count, const char *modifiers[], int mod_count) @@ -140,33 +48,33 @@ static void __dump_use_case(const char* prefix, const char *verb, const char *de int i; dump_data_t* dump = NULL; - if (!(dump = dump_new(DUMP_LEN))) { + if (!(dump = _audio_dump_new(DUMP_LEN))) { AUDIO_LOG_ERROR("Failed to create dump string..."); return; } /* Verb */ - dump_add_str(dump, "Verb [ %s ] Devices [ ", verb ? verb : AUDIO_USE_CASE_VERB_INACTIVE); + _audio_dump_add_str(dump, "Verb [ %s ] Devices [ ", verb ? verb : AUDIO_USE_CASE_VERB_INACTIVE); /* Devices */ if (devices) { for (i = 0; i < dev_count; i++) { - dump_add_str(dump, (i != dev_count - 1) ? "%s, " : "%s", devices[i]); + _audio_dump_add_str(dump, (i != dev_count - 1) ? "%s, " : "%s", devices[i]); } } - dump_add_str(dump, " ] Modifier [ "); + _audio_dump_add_str(dump, " ] Modifier [ "); /* Modifiers */ if (modifiers) { for (i = 0; i < mod_count; i++) { - dump_add_str(dump, (i != mod_count - 1) ? "%s, " : "%s", modifiers[i]); + _audio_dump_add_str(dump, (i != mod_count - 1) ? "%s, " : "%s", modifiers[i]); } } - dump_add_str(dump, " ]"); + _audio_dump_add_str(dump, " ]"); - AUDIO_LOG_INFO("TEST %s : %s", prefix, dump_get_str(dump)); + AUDIO_LOG_INFO("TEST %s : %s", prefix, _audio_dump_get_str(dump)); - dump_free(dump); + _audio_dump_free(dump); } #ifdef ALSA_UCM_DEBUG_TIME @@ -188,6 +96,32 @@ static inline int __set_use_case_with_time(snd_use_case_mgr_t *uc_mgr, const cha } #endif +audio_return_t _ucm_init(audio_hal_t *ah) +{ + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + + snd_use_case_mgr_open(&ah->ucm.uc_mgr, ALSA_DEFAULT_CARD); + + if (!ah->ucm.uc_mgr) { + AUDIO_LOG_ERROR("uc_mgr open failed"); + return AUDIO_ERR_RESOURCE; + } + return AUDIO_RET_OK; +} + +audio_return_t _ucm_deinit(audio_hal_t *ah) +{ + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(ah->ucm.uc_mgr, AUDIO_ERR_PARAMETER); + + if (ah->ucm.uc_mgr) { + snd_use_case_mgr_close(ah->ucm.uc_mgr); + ah->ucm.uc_mgr = NULL; + } + + return AUDIO_RET_OK; +} + /* UCM sequence 1) If verb is null or verb is not changed 1-1) If device is changed @@ -201,7 +135,7 @@ static inline int __set_use_case_with_time(snd_use_case_mgr_t *uc_mgr, const cha 2) If verb is changed -> Reset, set new verb, enable devices & modifiers */ -audio_return_t _audio_ucm_set_use_case(audio_hal_t *ah, const char *verb, const char *devices[], const char *modifiers[]) +audio_return_t _ucm_set_use_case(audio_hal_t *ah, const char *verb, const char *devices[], const char *modifiers[]) { audio_return_t audio_ret = AUDIO_RET_OK; int is_verb_changed = 0, is_dev_changed = 0, is_mod_changed = 0; @@ -415,7 +349,7 @@ exit: return audio_ret; } -audio_return_t _audio_ucm_set_devices(audio_hal_t *ah, const char *verb, const char *devices[]) +audio_return_t _ucm_set_devices(audio_hal_t *ah, const char *verb, const char *devices[]) { audio_return_t audio_ret = AUDIO_RET_OK; int is_verb_changed = 0, is_dev_changed = 0; @@ -507,7 +441,7 @@ audio_return_t _audio_ucm_set_devices(audio_hal_t *ah, const char *verb, const c } else { is_verb_changed = 1; - AUDIO_LOG_DEBUG("Setting new verb: %s", verb); + AUDIO_LOG_INFO("Setting new verb: %s", verb); /* set new verb */ if (snd_use_case_set(ah->ucm.uc_mgr, "_verb", verb) < 0) { AUDIO_LOG_ERROR("Setting verb %s failed", verb); @@ -516,7 +450,7 @@ audio_return_t _audio_ucm_set_devices(audio_hal_t *ah, const char *verb, const c } /* enable devices */ for (i = 0; i < dev_count; i++) { - AUDIO_LOG_DEBUG("Enable device : %s", devices[i]); + AUDIO_LOG_INFO("Enable device : %s", devices[i]); if (snd_use_case_set(ah->ucm.uc_mgr, "_enadev", devices[i]) < 0) AUDIO_LOG_ERROR("Enable %s device failed", devices[i]); } @@ -550,7 +484,7 @@ exit: } -audio_return_t _audio_ucm_set_modifiers(audio_hal_t *ah, const char *verb, const char *modifiers[]) +audio_return_t _ucm_set_modifiers(audio_hal_t *ah, const char *verb, const char *modifiers[]) { audio_return_t audio_ret = AUDIO_RET_OK; int is_verb_changed = 0, is_mod_changed = 0; @@ -683,7 +617,7 @@ exit: return audio_ret; } -audio_return_t _audio_ucm_get_verb(audio_hal_t *ah, const char **value) +audio_return_t _ucm_get_verb(audio_hal_t *ah, const char **value) { audio_return_t ret = AUDIO_RET_OK; @@ -699,8 +633,7 @@ audio_return_t _audio_ucm_get_verb(audio_hal_t *ah, const char **value) return ret; } - -audio_return_t _audio_ucm_reset_use_case(audio_hal_t *ah) +audio_return_t _ucm_reset_use_case(audio_hal_t *ah) { audio_return_t ret = AUDIO_RET_OK; @@ -715,5 +648,4 @@ audio_return_t _audio_ucm_reset_use_case(audio_hal_t *ah) } return ret; -} - +}
\ No newline at end of file diff --git a/tizen-audio-impl.h b/tizen-audio-impl.h new file mode 100644 index 0000000..4287ac8 --- /dev/null +++ b/tizen-audio-impl.h @@ -0,0 +1,57 @@ +#ifndef footizenaudioimplfoo +#define footizenaudioimplfoo + +/* + * audio-hal + * + * Copyright (c) 2016 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. + * + */ + +/* PCM */ +audio_return_t _pcm_open(void **pcm_handle, uint32_t direction, void *sample_spec, uint32_t period_size, uint32_t periods); +audio_return_t _pcm_start(void *pcm_handle); +audio_return_t _pcm_stop(void *pcm_handle); +audio_return_t _pcm_close(void *pcm_handle); +audio_return_t _pcm_avail(void *pcm_handle, uint32_t *avail); +audio_return_t _pcm_write(void *pcm_handle, const void *buffer, uint32_t frames); +audio_return_t _pcm_read(void *pcm_handle, void *buffer, uint32_t frames); +audio_return_t _pcm_get_fd(void *pcm_handle, int *fd); +audio_return_t _pcm_recover(void *pcm_handle, int revents); +audio_return_t _pcm_get_params(void *pcm_handle, uint32_t direction, void **sample_spec, uint32_t *period_size, uint32_t *periods); +audio_return_t _pcm_set_params(void *pcm_handle, uint32_t direction, void *sample_spec, uint32_t period_size, uint32_t periods); +audio_return_t _pcm_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t avail_min, uint8_t period_event); +audio_return_t _pcm_set_hw_params(snd_pcm_t *pcm, audio_pcm_sample_spec_t *sample_spec, uint8_t *use_mmap, snd_pcm_uframes_t *period_size, snd_pcm_uframes_t *buffer_size); + +/* Control */ +audio_return_t _control_init(audio_hal_t *ah); +audio_return_t _control_deinit(audio_hal_t *ah); +audio_return_t _mixer_control_set_param(audio_hal_t *ah, const char* ctl_name, snd_ctl_elem_value_t* value, int size); +audio_return_t _mixer_control_set_value(audio_hal_t *ah, const char *ctl_name, int val); +audio_return_t _mixer_control_set_value_string(audio_hal_t *ah, const char* ctl_name, const char* value); +audio_return_t _mixer_control_get_value(audio_hal_t *ah, const char *ctl_name, int *val); +audio_return_t _mixer_control_get_element(audio_hal_t *ah, const char *ctl_name, snd_hctl_elem_t **elem); + +/* UCM */ +audio_return_t _ucm_init(audio_hal_t *ah); +audio_return_t _ucm_deinit(audio_hal_t *ah); +#define _ucm_update_use_case _ucm_set_use_case +audio_return_t _ucm_set_use_case(audio_hal_t *ah, const char *verb, const char *devices[], const char *modifiers[]); +audio_return_t _ucm_set_devices(audio_hal_t *ah, const char *verb, const char *devices[]); +audio_return_t _ucm_set_modifiers(audio_hal_t *ah, const char *verb, const char *modifiers[]); +audio_return_t _ucm_get_verb(audio_hal_t *ah, const char **value); +audio_return_t _ucm_reset_use_case(audio_hal_t *ah); + +#endif diff --git a/tizen-audio-internal.h b/tizen-audio-internal.h index 21c79b7..cc2f41d 100644 --- a/tizen-audio-internal.h +++ b/tizen-audio-internal.h @@ -4,7 +4,7 @@ /* * audio-hal * - * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2015 - 2016 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. @@ -142,42 +142,14 @@ typedef struct device_type { /* type definitions */ typedef signed char int8_t; -/* pcm */ +/* PCM */ typedef struct { snd_pcm_format_t format; uint32_t rate; uint8_t channels; } audio_pcm_sample_spec_t; -/* Device */ -typedef enum audio_device_api { - AUDIO_DEVICE_API_UNKNOWN, - AUDIO_DEVICE_API_ALSA, - AUDIO_DEVICE_API_BLUEZ, -} audio_device_api_t; - -typedef struct audio_device_alsa_info { - char *card_name; - uint32_t card_idx; - uint32_t device_idx; -} audio_device_alsa_info_t; - -typedef struct audio_device_bluz_info { - char *protocol; - uint32_t nrec; -} audio_device_bluez_info_t; - -typedef struct audio_device_info { - audio_device_api_t api; - audio_direction_t direction; - char *name; - uint8_t is_default_device; - union { - audio_device_alsa_info_t alsa; - audio_device_bluez_info_t bluez; - }; -} audio_device_info_t; - +/* Routing */ typedef enum audio_route_mode { VERB_NORMAL, } audio_route_mode_t; @@ -192,7 +164,7 @@ typedef struct audio_hal_device { audio_route_mode_t mode; } audio_hal_device_t; -/* Stream */ +/* Volume */ #define AUDIO_VOLUME_LEVEL_MAX 16 typedef enum audio_volume { @@ -238,10 +210,12 @@ typedef struct audio_hal_volume { audio_volume_value_table_t *volume_value_table; } audio_hal_volume_t; +/* UCM */ typedef struct audio_hal_ucm { snd_use_case_mgr_t* uc_mgr; } audio_hal_ucm_t; +/* Mixer */ typedef struct audio_hal_mixer { snd_mixer_t *mixer; pthread_mutex_t mutex; @@ -279,42 +253,14 @@ typedef struct audio_hal { audio_hal_mixer_t mixer; } audio_hal_t; -typedef struct { - unsigned short is_open; /* if is_open is true, open device; else close device.*/ - unsigned short is_headphone; - unsigned int is_downlink_mute; - unsigned int is_uplink_mute; -} device_ctrl_t; - -typedef struct samplerate_ctrl { - unsigned int samplerate; /* change samplerate.*/ -} set_samplerate_t; - audio_return_t _audio_volume_init(audio_hal_t *ah); audio_return_t _audio_volume_deinit(audio_hal_t *ah); -audio_return_t _audio_device_init(audio_hal_t *ah); -audio_return_t _audio_device_deinit(audio_hal_t *ah); -audio_return_t _audio_ucm_init(audio_hal_t *ah); -audio_return_t _audio_ucm_deinit(audio_hal_t *ah); -audio_return_t _audio_util_init(audio_hal_t *ah); -audio_return_t _audio_util_deinit(audio_hal_t *ah); - -void _audio_ucm_get_device_name(audio_hal_t *ah, const char *use_case, audio_direction_t direction, const char **value); -#define _audio_ucm_update_use_case _audio_ucm_set_use_case -audio_return_t _audio_ucm_set_use_case(audio_hal_t *ah, const char *verb, const char *devices[], const char *modifiers[]); -audio_return_t _audio_ucm_set_devices(audio_hal_t *ah, const char *verb, const char *devices[]); -audio_return_t _audio_ucm_set_modifiers(audio_hal_t *ah, const char *verb, const char *modifiers[]); -int _audio_ucm_fill_device_info_list(audio_hal_t *ah, audio_device_info_t *device_info_list, const char *verb); -audio_return_t _audio_ucm_get_verb(audio_hal_t *ah, const char **value); -audio_return_t _audio_ucm_reset_use_case(audio_hal_t *ah); -audio_return_t _audio_mixer_control_set_param(audio_hal_t *ah, const char* ctl_name, snd_ctl_elem_value_t* value, int size); -audio_return_t _audio_mixer_control_set_value(audio_hal_t *ah, const char *ctl_name, int val); -audio_return_t _audio_mixer_control_set_value_string(audio_hal_t *ah, const char* ctl_name, const char* value); -audio_return_t _audio_mixer_control_get_value(audio_hal_t *ah, const char *ctl_name, int *val); -audio_return_t _audio_mixer_control_get_element(audio_hal_t *ah, const char *ctl_name, snd_hctl_elem_t **elem); -audio_return_t _audio_pcm_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t avail_min, uint8_t period_event); -audio_return_t _audio_pcm_set_hw_params(snd_pcm_t *pcm, audio_pcm_sample_spec_t *sample_spec, uint8_t *use_mmap, snd_pcm_uframes_t *period_size, snd_pcm_uframes_t *buffer_size); -uint32_t _convert_format(audio_sample_format_t format); +audio_return_t _audio_routing_init(audio_hal_t *ah); +audio_return_t _audio_routing_deinit(audio_hal_t *ah); +audio_return_t _audio_stream_init(audio_hal_t *ah); +audio_return_t _audio_stream_deinit(audio_hal_t *ah); +audio_return_t _audio_pcm_init(audio_hal_t *ah); +audio_return_t _audio_pcm_deinit(audio_hal_t *ah); typedef struct _dump_data { char *strbuf; @@ -322,9 +268,9 @@ typedef struct _dump_data { char *p; } dump_data_t; -dump_data_t* dump_new(int length); -void dump_add_str(dump_data_t *dump, const char *fmt, ...); -char* dump_get_str(dump_data_t *dump); -void dump_free(dump_data_t *dump); +dump_data_t* _audio_dump_new(int length); +void _audio_dump_add_str(dump_data_t *dump, const char *fmt, ...); +char* _audio_dump_get_str(dump_data_t *dump); +void _audio_dump_free(dump_data_t *dump); #endif diff --git a/tizen-audio-pcm.c b/tizen-audio-pcm.c new file mode 100644 index 0000000..0a09cba --- /dev/null +++ b/tizen-audio-pcm.c @@ -0,0 +1,203 @@ +/* + * audio-hal + * + * Copyright (c) 2016 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. + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "tizen-audio-internal.h" +#include "tizen-audio-impl.h" + +audio_return_t _audio_pcm_init(audio_hal_t *ah) +{ + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + + ah->device.pcm_in = NULL; + ah->device.pcm_out = NULL; + pthread_mutex_init(&ah->device.pcm_lock, NULL); + ah->device.pcm_count = 0; + + return AUDIO_RET_OK; +} + +audio_return_t _audio_pcm_deinit(audio_hal_t *ah) +{ + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + + pthread_mutex_destroy(&ah->device.pcm_lock); + + return AUDIO_RET_OK; +} + +audio_return_t audio_pcm_open(void *audio_handle, void **pcm_handle, uint32_t direction, void *sample_spec, uint32_t period_size, uint32_t periods) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + audio_hal_t *ah = NULL; + + AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(sample_spec, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL((period_size > 0), AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL((periods > 0), AUDIO_ERR_PARAMETER); + + if ((audio_ret = _pcm_open(pcm_handle, direction, sample_spec, period_size, periods))) + return audio_ret; + + ah = (audio_hal_t*)audio_handle; + ah->device.pcm_count++; + AUDIO_LOG_INFO("Opening PCM handle 0x%x", *pcm_handle); + + return AUDIO_RET_OK; +} + +audio_return_t audio_pcm_start(void *audio_handle, void *pcm_handle) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + + AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); + + audio_ret = _pcm_start(pcm_handle); + + return audio_ret; +} + +audio_return_t audio_pcm_stop(void *audio_handle, void *pcm_handle) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + + AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); + + audio_ret = _pcm_stop(pcm_handle); + + return audio_ret; +} + +audio_return_t audio_pcm_close(void *audio_handle, void *pcm_handle) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + audio_hal_t *ah = NULL; + + AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); + + if ((audio_ret = _pcm_close(pcm_handle))) + return audio_ret; + + pcm_handle = NULL; + ah = (audio_hal_t*)audio_handle; + ah->device.pcm_count--; + + AUDIO_LOG_INFO("PCM handle close success (count:%d)", ah->device.pcm_count); + + return audio_ret; +} + +audio_return_t audio_pcm_avail(void *audio_handle, void *pcm_handle, uint32_t *avail) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + + AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(avail, AUDIO_ERR_PARAMETER); + + audio_ret = _pcm_avail(pcm_handle, avail); + + return audio_ret; +} + +audio_return_t audio_pcm_write(void *audio_handle, void *pcm_handle, const void *buffer, uint32_t frames) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + + AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); + + audio_ret = _pcm_write(pcm_handle, buffer, frames); + + return audio_ret; +} + +audio_return_t audio_pcm_read(void *audio_handle, void *pcm_handle, void *buffer, uint32_t frames) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + + AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); + + audio_ret = _pcm_read(pcm_handle, buffer, frames); + + return audio_ret; +} + +audio_return_t audio_pcm_get_fd(void *audio_handle, void *pcm_handle, int *fd) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + + AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(fd, AUDIO_ERR_PARAMETER); + + audio_ret = _pcm_get_fd(pcm_handle, fd); + + return audio_ret; +} + +audio_return_t audio_pcm_recover(void *audio_handle, void *pcm_handle, int revents) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + + AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); + + audio_ret = _pcm_recover(pcm_handle, revents); + + return audio_ret; +} + +audio_return_t audio_pcm_get_params(void *audio_handle, void *pcm_handle, uint32_t direction, void **sample_spec, uint32_t *period_size, uint32_t *periods) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + + AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(sample_spec, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(period_size, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(periods, AUDIO_ERR_PARAMETER); + + audio_ret = _pcm_get_params(pcm_handle, direction, sample_spec, period_size, periods); + + return audio_ret; +} + +audio_return_t audio_pcm_set_params(void *audio_handle, void *pcm_handle, uint32_t direction, void *sample_spec, uint32_t period_size, uint32_t periods) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + + AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(sample_spec, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(period_size, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(periods, AUDIO_ERR_PARAMETER); + + audio_ret = _pcm_set_params(pcm_handle, direction, sample_spec, period_size, periods); + + return audio_ret; +}
\ No newline at end of file diff --git a/tizen-audio-routing.c b/tizen-audio-routing.c new file mode 100644 index 0000000..1194fb3 --- /dev/null +++ b/tizen-audio-routing.c @@ -0,0 +1,335 @@ +/* + * audio-hal + * + * Copyright (c) 2016 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. + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> + +#include "tizen-audio-internal.h" +#include "tizen-audio-impl.h" + +/* #define DEBUG_TIMING */ + +static device_type_t outDeviceTypes[] = { + { AUDIO_DEVICE_OUT_SPEAKER, "Speaker" }, + { AUDIO_DEVICE_OUT_JACK, "Headphones" }, + { AUDIO_DEVICE_OUT_BT_SCO, "Bluetooth" }, + { AUDIO_DEVICE_OUT_AUX, "Line" }, + { AUDIO_DEVICE_OUT_HDMI, "HDMI" }, + { 0, 0 }, +}; + +static device_type_t inDeviceTypes[] = { + { AUDIO_DEVICE_IN_MAIN_MIC, "MainMic" }, + { AUDIO_DEVICE_IN_JACK, "HeadsetMic" }, + { AUDIO_DEVICE_IN_BT_SCO, "BT Mic" }, + { 0, 0 }, +}; + +static const char* mode_to_verb_str[] = { + AUDIO_USE_CASE_VERB_HIFI, +}; + +static uint32_t __convert_device_string_to_enum(const char* device_str, uint32_t direction) +{ + uint32_t device = 0; + + if (!strncmp(device_str, "builtin-speaker", MAX_NAME_LEN)) { + device = AUDIO_DEVICE_OUT_SPEAKER; + } else if (!strncmp(device_str, "builtin-receiver", MAX_NAME_LEN)) { + device = AUDIO_DEVICE_OUT_RECEIVER; + } else if ((!strncmp(device_str, "audio-jack", MAX_NAME_LEN)) && (direction == AUDIO_DIRECTION_OUT)) { + device = AUDIO_DEVICE_OUT_JACK; + } else if ((!strncmp(device_str, "bt", MAX_NAME_LEN)) && (direction == AUDIO_DIRECTION_OUT)) { + device = AUDIO_DEVICE_OUT_BT_SCO; + } else if (!strncmp(device_str, "aux", MAX_NAME_LEN)) { + device = AUDIO_DEVICE_OUT_AUX; + } else if (!strncmp(device_str, "hdmi", MAX_NAME_LEN)) { + device = AUDIO_DEVICE_OUT_HDMI; + } else if ((!strncmp(device_str, "builtin-mic", MAX_NAME_LEN))) { + device = AUDIO_DEVICE_IN_MAIN_MIC; + } else if ((!strncmp(device_str, "audio-jack", MAX_NAME_LEN)) && (direction == AUDIO_DIRECTION_IN)) { + device = AUDIO_DEVICE_IN_JACK; + } else if ((!strncmp(device_str, "bt", MAX_NAME_LEN)) && (direction == AUDIO_DIRECTION_IN)) { + device = AUDIO_DEVICE_IN_BT_SCO; + } else { + device = AUDIO_DEVICE_NONE; + } + AUDIO_LOG_INFO("device type(%s), enum(0x%x)", device_str, device); + return device; +} + +static audio_return_t __set_devices(audio_hal_t *ah, const char *verb, device_info_t *devices, uint32_t num_of_devices) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + uint32_t new_device = 0; + const char *active_devices[MAX_DEVICES] = {NULL,}; + int i = 0, j = 0, dev_idx = 0; + + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(devices, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(num_of_devices, AUDIO_ERR_PARAMETER); + + if (num_of_devices > MAX_DEVICES) { + num_of_devices = MAX_DEVICES; + AUDIO_LOG_ERROR("error: num_of_devices"); + return AUDIO_ERR_PARAMETER; + } + + if (devices[0].direction == AUDIO_DIRECTION_OUT) { + ah->device.active_out &= 0x0; + if (ah->device.active_in) { + /* check the active in devices */ + for (j = 0; j < inDeviceTypes[j].type; j++) { + if (((ah->device.active_in & (~AUDIO_DEVICE_IN)) & inDeviceTypes[j].type)) + active_devices[dev_idx++] = inDeviceTypes[j].name; + } + } + } else if (devices[0].direction == AUDIO_DIRECTION_IN) { + ah->device.active_in &= 0x0; + if (ah->device.active_out) { + /* check the active out devices */ + for (j = 0; j < outDeviceTypes[j].type; j++) { + if (ah->device.active_out & outDeviceTypes[j].type) + active_devices[dev_idx++] = outDeviceTypes[j].name; + } + } + } + + for (i = 0; i < num_of_devices; i++) { + new_device = __convert_device_string_to_enum(devices[i].type, devices[i].direction); + if (new_device & AUDIO_DEVICE_IN) { + for (j = 0; j < inDeviceTypes[j].type; j++) { + if (new_device == inDeviceTypes[j].type) { + active_devices[dev_idx++] = inDeviceTypes[j].name; + ah->device.active_in |= new_device; + } + } + } else { + for (j = 0; j < outDeviceTypes[j].type; j++) { + if (new_device == outDeviceTypes[j].type) { + active_devices[dev_idx++] = outDeviceTypes[j].name; + ah->device.active_out |= new_device; + } + } + } + } + + if (active_devices[0] == NULL) { + AUDIO_LOG_ERROR("Failed to set device: active device is NULL"); + return AUDIO_ERR_PARAMETER; + } + + audio_ret = _ucm_set_devices(ah, verb, active_devices); + if (audio_ret) + AUDIO_LOG_ERROR("Failed to set device: error = %d", audio_ret); + + return audio_ret; +} + +static audio_return_t __update_route_ap_playback_capture(audio_hal_t *ah, audio_route_info_t *route_info) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + device_info_t *devices = NULL; + const char *verb = mode_to_verb_str[VERB_NORMAL]; + + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(route_info, AUDIO_ERR_PARAMETER); + + devices = route_info->device_infos; + + /* To Do: Set modifiers */ + /* int mod_idx = 0; */ + /* const char *modifiers[MAX_MODIFIERS] = {NULL,}; */ + + AUDIO_LOG_INFO("update_route_ap_playback_capture++ "); + + audio_ret = __set_devices(ah, verb, devices, route_info->num_of_devices); + if (audio_ret) { + AUDIO_LOG_ERROR("Failed to set devices: error = 0x%x", audio_ret); + return audio_ret; + } + ah->device.mode = VERB_NORMAL; + + /* To Do: Set modifiers */ + /* + if (!strncmp("voice_recognition", route_info->role, MAX_NAME_LEN)) { + modifiers[mod_idx++] = AUDIO_USE_CASE_MODIFIER_VOICESEARCH; + } else if ((!strncmp("alarm", route_info->role, MAX_NAME_LEN))||(!strncmp("notifiication", route_info->role, MAX_NAME_LEN))) { + if (ah->device.active_out &= AUDIO_DEVICE_OUT_JACK) + modifiers[mod_idx++] = AUDIO_USE_CASE_MODIFIER_DUAL_MEDIA; + else + modifiers[mod_idx++] = AUDIO_USE_CASE_MODIFIER_MEDIA; + } else { + if (ah->device.active_in) + modifiers[mod_idx++] = AUDIO_USE_CASE_MODIFIER_CAMCORDING; + else + modifiers[mod_idx++] = AUDIO_USE_CASE_MODIFIER_MEDIA; + } + audio_ret = _audio_ucm_set_modifiers (ah, verb, modifiers); + */ + + return audio_ret; +} + +static audio_return_t __update_route_voip(audio_hal_t *ah, device_info_t *devices, int32_t num_of_devices) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + const char *verb = mode_to_verb_str[VERB_NORMAL]; + + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(devices, AUDIO_ERR_PARAMETER); + + AUDIO_LOG_INFO("update_route_voip++"); + + audio_ret = __set_devices(ah, verb, devices, num_of_devices); + if (audio_ret) { + AUDIO_LOG_ERROR("Failed to set devices: error = 0x%x", audio_ret); + return audio_ret; + } + /* FIXME. If necessary, set VERB_VOIP */ + ah->device.mode = VERB_NORMAL; + + /* TO DO: Set modifiers */ + return audio_ret; +} + +static audio_return_t __update_route_reset(audio_hal_t *ah, uint32_t direction) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + const char *active_devices[MAX_DEVICES] = {NULL,}; + int i = 0, dev_idx = 0; + + /* FIXME: If you need to reset, set verb inactive */ + /* const char *verb = NULL; */ + /* verb = AUDIO_USE_CASE_VERB_INACTIVE; */ + + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + + AUDIO_LOG_INFO("update_route_reset++, direction(0x%x)", direction); + + if (direction == AUDIO_DIRECTION_OUT) { + ah->device.active_out &= 0x0; + if (ah->device.active_in) { + /* check the active in devices */ + for (i = 0; i < inDeviceTypes[i].type; i++) { + if (((ah->device.active_in & (~AUDIO_DEVICE_IN)) & inDeviceTypes[i].type)) { + active_devices[dev_idx++] = inDeviceTypes[i].name; + AUDIO_LOG_INFO("added for in : %s", inDeviceTypes[i].name); + } + } + } + } else { + ah->device.active_in &= 0x0; + if (ah->device.active_out) { + /* check the active out devices */ + for (i = 0; i < outDeviceTypes[i].type; i++) { + if (ah->device.active_out & outDeviceTypes[i].type) { + active_devices[dev_idx++] = outDeviceTypes[i].name; + AUDIO_LOG_INFO("added for out : %s", outDeviceTypes[i].name); + } + } + } + } + + if (active_devices[0] == NULL) { + AUDIO_LOG_DEBUG("active device is NULL, no need to update."); + return AUDIO_RET_OK; + } + + if ((audio_ret = _ucm_set_devices(ah, mode_to_verb_str[ah->device.mode], active_devices))) + AUDIO_LOG_ERROR("failed to _ucm_set_devices(), ret(0x%x)", audio_ret); + + return audio_ret; +} + +audio_return_t _audio_routing_init(audio_hal_t *ah) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + + ah->device.active_in = 0x0; + ah->device.active_out = 0x0; + ah->device.mode = VERB_NORMAL; + + if ((audio_ret = _ucm_init(ah))) + AUDIO_LOG_ERROR("failed to _ucm_init(), ret(0x%x)", audio_ret); + + return audio_ret; +} + +audio_return_t _audio_routing_deinit(audio_hal_t *ah) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + + if ((audio_ret = _ucm_deinit(ah))) + AUDIO_LOG_ERROR("failed to _ucm_deinit(), ret(0x%x)", audio_ret); + + return audio_ret; +} + +audio_return_t audio_update_route(void *audio_handle, audio_route_info_t *info) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + audio_hal_t *ah = (audio_hal_t *)audio_handle; + device_info_t *devices = NULL; + + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(info, AUDIO_ERR_PARAMETER); + + AUDIO_LOG_INFO("role:%s", info->role); + + devices = info->device_infos; + + if (!strncmp("voip", info->role, MAX_NAME_LEN)) { + if ((audio_ret = __update_route_voip(ah, devices, info->num_of_devices))) + AUDIO_LOG_WARN("update voip route return 0x%x", audio_ret); + + } else if (!strncmp("reset", info->role, MAX_NAME_LEN)) { + if ((audio_ret = __update_route_reset(ah, devices->direction))) + AUDIO_LOG_WARN("update reset return 0x%x", audio_ret); + + } else { + /* need to prepare for "alarm","notification","emergency","voice-information","voice-recognition","ringtone" */ + if ((audio_ret = __update_route_ap_playback_capture(ah, info))) + AUDIO_LOG_WARN("update playback route return 0x%x", audio_ret); + } + return audio_ret; +} + +audio_return_t audio_update_route_option(void *audio_handle, audio_route_option_t *option) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + audio_hal_t *ah = (audio_hal_t *)audio_handle; + + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(option, AUDIO_ERR_PARAMETER); + + AUDIO_LOG_INFO("role:%s, name:%s, value:%d", option->role, option->name, option->value); + + return audio_ret; +} diff --git a/tizen-audio-stream.c b/tizen-audio-stream.c new file mode 100644 index 0000000..435156d --- /dev/null +++ b/tizen-audio-stream.c @@ -0,0 +1,230 @@ +/* + * audio-hal + * + * Copyright (c) 2016 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. + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> + +#include "tizen-audio-internal.h" + +/* Audio latency */ +static const char* AUDIO_LATENCY_LOW = "low"; +static const char* AUDIO_LATENCY_MID = "mid"; +static const char* AUDIO_LATENCY_HIGH = "high"; +static const char* AUDIO_LATENCY_VOIP = "voip"; + +/* Latency msec */ +static const unsigned int PERIOD_TIME_FOR_ULOW_LATENCY_MSEC = 20; +static const unsigned int PERIOD_TIME_FOR_LOW_LATENCY_MSEC = 25; +static const unsigned int PERIOD_TIME_FOR_MID_LATENCY_MSEC = 50; +static const unsigned int PERIOD_TIME_FOR_HIGH_LATENCY_MSEC = 75; +static const unsigned int PERIOD_TIME_FOR_UHIGH_LATENCY_MSEC = 150; +static const unsigned int PERIOD_TIME_FOR_VOIP_LATENCY_MSEC = 20; + +static const uint32_t g_size_table[] = { + [AUDIO_SAMPLE_U8] = 1, + [AUDIO_SAMPLE_ULAW] = 1, + [AUDIO_SAMPLE_ALAW] = 1, + [AUDIO_SAMPLE_S16LE] = 2, + [AUDIO_SAMPLE_S16BE] = 2, + [AUDIO_SAMPLE_FLOAT32LE] = 4, + [AUDIO_SAMPLE_FLOAT32BE] = 4, + [AUDIO_SAMPLE_S32LE] = 4, + [AUDIO_SAMPLE_S32BE] = 4, + [AUDIO_SAMPLE_S24LE] = 3, + [AUDIO_SAMPLE_S24BE] = 3, + [AUDIO_SAMPLE_S24_32LE] = 4, + [AUDIO_SAMPLE_S24_32BE] = 4 +}; + +static int __sample_spec_valid(uint32_t rate, audio_sample_format_t format, uint32_t channels) +{ + if ((rate <= 0 || + rate > (48000U*4U) || + channels <= 0 || + channels > 32U || + format >= AUDIO_SAMPLE_MAX || + format < AUDIO_SAMPLE_U8)) + return 0; + + AUDIO_LOG_ERROR("hal-latency - __sample_spec_valid() -> return true"); + + return 1; +} + +static uint32_t __usec_to_bytes(uint64_t t, uint32_t rate, audio_sample_format_t format, uint32_t channels) +{ + uint32_t ret = (uint32_t) (((t * rate) / 1000000ULL)) * (g_size_table[format] * channels); + AUDIO_LOG_DEBUG("hal-latency - return %d", ret); + return ret; +} + +static uint32_t __sample_size(audio_sample_format_t format) +{ + return g_size_table[format]; +} + +audio_return_t _audio_stream_init(audio_hal_t *ah) +{ + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + + return AUDIO_RET_OK; +} + +audio_return_t _audio_stream_deinit(audio_hal_t *ah) +{ + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + + return AUDIO_RET_OK; +} + +audio_return_t audio_notify_stream_connection_changed(void *audio_handle, audio_stream_info_t *info, uint32_t is_connected) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + audio_hal_t *ah = (audio_hal_t *)audio_handle; + + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(info, AUDIO_ERR_PARAMETER); + + AUDIO_LOG_INFO("role:%s, direction:%u, idx:%u, is_connected:%d", info->role, info->direction, info->idx, is_connected); + + return audio_ret; +} + +audio_return_t audio_get_buffer_attr(void *audio_handle, + uint32_t direction, + const char *latency, + uint32_t samplerate, + audio_sample_format_t format, + uint32_t channels, + uint32_t *maxlength, + uint32_t *tlength, + uint32_t *prebuf, + uint32_t *minreq, + uint32_t *fragsize) +{ + AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(latency, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(maxlength, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(tlength, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(prebuf, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(minreq, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(fragsize, AUDIO_ERR_PARAMETER); + + AUDIO_LOG_DEBUG("hal-latency - audio_get_buffer_attr(direction:%d, latency:%s, samplerate:%d, format:%d, channels:%d)", direction, latency, samplerate, format, channels); + + uint32_t period_time = 0, + sample_per_period = 0; + + if (__sample_spec_valid(samplerate, format, channels) == 0) { + return AUDIO_ERR_PARAMETER; + } + + if (direction == AUDIO_DIRECTION_IN) { + if (!strcmp(latency, AUDIO_LATENCY_LOW)) { + AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_LOW"); + period_time = PERIOD_TIME_FOR_LOW_LATENCY_MSEC; + sample_per_period = (samplerate * period_time) / 1000; + *prebuf = 0; + *minreq = -1; + *tlength = -1; + *maxlength = -1; + *fragsize = sample_per_period * __sample_size(format); + } else if (!strcmp(latency, AUDIO_LATENCY_MID)) { + AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_MID"); + period_time = PERIOD_TIME_FOR_MID_LATENCY_MSEC; + sample_per_period = (samplerate * period_time) / 1000; + *prebuf = 0; + *minreq = -1; + *tlength = -1; + *maxlength = -1; + *fragsize = sample_per_period * __sample_size(format); + } else if (!strcmp(latency, AUDIO_LATENCY_HIGH)) { + AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_HIGH"); + period_time = PERIOD_TIME_FOR_HIGH_LATENCY_MSEC; + sample_per_period = (samplerate * period_time) / 1000; + *prebuf = 0; + *minreq = -1; + *tlength = -1; + *maxlength = -1; + *fragsize = sample_per_period * __sample_size(format); + } else if (!strcmp(latency, AUDIO_LATENCY_VOIP)) { + AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_VOIP"); + period_time = PERIOD_TIME_FOR_VOIP_LATENCY_MSEC; + sample_per_period = (samplerate * period_time) / 1000; + *prebuf = 0; + *minreq = -1; + *tlength = -1; + *maxlength = -1; + *fragsize = sample_per_period * __sample_size(format); + } else { + AUDIO_LOG_ERROR("hal-latency - The latency(%s) is undefined", latency); + return AUDIO_ERR_UNDEFINED; + } + } else { /* AUDIO_DIRECTION_OUT */ + if (!strcmp(latency, AUDIO_LATENCY_LOW)) { + AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_LOW"); + period_time = PERIOD_TIME_FOR_LOW_LATENCY_MSEC; + sample_per_period = (samplerate * period_time) / 1000; + *prebuf = 0; + *minreq = -1; + *tlength = (samplerate / 10) * __sample_size(format) * channels; /* 100ms */ + *maxlength = -1; + *fragsize = 0; + } else if (!strcmp(latency, AUDIO_LATENCY_MID)) { + AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_MID"); + period_time = PERIOD_TIME_FOR_MID_LATENCY_MSEC; + sample_per_period = (samplerate * period_time) / 1000; + *prebuf = 0; + *minreq = -1; + *tlength = (uint32_t) __usec_to_bytes(200000, samplerate, format, channels); + *maxlength = -1; + *fragsize = -1; + } else if (!strcmp(latency, AUDIO_LATENCY_HIGH)) { + AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_HIGH"); + period_time = PERIOD_TIME_FOR_HIGH_LATENCY_MSEC; + sample_per_period = (samplerate * period_time) / 1000; + *prebuf = 0; + *minreq = -1; + *tlength = (uint32_t) __usec_to_bytes(400000, samplerate, format, channels); + *maxlength = -1; + *fragsize = -1; + } else if (!strcmp(latency, AUDIO_LATENCY_VOIP)) { + AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_VOIP"); + period_time = PERIOD_TIME_FOR_VOIP_LATENCY_MSEC; + sample_per_period = (samplerate * period_time) / 1000; + *prebuf = 0; + *minreq = __usec_to_bytes(20000, samplerate, format, channels); + *tlength = __usec_to_bytes(100000, samplerate, format, channels); + *maxlength = -1; + *fragsize = 0; + } else { + AUDIO_LOG_ERROR("hal-latency - The latency(%s) is undefined", latency); + return AUDIO_ERR_UNDEFINED; + } + } + + AUDIO_LOG_INFO("hal-latency - return attr --> prebuf:%d, minreq:%d, tlength:%d, maxlength:%d, fragsize:%d", *prebuf, *minreq, *tlength, *maxlength, *fragsize); + return AUDIO_RET_OK; +}
\ No newline at end of file diff --git a/tizen-audio-util.c b/tizen-audio-util.c index 4e06923..6ab4aa0 100644 --- a/tizen-audio-util.c +++ b/tizen-audio-util.c @@ -1,7 +1,7 @@ /* * audio-hal * - * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2015 - 2016 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. @@ -24,436 +24,13 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <pthread.h> #include "tizen-audio-internal.h" -audio_return_t _audio_util_init(audio_hal_t *ah) -{ - AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - - pthread_mutex_init(&(ah->mixer.mutex), NULL); - return AUDIO_RET_OK; -} - -audio_return_t _audio_util_deinit(audio_hal_t *ah) -{ - AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - - pthread_mutex_destroy(&(ah->mixer.mutex)); - return AUDIO_RET_OK; -} - -#ifdef __MIXER_PARAM_DUMP - -static void __dump_mixer_param(char *dump, long *param, int size) -{ - int i, len; - - for (i = 0; i < size; i++) { - len = sprintf(dump, "%ld", *param); - if (len > 0) - dump += len; - if (i != size -1) { - *dump++ = ','; - } - - param++; - } - *dump = '\0'; -} - -#endif - -audio_return_t _audio_mixer_control_set_param(audio_hal_t *ah, const char* ctl_name, snd_ctl_elem_value_t* param, int size) -{ - AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - - /* TODO. */ - return AUDIO_RET_OK; -} - -audio_return_t audio_mixer_control_get_value(audio_hal_t *ah, const char *ctl_name, int *val) -{ - audio_return_t audio_ret = AUDIO_RET_OK; - - AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - - audio_ret = _audio_mixer_control_get_value(ah, ctl_name, val); - return audio_ret; -} - -audio_return_t _audio_mixer_control_get_value(audio_hal_t *ah, const char *ctl_name, int *val) -{ - snd_ctl_t *handle; - snd_ctl_elem_value_t *control; - snd_ctl_elem_id_t *id; - snd_ctl_elem_info_t *info; - snd_ctl_elem_type_t type; - - int ret = 0, count = 0, i = 0; - - AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - - pthread_mutex_lock(&(ah->mixer.mutex)); - - ret = snd_ctl_open(&handle, ALSA_DEFAULT_CARD, 0); - if (ret < 0) { - AUDIO_LOG_ERROR("snd_ctl_open error, %s\n", snd_strerror(ret)); - pthread_mutex_unlock(&(ah->mixer.mutex)); - return AUDIO_ERR_IOCTL; - } - - // Get Element Info - - snd_ctl_elem_id_alloca(&id); - snd_ctl_elem_info_alloca(&info); - snd_ctl_elem_value_alloca(&control); - - snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); - snd_ctl_elem_id_set_name(id, ctl_name); - - snd_ctl_elem_info_set_id(info, id); - if (snd_ctl_elem_info(handle, info) < 0) { - AUDIO_LOG_ERROR("Cannot find control element: %s\n", ctl_name); - goto close; - } - snd_ctl_elem_info_get_id(info, id); - - type = snd_ctl_elem_info_get_type(info); - count = snd_ctl_elem_info_get_count(info); - - snd_ctl_elem_value_set_id(control, id); - - if (snd_ctl_elem_read(handle, control) < 0) { - AUDIO_LOG_ERROR("snd_ctl_elem_read failed \n"); - goto close; -} - - switch (type) { - case SND_CTL_ELEM_TYPE_BOOLEAN: - *val = snd_ctl_elem_value_get_boolean(control, i); - break; - case SND_CTL_ELEM_TYPE_INTEGER: - for (i = 0; i < count; i++) - *val = snd_ctl_elem_value_get_integer(control, i); - break; - case SND_CTL_ELEM_TYPE_ENUMERATED: - for (i = 0; i < count; i++) - *val = snd_ctl_elem_value_get_enumerated(control, i); - break; - default: - AUDIO_LOG_WARN("unsupported control element type\n"); - goto close; - } - - snd_ctl_close(handle); - -#ifdef AUDIO_DEBUG - AUDIO_LOG_INFO("get mixer(%s) = %d success", ctl_name, *val); -#endif - - pthread_mutex_unlock(&(ah->mixer.mutex)); - return AUDIO_RET_OK; - -close: - AUDIO_LOG_ERROR("Error\n"); - snd_ctl_close(handle); - pthread_mutex_unlock(&(ah->mixer.mutex)); - return AUDIO_ERR_UNDEFINED; -} - -audio_return_t _audio_mixer_control_set_value(audio_hal_t *ah, const char *ctl_name, int val) -{ - snd_ctl_t *handle; - snd_ctl_elem_value_t *control; - snd_ctl_elem_id_t *id; - snd_ctl_elem_info_t *info; - snd_ctl_elem_type_t type; - - char *card_name = NULL; - int ret = 0, count = 0, i = 0; - - AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(ctl_name, AUDIO_ERR_PARAMETER); - - pthread_mutex_lock(&(ah->mixer.mutex)); - - ret = snd_ctl_open(&handle, ALSA_DEFAULT_CARD, 0); - if (ret < 0) { - AUDIO_LOG_ERROR("snd_ctl_open error, card: %s: %s", card_name, snd_strerror(ret)); - pthread_mutex_unlock(&(ah->mixer.mutex)); - return AUDIO_ERR_IOCTL; - } - - // Get Element Info - - snd_ctl_elem_id_alloca(&id); - snd_ctl_elem_info_alloca(&info); - snd_ctl_elem_value_alloca(&control); - - snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); - snd_ctl_elem_id_set_name(id, ctl_name); - - snd_ctl_elem_info_set_id(info, id); - if (snd_ctl_elem_info(handle, info) < 0) { - AUDIO_LOG_ERROR("Cannot find control element: %s", ctl_name); - goto close; - } - snd_ctl_elem_info_get_id(info, id); - - type = snd_ctl_elem_info_get_type(info); - count = snd_ctl_elem_info_get_count(info); - - snd_ctl_elem_value_set_id(control, id); - - snd_ctl_elem_read(handle, control); - - switch (type) { - case SND_CTL_ELEM_TYPE_BOOLEAN: - for (i = 0; i < count; i++) - snd_ctl_elem_value_set_boolean(control, i, val); - break; - case SND_CTL_ELEM_TYPE_INTEGER: - for (i = 0; i < count; i++) - snd_ctl_elem_value_set_integer(control, i, val); - break; - case SND_CTL_ELEM_TYPE_ENUMERATED: - for (i = 0; i < count; i++) - snd_ctl_elem_value_set_enumerated(control, i, val); - break; - - default: - AUDIO_LOG_WARN("unsupported control element type"); - goto close; - } - - snd_ctl_elem_write(handle, control); - - snd_ctl_close(handle); - - AUDIO_LOG_INFO("set mixer(%s) = %d success", ctl_name, val); - - pthread_mutex_unlock(&(ah->mixer.mutex)); - return AUDIO_RET_OK; - -close: - AUDIO_LOG_ERROR("Error"); - snd_ctl_close(handle); - pthread_mutex_unlock(&(ah->mixer.mutex)); - return AUDIO_ERR_UNDEFINED; -} - -audio_return_t _audio_mixer_control_set_value_string(audio_hal_t *ah, const char* ctl_name, const char* value) -{ - AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(ctl_name, AUDIO_ERR_PARAMETER); - - /* TODO. */ - return AUDIO_RET_OK; -} - - -audio_return_t _audio_mixer_control_get_element(audio_hal_t *ah, const char *ctl_name, snd_hctl_elem_t **elem) -{ - AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(ctl_name, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(elem, AUDIO_ERR_PARAMETER); - - /* TODO. */ - return AUDIO_RET_OK; -} - -#ifdef __USE_TINYALSA__ -/* Convert pcm format from pulse to alsa */ -static const uint32_t g_format_convert_table[] = { - [AUDIO_SAMPLE_U8] = PCM_FORMAT_S8, - [AUDIO_SAMPLE_S16LE] = PCM_FORMAT_S16_LE, - [AUDIO_SAMPLE_S32LE] = PCM_FORMAT_S32_LE, - [AUDIO_SAMPLE_S24_32LE] = PCM_FORMAT_S24_LE -}; -#else /* alsa-lib */ -/* Convert pcm format from pulse to alsa */ -static const uint32_t g_format_convert_table[] = { - [AUDIO_SAMPLE_U8] = SND_PCM_FORMAT_U8, - [AUDIO_SAMPLE_ALAW] = SND_PCM_FORMAT_A_LAW, - [AUDIO_SAMPLE_ULAW] = SND_PCM_FORMAT_MU_LAW, - [AUDIO_SAMPLE_S16LE] = SND_PCM_FORMAT_S16_LE, - [AUDIO_SAMPLE_S16BE] = SND_PCM_FORMAT_S16_BE, - [AUDIO_SAMPLE_FLOAT32LE] = SND_PCM_FORMAT_FLOAT_LE, - [AUDIO_SAMPLE_FLOAT32BE] = SND_PCM_FORMAT_FLOAT_BE, - [AUDIO_SAMPLE_S32LE] = SND_PCM_FORMAT_S32_LE, - [AUDIO_SAMPLE_S32BE] = SND_PCM_FORMAT_S32_BE, - [AUDIO_SAMPLE_S24LE] = SND_PCM_FORMAT_S24_3LE, - [AUDIO_SAMPLE_S24BE] = SND_PCM_FORMAT_S24_3BE, - [AUDIO_SAMPLE_S24_32LE] = SND_PCM_FORMAT_S24_LE, - [AUDIO_SAMPLE_S24_32BE] = SND_PCM_FORMAT_S24_BE -}; -#endif - -uint32_t _convert_format(audio_sample_format_t format) -{ - return g_format_convert_table[format]; -} - -/* Generic snd pcm interface APIs */ -audio_return_t _audio_pcm_set_hw_params(snd_pcm_t *pcm, audio_pcm_sample_spec_t *sample_spec, uint8_t *use_mmap, snd_pcm_uframes_t *period_size, snd_pcm_uframes_t *buffer_size) -{ - audio_return_t ret = AUDIO_RET_OK; - snd_pcm_hw_params_t *hwparams; - int err = 0; - int dir; - unsigned int val = 0; - snd_pcm_uframes_t _period_size = period_size ? *period_size : 0; - snd_pcm_uframes_t _buffer_size = buffer_size ? *buffer_size : 0; - uint8_t _use_mmap = use_mmap && *use_mmap; - uint32_t channels = 0; - - AUDIO_RETURN_VAL_IF_FAIL(pcm, AUDIO_ERR_PARAMETER); - - snd_pcm_hw_params_alloca(&hwparams); - - /* Skip parameter setting to null device. */ - if (snd_pcm_type(pcm) == SND_PCM_TYPE_NULL) - return AUDIO_ERR_IOCTL; - - /* Allocate a hardware parameters object. */ - snd_pcm_hw_params_alloca(&hwparams); - - /* Fill it in with default values. */ - if (snd_pcm_hw_params_any(pcm, hwparams) < 0) { - AUDIO_LOG_ERROR("snd_pcm_hw_params_any() : failed! - %s\n", snd_strerror(err)); - goto error; - } - - /* Set the desired hardware parameters. */ - - if (_use_mmap) { - - if (snd_pcm_hw_params_set_access(pcm, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0) { - - /* mmap() didn't work, fall back to interleaved */ - - if ((ret = snd_pcm_hw_params_set_access(pcm, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { - AUDIO_LOG_DEBUG("snd_pcm_hw_params_set_access() failed: %s", snd_strerror(ret)); - goto error; - } - - _use_mmap = 0; - } - - } else if ((ret = snd_pcm_hw_params_set_access(pcm, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { - AUDIO_LOG_DEBUG("snd_pcm_hw_params_set_access() failed: %s", snd_strerror(ret)); - goto error; - } - AUDIO_LOG_DEBUG("setting rate - %d", sample_spec->rate); - err = snd_pcm_hw_params_set_rate(pcm, hwparams, sample_spec->rate, 0); - if (err < 0) { - AUDIO_LOG_ERROR("snd_pcm_hw_params_set_rate() : failed! - %s\n", snd_strerror(err)); - } - - err = snd_pcm_hw_params(pcm, hwparams); - if (err < 0) { - AUDIO_LOG_ERROR("snd_pcm_hw_params() : failed! - %s\n", snd_strerror(err)); - goto error; - } - - /* Dump current param */ - - if ((ret = snd_pcm_hw_params_current(pcm, hwparams)) < 0) { - AUDIO_LOG_INFO("snd_pcm_hw_params_current() failed: %s", snd_strerror(ret)); - goto error; - } - - if ((ret = snd_pcm_hw_params_get_period_size(hwparams, &_period_size, &dir)) < 0 || - (ret = snd_pcm_hw_params_get_buffer_size(hwparams, &_buffer_size)) < 0) { - AUDIO_LOG_INFO("snd_pcm_hw_params_get_{period|buffer}_size() failed: %s", snd_strerror(ret)); - goto error; - } - - snd_pcm_hw_params_get_access(hwparams, (snd_pcm_access_t *) &val); - AUDIO_LOG_DEBUG("access type = %s\n", snd_pcm_access_name((snd_pcm_access_t)val)); - - snd_pcm_hw_params_get_format(hwparams, &sample_spec->format); - AUDIO_LOG_DEBUG("format = '%s' (%s)\n", - snd_pcm_format_name((snd_pcm_format_t)sample_spec->format), - snd_pcm_format_description((snd_pcm_format_t)sample_spec->format)); - - snd_pcm_hw_params_get_subformat(hwparams, (snd_pcm_subformat_t *)&val); - AUDIO_LOG_DEBUG("subformat = '%s' (%s)\n", - snd_pcm_subformat_name((snd_pcm_subformat_t)val), - snd_pcm_subformat_description((snd_pcm_subformat_t)val)); - - snd_pcm_hw_params_get_channels(hwparams, &channels); - sample_spec->channels = (uint8_t)channels; - AUDIO_LOG_DEBUG("channels = %d\n", sample_spec->channels); - - if (buffer_size) - *buffer_size = _buffer_size; - - if (period_size) - *period_size = _period_size; - - if (use_mmap) - *use_mmap = _use_mmap; - - return AUDIO_RET_OK; - -error: - return AUDIO_ERR_RESOURCE; -} - -audio_return_t _audio_pcm_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t avail_min, uint8_t period_event) -{ - snd_pcm_sw_params_t *swparams; - snd_pcm_uframes_t boundary; - int err; - - AUDIO_RETURN_VAL_IF_FAIL(pcm, AUDIO_ERR_PARAMETER); - - snd_pcm_sw_params_alloca(&swparams); - - if ((err = snd_pcm_sw_params_current(pcm, swparams)) < 0) { - AUDIO_LOG_WARN("Unable to determine current swparams: %s\n", snd_strerror(err)); - goto error; - } - if ((err = snd_pcm_sw_params_set_period_event(pcm, swparams, period_event)) < 0) { - AUDIO_LOG_WARN("Unable to disable period event: %s\n", snd_strerror(err)); - goto error; - } - if ((err = snd_pcm_sw_params_set_tstamp_mode(pcm, swparams, SND_PCM_TSTAMP_ENABLE)) < 0) { - AUDIO_LOG_WARN("Unable to enable time stamping: %s\n", snd_strerror(err)); - goto error; - } - if ((err = snd_pcm_sw_params_get_boundary(swparams, &boundary)) < 0) { - AUDIO_LOG_WARN("Unable to get boundary: %s\n", snd_strerror(err)); - goto error; - } - if ((err = snd_pcm_sw_params_set_stop_threshold(pcm, swparams, boundary)) < 0) { - AUDIO_LOG_WARN("Unable to set stop threshold: %s\n", snd_strerror(err)); - goto error; - } - if ((err = snd_pcm_sw_params_set_start_threshold(pcm, swparams, (snd_pcm_uframes_t) avail_min)) < 0) { - AUDIO_LOG_WARN("Unable to set start threshold: %s\n", snd_strerror(err)); - goto error; - } - if ((err = snd_pcm_sw_params_set_avail_min(pcm, swparams, avail_min)) < 0) { - AUDIO_LOG_WARN("snd_pcm_sw_params_set_avail_min() failed: %s", snd_strerror(err)); - goto error; - } - if ((err = snd_pcm_sw_params(pcm, swparams)) < 0) { - AUDIO_LOG_WARN("Unable to set sw params: %s\n", snd_strerror(err)); - goto error; - } - return AUDIO_RET_OK; -error: - return err; -} - /* ------ dump helper -------- */ #define MAX(a, b) ((a) > (b) ? (a) : (b)) -dump_data_t* dump_new(int length) +dump_data_t* _audio_dump_new(int length) { dump_data_t* dump = NULL; @@ -471,7 +48,7 @@ dump_data_t* dump_new(int length) return dump; } -void dump_add_str(dump_data_t *dump, const char *fmt, ...) +void _audio_dump_add_str(dump_data_t *dump, const char *fmt, ...) { int len; va_list ap; @@ -487,12 +64,12 @@ void dump_add_str(dump_data_t *dump, const char *fmt, ...) dump->left -= MAX(0, len); } -char* dump_get_str(dump_data_t *dump) +char* _audio_dump_get_str(dump_data_t *dump) { return (dump) ? dump->strbuf : NULL; } -void dump_free(dump_data_t *dump) +void _audio_dump_free(dump_data_t *dump) { if (dump) { if (dump->strbuf) diff --git a/tizen-audio-volume.c b/tizen-audio-volume.c index a81c160..6d83d29 100644 --- a/tizen-audio-volume.c +++ b/tizen-audio-volume.c @@ -1,7 +1,7 @@ /* * audio-hal * - * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2015 - 2016 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. diff --git a/tizen-audio.c b/tizen-audio.c index 882a9b4..b83397b 100644 --- a/tizen-audio.c +++ b/tizen-audio.c @@ -1,7 +1,7 @@ /* * audio-hal * - * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2015 - 2016 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. @@ -23,12 +23,6 @@ #include "tizen-audio-internal.h" -/* audio latency */ -static const char* AUDIO_LATENCY_LOW = "low"; -static const char* AUDIO_LATENCY_MID = "mid"; -static const char* AUDIO_LATENCY_HIGH = "high"; -static const char* AUDIO_LATENCY_VOIP = "voip"; - audio_return_t audio_init(void **audio_handle) { audio_hal_t *ah; @@ -37,23 +31,23 @@ audio_return_t audio_init(void **audio_handle) AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); if (!(ah = malloc(sizeof(audio_hal_t)))) { - AUDIO_LOG_ERROR("am malloc failed"); + AUDIO_LOG_ERROR("failed to malloc()"); return AUDIO_ERR_RESOURCE; } - if (AUDIO_IS_ERROR((ret = _audio_device_init(ah)))) { - AUDIO_LOG_ERROR("device init failed"); + if ((ret = _audio_volume_init(ah))) { + AUDIO_LOG_ERROR("failed to _audio_volume_init(), ret(0x%x)", ret); goto error_exit; } - if (AUDIO_IS_ERROR((ret = _audio_volume_init(ah)))) { - AUDIO_LOG_ERROR("stream init failed"); + if ((ret = _audio_routing_init(ah))) { + AUDIO_LOG_ERROR("failed to _audio_routing_init(), ret(0x%x)", ret); goto error_exit; } - if (AUDIO_IS_ERROR((ret = _audio_ucm_init(ah)))) { - AUDIO_LOG_ERROR("ucm init failed"); + if ((ret = _audio_stream_init(ah))) { + AUDIO_LOG_ERROR("failed to _audio_stream_init(), ret(0x%x)", ret); goto error_exit; } - if (AUDIO_IS_ERROR((ret = _audio_util_init(ah)))) { - AUDIO_LOG_ERROR("mixer init failed"); + if ((ret = _audio_pcm_init(ah))) { + AUDIO_LOG_ERROR("failed to _audio_pcm_init(), ret(0x%x)", ret); goto error_exit; } @@ -73,179 +67,12 @@ audio_return_t audio_deinit(void *audio_handle) AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - _audio_device_deinit(ah); _audio_volume_deinit(ah); - _audio_ucm_deinit(ah); - _audio_util_deinit(ah); + _audio_routing_deinit(ah); + _audio_stream_deinit(ah); + _audio_pcm_deinit(ah); free(ah); ah = NULL; return AUDIO_RET_OK; -} - -/* Latency msec */ -static const unsigned int PERIOD_TIME_FOR_ULOW_LATENCY_MSEC = 20; -static const unsigned int PERIOD_TIME_FOR_LOW_LATENCY_MSEC = 25; -static const unsigned int PERIOD_TIME_FOR_MID_LATENCY_MSEC = 50; -static const unsigned int PERIOD_TIME_FOR_HIGH_LATENCY_MSEC = 75; -static const unsigned int PERIOD_TIME_FOR_UHIGH_LATENCY_MSEC = 150; -static const unsigned int PERIOD_TIME_FOR_VOIP_LATENCY_MSEC = 20; - -static const uint32_t g_size_table[] = { - [AUDIO_SAMPLE_U8] = 1, - [AUDIO_SAMPLE_ULAW] = 1, - [AUDIO_SAMPLE_ALAW] = 1, - [AUDIO_SAMPLE_S16LE] = 2, - [AUDIO_SAMPLE_S16BE] = 2, - [AUDIO_SAMPLE_FLOAT32LE] = 4, - [AUDIO_SAMPLE_FLOAT32BE] = 4, - [AUDIO_SAMPLE_S32LE] = 4, - [AUDIO_SAMPLE_S32BE] = 4, - [AUDIO_SAMPLE_S24LE] = 3, - [AUDIO_SAMPLE_S24BE] = 3, - [AUDIO_SAMPLE_S24_32LE] = 4, - [AUDIO_SAMPLE_S24_32BE] = 4 -}; - -int _sample_spec_valid(uint32_t rate, audio_sample_format_t format, uint32_t channels) -{ - if ((rate <= 0 || - rate > (48000U*4U) || - channels <= 0 || - channels > 32U || - format >= AUDIO_SAMPLE_MAX || - format < AUDIO_SAMPLE_U8)) - return 0; - - AUDIO_LOG_ERROR("hal-latency - _sample_spec_valid() -> return true"); - - return 1; -} - -uint32_t _audio_usec_to_bytes(uint64_t t, uint32_t rate, audio_sample_format_t format, uint32_t channels) -{ - uint32_t ret = (uint32_t) (((t * rate) / 1000000ULL)) * (g_size_table[format] * channels); - AUDIO_LOG_DEBUG("hal-latency - return %d", ret); - return ret; -} - -uint32_t _audio_sample_size(audio_sample_format_t format) -{ - return g_size_table[format]; -} -audio_return_t audio_get_buffer_attr(void *audio_handle, - uint32_t direction, - const char *latency, - uint32_t samplerate, - audio_sample_format_t format, - uint32_t channels, - uint32_t *maxlength, - uint32_t *tlength, - uint32_t *prebuf, - uint32_t *minreq, - uint32_t *fragsize) -{ - AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(latency, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(maxlength, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(tlength, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(prebuf, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(minreq, AUDIO_ERR_PARAMETER); - AUDIO_RETURN_VAL_IF_FAIL(fragsize, AUDIO_ERR_PARAMETER); - - AUDIO_LOG_DEBUG("hal-latency - audio_get_buffer_attr(direction:%d, latency:%s, samplerate:%d, format:%d, channels:%d)", direction, latency, samplerate, format, channels); - - uint32_t period_time = 0, - sample_per_period = 0; - - if (_sample_spec_valid(samplerate, format, channels) == 0) { - return AUDIO_ERR_PARAMETER; - } - - if (direction == AUDIO_DIRECTION_IN) { - if (!strcmp(latency, AUDIO_LATENCY_LOW)) { - AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_LOW"); - period_time = PERIOD_TIME_FOR_LOW_LATENCY_MSEC; - sample_per_period = (samplerate * period_time) / 1000; - *prebuf = 0; - *minreq = -1; - *tlength = -1; - *maxlength = -1; - *fragsize = sample_per_period * _audio_sample_size(format); - } else if (!strcmp(latency, AUDIO_LATENCY_MID)) { - AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_MID"); - period_time = PERIOD_TIME_FOR_MID_LATENCY_MSEC; - sample_per_period = (samplerate * period_time) / 1000; - *prebuf = 0; - *minreq = -1; - *tlength = -1; - *maxlength = -1; - *fragsize = sample_per_period * _audio_sample_size(format); - } else if (!strcmp(latency, AUDIO_LATENCY_HIGH)) { - AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_HIGH"); - period_time = PERIOD_TIME_FOR_HIGH_LATENCY_MSEC; - sample_per_period = (samplerate * period_time) / 1000; - *prebuf = 0; - *minreq = -1; - *tlength = -1; - *maxlength = -1; - *fragsize = sample_per_period * _audio_sample_size(format); - } else if (!strcmp(latency, AUDIO_LATENCY_VOIP)) { - AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_VOIP"); - period_time = PERIOD_TIME_FOR_VOIP_LATENCY_MSEC; - sample_per_period = (samplerate * period_time) / 1000; - *prebuf = 0; - *minreq = -1; - *tlength = -1; - *maxlength = -1; - *fragsize = sample_per_period * _audio_sample_size(format); - } else { - AUDIO_LOG_ERROR("hal-latency - The latency(%s) is undefined", latency); - return AUDIO_ERR_UNDEFINED; - } - } else { /* AUDIO_DIRECTION_OUT */ - if (!strcmp(latency, AUDIO_LATENCY_LOW)) { - AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_LOW"); - period_time = PERIOD_TIME_FOR_LOW_LATENCY_MSEC; - sample_per_period = (samplerate * period_time) / 1000; - *prebuf = 0; - *minreq = -1; - *tlength = (samplerate / 10) * _audio_sample_size(format) * channels; /* 100ms */ - *maxlength = -1; - *fragsize = 0; - } else if (!strcmp(latency, AUDIO_LATENCY_MID)) { - AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_MID"); - period_time = PERIOD_TIME_FOR_MID_LATENCY_MSEC; - sample_per_period = (samplerate * period_time) / 1000; - *prebuf = 0; - *minreq = -1; - *tlength = (uint32_t) _audio_usec_to_bytes(200000, samplerate, format, channels); - *maxlength = -1; - *fragsize = -1; - } else if (!strcmp(latency, AUDIO_LATENCY_HIGH)) { - AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_HIGH"); - period_time = PERIOD_TIME_FOR_HIGH_LATENCY_MSEC; - sample_per_period = (samplerate * period_time) / 1000; - *prebuf = 0; - *minreq = -1; - *tlength = (uint32_t) _audio_usec_to_bytes(400000, samplerate, format, channels); - *maxlength = -1; - *fragsize = -1; - } else if (!strcmp(latency, AUDIO_LATENCY_VOIP)) { - AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_VOIP"); - period_time = PERIOD_TIME_FOR_VOIP_LATENCY_MSEC; - sample_per_period = (samplerate * period_time) / 1000; - *prebuf = 0; - *minreq = _audio_usec_to_bytes(20000, samplerate, format, channels); - *tlength = _audio_usec_to_bytes(100000, samplerate, format, channels); - *maxlength = -1; - *fragsize = 0; - } else { - AUDIO_LOG_ERROR("hal-latency - The latency(%s) is undefined", latency); - return AUDIO_ERR_UNDEFINED; - } - } - - AUDIO_LOG_INFO("hal-latency - return attr --> prebuf:%d, minreq:%d, tlength:%d, maxlength:%d, fragsize:%d", *prebuf, *minreq, *tlength, *maxlength, *fragsize); - return AUDIO_RET_OK; -} +}
\ No newline at end of file diff --git a/tizen-audio.h b/tizen-audio.h index 0207844..b3949dc 100644 --- a/tizen-audio.h +++ b/tizen-audio.h @@ -4,7 +4,7 @@ /* * audio-hal * - * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2015 - 2016 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. @@ -23,7 +23,6 @@ #include <stdint.h> /* Error code */ -#define AUDIO_IS_ERROR(ret) (ret < 0) typedef enum audio_return { AUDIO_RET_OK = 0, AUDIO_ERR_UNDEFINED = (int32_t)0x80001000, @@ -88,10 +87,9 @@ typedef struct audio_interface { audio_return_t (*update_route_option)(void *audio_handle, audio_route_option_t *option); /* Stream */ audio_return_t (*notify_stream_connection_changed)(void *audio_handle, audio_stream_info_t *info, uint32_t is_connected); - /* Buffer attribute */ audio_return_t (*get_buffer_attr)(void *audio_handle, uint32_t direction, const char *latency, uint32_t samplerate, int format, uint32_t channels, uint32_t *maxlength, uint32_t *tlength, uint32_t *prebuf, uint32_t* minreq, uint32_t *fragsize); - /* PCM device */ + /* PCM */ audio_return_t (*pcm_open)(void *audio_handle, void **pcm_handle, uint32_t direction, void *sample_spec, uint32_t period_size, uint32_t periods); audio_return_t (*pcm_start)(void *audio_handle, void *pcm_handle); audio_return_t (*pcm_stop)(void *audio_handle, void *pcm_handle); |