summaryrefslogtreecommitdiff
path: root/tizen-audio-stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'tizen-audio-stream.c')
-rwxr-xr-x[-rw-r--r--]tizen-audio-stream.c188
1 files changed, 117 insertions, 71 deletions
diff --git a/tizen-audio-stream.c b/tizen-audio-stream.c
index 0c263ae..017ff79 100644..100755
--- a/tizen-audio-stream.c
+++ b/tizen-audio-stream.c
@@ -3,8 +3,6 @@
*
* Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
*
- * Contact: Hyunseok Lee <hs7388.lee@samsung.com>
- *
* 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
@@ -26,9 +24,9 @@
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
+#include <math.h>
#include <vconf.h>
#include <iniparser.h>
-#include <alsa/asoundlib.h>
#include "tizen-audio-internal.h"
@@ -42,6 +40,7 @@ enum {
STREAM_DEVICE_HEADSET,
STREAM_DEVICE_BLUETOOTH,
STREAM_DEVICE_HDMI,
+ STREAM_DEVICE_DOCK,
STREAM_DEVICE_MAX,
};
@@ -53,14 +52,26 @@ static const char *g_volume_vconf[AUDIO_VOLUME_TYPE_MAX] = {
"file/private/sound/volume/media", /* AUDIO_VOLUME_TYPE_MEDIA */
"file/private/sound/volume/call", /* AUDIO_VOLUME_TYPE_CALL */
"file/private/sound/volume/voip", /* AUDIO_VOLUME_TYPE_VOIP */
- "file/private/sound/volume/svoice", /* AUDIO_VOLUME_TYPE_SVOICE */
+ "file/private/sound/volume/voice", /* AUDIO_VOLUME_TYPE_VOICE */
"file/private/sound/volume/fixed", /* AUDIO_VOLUME_TYPE_FIXED */
- "file/private/sound/volume/java" /* AUDIO_VOLUME_TYPE_EXT_JAVA */
};
static inline uint8_t __get_volume_dev_index(audio_mgr_t *am, uint32_t volume_type)
{
- return 0;
+
+ switch (am->device.active_out) {
+ case AUDIO_DEVICE_OUT_SPEAKER: return AUDIO_VOLUME_DEVICE_SPEAKER;
+ case AUDIO_DEVICE_OUT_RECEIVER: return AUDIO_VOLUME_DEVICE_RECEIVER;
+ case AUDIO_DEVICE_OUT_WIRED_ACCESSORY: return AUDIO_VOLUME_DEVICE_EARJACK;
+ case AUDIO_DEVICE_OUT_BT_SCO: return AUDIO_VOLUME_DEVICE_BT_SCO;
+ case AUDIO_DEVICE_OUT_BT_A2DP: return AUDIO_VOLUME_DEVICE_BT_A2DP;
+ case AUDIO_DEVICE_OUT_DOCK: return AUDIO_VOLUME_DEVICE_DOCK;
+ case AUDIO_DEVICE_OUT_HDMI: return AUDIO_VOLUME_DEVICE_HDMI;
+ case AUDIO_DEVICE_OUT_MIRRORING: return AUDIO_VOLUME_DEVICE_MIRRORING;
+ case AUDIO_DEVICE_OUT_USB_AUDIO: return AUDIO_VOLUME_DEVICE_USB;
+ case AUDIO_DEVICE_OUT_MULTIMEDIA_DOCK: return AUDIO_VOLUME_DEVICE_MULTIMEDIA_DOCK;
+ default: return AUDIO_VOLUME_DEVICE_SPEAKER;
+ }
}
static const uint8_t __get_stream_dev_index (uint32_t device_out)
@@ -71,11 +82,11 @@ static const uint8_t __get_stream_dev_index (uint32_t device_out)
case AUDIO_DEVICE_OUT_WIRED_ACCESSORY: return STREAM_DEVICE_HEADSET;
case AUDIO_DEVICE_OUT_BT_SCO: return STREAM_DEVICE_BLUETOOTH;
case AUDIO_DEVICE_OUT_BT_A2DP: return STREAM_DEVICE_BLUETOOTH;
- case AUDIO_DEVICE_OUT_DOCK: return STREAM_DEVICE_SPEAKER;
+ case AUDIO_DEVICE_OUT_DOCK: return STREAM_DEVICE_DOCK;
case AUDIO_DEVICE_OUT_HDMI: return STREAM_DEVICE_HDMI;
case AUDIO_DEVICE_OUT_MIRRORING: return STREAM_DEVICE_SPEAKER;
case AUDIO_DEVICE_OUT_USB_AUDIO: return STREAM_DEVICE_SPEAKER;
- case AUDIO_DEVICE_OUT_MULTIMEDIA_DOCK: return STREAM_DEVICE_SPEAKER;
+ case AUDIO_DEVICE_OUT_MULTIMEDIA_DOCK: return STREAM_DEVICE_DOCK;
default:
AUDIO_LOG_DEBUG("invalid device_out:%d", device_out);
break;
@@ -91,16 +102,7 @@ static const char *__get_device_string_by_idx (uint32_t dev_idx)
case STREAM_DEVICE_HEADSET: return "headset";
case STREAM_DEVICE_BLUETOOTH: return "btheadset";
case STREAM_DEVICE_HDMI: return "hdmi";
- default: return "invalid";
- }
-}
-
-static const char *__get_direction_string_by_idx (uint32_t dir_idx)
-{
- switch (dir_idx) {
- case AUDIO_DIRECTION_NONE: return "none";
- case AUDIO_DIRECTION_IN: return "in";
- case AUDIO_DIRECTION_OUT: return "out";
+ case STREAM_DEVICE_DOCK: return "dock";
default: return "invalid";
}
}
@@ -115,9 +117,8 @@ static const char *__get_volume_type_string_by_idx (uint32_t vol_type_idx)
case AUDIO_VOLUME_TYPE_MEDIA: return "media";
case AUDIO_VOLUME_TYPE_CALL: return "call";
case AUDIO_VOLUME_TYPE_VOIP: return "voip";
- case AUDIO_VOLUME_TYPE_SVOICE: return "svoice";
+ case AUDIO_VOLUME_TYPE_VOICE: return "voice";
case AUDIO_VOLUME_TYPE_FIXED: return "fixed";
- case AUDIO_VOLUME_TYPE_EXT_JAVA: return "java";
default: return "invalid";
}
}
@@ -143,20 +144,22 @@ static const char *__get_gain_type_string_by_idx (uint32_t gain_type_idx)
static void __dump_info(char *dump, audio_info_t *info)
{
int len;
+ char name[64] = { '\0', };
if (info->device.api == AUDIO_DEVICE_API_ALSA) {
- len = sprintf(dump, "device:alsa(%d.%d)", info->device.alsa.card_idx, info->device.alsa.device_idx);
+ len = snprintf(dump, AUDIO_DUMP_STR_LEN, "device:alsa(%d.%d)", info->device.alsa.card_idx, info->device.alsa.device_idx);
} else if (info->device.api == AUDIO_DEVICE_API_ALSA) {
- len = sprintf(dump, "device:bluez(%s,nrec:%d)", info->device.bluez.protocol, info->device.bluez.nrec);
+ len = snprintf(dump, AUDIO_DUMP_STR_LEN, "device:bluez(%s,nrec:%d)", info->device.bluez.protocol, info->device.bluez.nrec);
} else {
- len = sprintf(dump, "device:unknown");
+ len = snprintf(dump, AUDIO_DUMP_STR_LEN, "device:unknown");
}
if (len > 0)
dump += len;
- len = sprintf(dump, "stream:%s(%dhz,%dch,vol:%s,gain:%s)",
- info->stream.name ? info->stream.name : "null", info->stream.samplerate, info->stream.channels,
+ strncpy(name, info->stream.name ? info->stream.name : "null", sizeof(name)-1);
+ len = snprintf(dump, AUDIO_DUMP_STR_LEN, "stream:%s(%dhz,%dch,vol:%s,gain:%s)",
+ name, info->stream.samplerate, info->stream.channels,
__get_volume_type_string_by_idx(info->stream.volume_type), __get_gain_type_string_by_idx(info->stream.gain_type));
if (len > 0)
@@ -165,7 +168,6 @@ static void __dump_info(char *dump, audio_info_t *info)
*dump = '\0';
}
-#ifdef AUDIO_DEBUG
static void __dump_tb (audio_mgr_t *am)
{
audio_volume_gain_table_t *volume_gain_table = am->stream.volume_gain_table;
@@ -186,12 +188,12 @@ static void __dump_tb (audio_mgr_t *am)
char dump_str[AUDIO_DUMP_STR_LEN], *dump_str_ptr;
/* Dump volume table */
- AUDIO_LOG_DEBUG("<<<<< volume table >>>>>");
+ AUDIO_LOG_INFO("<<<<< volume table >>>>>");
for (dev_idx = 0; dev_idx < STREAM_DEVICE_MAX; dev_idx++) {
const char *dev_str = __get_device_string_by_idx(dev_idx);
- AUDIO_LOG_DEBUG("<< %s >>", dev_str);
+ AUDIO_LOG_INFO("<< %s >>", dev_str);
for (vol_type_idx = 0; vol_type_idx < AUDIO_VOLUME_TYPE_MAX; vol_type_idx++) {
const char *vol_type_str = __get_volume_type_string_by_idx(vol_type_idx);
@@ -205,7 +207,7 @@ static void __dump_tb (audio_mgr_t *am)
snprintf(dump_str_ptr, 6, "%01.2f ", volume_gain_table->volume[vol_type_idx][vol_level_idx]);
dump_str_ptr += strlen(dump_str_ptr);
}
- AUDIO_LOG_DEBUG("%s", dump_str);
+ AUDIO_LOG_INFO("%s", dump_str);
}
volume_gain_table++;
}
@@ -213,7 +215,7 @@ static void __dump_tb (audio_mgr_t *am)
volume_gain_table = am->stream.volume_gain_table;
/* Dump gain table */
- AUDIO_LOG_DEBUG("<<<<< gain table >>>>>");
+ AUDIO_LOG_INFO("<<<<< gain table >>>>>");
dump_str_ptr = &dump_str[0];
memset(dump_str, 0x00, sizeof(char) * sizeof(dump_str));
@@ -225,7 +227,7 @@ static void __dump_tb (audio_mgr_t *am)
snprintf(dump_str_ptr, 7, "%5s ", gain_type_str[gain_type_idx]);
dump_str_ptr += strlen(dump_str_ptr);
}
- AUDIO_LOG_DEBUG("%s", dump_str);
+ AUDIO_LOG_INFO("%s", dump_str);
for (dev_idx = 0; dev_idx < STREAM_DEVICE_MAX; dev_idx++) {
const char *dev_str = __get_device_string_by_idx(dev_idx);
@@ -240,22 +242,22 @@ static void __dump_tb (audio_mgr_t *am)
snprintf(dump_str_ptr, 7, "%01.3f ", volume_gain_table->gain[gain_type_idx]);
dump_str_ptr += strlen(dump_str_ptr);
}
- AUDIO_LOG_DEBUG("%s", dump_str);
+ AUDIO_LOG_INFO("%s", dump_str);
volume_gain_table++;
}
}
-#endif
static audio_return_t __load_volume_gain_table_from_ini (audio_mgr_t *am)
{
dictionary * dict = NULL;
uint32_t dev_idx, vol_type_idx, vol_level_idx, gain_type_idx;
audio_volume_gain_table_t *volume_gain_table = am->stream.volume_gain_table;
+ int size = 0;
dict = iniparser_load(VOLUME_INI_TEMP_PATH);
if (!dict) {
- AUDIO_LOG_DEBUG("Use temporary volume&gain ini file");
+ AUDIO_LOG_DEBUG("Use default volume&gain ini file");
dict = iniparser_load(VOLUME_INI_DEFAULT_PATH);
if (!dict) {
AUDIO_LOG_WARN("Loading volume&gain table from ini file failed");
@@ -273,18 +275,23 @@ static audio_return_t __load_volume_gain_table_from_ini (audio_mgr_t *am)
const char *vol_type_str = __get_volume_type_string_by_idx(vol_type_idx);
volume_gain_table->volume_level_max[vol_type_idx] = 0;
-
- key = malloc(strlen(dev_str) + strlen(vol_type_str) + 2);
+ size = strlen(dev_str) + strlen(vol_type_str) + 2;
+ key = malloc(size);
if (key) {
- sprintf(key, "%s:%s", dev_str, vol_type_str);
+ snprintf(key, size, "%s:%s", dev_str, vol_type_str);
list_str = iniparser_getstr(dict, key);
if (list_str) {
token = strtok_r(list_str, delimiter, &ptr);
while (token) {
- volume_gain_table->volume[vol_type_idx][volume_gain_table->volume_level_max[vol_type_idx]++] = atof(token);
+ /* convert dB volume to linear volume */
+ double vol_value = 0.0f;
+ if(strncmp(token, "0", strlen(token)))
+ vol_value = pow(10.0, (atof(token) - 100) / 20.0);
+ volume_gain_table->volume[vol_type_idx][volume_gain_table->volume_level_max[vol_type_idx]++] = vol_value;
token = strtok_r(NULL, delimiter, &ptr);
}
} else {
+ volume_gain_table->volume_level_max[vol_type_idx] = 1;
for (vol_level_idx = 0; vol_level_idx < AUDIO_VOLUME_LEVEL_MAX; vol_level_idx++) {
volume_gain_table->volume[vol_type_idx][vol_level_idx] = VOLUME_VALUE_MAX;
}
@@ -294,54 +301,71 @@ static audio_return_t __load_volume_gain_table_from_ini (audio_mgr_t *am)
}
/* Load gain table */
- key = malloc(strlen(dev_str) + strlen("gain") + 2);
- if (key) {
- sprintf(key, "%s:gain", dev_str);
- list_str = iniparser_getstr(dict, key);
- if (list_str) {
- token = strtok_r(list_str, delimiter, &ptr);
volume_gain_table->gain[AUDIO_GAIN_TYPE_DEFAULT] = GAIN_VALUE_MAX;
for (gain_type_idx = AUDIO_GAIN_TYPE_DEFAULT + 1; gain_type_idx < AUDIO_GAIN_TYPE_MAX; gain_type_idx++) {
+ const char *gain_type_str = __get_gain_type_string_by_idx(gain_type_idx);
+
+ size = strlen(dev_str) + strlen("gain") + strlen(gain_type_str) + 3;
+ key = malloc(size);
+ if (key) {
+ snprintf(key, size, "%s:gain_%s", dev_str, gain_type_str);
+ token = iniparser_getstr(dict, key);
if (token) {
volume_gain_table->gain[gain_type_idx] = atof(token);
- token = strtok_r(NULL, delimiter, &ptr);
} else {
volume_gain_table->gain[gain_type_idx] = GAIN_VALUE_MAX;
}
- }
+ free(key);
} else {
- for (gain_type_idx = 0; gain_type_idx < AUDIO_GAIN_TYPE_MAX; gain_type_idx++)
volume_gain_table->gain[gain_type_idx] = GAIN_VALUE_MAX;
}
- free(key);
}
volume_gain_table++;
}
iniparser_freedict(dict);
-#ifdef AUDIO_DEBUG
+
__dump_tb(am);
-#endif
return AUDIO_RET_OK;
}
audio_return_t _audio_stream_init (audio_mgr_t *am)
{
- int i, value;
+ int i, j;
+ char *str = NULL;
+ audio_return_t audio_ret = AUDIO_RET_OK;
+ int init_value[AUDIO_VOLUME_TYPE_MAX] = { 9, 11, 7, 11, 7, 4, 4, 7, 4, 0 };
AUDIO_RETURN_VAL_IF_FAIL(am, AUDIO_ERR_PARAMETER);
for (i = 0; i < AUDIO_VOLUME_TYPE_MAX; i++) {
+ for (j = 0; j < AUDIO_VOLUME_DEVICE_MAX; j++) {
+ am->stream.volume_level[j][i] = init_value[i];
+ }
+ }
+
+ for (i = 0; i < AUDIO_VOLUME_TYPE_MAX; i++) {
/* Get volume value string from VCONF */
- if (vconf_get_int(g_volume_vconf[i], &value) != 0) {
- AUDIO_LOG_ERROR("vconf_get_int(%s) failed", g_volume_vconf[i]);
+ if((str = vconf_get_str(g_volume_vconf[i])) == NULL) {
+ AUDIO_LOG_ERROR("vconf_get_str(%s) failed", g_volume_vconf[i]);
continue;
}
- AUDIO_LOG_INFO("read vconf. %s = %d", g_volume_vconf[i], value);
+
+ AUDIO_LOG_INFO("read vconf. %s = %s", g_volume_vconf[i], str);
/* Unified type uses only fisrt index of volume devices */
- am->stream.volume_level[i] = value;
+
+ for (j = 0; j < AUDIO_VOLUME_DEVICE_MAX; j++) {
+ char val[3];
+ memset(val, 0, sizeof(val));
+ val[0] = str[j*2];
+ val[1] = str[j*2+1];
+ am->stream.volume_level[j][i] = atoi(val);
+ }
+
+ if (str)
+ free(str);
}
if (!(am->stream.volume_gain_table = malloc(STREAM_DEVICE_MAX * sizeof(audio_volume_gain_table_t)))) {
@@ -349,7 +373,13 @@ audio_return_t _audio_stream_init (audio_mgr_t *am)
return AUDIO_ERR_RESOURCE;
}
- return __load_volume_gain_table_from_ini(am);
+ audio_ret = __load_volume_gain_table_from_ini(am);
+ if(audio_ret != AUDIO_RET_OK) {
+ AUDIO_LOG_ERROR("gain table load error");
+ return AUDIO_ERR_UNDEFINED;
+ }
+
+ return audio_ret;
}
audio_return_t _audio_stream_deinit (audio_mgr_t *am)
@@ -387,7 +417,7 @@ audio_return_t audio_get_volume_level (void *userdata, uint32_t volume_type, uin
AUDIO_RETURN_VAL_IF_FAIL(am, AUDIO_ERR_PARAMETER);
- *level = am->stream.volume_level[volume_type];
+ *level = am->stream.volume_level[__get_volume_dev_index(am, volume_type)][volume_type];
return AUDIO_RET_OK;
}
@@ -401,9 +431,7 @@ audio_return_t audio_get_volume_value (void *userdata, audio_info_t *info, uint3
AUDIO_RETURN_VAL_IF_FAIL(am, AUDIO_ERR_PARAMETER);
AUDIO_RETURN_VAL_IF_FAIL(am->stream.volume_gain_table, AUDIO_ERR_PARAMETER);
-
__dump_info(&dump_str[0], info);
-
/* Get basic volume by device & type & level */
volume_gain_table = am->stream.volume_gain_table + __get_stream_dev_index(am->device.active_out);
if (volume_gain_table->volume_level_max[volume_type] < level)
@@ -420,28 +448,32 @@ audio_return_t audio_get_volume_value (void *userdata, audio_info_t *info, uint3
audio_return_t audio_set_volume_level (void *userdata, audio_info_t *info, uint32_t volume_type, uint32_t level)
{
+ audio_return_t audio_ret = AUDIO_RET_OK;
audio_mgr_t *am = (audio_mgr_t *)userdata;
AUDIO_RETURN_VAL_IF_FAIL(am, AUDIO_ERR_PARAMETER);
if (info == NULL) {
+
/* Update volume level */
- am->stream.volume_level[volume_type] = level;
+ am->stream.volume_level[__get_volume_dev_index(am, volume_type)][volume_type] = level;
+ AUDIO_LOG_INFO("set_volume_level:session(%d), %d(%s)", am->session.session, level, __get_volume_type_string_by_idx(volume_type));
}
- return AUDIO_RET_OK;
+ return audio_ret;
}
-audio_return_t _audio_update_volume_level (audio_mgr_t *am)
+audio_return_t audio_get_gain_value (void *userdata, audio_info_t *info, uint32_t volume_type, double *value)
{
- int i;
+ audio_mgr_t *am = (audio_mgr_t *)userdata;
+ audio_volume_gain_table_t *volume_gain_table;
- for (i = 0; i < AUDIO_VOLUME_TYPE_MAX; i++) {
- /* Update vconf */
- if (vconf_set_int(g_volume_vconf[i], am->stream.volume_level[i]) != 0) {
- AUDIO_LOG_ERROR("vconf_set_int(%s) failed", g_volume_vconf[i]);
- continue;
- }
+ AUDIO_RETURN_VAL_IF_FAIL(am, AUDIO_ERR_PARAMETER);
+ AUDIO_RETURN_VAL_IF_FAIL(am->stream.volume_gain_table, AUDIO_ERR_PARAMETER);
+
+ if (info != NULL) {
+ volume_gain_table = am->stream.volume_gain_table + __get_stream_dev_index(am->device.active_out);
+ *value = volume_gain_table->gain[info->stream.gain_type];
}
return AUDIO_RET_OK;
@@ -449,9 +481,23 @@ audio_return_t _audio_update_volume_level (audio_mgr_t *am)
audio_return_t audio_get_mute (void *userdata, audio_info_t *info, uint32_t volume_type, uint32_t direction, uint32_t *mute)
{
- return AUDIO_RET_OK; }
+ audio_return_t audio_ret = AUDIO_RET_OK;
+ audio_mgr_t *am = (audio_mgr_t *)userdata;
+
+ AUDIO_RETURN_VAL_IF_FAIL(am, AUDIO_ERR_PARAMETER);
+
+ /* TODO. Not implemented */
+
+ return audio_ret;
+}
audio_return_t audio_set_mute (void *userdata, audio_info_t *info, uint32_t volume_type, uint32_t direction, uint32_t mute)
{
- return AUDIO_RET_OK;
+ audio_return_t audio_ret = AUDIO_RET_OK;
+ audio_mgr_t *am = (audio_mgr_t *)userdata;
+
+ AUDIO_RETURN_VAL_IF_FAIL(am, AUDIO_ERR_PARAMETER);
+ /* TODO. Not implemented */
+
+ return audio_ret;
}