hal: Support config selection for playback on speaker
Support bit width selection for playback on speakers based on
platform info.
Change-Id: I8dd2cc7049186e7468615a43db550d7d580a81d1
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 6818161..8bd98a0 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -436,6 +436,9 @@
if ((24 == bit_width) &&
(devices & AUDIO_DEVICE_OUT_SPEAKER)) {
+ int32_t bw = platform_get_snd_device_bit_width(SND_DEVICE_OUT_SPEAKER);
+ if (-ENOSYS != bw)
+ bit_width = (uint32_t)bw;
sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
ALOGI("%s Allowing 24-bit playback on speaker ONLY at default sampling rate", __func__);
}
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 7b945cf..b4476f5 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -1035,6 +1035,18 @@
return acdb_device_table[snd_device];
}
+int platform_set_snd_device_bit_width(snd_device_t snd_device, unsigned int bit_width)
+{
+ ALOGE("%s: Not implemented", __func__);
+ return -ENOSYS;
+}
+
+int platform_get_snd_device_bit_width(snd_device_t snd_device)
+{
+ ALOGE("%s: Not implemented", __func__);
+ return -ENOSYS;
+}
+
int platform_send_audio_calibration(void *platform, snd_device_t snd_device,
int app_type, int sample_rate)
{
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index e2c30f4..87ce2cd 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -421,6 +421,18 @@
return -ENOSYS;
}
+int platform_set_snd_device_bit_width(snd_device_t snd_device, unsigned int bit_width)
+{
+ ALOGE("%s: Not implemented", __func__);
+ return -ENOSYS;
+}
+
+int platform_get_snd_device_bit_width(snd_device_t snd_device)
+{
+ ALOGE("%s: Not implemented", __func__);
+ return -ENOSYS;
+}
+
int platform_switch_voice_call_enable_device_config(void *platform __unused,
snd_device_t out_snd_device __unused,
snd_device_t in_snd_device __unused)
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index ff1f9b8..66c7731 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -298,6 +298,9 @@
[SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE] = "speaker-dmic-broadside",
};
+// Platform specific backend bit width table
+static int backend_bit_width_table[SND_DEVICE_MAX] = {0};
+
/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
static int acdb_device_table[SND_DEVICE_MAX] = {
[SND_DEVICE_NONE] = -1,
@@ -693,6 +696,9 @@
for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
backend_table[dev] = NULL;
}
+ for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
+ backend_bit_width_table[dev] = 16;
+ }
// TBD - do these go to the platform-info.xml file.
// will help in avoiding strdups here
@@ -1164,6 +1170,31 @@
return acdb_device_table[snd_device];
}
+int platform_set_snd_device_bit_width(snd_device_t snd_device, unsigned int bit_width)
+{
+ int ret = 0;
+
+ if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
+ ALOGE("%s: Invalid snd_device = %d",
+ __func__, snd_device);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ backend_bit_width_table[snd_device] = bit_width;
+done:
+ return ret;
+}
+
+int platform_get_snd_device_bit_width(snd_device_t snd_device)
+{
+ if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
+ ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
+ return DEFAULT_OUTPUT_SAMPLING_RATE;
+ }
+ return backend_bit_width_table[snd_device];
+}
+
int platform_send_audio_calibration(void *platform, snd_device_t snd_device,
int app_type, int sample_rate)
{
@@ -2559,11 +2590,15 @@
}
}
- // 24 bit playback on speakers and all 16 bit playbacks is allowed through
- // 16 bit/48 khz backend only
- if ((16 == bit_width) ||
- ((24 == bit_width) &&
- (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER))) {
+ // 16 bit playback on speakers is allowed through 48 khz backend only
+ if (16 == bit_width) {
+ sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ }
+ // 24 bit playback on speakers is allowed through 48 khz backend only
+ // bit width re-configured based on platform info
+ if ((24 == bit_width) &&
+ (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
+ bit_width = (uint32_t)platform_get_snd_device_bit_width(SND_DEVICE_OUT_SPEAKER);
sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
}
// Force routing if the expected bitwdith or samplerate
diff --git a/hal/platform_api.h b/hal/platform_api.h
index b11a0c7..534630c 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -36,6 +36,8 @@
int platform_get_fluence_type(void *platform, char *value, uint32_t len);
int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id);
int platform_get_snd_device_acdb_id(snd_device_t snd_device);
+int platform_set_snd_device_bit_width(snd_device_t snd_device, unsigned int bit_width);
+int platform_get_snd_device_bit_width(snd_device_t snd_device);
int platform_send_audio_calibration(void *platform, snd_device_t snd_device,
int app_type, int sample_rate);
int platform_get_default_app_type(void *platform);
diff --git a/hal/platform_info.c b/hal/platform_info.c
index 615b9f3..a176177 100644
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -43,6 +43,7 @@
typedef enum {
ROOT,
ACDB,
+ BITWIDTH,
PCM_ID,
BACKEND_NAME,
} section_t;
@@ -50,6 +51,7 @@
typedef void (* section_process_fn)(const XML_Char **attr);
static void process_acdb_id(const XML_Char **attr);
+static void process_bit_width(const XML_Char **attr);
static void process_pcm_id(const XML_Char **attr);
static void process_backend_name(const XML_Char **attr);
static void process_root(const XML_Char **attr);
@@ -57,6 +59,7 @@
static section_process_fn section_table[] = {
[ROOT] = process_root,
[ACDB] = process_acdb_id,
+ [BITWIDTH] = process_bit_width,
[PCM_ID] = process_pcm_id,
[BACKEND_NAME] = process_backend_name,
};
@@ -202,6 +205,38 @@
return;
}
+static void process_bit_width(const XML_Char **attr)
+{
+ int index;
+
+ if (strcmp(attr[0], "name") != 0) {
+ ALOGE("%s: 'name' not found, no ACDB ID set!", __func__);
+ goto done;
+ }
+
+ index = platform_get_snd_device_index((char *)attr[1]);
+ if (index < 0) {
+ ALOGE("%s: Device %s in platform info xml not found, no ACDB ID set!",
+ __func__, attr[1]);
+ goto done;
+ }
+
+ if (strcmp(attr[2], "bit_width") != 0) {
+ ALOGE("%s: Device %s in platform info xml has no bit_width, no ACDB ID set!",
+ __func__, attr[1]);
+ goto done;
+ }
+
+ if (platform_set_snd_device_bit_width(index, atoi((char *)attr[3])) < 0) {
+ ALOGE("%s: Device %s, ACDB ID %d was not set!",
+ __func__, attr[1], atoi((char *)attr[3]));
+ goto done;
+ }
+
+done:
+ return;
+}
+
static void start_tag(void *userdata __unused, const XML_Char *tag_name,
const XML_Char **attr)
{
@@ -209,14 +244,16 @@
const XML_Char *attr_value = NULL;
unsigned int i;
- if (strcmp(tag_name, "acdb_ids") == 0) {
+ if (strcmp(tag_name, "bit_width_configs") == 0) {
+ section = BITWIDTH;
+ } else if (strcmp(tag_name, "acdb_ids") == 0) {
section = ACDB;
} else if (strcmp(tag_name, "pcm_ids") == 0) {
section = PCM_ID;
} else if (strcmp(tag_name, "backend_names") == 0) {
section = BACKEND_NAME;
} else if (strcmp(tag_name, "device") == 0) {
- if ((section != ACDB) && (section != BACKEND_NAME)) {
+ if ((section != ACDB) && (section != BACKEND_NAME) && (section != BITWIDTH)) {
ALOGE("device tag only supported for acdb/backend names");
return;
}
@@ -239,7 +276,9 @@
static void end_tag(void *userdata __unused, const XML_Char *tag_name)
{
- if (strcmp(tag_name, "acdb_ids") == 0) {
+ if (strcmp(tag_name, "bit_width_configs") == 0) {
+ section = ROOT;
+ } else if (strcmp(tag_name, "acdb_ids") == 0) {
section = ROOT;
} else if (strcmp(tag_name, "pcm_ids") == 0) {
section = ROOT;