hal: get correspoding sample rate per device when sending cal data
For combo devices, each of the sound device may have different
sample rate, so calibration data should be sent with its own
sample rate value.
Use the sample rate per sound device for calibration.
Change-Id: If1989b8ceb166a905f3e438161765b4b3a6dc5f5
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index b3297ed..5e2e643 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -157,7 +157,7 @@
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_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 8c6ff06..b51a7d5 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.c
@@ -1030,7 +1030,7 @@
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 @@
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 @@
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 @@
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 09921af..ea0d324 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -1025,6 +1025,87 @@
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 @@
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 @@
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 @@
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 @@
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 @@
} 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 @@
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 80a52c7..f5180fa 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -3618,7 +3618,7 @@
}
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;
@@ -3627,6 +3627,7 @@
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);
@@ -3656,11 +3657,16 @@
}
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 e16d20a..0a81969 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -522,7 +522,7 @@
}
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 7fd2019..6103747 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -4715,7 +4715,7 @@
}
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;
@@ -4724,6 +4724,7 @@
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);
@@ -4758,11 +4759,16 @@
}
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 f43aa88..3fc1f93 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -154,7 +154,7 @@
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);