Promotion of audio-userspace.lnx.2.1-00037.
CRs Change ID Subject
--------------------------------------------------------------------------------------------------------------
1075152 I4a81e93d246d234b86a81eb6597cf641e1ea1991 hal: Changes Relating to DisplayPort Audio
1065036 I94df832ba5e2a26e9179d66d4639f168b5c30eeb hal: native DSD and mix path concurrency fix.
1074909 Ic1c437d4cb15db709941eec065d40b2ae173ea9d audio: Update hal to handle 32bit/384kHz playback.
1073616 Ic89553a69fd4746c7b6731b0f38ae830f44c3914 hal: Add support for aptxHD encoder for a2dp
1065036 Ie2b44ab26ed2262d1ed79fd8bead4a703096a861 configs: msmcobalt: select fractional output mode for as
Change-Id: Ifbc40248e9f9cacb06d793ff878159a85ba807d8
CRs-Fixed: 1065036, 1073616, 1074909, 1075152
diff --git a/configs/msmcobalt/mixer_paths_tavil.xml b/configs/msmcobalt/mixer_paths_tavil.xml
index 34543f5..29212f9 100644
--- a/configs/msmcobalt/mixer_paths_tavil.xml
+++ b/configs/msmcobalt/mixer_paths_tavil.xml
@@ -474,6 +474,8 @@
<!-- Headphone Default mode - uLP -->
<ctl name="RX HPH Mode" value="CLS_H_ULP" />
+ <ctl name="ASRC0 Output Mode" value="INT" />
+ <ctl name="ASRC1 Output Mode" value="INT" />
<!-- IIR/voice anc -->
<ctl name="IIR0 Band1" id ="0" value="268435456" />
@@ -1881,6 +1883,8 @@
</path>
<path name="asrc-mode">
+ <ctl name="ASRC0 Output Mode" value="FRAC" />
+ <ctl name="ASRC1 Output Mode" value="FRAC" />
<ctl name="RX INT1_2 NATIVE MUX" value="ON" />
<ctl name="RX INT2_2 NATIVE MUX" value="ON" />
<ctl name="ASRC0 MUX" value="ASRC_IN_HPHL" />
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index ea1092a..e72cb76 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -62,6 +62,7 @@
#define MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS 0
#define MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR 1
#define MIXER_ENC_CONFIG_BLOCK "SLIM_7_RX Encoder Config"
+#define MIXER_ENC_BIT_FORMAT "AFE Input Bit Format"
#define MIXER_ENC_FMT_SBC "SBC"
#define MIXER_ENC_FMT_AAC "AAC"
#define MIXER_ENC_FMT_APTX "APTX"
@@ -103,7 +104,7 @@
audio_get_codec_config_t audio_get_codec_config;
enum A2DP_STATE bt_state;
audio_format_t bt_encoder_format;
- void *enc_config_data;
+ uint32_t enc_sampling_rate;
bool a2dp_started;
bool a2dp_suspended;
int a2dp_total_active_session_request;
@@ -280,7 +281,7 @@
a2dp.a2dp_total_active_session_request = 0;
a2dp.a2dp_suspended = false;
a2dp.bt_encoder_format = AUDIO_FORMAT_INVALID;
- a2dp.enc_config_data = NULL;
+ a2dp.enc_sampling_rate = 48000;
a2dp.bt_state = A2DP_STATE_DISCONNECTED;
} else {
ALOGD("close a2dp called in improper state");
@@ -288,7 +289,7 @@
a2dp.a2dp_total_active_session_request = 0;
a2dp.a2dp_suspended = false;
a2dp.bt_encoder_format = AUDIO_FORMAT_INVALID;
- a2dp.enc_config_data = NULL;
+ a2dp.enc_sampling_rate = 48000;
a2dp.bt_state = A2DP_STATE_DISCONNECTED;
}
@@ -298,7 +299,7 @@
/* API to configure SBC DSP encoder */
bool configure_sbc_enc_format(audio_sbc_encoder_config *sbc_bt_cfg)
{
- struct mixer_ctl *ctl_enc_data;
+ struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
struct sbc_enc_cfg_t sbc_dsp_cfg;
bool is_configured = false;
int ret = 0;
@@ -343,8 +344,25 @@
if (ret != 0) {
ALOGE("%s: failed to set SBC encoder config", __func__);
is_configured = false;
- } else
- is_configured = true;
+ goto fail;
+ }
+ ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
+ MIXER_ENC_BIT_FORMAT);
+ if (!ctrl_bit_format) {
+ ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
+ is_configured = false;
+ goto fail;
+ }
+ ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
+ if (ret != 0) {
+ ALOGE("%s: Failed to set bit format to encoder", __func__);
+ is_configured = false;
+ goto fail;
+ }
+ is_configured = true;
+ a2dp.enc_sampling_rate = sbc_bt_cfg->sampling_rate;
+ ALOGV("Successfully updated SBC enc format with samplingrate: %d channelmode:%d",
+ sbc_dsp_cfg.sample_rate, sbc_dsp_cfg.channel_mode);
fail:
return is_configured;
}
@@ -352,7 +370,7 @@
/* API to configure APTX DSP encoder */
bool configure_aptx_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
{
- struct mixer_ctl *ctl_enc_data;
+ struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
struct custom_enc_cfg_aptx_t aptx_dsp_cfg;
bool is_configured = false;
int ret = 0;
@@ -388,17 +406,33 @@
is_configured = false;
goto fail;
}
+ ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
+ MIXER_ENC_BIT_FORMAT);
+ if (!ctrl_bit_format) {
+ ALOGE("ERROR bit format CONFIG data mixer control not identifed");
+ is_configured = false;
+ goto fail;
+ } else {
+ ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
+ if (ret != 0) {
+ ALOGE("%s: Failed to set bit format to encoder", __func__);
+ is_configured = false;
+ goto fail;
+ }
+ }
is_configured = true;
+ a2dp.enc_sampling_rate = aptx_bt_cfg->sampling_rate;
+ ALOGV("Successfully updated APTX enc format with samplingrate: %d channels:%d",
+ aptx_dsp_cfg.sample_rate, aptx_dsp_cfg.num_channels);
fail:
return is_configured;
}
/* API to configure APTX HD DSP encoder
- * TODO: ADD 24 bit configuration support
*/
bool configure_aptx_hd_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
{
- struct mixer_ctl *ctl_enc_data;
+ struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
struct custom_enc_cfg_aptx_t aptx_dsp_cfg;
bool is_configured = false;
int ret = 0;
@@ -412,6 +446,7 @@
is_configured = false;
goto fail;
}
+
a2dp.bt_encoder_format = AUDIO_FORMAT_APTX_HD;
memset(&aptx_dsp_cfg, 0x0, sizeof(struct custom_enc_cfg_aptx_t));
aptx_dsp_cfg.enc_format = ENC_MEDIA_FMT_APTX_HD;
@@ -434,7 +469,22 @@
is_configured = false;
goto fail;
}
+ ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_BIT_FORMAT);
+ if (!ctrl_bit_format) {
+ ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
+ is_configured = false;
+ goto fail;
+ }
+ ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S24_LE");
+ if (ret != 0) {
+ ALOGE("%s: Failed to set APTX HD encoder config", __func__);
+ is_configured = false;
+ goto fail;
+ }
is_configured = true;
+ a2dp.enc_sampling_rate = aptx_bt_cfg->sampling_rate;
+ ALOGV("Successfully updated APTX HD encformat with samplingrate: %d channels:%d",
+ aptx_dsp_cfg.sample_rate, aptx_dsp_cfg.num_channels);
fail:
return is_configured;
}
@@ -442,7 +492,7 @@
/* API to configure AAC DSP encoder */
bool configure_aac_enc_format(audio_aac_encoder_config *aac_bt_cfg)
{
- struct mixer_ctl *ctl_enc_data;
+ struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
struct aac_enc_cfg_t aac_dsp_cfg;
bool is_configured = false;
int ret = 0;
@@ -480,8 +530,25 @@
if (ret != 0) {
ALOGE("%s: failed to set SBC encoder config", __func__);
is_configured = false;
- } else
- is_configured = true;
+ goto fail;
+ }
+ ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
+ MIXER_ENC_BIT_FORMAT);
+ if (!ctrl_bit_format) {
+ is_configured = false;
+ ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
+ goto fail;
+ }
+ ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
+ if (ret != 0) {
+ ALOGE("%s: Failed to set bit format to encoder", __func__);
+ is_configured = false;
+ goto fail;
+ }
+ is_configured = true;
+ a2dp.enc_sampling_rate = aac_bt_cfg->sampling_rate;
+ ALOGV("Successfully updated AAC enc format with samplingrate: %d channels:%d",
+ aac_dsp_cfg.sample_rate, aac_dsp_cfg.channel_cfg);
fail:
return is_configured;
}
@@ -592,7 +659,7 @@
a2dp.a2dp_total_active_session_request--;
if ( a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
- struct mixer_ctl *ctl_enc_config;
+ struct mixer_ctl *ctl_enc_config, *ctrl_bit_format;
struct sbc_enc_cfg_t dummy_reset_config;
ALOGV("calling BT module stream stop");
@@ -611,6 +678,16 @@
sizeof(struct sbc_enc_cfg_t));
a2dp.bt_encoder_format = ENC_MEDIA_FMT_NONE;
}
+ ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
+ MIXER_ENC_BIT_FORMAT);
+ if (!ctrl_bit_format) {
+ ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
+ } else {
+ ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
+ if (ret != 0) {
+ ALOGE("%s: Failed to set bit format to encoder", __func__);
+ }
+ }
}
if(!a2dp.a2dp_total_active_session_request)
a2dp.a2dp_started = false;
@@ -684,6 +761,15 @@
return a2dp.is_handoff_in_progress;
}
+void audio_extn_a2dp_get_apptype_params(uint32_t *sample_rate,
+ uint32_t *bit_width)
+{
+ if(a2dp.bt_encoder_format == AUDIO_FORMAT_APTX_HD)
+ *bit_width = 24;
+ else
+ *bit_width = 16;
+ *sample_rate = a2dp.enc_sampling_rate;
+}
void audio_extn_a2dp_init (void *adev)
{
a2dp.adev = (struct audio_device*)adev;
@@ -693,7 +779,7 @@
a2dp.a2dp_total_active_session_request = 0;
a2dp.a2dp_suspended = false;
a2dp.bt_encoder_format = AUDIO_FORMAT_INVALID;
- a2dp.enc_config_data = NULL;
+ a2dp.enc_sampling_rate = 48000;
a2dp.is_a2dp_offload_supported = false;
a2dp.is_handoff_in_progress = false;
update_offload_codec_capabilities();
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 65f516c..083b925 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -129,7 +129,7 @@
int i = 0;
FILE *ext_disp_fd = NULL;
- for(i = 0; i < 3; i++) {
+ while (1) {
snprintf(fbpath, sizeof(fbpath),
"/sys/class/graphics/fb%d/msm_fb_type", i);
ext_disp_fd = fopen(fbpath, "r");
@@ -146,8 +146,10 @@
}
}
fclose(ext_disp_fd);
+ i++;
} else {
- ALOGE("%s: Failed to open fb node %d", __func__, i);
+ ALOGE("%s: Scanned till end of fbs or Failed to open fb node %d", __func__, i);
+ break;
}
}
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index b57bb81..cd9763e 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -179,6 +179,8 @@
#define audio_extn_a2dp_set_parameters(parms) (0)
#define audio_extn_a2dp_is_force_device_switch() (0)
#define audio_extn_a2dp_set_handoff_mode(is_on) (0)
+#define audio_extn_a2dp_get_apptype_params(sample_rate,bit_width) (0)
+
#else
void audio_extn_a2dp_init(void *adev);
int audio_extn_a2dp_start_playback();
@@ -186,6 +188,9 @@
void audio_extn_a2dp_set_parameters(struct str_parms *parms);
bool audio_extn_a2dp_is_force_device_switch();
void audio_extn_a2dp_set_handoff_mode(bool is_on);
+void audio_extn_a2dp_get_apptype_params(uint32_t *sample_rate,
+ uint32_t *bit_width);
+
#endif
#ifndef SSR_ENABLED
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index b3bd58f..f936f99 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -47,7 +47,7 @@
#define SAMPLE_RATE_11025 11025
// Supported sample rates for USB
static uint32_t supported_sample_rates[] =
- {44100, 48000, 64000, 88200, 96000, 176400, 192000};
+ {44100, 48000, 64000, 88200, 96000, 176400, 192000, 384000};
#define MAX_SAMPLE_RATE_SIZE sizeof(supported_sample_rates)/sizeof(supported_sample_rates[0])
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 26c43b4..9542fbd 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -495,7 +495,7 @@
struct stream_format *sf_info;
char value[PROPERTY_VALUE_MAX] = {0};
- if ((24 == bit_width) &&
+ if ((bit_width >= 24) &&
(devices & AUDIO_DEVICE_OUT_SPEAKER)) {
int32_t bw = platform_get_snd_device_bit_width(SND_DEVICE_OUT_SPEAKER);
if (-ENOSYS != bw)
@@ -529,6 +529,13 @@
sample_rate = OUTPUT_SAMPLING_RATE_DSD128;
}
+ if(devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ //TODO: Handle fractional sampling rate configuration for LL
+ audio_extn_a2dp_get_apptype_params(&sample_rate, &bit_width);
+ ALOGI("%s using %d sampling rate %d bit width for A2DP CoPP",
+ __func__, sample_rate, bit_width);
+ }
+
ALOGV("%s: flags: %x, format: %x sample_rate %d",
__func__, flags, format, sample_rate);
list_for_each(node_i, streams_output_cfg_list) {
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 673c17e..7888e5a 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -622,29 +622,75 @@
return 0;
}
-/*
- * Enable ASRC mode if native or DSD stream is active.
- */
-static void audio_check_and_set_asrc_mode(struct audio_device *adev, snd_device_t snd_device)
+static void enable_asrc_mode(struct audio_device *adev)
{
- if (SND_DEVICE_OUT_HEADPHONES == snd_device &&
- !adev->asrc_mode_enabled) {
+ ALOGV("%s", __func__);
+ audio_route_apply_and_update_path(adev->audio_route,
+ "asrc-mode");
+ adev->asrc_mode_enabled = true;
+}
+
+static void disable_asrc_mode(struct audio_device *adev)
+{
+ ALOGV("%s", __func__);
+ audio_route_reset_and_update_path(adev->audio_route,
+ "asrc-mode");
+ adev->asrc_mode_enabled = false;
+}
+
+/*
+ * - Enable ASRC mode for incoming mix path use case(Headphone backend)if Headphone
+ * 44.1 or Native DSD backends are enabled for any of current use case.
+ * e.g. 48-> + (Naitve DSD or Headphone 44.1)
+ * - Disable current mix path use case(Headphone backend) and re-enable it with
+ * ASRC mode for incoming Headphone 44.1 or Native DSD use case.
+ * e.g. Naitve DSD or Headphone 44.1 -> + 48
+ */
+static void check_and_set_asrc_mode(struct audio_device *adev, snd_device_t snd_device)
+{
+ ALOGV("%s snd device %d", __func__, snd_device);
+ int new_backend_idx = platform_get_backend_index(snd_device);
+
+ if (((new_backend_idx == HEADPHONE_BACKEND) ||
+ (new_backend_idx == HEADPHONE_44_1_BACKEND) ||
+ (new_backend_idx == DSD_NATIVE_BACKEND)) &&
+ !adev->asrc_mode_enabled) {
struct listnode *node = NULL;
struct audio_usecase *uc = NULL;
struct stream_out *curr_out = NULL;
+ int usecase_backend_idx = DEFAULT_CODEC_BACKEND;
list_for_each(node, &adev->usecase_list) {
uc = node_to_item(node, struct audio_usecase, list);
curr_out = (struct stream_out*) uc->stream.out;
-
if (curr_out && PCM_PLAYBACK == uc->type) {
- if((platform_get_backend_index(uc->out_snd_device) == HEADPHONE_44_1_BACKEND) ||
- (platform_get_backend_index(uc->out_snd_device) == DSD_NATIVE_BACKEND)) {
+ usecase_backend_idx = platform_get_backend_index(uc->out_snd_device);
+
+ if((new_backend_idx == HEADPHONE_BACKEND) &&
+ ((usecase_backend_idx == HEADPHONE_44_1_BACKEND) ||
+ (usecase_backend_idx == DSD_NATIVE_BACKEND))) {
ALOGD("%s:DSD or native stream detected enabling asrcmode in hardware",
__func__);
- audio_route_apply_and_update_path(adev->audio_route,
- "asrc-mode");
- adev->asrc_mode_enabled = true;
+ enable_asrc_mode(adev);
+ break;
+ } else if(((new_backend_idx == HEADPHONE_44_1_BACKEND) ||
+ (new_backend_idx == DSD_NATIVE_BACKEND)) &&
+ (usecase_backend_idx == HEADPHONE_BACKEND)) {
+ ALOGD("%s:48K stream detected, disabling and enabling it with asrcmode in hardware",
+ __func__);
+ disable_audio_route(adev, uc);
+ disable_snd_device(adev, uc->out_snd_device);
+ // Apply true-high-quality-mode if DSD or > 44.1KHz or >=24-bit
+ if (new_backend_idx == DSD_NATIVE_BACKEND)
+ audio_route_apply_and_update_path(adev->audio_route,
+ "hph-true-highquality-mode");
+ else if ((new_backend_idx == HEADPHONE_44_1_BACKEND) &&
+ (curr_out->bit_width >= 24))
+ audio_route_apply_and_update_path(adev->audio_route,
+ "hph-highquality-mode");
+ enable_asrc_mode(adev);
+ enable_snd_device(adev, uc->out_snd_device);
+ enable_audio_route(adev, uc);
break;
}
}
@@ -802,8 +848,7 @@
audio_route_apply_and_update_path(adev->audio_route,
"true-native-mode");
adev->native_playback_enabled = true;
- } else
- audio_check_and_set_asrc_mode(adev, snd_device);
+ }
}
return 0;
}
@@ -862,8 +907,8 @@
} else if (SND_DEVICE_OUT_HEADPHONES == snd_device &&
adev->asrc_mode_enabled) {
ALOGD("%s: %d: disabling asrc mode in hardware", __func__, __LINE__);
- audio_route_reset_and_update_path(adev->audio_route, "asrc-mode");
- adev->asrc_mode_enabled = false;
+ disable_asrc_mode(adev);
+ audio_route_apply_and_update_path(adev->audio_route, "hph-lowpower-mode");
}
audio_extn_dev_arbi_release(snd_device);
@@ -936,9 +981,8 @@
(usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) ||
(usecase->devices & AUDIO_DEVICE_OUT_USB_DEVICE) ||
(force_restart_session)) &&
- (platform_check_backends_match(snd_device, usecase->out_snd_device)||
- (platform_check_codec_asrc_support(adev->platform) && !adev->asrc_mode_enabled &&
- platform_check_if_backend_has_to_be_disabled(snd_device,usecase->out_snd_device)))) {
+ (platform_check_backends_match(snd_device, usecase->out_snd_device))) {
+
ALOGD("%s:becf: check_usecases (%s) is active on (%s) - disabling ..",
__func__, use_case_table[usecase->id],
platform_get_snd_device_name(usecase->out_snd_device));
@@ -1087,10 +1131,9 @@
reset_hdmi_sink_caps(out);
/* Cache ext disp type */
- ret = platform_get_ext_disp_type(adev->platform);
- if (ret < 0) {
+ if (platform_get_ext_disp_type(adev->platform) <= 0) {
ALOGE("%s: Failed to query disp type, ret:%d", __func__, ret);
- return ret;
+ return -EINVAL;
}
switch (channels) {
@@ -1422,6 +1465,8 @@
/* Enable new sound devices */
if (out_snd_device != SND_DEVICE_NONE) {
check_usecases_codec_backend(adev, usecase, out_snd_device);
+ if (platform_check_codec_asrc_support(adev->platform))
+ check_and_set_asrc_mode(adev, out_snd_device);
enable_snd_device(adev, out_snd_device);
}
@@ -2183,6 +2228,35 @@
return size;
}
+static size_t get_output_period_size(uint32_t sample_rate,
+ audio_format_t format,
+ int channel_count,
+ int duration /*in millisecs*/)
+{
+ size_t size = 0;
+ uint32_t bytes_per_sample = audio_bytes_per_sample(format);
+
+ if ((duration == 0) || (sample_rate == 0) ||
+ (bytes_per_sample == 0) || (channel_count == 0)) {
+ ALOGW("Invalid config duration %d sr %d bps %d ch %d", duration, sample_rate,
+ bytes_per_sample, channel_count);
+ return -EINVAL;
+ }
+
+ size = (sample_rate *
+ duration *
+ bytes_per_sample *
+ channel_count) / 1000;
+ /*
+ * To have same PCM samples for all channels, the buffer size requires to
+ * be multiple of (number of channels * bytes per sample)
+ * For writes to succeed, the buffer must be written at address which is multiple of 32
+ */
+ size = ALIGN(size, (bytes_per_sample * channel_count * 32));
+
+ return (size/(channel_count * bytes_per_sample));
+}
+
static uint64_t get_actual_pcm_frames_rendered(struct stream_out *out)
{
uint64_t actual_frames_rendered = 0;
@@ -3853,6 +3927,17 @@
out->config = pcm_config_afe_proxy_playback;
adev->voice_tx_output = out;
} else {
+ unsigned int channels = 0;
+ /*Update config params to default if not set by the caller*/
+ if (config->sample_rate == 0)
+ config->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+ if (config->channel_mask == AUDIO_CHANNEL_NONE)
+ config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ if (config->format == AUDIO_FORMAT_DEFAULT)
+ config->format = AUDIO_FORMAT_PCM_16_BIT;
+
+ channels = audio_channel_count_from_out_mask(out->channel_mask);
+
if (out->flags & AUDIO_OUTPUT_FLAG_RAW) {
out->usecase = USECASE_AUDIO_PLAYBACK_ULL;
out->realtime = may_use_noirq_mode(adev, USECASE_AUDIO_PLAYBACK_ULL,
@@ -3864,6 +3949,13 @@
} else if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) {
out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
out->config = pcm_config_deep_buffer;
+ out->config.period_size = get_output_period_size(config->sample_rate, out->format,
+ channels, DEEP_BUFFER_OUTPUT_PERIOD_DURATION);
+ if (out->config.period_size <= 0) {
+ ALOGE("Invalid configuration period size is not valid");
+ ret = -EINVAL;
+ goto error_open;
+ }
} else {
/* primary path is the default path selected if no other outputs are available/suitable */
out->usecase = USECASE_AUDIO_PLAYBACK_PRIMARY;
@@ -3875,7 +3967,7 @@
out->bit_width = format_to_bitwidth_table[out->hal_op_format] << 3;
out->config.rate = config->sample_rate;
out->sample_rate = out->config.rate;
- out->config.channels = audio_channel_count_from_out_mask(out->channel_mask);
+ out->config.channels = channels;
if (out->hal_ip_format != out->hal_op_format) {
uint32_t buffer_size = out->config.period_size *
format_to_bitwidth_table[out->hal_op_format] *
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 47943da..a5cc804 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -4304,7 +4304,7 @@
else
mixer_ctl_set_enum_by_string(ctl, "S24_LE");
} else if (bit_width == 32) {
- mixer_ctl_set_enum_by_string(ctl, "S24_LE");
+ mixer_ctl_set_enum_by_string(ctl, "S32_LE");
} else {
mixer_ctl_set_enum_by_string(ctl, "S16_LE");
}
@@ -4640,6 +4640,13 @@
} else if ((usecase->devices & AUDIO_DEVICE_OUT_SPEAKER) ||
(usecase->devices & AUDIO_DEVICE_OUT_EARPIECE) ) {
sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+
+ if (bit_width >= 24) {
+ bit_width = platform_get_snd_device_bit_width(SND_DEVICE_OUT_SPEAKER);
+ ALOGD("%s:becf: afe: reset bitwidth to %d (based on supported"
+ " value for this platform)", __func__, bit_width);
+ }
+
ALOGD("%s:becf: afe: playback on codec device not supporting native playback set "
"default Sample Rate(48k)", __func__);
}
@@ -4660,6 +4667,13 @@
hdmi_backend_cfg.channels = channels;
hdmi_backend_cfg.passthrough_enabled = false;
+ /*HDMI does not support 384Khz/32bit playback hence configure BE to 24b/192Khz*/
+ /* TODO: Instead have the validation against edid return the next best match*/
+ if (bit_width > 24)
+ hdmi_backend_cfg.bit_width = 24;
+ if (sample_rate > 192000)
+ hdmi_backend_cfg.sample_rate = 192000;
+
platform_check_hdmi_backend_cfg(adev, usecase, backend_idx, &hdmi_backend_cfg);
bit_width = hdmi_backend_cfg.bit_width;
@@ -5618,12 +5632,6 @@
return false;
}
-bool platform_check_if_backend_has_to_be_disabled(snd_device_t new_snd_device __unused,
- snd_device_t cuurent_snd_device __unused)
-{
- return false;
-}
-
int platform_send_audio_cal(void* platform __unused,
int acdb_dev_id __unused, int acdb_device_type __unused,
int app_type __unused, int topology_id __unused,
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index 33be141..cba9068 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -267,6 +267,7 @@
* the buffer size of an input/output stream
*/
#define DEEP_BUFFER_OUTPUT_PERIOD_SIZE 1920
+#define DEEP_BUFFER_OUTPUT_PERIOD_DURATION 40 /* 40 millisecs */
#define DEEP_BUFFER_OUTPUT_PERIOD_COUNT 2
#define LOW_LATENCY_OUTPUT_PERIOD_SIZE 240
#define LOW_LATENCY_OUTPUT_PERIOD_COUNT 2
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index b687d96..b5a4f11 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -1330,8 +1330,3 @@
return false;
}
-bool platform_check_if_backend_has_to_be_disabled(snd_device_t new_snd_device __unused,
- snd_device_t cuurent_snd_device __unused)
-{
- return false;
-}
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 6930286..fa67342 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1987,32 +1987,6 @@
return result;
}
-bool platform_check_if_backend_has_to_be_disabled(snd_device_t new_snd_device,
- snd_device_t cuurent_snd_device)
-{
- bool result = false;
-
- ALOGV("%s: current snd device = %s, new snd device = %s", __func__,
- platform_get_snd_device_name(cuurent_snd_device),
- platform_get_snd_device_name(new_snd_device));
-
- if ((new_snd_device < SND_DEVICE_MIN) || (new_snd_device >= SND_DEVICE_OUT_END) ||
- (cuurent_snd_device < SND_DEVICE_MIN) || (cuurent_snd_device >= SND_DEVICE_OUT_END)) {
- ALOGE("%s: Invalid snd_device",__func__);
- return false;
- }
-
- if (cuurent_snd_device == SND_DEVICE_OUT_HEADPHONES &&
- (new_snd_device == SND_DEVICE_OUT_HEADPHONES_44_1 ||
- new_snd_device == SND_DEVICE_OUT_HEADPHONES_DSD)) {
- result = true;
- }
-
- ALOGV("%s: Need to disable current backend %s, %d",
- __func__, platform_get_snd_device_name(cuurent_snd_device), result);
- return result;
-}
-
int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
{
int device_id;
@@ -2191,7 +2165,7 @@
{
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 CODEC_BACKEND_DEFAULT_BIT_WIDTH;
}
return backend_bit_width_table[snd_device];
}
@@ -4389,7 +4363,7 @@
else
ret = mixer_ctl_set_enum_by_string(ctl, "S24_LE");
} else if (bit_width == 32) {
- ret = mixer_ctl_set_enum_by_string(ctl, "S24_LE");
+ ret = mixer_ctl_set_enum_by_string(ctl, "S32_LE");
} else {
ret = mixer_ctl_set_enum_by_string(ctl, "S16_LE");
}
@@ -4723,13 +4697,20 @@
ALOGD("%s:becf: afe: true napb active set rate to 44.1 khz",
__func__);
}
- } else if (OUTPUT_SAMPLING_RATE_44100 == sample_rate) {
+ } else if ((OUTPUT_SAMPLING_RATE_44100 == sample_rate) &&
+ (na_mode != NATIVE_AUDIO_MODE_MULTIPLE_44_1)) {
sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
ALOGD("%s:becf: afe: napb not active - set (48k) default rate",
__func__);
}
} else if ((usecase->devices & AUDIO_DEVICE_OUT_SPEAKER) ||
(usecase->devices & AUDIO_DEVICE_OUT_EARPIECE) ) {
+
+ if (bit_width >= 24) {
+ bit_width = platform_get_snd_device_bit_width(SND_DEVICE_OUT_SPEAKER);
+ ALOGD("%s:becf: afe: reset bitwidth to %d (based on supported"
+ " value for this platform)", __func__, bit_width);
+ }
sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
ALOGD("%s:becf: afe: playback on codec device not supporting native playback set "
"default Sample Rate(48k)", __func__);
@@ -4750,6 +4731,15 @@
hdmi_backend_cfg.channels = channels;
hdmi_backend_cfg.passthrough_enabled = false;
+ /*
+ * HDMI does not support 384Khz/32bit playback hence configure BE to 24b/192Khz
+ * TODO: Instead have the validation against edid return the next best match
+ */
+ if (bit_width > 24)
+ hdmi_backend_cfg.bit_width = 24;
+ if (sample_rate > 192000)
+ hdmi_backend_cfg.sample_rate = 192000;
+
platform_check_hdmi_backend_cfg(adev, usecase, backend_idx, &hdmi_backend_cfg);
bit_width = hdmi_backend_cfg.bit_width;
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 2b65950..c231843 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -257,7 +257,14 @@
* We should take care of returning proper size when AudioFlinger queries for
* the buffer size of an input/output stream
*/
+
+/* for 384Khz output below period size corresponds to 20ms worth duration of buffer,
+ * current implementation can support buffer size of 40ms duration
+ * for 32b/384Khz/stereo output.
+ */
#define DEEP_BUFFER_OUTPUT_PERIOD_SIZE 1920
+#define DEEP_BUFFER_OUTPUT_PERIOD_DURATION 40 /* 40 milisecs */
+
#define DEEP_BUFFER_OUTPUT_PERIOD_COUNT 2
#define LOW_LATENCY_OUTPUT_PERIOD_SIZE 240
#define LOW_LATENCY_OUTPUT_PERIOD_COUNT 2