hal: Add support for aptxHD encoder for a2dp
- Add support to configure ADM with encoder bit width and sampling rate for a2dp device - Add support to configure AFE bit rate based on a2dp encoder format Change-Id: Ic89553a69fd4746c7b6731b0f38ae830f44c3914
This commit is contained in:
parent
df4367974c
commit
f5ba8d0128
|
@ -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 @@ struct a2dp_data {
|
|||
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 @@ static int close_a2dp_output()
|
|||
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 @@ static int close_a2dp_output()
|
|||
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 @@ static int close_a2dp_output()
|
|||
/* 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 @@ bool configure_sbc_enc_format(audio_sbc_encoder_config *sbc_bt_cfg)
|
|||
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 @@ fail:
|
|||
/* 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 @@ bool configure_aptx_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
|
|||
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 @@ bool configure_aptx_hd_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
|
|||
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 @@ bool configure_aptx_hd_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
|
|||
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 @@ fail:
|
|||
/* 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 @@ bool configure_aac_enc_format(audio_aac_encoder_config *aac_bt_cfg)
|
|||
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 @@ int audio_extn_a2dp_stop_playback()
|
|||
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 @@ int audio_extn_a2dp_stop_playback()
|
|||
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 @@ bool audio_extn_a2dp_is_force_device_switch()
|
|||
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 @@ void audio_extn_a2dp_init (void *adev)
|
|||
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();
|
||||
|
|
|
@ -179,6 +179,8 @@ int audio_extn_usb_set_sidetone_gain(struct str_parms *parms,
|
|||
#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_stop_playback();
|
|||
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
|
||||
|
|
|
@ -529,6 +529,13 @@ void audio_extn_utils_update_stream_app_type_cfg(void *platform,
|
|||
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) {
|
||||
|
|
Loading…
Reference in New Issue