Loading Android.mk +1 −1 Original line number Diff line number Diff line # TODO: Find a better way to separate build configs for ADP vs non-ADP devices ifneq ($(TARGET_BOARD_AUTO),true) ifneq ($(filter msm8960 msm8226 msm8x26 msm8x84 msm8084 msm8992 msm8994 msm8996 msm8909 msm8952 msm8998 sdm845,$(TARGET_BOARD_PLATFORM)),) ifneq ($(filter msm8960 msm8226 msm8x26 msm8x84 msm8084 msm8992 msm8994 msm8996 msm8909 msm8952 msm8998 sdm845 sdm710,$(TARGET_BOARD_PLATFORM)),) MY_LOCAL_PATH := $(call my-dir) Loading hal/Android.mk +9 −2 Original line number Diff line number Diff line Loading @@ -10,7 +10,7 @@ AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM) ifneq ($(filter msm8960,$(TARGET_BOARD_PLATFORM)),) LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="2" endif ifneq ($(filter msm8974 msm8226 msm8084 msm8992 msm8994 msm8996 msm8998 sdm845,$(TARGET_BOARD_PLATFORM)),) ifneq ($(filter msm8974 msm8226 msm8084 msm8992 msm8994 msm8996 msm8998 sdm845 sdm710,$(TARGET_BOARD_PLATFORM)),) # B-family platform uses msm8974 code base AUDIO_PLATFORM = msm8974 ifneq ($(filter msm8974,$(TARGET_BOARD_PLATFORM)),) Loading Loading @@ -55,6 +55,13 @@ ifneq ($(filter sdm845,$(TARGET_BOARD_PLATFORM)),) LOCAL_CFLAGS += -DINCALL_STEREO_CAPTURE_ENABLED MULTIPLE_HW_VARIANTS_ENABLED := true endif ifneq ($(filter sdm710,$(TARGET_BOARD_PLATFORM)),) LOCAL_CFLAGS := -DPLATFORM_SDM710 LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="4" LOCAL_CFLAGS += -DINCALL_MUSIC_ENABLED LOCAL_CFLAGS += -DINCALL_STEREO_CAPTURE_ENABLED MULTIPLE_HW_VARIANTS_ENABLED := true endif endif ifneq ($(filter msm8916 msm8909 msm8952,$(TARGET_BOARD_PLATFORM)),) Loading Loading @@ -171,7 +178,7 @@ ifeq ($(strip $(AUDIO_FEATURE_ENABLED_A2DP_OFFLOAD)),true) LOCAL_SRC_FILES += audio_extn/a2dp.c endif ifneq ($(filter msm8992 msm8994 msm8996 msm8998 sdm845,$(TARGET_BOARD_PLATFORM)),) ifneq ($(filter msm8992 msm8994 msm8996 msm8998 sdm845 sdm710,$(TARGET_BOARD_PLATFORM)),) # push codec/mad calibration to HW dep node # applicable to msm8992/8994 or newer platforms LOCAL_CFLAGS += -DHWDEP_CAL_ENABLED Loading hal/audio_extn/a2dp.c +92 −46 Original line number Diff line number Diff line Loading @@ -159,6 +159,11 @@ typedef enum { IMC_ENABLE, } imc_status_t; typedef enum { MTU_SIZE, PEAK_BIT_RATE, } frame_control_type_t; /* PCM config for ABR Feedback hostless front end */ static struct pcm_config pcm_config_abr = { .channels = 1, Loading Loading @@ -288,12 +293,25 @@ struct imc_dec_enc_info { uint32_t comm_instance; }; /* Structure to control frame size of AAC encoded frames. */ struct aac_frame_size_control_t { /* Type of frame size control: MTU_SIZE / PEAK_BIT_RATE*/ uint32_t ctl_type; /* Control value * MTU_SIZE: MTU size in bytes * PEAK_BIT_RATE: Peak bitrate in bits per second. */ uint32_t ctl_value; }; /* Structure used for ABR config of AFE encoder and decoder. */ struct abr_enc_cfg_t { /* Link quality level to bitrate mapping info sent to DSP. */ struct quality_level_to_bitrate_info mapping_info; /* Information to set up IMC between decoder and encoder */ struct imc_dec_enc_info imc_info; /* Flag to indicate whether ABR is enabled */ bool is_abr_enabled; } __attribute__ ((packed)); /* Structure to send configuration for decoder introduced Loading @@ -310,10 +328,7 @@ struct abr_dec_cfg_t { * These values should match with DSP interface defintion */ /* AAC encoder configuration structure. */ typedef struct aac_enc_cfg_t aac_enc_cfg_t; struct aac_enc_cfg_t { struct aac_cfg_blk_t { /* Encoder media format for AAC */ uint32_t enc_format; Loading @@ -333,6 +348,14 @@ struct aac_enc_cfg_t { uint32_t sample_rate; } __attribute__ ((packed)); /* AAC encoder configuration structure. */ typedef struct aac_enc_cfg_t aac_enc_cfg_t; struct aac_enc_cfg_t { struct aac_cfg_blk_t aac_cfg; struct aac_frame_size_control_t frame_ctl; } __attribute__ ((packed)); /* SBC encoder configuration structure. */ typedef struct sbc_enc_cfg_t sbc_enc_cfg_t; Loading Loading @@ -493,6 +516,7 @@ typedef struct { uint32_t sampling_rate; uint32_t bitrate; uint32_t bits_per_sample; struct aac_frame_size_control_t frame_ctl; } audio_aac_encoder_config; /* Information about Bluetooth LDAC encoder configuration Loading Loading @@ -807,7 +831,7 @@ static int a2dp_set_backend_cfg() } // Set Tx backend sample rate if (a2dp.abr_config.is_abr_enabled) if (a2dp.abr_config.is_abr_enabled) { rate_str = ABR_TX_SAMPLE_RATE; ALOGV("%s: set backend tx sample rate = %s", __func__, rate_str); Loading @@ -822,6 +846,7 @@ static int a2dp_set_backend_cfg() __func__, rate_str); return -ENOSYS; } } // Configure AFE input channels switch (a2dp.enc_channels) { Loading Loading @@ -901,6 +926,7 @@ static int a2dp_reset_backend_cfg() return -ENOSYS; } if (a2dp.abr_config.is_abr_enabled) { ctl_sample_rate_tx = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_SAMPLE_RATE_TX); if (!ctl_sample_rate_tx) { Loading @@ -911,6 +937,7 @@ static int a2dp_reset_backend_cfg() ALOGE("%s: Failed to reset Tx backend sample rate = %s", __func__, rate_str); return -ENOSYS; } } // Reset AFE input channels ALOGV("%s: reset AFE input channels = %s", __func__, in_channels); Loading Loading @@ -1184,23 +1211,25 @@ static bool configure_aac_enc_format(audio_aac_encoder_config *aac_bt_cfg) goto exit; } memset(&aac_dsp_cfg, 0x0, sizeof(aac_dsp_cfg)); aac_dsp_cfg.enc_format = ENC_MEDIA_FMT_AAC; aac_dsp_cfg.bit_rate = aac_bt_cfg->bitrate; aac_dsp_cfg.sample_rate = aac_bt_cfg->sampling_rate; aac_dsp_cfg.aac_cfg.enc_format = ENC_MEDIA_FMT_AAC; aac_dsp_cfg.aac_cfg.bit_rate = aac_bt_cfg->bitrate; aac_dsp_cfg.aac_cfg.sample_rate = aac_bt_cfg->sampling_rate; switch (aac_bt_cfg->enc_mode) { case 0: aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_LC; aac_dsp_cfg.aac_cfg.enc_mode = MEDIA_FMT_AAC_AOT_LC; break; case 2: aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_PS; aac_dsp_cfg.aac_cfg.enc_mode = MEDIA_FMT_AAC_AOT_PS; break; case 1: default: aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_SBR; aac_dsp_cfg.aac_cfg.enc_mode = MEDIA_FMT_AAC_AOT_SBR; break; } aac_dsp_cfg.aac_fmt_flag = aac_bt_cfg->format_flag; aac_dsp_cfg.channel_cfg = aac_bt_cfg->channels; aac_dsp_cfg.aac_cfg.aac_fmt_flag = aac_bt_cfg->format_flag; aac_dsp_cfg.aac_cfg.channel_cfg = aac_bt_cfg->channels; aac_dsp_cfg.frame_ctl.ctl_type = aac_bt_cfg->frame_ctl.ctl_type; aac_dsp_cfg.frame_ctl.ctl_value = aac_bt_cfg->frame_ctl.ctl_value; ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aac_dsp_cfg, sizeof(aac_dsp_cfg)); if (ret != 0) { Loading @@ -1218,7 +1247,7 @@ static bool configure_aac_enc_format(audio_aac_encoder_config *aac_bt_cfg) a2dp.enc_sampling_rate = aac_bt_cfg->sampling_rate; a2dp.enc_channels = aac_bt_cfg->channels; ALOGV("%s: Successfully updated AAC enc format with sampling rate: %d channels:%d", __func__, aac_dsp_cfg.sample_rate, aac_dsp_cfg.channel_cfg); __func__, aac_dsp_cfg.aac_cfg.sample_rate, aac_dsp_cfg.aac_cfg.channel_cfg); exit: return is_configured; } Loading Loading @@ -1269,6 +1298,7 @@ static bool configure_ldac_enc_format(audio_ldac_encoder_config *ldac_bt_cfg) ldac_dsp_cfg.abr_cfg.imc_info.enable = IMC_ENABLE; ldac_dsp_cfg.abr_cfg.imc_info.purpose = IMC_PURPOSE_ID_BT_INFO; ldac_dsp_cfg.abr_cfg.imc_info.comm_instance = a2dp.abr_config.imc_instance; ldac_dsp_cfg.abr_cfg.is_abr_enabled = ldac_bt_cfg->is_abr_enabled; } ret = mixer_ctl_set_array(ldac_enc_data, (void *)&ldac_dsp_cfg, Loading Loading @@ -1457,6 +1487,15 @@ static int reset_a2dp_dec_config_params() return ret; } static void reset_a2dp_config() { reset_a2dp_enc_config_params(); reset_a2dp_dec_config_params(); a2dp_reset_backend_cfg(); if (a2dp.abr_config.is_abr_enabled && a2dp.abr_config.abr_started) stop_abr(); a2dp.abr_config.is_abr_enabled = false; } int audio_extn_a2dp_stop_playback() { int ret = 0; Loading @@ -1479,12 +1518,8 @@ int audio_extn_a2dp_stop_playback() ALOGE("%s: stop stream to Bluetooth IPC lib failed", __func__); else ALOGV("%s: stop steam to Bluetooth IPC lib successful", __func__); reset_a2dp_enc_config_params(); reset_a2dp_dec_config_params(); a2dp_reset_backend_cfg(); if (a2dp.abr_config.is_abr_enabled && a2dp.abr_config.abr_started) stop_abr(); a2dp.abr_config.is_abr_enabled = false; if (!a2dp.a2dp_suspended) reset_a2dp_config(); a2dp.a2dp_started = false; } ALOGD("%s: Stop A2DP playback total active sessions :%d", __func__, Loading @@ -1495,13 +1530,14 @@ int audio_extn_a2dp_stop_playback() int audio_extn_a2dp_set_parameters(struct str_parms *parms, bool *reconfig) { int ret = 0, val; int status = 0; char value[32] = {0}; struct audio_usecase *uc_info; struct listnode *node; if (a2dp.is_a2dp_offload_enabled == false) { ALOGV("%s: No supported encoders identified,ignoring A2DP setparam", __func__); ret = -EINVAL; status = -EINVAL; goto param_handled; } Loading Loading @@ -1549,8 +1585,7 @@ int audio_extn_a2dp_set_parameters(struct str_parms *parms, bool *reconfig) pthread_mutex_lock(&a2dp.adev->lock); } } reset_a2dp_enc_config_params(); reset_a2dp_dec_config_params(); reset_a2dp_config(); if (a2dp.audio_stream_suspend) { a2dp.audio_stream_suspend(); } Loading Loading @@ -1580,12 +1615,23 @@ int audio_extn_a2dp_set_parameters(struct str_parms *parms, bool *reconfig) if (a2dp.a2dp_total_active_session_request > 0) { ALOGD("%s: Calling Bluetooth IPC lib start post suspend state", __func__); if (a2dp.audio_stream_start) { ret = a2dp.audio_stream_start(); if (ret != 0) { status = a2dp.audio_stream_start(); if (status != 0) { ALOGE("%s: Bluetooth controller start failed", __func__); a2dp.a2dp_started = false; } else { if (!configure_a2dp_encoder_format()) { ALOGE("%s: Encoder params configuration failed post suspend", __func__); a2dp.a2dp_started = false; status = -ETIMEDOUT; } } } if (a2dp.a2dp_started) { a2dp_set_backend_cfg(); if (a2dp.abr_config.is_abr_enabled) start_abr(); } } list_for_each(node, &a2dp.adev->usecase_list) { uc_info = node_to_item(node, struct audio_usecase, list); Loading Loading @@ -1613,7 +1659,7 @@ int audio_extn_a2dp_set_parameters(struct str_parms *parms, bool *reconfig) param_handled: ALOGV("%s: end of A2DP setparam", __func__); return ret; return status; } void audio_extn_a2dp_set_handoff_mode(bool is_on) Loading hal/audio_extn/audio_extn.h +3 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ void audio_extn_set_snd_card_split(const char* in_snd_card_name); #define audio_extn_spkr_prot_stop_processing(snd_device) (0) #define audio_extn_spkr_prot_is_enabled() (false) #define audio_extn_get_spkr_prot_snd_device(snd_device) (snd_device) #define audio_extn_spkr_prot_deinit(adev) (0) #else void audio_extn_spkr_prot_init(void *adev); int audio_extn_spkr_prot_start_processing(snd_device_t snd_device); Loading @@ -49,6 +50,8 @@ void audio_extn_spkr_prot_stop_processing(snd_device_t snd_device); bool audio_extn_spkr_prot_is_enabled(); int audio_extn_get_spkr_prot_snd_device(snd_device_t snd_device); void audio_extn_spkr_prot_calib_cancel(void *adev); void audio_extn_spkr_prot_deinit(void *adev); #endif #ifndef HFP_ENABLED Loading hal/audio_extn/cirrus_playback.c +106 −2 Original line number Diff line number Diff line Loading @@ -155,7 +155,11 @@ static struct pcm_config pcm_config_cirrus_rx = { static struct cirrus_playback_session handle; #ifdef CIRRUS_FACTORY_CALIBRATION static void *audio_extn_cirrus_calibration_thread(); #else static void *audio_extn_cirrus_config_thread(); #endif #ifdef ENABLE_CIRRUS_DETECTION static void *audio_extn_cirrus_failure_detect_thread(); Loading @@ -175,11 +179,30 @@ void audio_extn_spkr_prot_init(void *adev) { pthread_mutex_init(&handle.fb_prot_mutex, NULL); #ifdef CIRRUS_FACTORY_CALIBRATION (void)pthread_create(&handle.calibration_thread, (const pthread_attr_t *) NULL, audio_extn_cirrus_calibration_thread, &handle); #else (void)pthread_create(&handle.calibration_thread, (const pthread_attr_t *) NULL, audio_extn_cirrus_config_thread, &handle); #endif } void audio_extn_spkr_prot_deinit(void *adev __unused) { ALOGV("%s: Entry", __func__); #ifdef ENABLE_CIRRUS_DETECTION pthread_join(handle.failure_detect_thread, NULL); #endif pthread_join(handle.calibration_thread, NULL); pthread_mutex_destroy(&handle.fb_prot_mutex); ALOGV("%s: Exit", __func__); } #ifdef CIRRUS_FACTORY_CALIBRATION static int audio_extn_cirrus_run_calibration() { struct audio_device *adev = handle.adev_handle; struct crus_sp_ioctl_header header; Loading Loading @@ -282,7 +305,6 @@ static int audio_extn_cirrus_run_calibration() { if (ret < 0) goto exit; #ifdef ENABLED_CIRRUS_WRITE_CAL_FILE cal_file = fopen(CRUS_CAL_FILE, "wb"); if (cal_file == NULL) { ALOGE("%s: Cannot create Cirrus SP calibration file (%s)", Loading @@ -305,7 +327,6 @@ static int audio_extn_cirrus_run_calibration() { ALOGI("%s: Cirrus calibration file successfully written", __func__); #endif } header.size = sizeof(header); Loading Loading @@ -531,6 +552,89 @@ exit: return NULL; } #else static void *audio_extn_cirrus_config_thread(void) { struct audio_device *adev = handle.adev_handle; struct crus_sp_ioctl_header header; struct cirrus_cal_result_t result; struct mixer_ctl *ctl_config = NULL; FILE *cal_file = NULL; int ret = 0, dev_file = -1; ALOGI("%s: ++", __func__); memset(&result, 0, sizeof(result)); dev_file = open(CRUS_SP_FILE, O_RDWR | O_NONBLOCK); if (dev_file < 0) { ALOGE("%s: Failed to open Cirrus Playback IOCTL (%d)", __func__, dev_file); ret = -EINVAL; goto exit; } cal_file = fopen(CRUS_CAL_FILE, "r"); if (cal_file) { ret = fread(&result, sizeof(result), 1, cal_file); if (ret != 1) { ALOGE("%s: Cirrus SP calibration file cannot be read , read size: %lu file error: %d", __func__, (unsigned long)ret * sizeof(result), ferror(cal_file)); ret = -EINVAL; goto exit; } } header.size = sizeof(header); header.module_id = CRUS_MODULE_ID_TX; header.param_id = 0; header.data_length = sizeof(result); header.data = &result; ret = ioctl(dev_file, CRUS_SP_IOCTL_SET_CALIB, &header); if (ret < 0) { ALOGE("%s: Cirrus SP calibration IOCTL failure", __func__); goto exit; } ctl_config = mixer_get_ctl_by_name(adev->mixer, CRUS_SP_LOAD_CONF_MIXER); if (!ctl_config) { ALOGE("%s: Could not get ctl for mixer commands", __func__); ret = -EINVAL; goto exit; } ret = mixer_ctl_set_value(ctl_config, 0, 2); if (ret < 0) { ALOGE("%s load tx config failed", __func__); goto exit; } ret = mixer_ctl_set_value(ctl_config, 0, 1); if (ret < 0) { ALOGE("%s load rx config failed", __func__); goto exit; } ret = mixer_ctl_set_value(ctl_config, 0, 0); if (ret < 0) { ALOGE("%s set idle state failed", __func__); goto exit; } exit: if (dev_file >= 0) close(dev_file); if (cal_file) fclose(cal_file); ALOGI("%s: ret: %d --", __func__, ret); return NULL; } #endif #ifdef ENABLE_CIRRUS_DETECTION void *audio_extn_cirrus_failure_detect_thread() { struct audio_device *adev = handle.adev_handle; Loading Loading
Android.mk +1 −1 Original line number Diff line number Diff line # TODO: Find a better way to separate build configs for ADP vs non-ADP devices ifneq ($(TARGET_BOARD_AUTO),true) ifneq ($(filter msm8960 msm8226 msm8x26 msm8x84 msm8084 msm8992 msm8994 msm8996 msm8909 msm8952 msm8998 sdm845,$(TARGET_BOARD_PLATFORM)),) ifneq ($(filter msm8960 msm8226 msm8x26 msm8x84 msm8084 msm8992 msm8994 msm8996 msm8909 msm8952 msm8998 sdm845 sdm710,$(TARGET_BOARD_PLATFORM)),) MY_LOCAL_PATH := $(call my-dir) Loading
hal/Android.mk +9 −2 Original line number Diff line number Diff line Loading @@ -10,7 +10,7 @@ AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM) ifneq ($(filter msm8960,$(TARGET_BOARD_PLATFORM)),) LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="2" endif ifneq ($(filter msm8974 msm8226 msm8084 msm8992 msm8994 msm8996 msm8998 sdm845,$(TARGET_BOARD_PLATFORM)),) ifneq ($(filter msm8974 msm8226 msm8084 msm8992 msm8994 msm8996 msm8998 sdm845 sdm710,$(TARGET_BOARD_PLATFORM)),) # B-family platform uses msm8974 code base AUDIO_PLATFORM = msm8974 ifneq ($(filter msm8974,$(TARGET_BOARD_PLATFORM)),) Loading Loading @@ -55,6 +55,13 @@ ifneq ($(filter sdm845,$(TARGET_BOARD_PLATFORM)),) LOCAL_CFLAGS += -DINCALL_STEREO_CAPTURE_ENABLED MULTIPLE_HW_VARIANTS_ENABLED := true endif ifneq ($(filter sdm710,$(TARGET_BOARD_PLATFORM)),) LOCAL_CFLAGS := -DPLATFORM_SDM710 LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="4" LOCAL_CFLAGS += -DINCALL_MUSIC_ENABLED LOCAL_CFLAGS += -DINCALL_STEREO_CAPTURE_ENABLED MULTIPLE_HW_VARIANTS_ENABLED := true endif endif ifneq ($(filter msm8916 msm8909 msm8952,$(TARGET_BOARD_PLATFORM)),) Loading Loading @@ -171,7 +178,7 @@ ifeq ($(strip $(AUDIO_FEATURE_ENABLED_A2DP_OFFLOAD)),true) LOCAL_SRC_FILES += audio_extn/a2dp.c endif ifneq ($(filter msm8992 msm8994 msm8996 msm8998 sdm845,$(TARGET_BOARD_PLATFORM)),) ifneq ($(filter msm8992 msm8994 msm8996 msm8998 sdm845 sdm710,$(TARGET_BOARD_PLATFORM)),) # push codec/mad calibration to HW dep node # applicable to msm8992/8994 or newer platforms LOCAL_CFLAGS += -DHWDEP_CAL_ENABLED Loading
hal/audio_extn/a2dp.c +92 −46 Original line number Diff line number Diff line Loading @@ -159,6 +159,11 @@ typedef enum { IMC_ENABLE, } imc_status_t; typedef enum { MTU_SIZE, PEAK_BIT_RATE, } frame_control_type_t; /* PCM config for ABR Feedback hostless front end */ static struct pcm_config pcm_config_abr = { .channels = 1, Loading Loading @@ -288,12 +293,25 @@ struct imc_dec_enc_info { uint32_t comm_instance; }; /* Structure to control frame size of AAC encoded frames. */ struct aac_frame_size_control_t { /* Type of frame size control: MTU_SIZE / PEAK_BIT_RATE*/ uint32_t ctl_type; /* Control value * MTU_SIZE: MTU size in bytes * PEAK_BIT_RATE: Peak bitrate in bits per second. */ uint32_t ctl_value; }; /* Structure used for ABR config of AFE encoder and decoder. */ struct abr_enc_cfg_t { /* Link quality level to bitrate mapping info sent to DSP. */ struct quality_level_to_bitrate_info mapping_info; /* Information to set up IMC between decoder and encoder */ struct imc_dec_enc_info imc_info; /* Flag to indicate whether ABR is enabled */ bool is_abr_enabled; } __attribute__ ((packed)); /* Structure to send configuration for decoder introduced Loading @@ -310,10 +328,7 @@ struct abr_dec_cfg_t { * These values should match with DSP interface defintion */ /* AAC encoder configuration structure. */ typedef struct aac_enc_cfg_t aac_enc_cfg_t; struct aac_enc_cfg_t { struct aac_cfg_blk_t { /* Encoder media format for AAC */ uint32_t enc_format; Loading @@ -333,6 +348,14 @@ struct aac_enc_cfg_t { uint32_t sample_rate; } __attribute__ ((packed)); /* AAC encoder configuration structure. */ typedef struct aac_enc_cfg_t aac_enc_cfg_t; struct aac_enc_cfg_t { struct aac_cfg_blk_t aac_cfg; struct aac_frame_size_control_t frame_ctl; } __attribute__ ((packed)); /* SBC encoder configuration structure. */ typedef struct sbc_enc_cfg_t sbc_enc_cfg_t; Loading Loading @@ -493,6 +516,7 @@ typedef struct { uint32_t sampling_rate; uint32_t bitrate; uint32_t bits_per_sample; struct aac_frame_size_control_t frame_ctl; } audio_aac_encoder_config; /* Information about Bluetooth LDAC encoder configuration Loading Loading @@ -807,7 +831,7 @@ static int a2dp_set_backend_cfg() } // Set Tx backend sample rate if (a2dp.abr_config.is_abr_enabled) if (a2dp.abr_config.is_abr_enabled) { rate_str = ABR_TX_SAMPLE_RATE; ALOGV("%s: set backend tx sample rate = %s", __func__, rate_str); Loading @@ -822,6 +846,7 @@ static int a2dp_set_backend_cfg() __func__, rate_str); return -ENOSYS; } } // Configure AFE input channels switch (a2dp.enc_channels) { Loading Loading @@ -901,6 +926,7 @@ static int a2dp_reset_backend_cfg() return -ENOSYS; } if (a2dp.abr_config.is_abr_enabled) { ctl_sample_rate_tx = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_SAMPLE_RATE_TX); if (!ctl_sample_rate_tx) { Loading @@ -911,6 +937,7 @@ static int a2dp_reset_backend_cfg() ALOGE("%s: Failed to reset Tx backend sample rate = %s", __func__, rate_str); return -ENOSYS; } } // Reset AFE input channels ALOGV("%s: reset AFE input channels = %s", __func__, in_channels); Loading Loading @@ -1184,23 +1211,25 @@ static bool configure_aac_enc_format(audio_aac_encoder_config *aac_bt_cfg) goto exit; } memset(&aac_dsp_cfg, 0x0, sizeof(aac_dsp_cfg)); aac_dsp_cfg.enc_format = ENC_MEDIA_FMT_AAC; aac_dsp_cfg.bit_rate = aac_bt_cfg->bitrate; aac_dsp_cfg.sample_rate = aac_bt_cfg->sampling_rate; aac_dsp_cfg.aac_cfg.enc_format = ENC_MEDIA_FMT_AAC; aac_dsp_cfg.aac_cfg.bit_rate = aac_bt_cfg->bitrate; aac_dsp_cfg.aac_cfg.sample_rate = aac_bt_cfg->sampling_rate; switch (aac_bt_cfg->enc_mode) { case 0: aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_LC; aac_dsp_cfg.aac_cfg.enc_mode = MEDIA_FMT_AAC_AOT_LC; break; case 2: aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_PS; aac_dsp_cfg.aac_cfg.enc_mode = MEDIA_FMT_AAC_AOT_PS; break; case 1: default: aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_SBR; aac_dsp_cfg.aac_cfg.enc_mode = MEDIA_FMT_AAC_AOT_SBR; break; } aac_dsp_cfg.aac_fmt_flag = aac_bt_cfg->format_flag; aac_dsp_cfg.channel_cfg = aac_bt_cfg->channels; aac_dsp_cfg.aac_cfg.aac_fmt_flag = aac_bt_cfg->format_flag; aac_dsp_cfg.aac_cfg.channel_cfg = aac_bt_cfg->channels; aac_dsp_cfg.frame_ctl.ctl_type = aac_bt_cfg->frame_ctl.ctl_type; aac_dsp_cfg.frame_ctl.ctl_value = aac_bt_cfg->frame_ctl.ctl_value; ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aac_dsp_cfg, sizeof(aac_dsp_cfg)); if (ret != 0) { Loading @@ -1218,7 +1247,7 @@ static bool configure_aac_enc_format(audio_aac_encoder_config *aac_bt_cfg) a2dp.enc_sampling_rate = aac_bt_cfg->sampling_rate; a2dp.enc_channels = aac_bt_cfg->channels; ALOGV("%s: Successfully updated AAC enc format with sampling rate: %d channels:%d", __func__, aac_dsp_cfg.sample_rate, aac_dsp_cfg.channel_cfg); __func__, aac_dsp_cfg.aac_cfg.sample_rate, aac_dsp_cfg.aac_cfg.channel_cfg); exit: return is_configured; } Loading Loading @@ -1269,6 +1298,7 @@ static bool configure_ldac_enc_format(audio_ldac_encoder_config *ldac_bt_cfg) ldac_dsp_cfg.abr_cfg.imc_info.enable = IMC_ENABLE; ldac_dsp_cfg.abr_cfg.imc_info.purpose = IMC_PURPOSE_ID_BT_INFO; ldac_dsp_cfg.abr_cfg.imc_info.comm_instance = a2dp.abr_config.imc_instance; ldac_dsp_cfg.abr_cfg.is_abr_enabled = ldac_bt_cfg->is_abr_enabled; } ret = mixer_ctl_set_array(ldac_enc_data, (void *)&ldac_dsp_cfg, Loading Loading @@ -1457,6 +1487,15 @@ static int reset_a2dp_dec_config_params() return ret; } static void reset_a2dp_config() { reset_a2dp_enc_config_params(); reset_a2dp_dec_config_params(); a2dp_reset_backend_cfg(); if (a2dp.abr_config.is_abr_enabled && a2dp.abr_config.abr_started) stop_abr(); a2dp.abr_config.is_abr_enabled = false; } int audio_extn_a2dp_stop_playback() { int ret = 0; Loading @@ -1479,12 +1518,8 @@ int audio_extn_a2dp_stop_playback() ALOGE("%s: stop stream to Bluetooth IPC lib failed", __func__); else ALOGV("%s: stop steam to Bluetooth IPC lib successful", __func__); reset_a2dp_enc_config_params(); reset_a2dp_dec_config_params(); a2dp_reset_backend_cfg(); if (a2dp.abr_config.is_abr_enabled && a2dp.abr_config.abr_started) stop_abr(); a2dp.abr_config.is_abr_enabled = false; if (!a2dp.a2dp_suspended) reset_a2dp_config(); a2dp.a2dp_started = false; } ALOGD("%s: Stop A2DP playback total active sessions :%d", __func__, Loading @@ -1495,13 +1530,14 @@ int audio_extn_a2dp_stop_playback() int audio_extn_a2dp_set_parameters(struct str_parms *parms, bool *reconfig) { int ret = 0, val; int status = 0; char value[32] = {0}; struct audio_usecase *uc_info; struct listnode *node; if (a2dp.is_a2dp_offload_enabled == false) { ALOGV("%s: No supported encoders identified,ignoring A2DP setparam", __func__); ret = -EINVAL; status = -EINVAL; goto param_handled; } Loading Loading @@ -1549,8 +1585,7 @@ int audio_extn_a2dp_set_parameters(struct str_parms *parms, bool *reconfig) pthread_mutex_lock(&a2dp.adev->lock); } } reset_a2dp_enc_config_params(); reset_a2dp_dec_config_params(); reset_a2dp_config(); if (a2dp.audio_stream_suspend) { a2dp.audio_stream_suspend(); } Loading Loading @@ -1580,12 +1615,23 @@ int audio_extn_a2dp_set_parameters(struct str_parms *parms, bool *reconfig) if (a2dp.a2dp_total_active_session_request > 0) { ALOGD("%s: Calling Bluetooth IPC lib start post suspend state", __func__); if (a2dp.audio_stream_start) { ret = a2dp.audio_stream_start(); if (ret != 0) { status = a2dp.audio_stream_start(); if (status != 0) { ALOGE("%s: Bluetooth controller start failed", __func__); a2dp.a2dp_started = false; } else { if (!configure_a2dp_encoder_format()) { ALOGE("%s: Encoder params configuration failed post suspend", __func__); a2dp.a2dp_started = false; status = -ETIMEDOUT; } } } if (a2dp.a2dp_started) { a2dp_set_backend_cfg(); if (a2dp.abr_config.is_abr_enabled) start_abr(); } } list_for_each(node, &a2dp.adev->usecase_list) { uc_info = node_to_item(node, struct audio_usecase, list); Loading Loading @@ -1613,7 +1659,7 @@ int audio_extn_a2dp_set_parameters(struct str_parms *parms, bool *reconfig) param_handled: ALOGV("%s: end of A2DP setparam", __func__); return ret; return status; } void audio_extn_a2dp_set_handoff_mode(bool is_on) Loading
hal/audio_extn/audio_extn.h +3 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ void audio_extn_set_snd_card_split(const char* in_snd_card_name); #define audio_extn_spkr_prot_stop_processing(snd_device) (0) #define audio_extn_spkr_prot_is_enabled() (false) #define audio_extn_get_spkr_prot_snd_device(snd_device) (snd_device) #define audio_extn_spkr_prot_deinit(adev) (0) #else void audio_extn_spkr_prot_init(void *adev); int audio_extn_spkr_prot_start_processing(snd_device_t snd_device); Loading @@ -49,6 +50,8 @@ void audio_extn_spkr_prot_stop_processing(snd_device_t snd_device); bool audio_extn_spkr_prot_is_enabled(); int audio_extn_get_spkr_prot_snd_device(snd_device_t snd_device); void audio_extn_spkr_prot_calib_cancel(void *adev); void audio_extn_spkr_prot_deinit(void *adev); #endif #ifndef HFP_ENABLED Loading
hal/audio_extn/cirrus_playback.c +106 −2 Original line number Diff line number Diff line Loading @@ -155,7 +155,11 @@ static struct pcm_config pcm_config_cirrus_rx = { static struct cirrus_playback_session handle; #ifdef CIRRUS_FACTORY_CALIBRATION static void *audio_extn_cirrus_calibration_thread(); #else static void *audio_extn_cirrus_config_thread(); #endif #ifdef ENABLE_CIRRUS_DETECTION static void *audio_extn_cirrus_failure_detect_thread(); Loading @@ -175,11 +179,30 @@ void audio_extn_spkr_prot_init(void *adev) { pthread_mutex_init(&handle.fb_prot_mutex, NULL); #ifdef CIRRUS_FACTORY_CALIBRATION (void)pthread_create(&handle.calibration_thread, (const pthread_attr_t *) NULL, audio_extn_cirrus_calibration_thread, &handle); #else (void)pthread_create(&handle.calibration_thread, (const pthread_attr_t *) NULL, audio_extn_cirrus_config_thread, &handle); #endif } void audio_extn_spkr_prot_deinit(void *adev __unused) { ALOGV("%s: Entry", __func__); #ifdef ENABLE_CIRRUS_DETECTION pthread_join(handle.failure_detect_thread, NULL); #endif pthread_join(handle.calibration_thread, NULL); pthread_mutex_destroy(&handle.fb_prot_mutex); ALOGV("%s: Exit", __func__); } #ifdef CIRRUS_FACTORY_CALIBRATION static int audio_extn_cirrus_run_calibration() { struct audio_device *adev = handle.adev_handle; struct crus_sp_ioctl_header header; Loading Loading @@ -282,7 +305,6 @@ static int audio_extn_cirrus_run_calibration() { if (ret < 0) goto exit; #ifdef ENABLED_CIRRUS_WRITE_CAL_FILE cal_file = fopen(CRUS_CAL_FILE, "wb"); if (cal_file == NULL) { ALOGE("%s: Cannot create Cirrus SP calibration file (%s)", Loading @@ -305,7 +327,6 @@ static int audio_extn_cirrus_run_calibration() { ALOGI("%s: Cirrus calibration file successfully written", __func__); #endif } header.size = sizeof(header); Loading Loading @@ -531,6 +552,89 @@ exit: return NULL; } #else static void *audio_extn_cirrus_config_thread(void) { struct audio_device *adev = handle.adev_handle; struct crus_sp_ioctl_header header; struct cirrus_cal_result_t result; struct mixer_ctl *ctl_config = NULL; FILE *cal_file = NULL; int ret = 0, dev_file = -1; ALOGI("%s: ++", __func__); memset(&result, 0, sizeof(result)); dev_file = open(CRUS_SP_FILE, O_RDWR | O_NONBLOCK); if (dev_file < 0) { ALOGE("%s: Failed to open Cirrus Playback IOCTL (%d)", __func__, dev_file); ret = -EINVAL; goto exit; } cal_file = fopen(CRUS_CAL_FILE, "r"); if (cal_file) { ret = fread(&result, sizeof(result), 1, cal_file); if (ret != 1) { ALOGE("%s: Cirrus SP calibration file cannot be read , read size: %lu file error: %d", __func__, (unsigned long)ret * sizeof(result), ferror(cal_file)); ret = -EINVAL; goto exit; } } header.size = sizeof(header); header.module_id = CRUS_MODULE_ID_TX; header.param_id = 0; header.data_length = sizeof(result); header.data = &result; ret = ioctl(dev_file, CRUS_SP_IOCTL_SET_CALIB, &header); if (ret < 0) { ALOGE("%s: Cirrus SP calibration IOCTL failure", __func__); goto exit; } ctl_config = mixer_get_ctl_by_name(adev->mixer, CRUS_SP_LOAD_CONF_MIXER); if (!ctl_config) { ALOGE("%s: Could not get ctl for mixer commands", __func__); ret = -EINVAL; goto exit; } ret = mixer_ctl_set_value(ctl_config, 0, 2); if (ret < 0) { ALOGE("%s load tx config failed", __func__); goto exit; } ret = mixer_ctl_set_value(ctl_config, 0, 1); if (ret < 0) { ALOGE("%s load rx config failed", __func__); goto exit; } ret = mixer_ctl_set_value(ctl_config, 0, 0); if (ret < 0) { ALOGE("%s set idle state failed", __func__); goto exit; } exit: if (dev_file >= 0) close(dev_file); if (cal_file) fclose(cal_file); ALOGI("%s: ret: %d --", __func__, ret); return NULL; } #endif #ifdef ENABLE_CIRRUS_DETECTION void *audio_extn_cirrus_failure_detect_thread() { struct audio_device *adev = handle.adev_handle; Loading