summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSangchul Lee <sc11.lee@samsung.com>2016-05-30 10:54:56 +0900
committerSangchul Lee <sc11.lee@samsung.com>2016-05-30 10:55:41 +0900
commit6e6425fcd1d064604db43cf21d6c3a2c9032a018 (patch)
tree7e9326087f40c511e9841eb7c423fefdee720771
parentf8d6e723269939482f162fedf6da3598f7a0a664 (diff)
downloadaudio-hal-wm1831-6e6425fcd1d064604db43cf21d6c3a2c9032a018.tar.gz
audio-hal-wm1831-6e6425fcd1d064604db43cf21d6c3a2c9032a018.tar.bz2
audio-hal-wm1831-6e6425fcd1d064604db43cf21d6c3a2c9032a018.zip
- 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.am10
-rw-r--r--packaging/audio-hal-wm1831.spec2
-rw-r--r--tizen-audio-impl-ctrl.c251
-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.h57
-rw-r--r--tizen-audio-internal.h86
-rw-r--r--tizen-audio-pcm.c203
-rw-r--r--tizen-audio-routing.c335
-rw-r--r--tizen-audio-stream.c230
-rw-r--r--tizen-audio-util.c433
-rw-r--r--tizen-audio-volume.c2
-rw-r--r--tizen-audio.c201
-rw-r--r--tizen-audio.h6
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);