diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h index b3297ed0..5e2e6432 100644 --- a/hal/audio_extn/audio_extn.h +++ b/hal/audio_extn/audio_extn.h @@ -157,7 +157,7 @@ typedef int (*fp_platform_get_snd_device_name_extn_t)(void *platform, snd_device char *device_name); typedef int (*fp_platform_get_default_app_type_v2_t)(void *, usecase_type_t); typedef int (*fp_platform_send_audio_calibration_t)(void *, struct audio_usecase *, - int, int); + int); typedef int (*fp_platform_get_pcm_device_id_t)(audio_usecase_t, int); typedef const char *(*fp_platform_get_snd_device_name_t)(snd_device_t); typedef int (*fp_platform_spkr_prot_is_wsa_analog_mode_t)(void *); @@ -801,6 +801,8 @@ int audio_extn_utils_get_sample_rate_from_string(const char *); int audio_extn_utils_get_channels_from_string(const char *); void audio_extn_utils_release_snd_device(snd_device_t snd_device); int audio_extn_utils_is_vendor_enhanced_fwk(); +int audio_extn_utils_get_app_sample_rate_for_device(struct audio_device *adev, + struct audio_usecase *usecase, int snd_device); #ifdef DS2_DOLBY_DAP_ENABLED #define LIB_DS2_DAP_HAL "vendor/lib/libhwdaphal.so" diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c index 8c6ff063..b51a7d5a 100644 --- a/hal/audio_extn/spkr_protection.c +++ b/hal/audio_extn/spkr_protection.c @@ -1030,7 +1030,7 @@ exit: app_type = fp_platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE); fp_platform_send_audio_calibration(adev->platform, uc_info_tx, - app_type, 8000); + app_type); } if (!v_validation) { if (!status.status) { @@ -2281,6 +2281,8 @@ int spkr_prot_start_processing(snd_device_t snd_device) if (!uc_info_tx) { return -ENOMEM; } + uc_info_tx->id = USECASE_AUDIO_SPKR_CALIB_TX; + uc_info_tx->type = PCM_CAPTURE; if (fp_platform_get_snd_device_name_extn(adev->platform, snd_device, device_name) < 0) { ALOGE("%s: Invalid sound device returned", __func__); @@ -2293,8 +2295,6 @@ int spkr_prot_start_processing(snd_device_t snd_device) pthread_mutex_lock(&handle.mutex_spkr_prot); if (handle.spkr_processing_state == SPKR_PROCESSING_IN_IDLE) { - uc_info_tx->id = USECASE_AUDIO_SPKR_CALIB_TX; - uc_info_tx->type = PCM_CAPTURE; uc_info_tx->in_snd_device = in_snd_device; uc_info_tx->out_snd_device = SND_DEVICE_NONE; handle.pcm_tx = NULL; @@ -2333,15 +2333,13 @@ exit: app_type = fp_platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE); fp_platform_send_audio_calibration(adev->platform, uc_info_tx, - app_type, 8000); + app_type); } if (ret) { if (handle.pcm_tx) pcm_close(handle.pcm_tx); handle.pcm_tx = NULL; list_remove(&uc_info_tx->list); - uc_info_tx->id = USECASE_AUDIO_SPKR_CALIB_TX; - uc_info_tx->type = PCM_CAPTURE; uc_info_tx->in_snd_device = in_snd_device; uc_info_tx->out_snd_device = SND_DEVICE_NONE; fp_disable_snd_device(adev, in_snd_device); diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c index 09921af1..ea0d3245 100644 --- a/hal/audio_extn/utils.c +++ b/hal/audio_extn/utils.c @@ -1025,6 +1025,87 @@ exit_send_app_type_cfg: return rc; } +int audio_extn_utils_get_app_sample_rate_for_device( + struct audio_device *adev, + struct audio_usecase *usecase, int snd_device) +{ + char value[PROPERTY_VALUE_MAX] = {0}; + int sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE; + + if ((usecase->type == PCM_PLAYBACK) && (usecase->stream.out != NULL)) { + property_get("vendor.audio.playback.mch.downsample",value,""); + if (!strncmp("true", value, sizeof("true"))) { + if ((popcount(usecase->stream.out->channel_mask) > 2) && + (usecase->stream.out->app_type_cfg.sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) && + !(usecase->stream.out->flags & + (audio_output_flags_t)AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH)) + sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE; + } + + if (usecase->id == USECASE_AUDIO_PLAYBACK_VOIP) { + usecase->stream.out->app_type_cfg.sample_rate = usecase->stream.out->sample_rate; + } else if (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER) { + usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE; + } else if ((snd_device == SND_DEVICE_OUT_HDMI || + snd_device == SND_DEVICE_OUT_USB_HEADSET || + snd_device == SND_DEVICE_OUT_DISPLAY_PORT) && + (usecase->stream.out->sample_rate >= OUTPUT_SAMPLING_RATE_44100)) { + /* + * To best utlize DSP, check if the stream sample rate is supported/multiple of + * configured device sample rate, if not update the COPP rate to be equal to the + * device sample rate, else open COPP at stream sample rate + */ + platform_check_and_update_copp_sample_rate(adev->platform, snd_device, + usecase->stream.out->sample_rate, + &usecase->stream.out->app_type_cfg.sample_rate); + } else if (((snd_device != SND_DEVICE_OUT_HEADPHONES_44_1 && + !audio_is_this_native_usecase(usecase)) && + usecase->stream.out->sample_rate == OUTPUT_SAMPLING_RATE_44100) || + (usecase->stream.out->sample_rate < OUTPUT_SAMPLING_RATE_44100)) { + /* Reset to default if no native stream is active*/ + usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE; + } else if (usecase->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) { + /* + * For a2dp playback get encoder sampling rate and set copp sampling rate, + * for bit width use the stream param only. + */ + audio_extn_a2dp_get_enc_sample_rate(&usecase->stream.out->app_type_cfg.sample_rate); + ALOGI("%s using %d sample rate rate for A2DP CoPP", + __func__, usecase->stream.out->app_type_cfg.sample_rate); + } + audio_extn_btsco_get_sample_rate(snd_device, &usecase->stream.out->app_type_cfg.sample_rate); + sample_rate = usecase->stream.out->app_type_cfg.sample_rate; + + if (((usecase->stream.out->format == AUDIO_FORMAT_E_AC3) || + (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC) || + (usecase->stream.out->format == AUDIO_FORMAT_DOLBY_TRUEHD)) + && audio_extn_passthru_is_passthrough_stream(usecase->stream.out) + && !audio_extn_passthru_is_convert_supported(adev, usecase->stream.out)) { + sample_rate = sample_rate * 4; + if (sample_rate > HDMI_PASSTHROUGH_MAX_SAMPLE_RATE) + sample_rate = HDMI_PASSTHROUGH_MAX_SAMPLE_RATE; + } + } else if (usecase->type == PCM_CAPTURE) { + if (usecase->stream.in != NULL) { + if (usecase->id == USECASE_AUDIO_RECORD_VOIP) + usecase->stream.in->app_type_cfg.sample_rate = usecase->stream.in->sample_rate; + if (voice_is_in_call_rec_stream(usecase->stream.in)) { + audio_extn_btsco_get_sample_rate(usecase->in_snd_device, + &usecase->stream.in->app_type_cfg.sample_rate); + } else { + audio_extn_btsco_get_sample_rate(snd_device, + &usecase->stream.in->app_type_cfg.sample_rate); + } + sample_rate = usecase->stream.in->app_type_cfg.sample_rate; + } else if (usecase->id == USECASE_AUDIO_SPKR_CALIB_TX) { + sample_rate = SAMPLE_RATE_8000; + } + } else if (usecase->type == TRANSCODE_LOOPBACK_RX) { + sample_rate = usecase->stream.inout->out_config.sample_rate; + } + return sample_rate; +} + static int send_app_type_cfg_for_device(struct audio_device *adev, struct audio_usecase *usecase, int split_snd_device) @@ -1036,7 +1117,6 @@ static int send_app_type_cfg_for_device(struct audio_device *adev, int pcm_device_id = 0, acdb_dev_id, app_type; int snd_device = split_snd_device, snd_device_be_idx = -1; int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE; - char value[PROPERTY_VALUE_MAX] = {0}; struct streams_io_cfg *s_info = NULL; struct listnode *node = NULL; int bd_app_type = 0; @@ -1111,58 +1191,9 @@ static int send_app_type_cfg_for_device(struct audio_device *adev, snd_device_be_idx); } + sample_rate = audio_extn_utils_get_app_sample_rate_for_device(adev, usecase, snd_device); + if ((usecase->type == PCM_PLAYBACK) && (usecase->stream.out != NULL)) { - - property_get("vendor.audio.playback.mch.downsample",value,""); - if (!strncmp("true", value, sizeof("true"))) { - if ((popcount(usecase->stream.out->channel_mask) > 2) && - (usecase->stream.out->app_type_cfg.sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) && - !(usecase->stream.out->flags & - (audio_output_flags_t)AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH)) - sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE; - } - - if (usecase->id == USECASE_AUDIO_PLAYBACK_VOIP) { - usecase->stream.out->app_type_cfg.sample_rate = usecase->stream.out->sample_rate; - } else if (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER) { - if (platform_spkr_use_default_sample_rate(adev->platform)) { - usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE; - } else { - platform_check_and_update_copp_sample_rate(adev->platform, snd_device, - usecase->stream.out->sample_rate, - &usecase->stream.out->app_type_cfg.sample_rate); - } - - } else if ((snd_device == SND_DEVICE_OUT_HDMI || - snd_device == SND_DEVICE_OUT_USB_HEADSET || - snd_device == SND_DEVICE_OUT_DISPLAY_PORT) && - (usecase->stream.out->sample_rate >= OUTPUT_SAMPLING_RATE_44100)) { - /* - * To best utlize DSP, check if the stream sample rate is supported/multiple of - * configured device sample rate, if not update the COPP rate to be equal to the - * device sample rate, else open COPP at stream sample rate - */ - platform_check_and_update_copp_sample_rate(adev->platform, snd_device, - usecase->stream.out->sample_rate, - &usecase->stream.out->app_type_cfg.sample_rate); - } else if (((snd_device != SND_DEVICE_OUT_HEADPHONES_44_1 && - !audio_is_this_native_usecase(usecase)) && - usecase->stream.out->sample_rate == OUTPUT_SAMPLING_RATE_44100) || - (usecase->stream.out->sample_rate < OUTPUT_SAMPLING_RATE_44100)) { - /* Reset to default if no native stream is active*/ - usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE; - } else if (usecase->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) { - /* - * For a2dp playback get encoder sampling rate and set copp sampling rate, - * for bit width use the stream param only. - */ - audio_extn_a2dp_get_enc_sample_rate(&usecase->stream.out->app_type_cfg.sample_rate); - ALOGI("%s using %d sample rate rate for A2DP CoPP", - __func__, usecase->stream.out->app_type_cfg.sample_rate); - } - audio_extn_btsco_get_sample_rate(snd_device, &usecase->stream.out->app_type_cfg.sample_rate); - sample_rate = usecase->stream.out->app_type_cfg.sample_rate; - /* Interactive streams are supported with only direct app type id. * Get Direct profile app type and use it for interactive streams */ @@ -1179,16 +1210,6 @@ static int send_app_type_cfg_for_device(struct audio_device *adev, app_type = usecase->stream.out->app_type_cfg.app_type; app_type_cfg[len++] = app_type; app_type_cfg[len++] = acdb_dev_id; - if (((usecase->stream.out->format == AUDIO_FORMAT_E_AC3) || - (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC) || - (usecase->stream.out->format == AUDIO_FORMAT_DOLBY_TRUEHD)) - && audio_extn_passthru_is_passthrough_stream(usecase->stream.out) - && !audio_extn_passthru_is_convert_supported(adev, usecase->stream.out)) { - - sample_rate = sample_rate * 4; - if (sample_rate > HDMI_PASSTHROUGH_MAX_SAMPLE_RATE) - sample_rate = HDMI_PASSTHROUGH_MAX_SAMPLE_RATE; - } app_type_cfg[len++] = sample_rate; if (snd_device_be_idx > 0) @@ -1201,19 +1222,6 @@ static int send_app_type_cfg_for_device(struct audio_device *adev, app_type = usecase->stream.in->app_type_cfg.app_type; app_type_cfg[len++] = app_type; app_type_cfg[len++] = acdb_dev_id; - if (usecase->id == USECASE_AUDIO_RECORD_VOIP) - usecase->stream.in->app_type_cfg.sample_rate = usecase->stream.in->sample_rate; - if (voice_is_in_call_rec_stream(usecase->stream.in)) { - audio_extn_btsco_get_sample_rate(usecase->in_snd_device, &usecase->stream.in->app_type_cfg.sample_rate); - } else { - audio_extn_btsco_get_sample_rate(snd_device, &usecase->stream.in->app_type_cfg.sample_rate); - } - if (usecase->stream.in->device & AUDIO_DEVICE_IN_BLUETOOTH_A2DP & ~AUDIO_DEVICE_BIT_IN) { - audio_extn_a2dp_get_dec_sample_rate(&usecase->stream.in->app_type_cfg.sample_rate); - ALOGI("%s using %d sample rate rate for A2DP dec CoPP", - __func__, usecase->stream.in->app_type_cfg.sample_rate); - } - sample_rate = usecase->stream.in->app_type_cfg.sample_rate; app_type_cfg[len++] = sample_rate; if (snd_device_be_idx > 0) app_type_cfg[len++] = snd_device_be_idx; @@ -1222,7 +1230,6 @@ static int send_app_type_cfg_for_device(struct audio_device *adev, } else { app_type = platform_get_default_app_type_v2(adev->platform, usecase->type); if(usecase->type == TRANSCODE_LOOPBACK_RX) { - sample_rate = usecase->stream.inout->out_config.sample_rate; app_type = usecase->stream.inout->out_app_type_cfg.app_type; } app_type_cfg[len++] = app_type; @@ -1582,29 +1589,15 @@ void audio_extn_utils_send_audio_calibration(struct audio_device *adev, int type = usecase->type; if (type == PCM_PLAYBACK && usecase->stream.out != NULL) { - struct stream_out *out = usecase->stream.out; - int snd_device = usecase->out_snd_device; - snd_device = (snd_device == SND_DEVICE_OUT_SPEAKER) ? - platform_get_spkr_prot_snd_device(snd_device) : snd_device; platform_send_audio_calibration(adev->platform, usecase, - out->app_type_cfg.app_type, - usecase->stream.out->app_type_cfg.sample_rate); + usecase->stream.out->app_type_cfg.app_type); } else if (type == PCM_CAPTURE && usecase->stream.in != NULL) { platform_send_audio_calibration(adev->platform, usecase, - usecase->stream.in->app_type_cfg.app_type, - usecase->stream.in->app_type_cfg.sample_rate); - } else if (type == PCM_HFP_CALL || type == PCM_CAPTURE) { - /* when app type is default. the sample rate is not used to send cal */ + usecase->stream.in->app_type_cfg.app_type); + } else if ((type == PCM_HFP_CALL) || (type == PCM_CAPTURE) || + (type == TRANSCODE_LOOPBACK_RX && usecase->stream.inout != NULL)) { platform_send_audio_calibration(adev->platform, usecase, - platform_get_default_app_type_v2(adev->platform, usecase->type), - 48000); - } else if (type == TRANSCODE_LOOPBACK_RX && usecase->stream.inout != NULL) { - int snd_device = usecase->out_snd_device; - snd_device = (snd_device == SND_DEVICE_OUT_SPEAKER) ? - platform_get_spkr_prot_snd_device(snd_device) : snd_device; - platform_send_audio_calibration(adev->platform, usecase, - platform_get_default_app_type_v2(adev->platform, usecase->type), - usecase->stream.inout->out_config.sample_rate); + platform_get_default_app_type_v2(adev->platform, usecase->type)); } else { /* No need to send audio calibration for voice and voip call usecases */ if ((type != VOICE_CALL) && (type != VOIP_CALL)) diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c index 903b8459..bdd10b01 100644 --- a/hal/msm8916/platform.c +++ b/hal/msm8916/platform.c @@ -3622,7 +3622,7 @@ int platform_get_backend_index(snd_device_t snd_device) } int platform_send_audio_calibration(void *platform, struct audio_usecase *usecase, - int app_type, int sample_rate) + int app_type) { struct platform_data *my_data = (struct platform_data *)platform; int acdb_dev_id, acdb_dev_type; @@ -3631,6 +3631,7 @@ int platform_send_audio_calibration(void *platform, struct audio_usecase *usecas int i, num_devices = 1; bool is_incall_rec_usecase = false; snd_device_t incall_rec_device; + int sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE; if (voice_is_in_call(my_data->adev)) is_incall_rec_usecase = voice_is_in_call_rec_stream(usecase->stream.in); @@ -3660,11 +3661,16 @@ int platform_send_audio_calibration(void *platform, struct audio_usecase *usecas } for (i = 0; i < num_devices; i++) { - if (!is_incall_rec_usecase) + if (!is_incall_rec_usecase) { acdb_dev_id = acdb_device_table[platform_get_spkr_prot_snd_device(new_snd_device[i])]; - else + sample_rate = audio_extn_utils_get_app_sample_rate_for_device(my_data->adev, usecase, + new_snd_device[i]); + } else { // Use in_call_rec snd_device to extract the ACDB device ID instead of split snd devices acdb_dev_id = acdb_device_table[platform_get_spkr_prot_snd_device(snd_device)]; + sample_rate = audio_extn_utils_get_app_sample_rate_for_device(my_data->adev, usecase, + snd_device); + } // Do not use Rx path default app type for TX path if ((usecase->type == PCM_CAPTURE) && (app_type == DEFAULT_APP_TYPE_RX_PATH)) { diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c index e16d20a1..0a819699 100644 --- a/hal/msm8960/platform.c +++ b/hal/msm8960/platform.c @@ -522,7 +522,7 @@ int platform_get_default_app_type(void *platform __unused) } int platform_send_audio_calibration(void *platform, struct audio_usecase *usecase, - int app_type __unused, int sample_rate __unused) + int app_type __unused) { struct platform_data *my_data = (struct platform_data *)platform; int acdb_dev_id, acdb_dev_type; diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c index 949499fb..345982e6 100644 --- a/hal/msm8974/platform.c +++ b/hal/msm8974/platform.c @@ -4719,7 +4719,7 @@ int platform_get_backend_index(snd_device_t snd_device) } int platform_send_audio_calibration(void *platform, struct audio_usecase *usecase, - int app_type, int sample_rate) + int app_type) { struct platform_data *my_data = (struct platform_data *)platform; int acdb_dev_id, acdb_dev_type; @@ -4728,6 +4728,7 @@ int platform_send_audio_calibration(void *platform, struct audio_usecase *usecas int i, num_devices = 1; bool is_incall_rec_usecase = false; snd_device_t incall_rec_device; + int sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE; if (voice_is_in_call(my_data->adev)) is_incall_rec_usecase = voice_is_in_call_rec_stream(usecase->stream.in); @@ -4762,11 +4763,16 @@ int platform_send_audio_calibration(void *platform, struct audio_usecase *usecas } for (i = 0; i < num_devices; i++) { - if (!is_incall_rec_usecase) + if (!is_incall_rec_usecase) { acdb_dev_id = acdb_device_table[platform_get_spkr_prot_snd_device(new_snd_device[i])]; - else + sample_rate = audio_extn_utils_get_app_sample_rate_for_device(my_data->adev, usecase, + new_snd_device[i]); + } else { // Use in_call_rec snd_device to extract the ACDB device ID instead of split snd devices acdb_dev_id = acdb_device_table[platform_get_spkr_prot_snd_device(snd_device)]; + sample_rate = audio_extn_utils_get_app_sample_rate_for_device(my_data->adev, usecase, + snd_device); + } // Do not use Rx path default app type for TX path if ((usecase->type == PCM_CAPTURE) && (app_type == DEFAULT_APP_TYPE_RX_PATH)) { diff --git a/hal/platform_api.h b/hal/platform_api.h index cae22ac5..fd85aab4 100644 --- a/hal/platform_api.h +++ b/hal/platform_api.h @@ -155,7 +155,7 @@ int platform_get_meta_info_key_from_list(void *platform, char *mod_name); int platform_set_native_support(int na_mode); int platform_get_native_support(); int platform_send_audio_calibration(void *platform, struct audio_usecase *usecase, - int app_type, int sample_rate); + int app_type); int platform_get_default_app_type(void *platform); int platform_get_default_app_type_v2(void *platform, usecase_type_t type); int platform_switch_voice_call_device_pre(void *platform);