Merge "hal: mute stream and switch to speaker during a2dp suspend"
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 2a6cdfa..f1ff4ef 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -102,6 +102,7 @@
#define INVALID_OUT_VOLUME -1
#define AUDIO_IO_PORTS_MAX 32
+#define PLAYBACK_GAIN_MAX 1.0f
#define RECORD_GAIN_MIN 0.0f
#define RECORD_GAIN_MAX 1.0f
#define RECORD_VOLUME_CTL_MAX 0x2000
@@ -1227,15 +1228,10 @@
if (audio_extn_is_maxx_audio_enabled())
audio_extn_ma_set_device(usecase);
audio_extn_utils_send_audio_calibration(adev, usecase);
- if ((usecase->type == PCM_PLAYBACK) &&
- ((out = usecase->stream.out) != NULL)) {
- if (!is_offload_usecase(out->usecase)) {
- pthread_mutex_lock(&out->latch_lock);
- out->muted = false;
- pthread_mutex_unlock(&out->latch_lock);
- } else if (out->compr) {
+ if ((usecase->type == PCM_PLAYBACK) && is_offload_usecase(usecase->id)) {
+ out = usecase->stream.out;
+ if (out && out->compr)
audio_extn_utils_compress_set_clk_rec_mode(usecase);
- }
}
if (usecase->type == PCM_CAPTURE) {
@@ -3641,6 +3637,8 @@
return -EINVAL;
}
+ out->a2dp_muted = false;
+
if (audio_extn_ext_hw_plugin_usecase_stop(adev->ext_hw_plugin, uc_info))
ALOGE("%s: failed to stop ext hw plugin", __func__);
@@ -3689,9 +3687,6 @@
list_remove(&uc_info->list);
out->started = 0;
- pthread_mutex_lock(&out->latch_lock);
- out->muted = false;
- pthread_mutex_unlock(&out->latch_lock);
if (is_offload_usecase(out->usecase) &&
(audio_extn_passthru_is_passthrough_stream(out))) {
ALOGV("Disable passthrough , reset mixer to pcm");
@@ -4979,17 +4974,19 @@
platform_set_swap_channels(adev, true);
audio_extn_perf_lock_release(&adev->perf_lock_handle);
}
- if (is_offload_usecase(out->usecase) &&
- (!is_a2dp_out_device_type(&out->device_list) || audio_extn_a2dp_source_is_ready())) {
- pthread_mutex_lock(&out->latch_lock);
- if (out->a2dp_compress_mute) {
- out->a2dp_compress_mute = false;
- out_set_compr_volume(&out->stream, out->volume_l, out->volume_r);
+ pthread_mutex_lock(&out->latch_lock);
+ if (!is_a2dp_out_device_type(&out->device_list) || audio_extn_a2dp_source_is_ready()) {
+ if (out->a2dp_muted) {
+ out->a2dp_muted = false;
+ if (is_offload_usecase(out->usecase))
+ out_set_compr_volume(&out->stream, out->volume_l, out->volume_r);
+ else if (out->usecase != USECASE_AUDIO_PLAYBACK_VOIP)
+ out_set_pcm_volume(&out->stream, out->volume_l, out->volume_r);
}
- pthread_mutex_unlock(&out->latch_lock);
- } else if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP) {
- out_set_voip_volume(&out->stream, out->volume_l, out->volume_r);
}
+ if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP && !out->a2dp_muted)
+ out_set_voip_volume(&out->stream, out->volume_l, out->volume_r);
+ pthread_mutex_unlock(&out->latch_lock);
}
}
@@ -5541,9 +5538,7 @@
ALOGD("%s: called with left_vol=%f, right_vol=%f", __func__, left, right);
if (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
/* only take left channel into account: the API is for stereo anyway */
- pthread_mutex_lock(&out->latch_lock);
out->muted = (left == 0.0f);
- pthread_mutex_unlock(&out->latch_lock);
return 0;
} else if (is_offload_usecase(out->usecase)) {
if (audio_extn_passthru_is_passthrough_stream(out)) {
@@ -5581,15 +5576,15 @@
}
}
pthread_mutex_lock(&out->latch_lock);
- if (!out->a2dp_compress_mute) {
+ if (!out->a2dp_muted) {
ret = out_set_compr_volume(&out->stream, out->volume_l, out->volume_r);
}
pthread_mutex_unlock(&out->latch_lock);
return ret;
} else {
pthread_mutex_lock(&out->latch_lock);
- ALOGV("%s: compress mute %d", __func__, out->a2dp_compress_mute);
- if (!out->a2dp_compress_mute)
+ ALOGV("%s: compress mute %d", __func__, out->a2dp_muted);
+ if (!out->a2dp_muted)
ret = out_set_compr_volume(stream, left, right);
out->volume_l = left;
out->volume_r = right;
@@ -5599,14 +5594,17 @@
} else if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP) {
out->app_type_cfg.gain[0] = (int)(left * VOIP_PLAYBACK_VOLUME_MAX);
out->app_type_cfg.gain[1] = (int)(right * VOIP_PLAYBACK_VOLUME_MAX);
+ pthread_mutex_lock(&out->latch_lock);
if (!out->standby) {
audio_extn_utils_send_app_type_gain(out->dev,
out->app_type_cfg.app_type,
&out->app_type_cfg.gain[0]);
- ret = out_set_voip_volume(stream, left, right);
+ if (!out->a2dp_muted)
+ ret = out_set_voip_volume(stream, left, right);
}
out->volume_l = left;
out->volume_r = right;
+ pthread_mutex_unlock(&out->latch_lock);
return ret;
} else if (out->usecase == USECASE_AUDIO_PLAYBACK_MMAP) {
ALOGV("%s: MMAP set volume called", __func__);
@@ -5618,21 +5616,25 @@
} else if (out->usecase == USECASE_AUDIO_PLAYBACK_LOW_LATENCY ||
out->usecase == USECASE_AUDIO_PLAYBACK_DEEP_BUFFER ||
out->usecase == USECASE_AUDIO_PLAYBACK_ULL) {
+ pthread_mutex_lock(&out->latch_lock);
/* Volume control for pcm playback */
- if (!out->standby)
+ if (!out->standby && !out->a2dp_muted)
ret = out_set_pcm_volume(stream, left, right);
else
out->apply_volume = true;
out->volume_l = left;
out->volume_r = right;
+ pthread_mutex_unlock(&out->latch_lock);
return ret;
} else if (audio_extn_auto_hal_is_bus_device_usecase(out->usecase)) {
ALOGV("%s: bus device set volume called", __func__);
- if (!out->standby)
+ pthread_mutex_lock(&out->latch_lock);
+ if (!out->standby && !out->a2dp_muted)
ret = out_set_pcm_volume(stream, left, right);
out->volume_l = left;
out->volume_r = right;
+ pthread_mutex_unlock(&out->latch_lock);
return ret;
}
@@ -6018,10 +6020,8 @@
} else {
if (out->pcm) {
size_t bytes_to_write = bytes;
- pthread_mutex_lock(&out->latch_lock);
if (out->muted)
memset((void *)buffer, 0, bytes);
- pthread_mutex_unlock(&out->latch_lock);
ALOGV("%s: frames=%zu, frame_size=%zu, bytes_to_write=%zu",
__func__, frames, frame_size, bytes_to_write);
@@ -7773,7 +7773,7 @@
out->non_blocking = 0;
out->convert_buffer = NULL;
out->started = 0;
- out->a2dp_compress_mute = false;
+ out->a2dp_muted = false;
out->hal_output_suspend_supported = 0;
out->dynamic_pm_qos_config_supported = 0;
out->set_dual_mono = false;
@@ -8504,6 +8504,8 @@
out->kernel_buffer_size = out->config.period_size * out->config.period_count;
out->standby = 1;
+ out->volume_l = PLAYBACK_GAIN_MAX;
+ out->volume_r = PLAYBACK_GAIN_MAX;
/* out->muted = false; by calloc() */
/* out->written = 0; by calloc() */
@@ -8644,7 +8646,7 @@
free(out->compr_config.codec);
}
- out->a2dp_compress_mute = false;
+ out->a2dp_muted = false;
if (is_interactive_usecase(out->usecase))
free_interactive_usecase(adev, out->usecase);
@@ -8897,17 +8899,12 @@
//force device switch to re configure encoder
select_devices(adev, usecase->id);
ALOGD("Unmuting the stream after select_devices");
- pthread_mutex_lock(&usecase->stream.out->latch_lock);
- usecase->stream.out->a2dp_compress_mute = false;
- out_set_compr_volume(&usecase->stream.out->stream,
- usecase->stream.out->volume_l,
- usecase->stream.out->volume_r);
- pthread_mutex_unlock(&usecase->stream.out->latch_lock);
+ check_a2dp_restore_l(adev, usecase->stream.out, true);
audio_extn_a2dp_set_handoff_mode(false);
break;
} else if (is_offload_usecase(usecase->stream.out->usecase)) {
pthread_mutex_lock(&usecase->stream.out->latch_lock);
- if (usecase->stream.out->a2dp_compress_mute) {
+ if (usecase->stream.out->a2dp_muted) {
pthread_mutex_unlock(&usecase->stream.out->latch_lock);
reassign_device_list(&usecase->stream.out->device_list,
AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, "");
@@ -10358,8 +10355,8 @@
}
list_init(&devices);
- ALOGD("%s: enter: usecase(%d: %s)", __func__,
- out->usecase, use_case_table[out->usecase]);
+ ALOGD("%s: enter: usecase(%d: %s), a2dp muted %d", __func__,
+ out->usecase, use_case_table[out->usecase], out->a2dp_muted);
if (restore) {
pthread_mutex_lock(&out->latch_lock);
@@ -10368,42 +10365,50 @@
ALOGD("%s: restoring A2dp and unmuting stream", __func__);
if (uc_info->out_snd_device != SND_DEVICE_OUT_BT_A2DP)
select_devices(adev, uc_info->id);
- if (is_offload_usecase(out->usecase) &&
- (uc_info->out_snd_device == SND_DEVICE_OUT_BT_A2DP)) {
- if (out->a2dp_compress_mute) {
- out->a2dp_compress_mute = false;
+
+ if (is_offload_usecase(out->usecase)) {
+ if (uc_info->out_snd_device == SND_DEVICE_OUT_BT_A2DP)
out_set_compr_volume(&out->stream, out->volume_l, out->volume_r);
- }
+ } else if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP) {
+ out_set_voip_volume(&out->stream, out->volume_l, out->volume_r);
+ } else {
+ out_set_pcm_volume(&out->stream, out->volume_l, out->volume_r);
}
+ out->a2dp_muted = false;
}
- out->muted = false;
pthread_mutex_unlock(&out->latch_lock);
} else {
pthread_mutex_lock(&out->latch_lock);
- if (is_offload_usecase(out->usecase)) {
- // mute compress stream if suspended
- if (!out->a2dp_compress_mute && !out->standby) {
- ALOGD("%s: selecting speaker and muting stream", __func__);
- assign_devices(&devices, &out->device_list);
- reassign_device_list(&out->device_list, AUDIO_DEVICE_OUT_SPEAKER, "");
- left_p = out->volume_l;
- right_p = out->volume_r;
+ // mute stream and switch to speaker if suspended
+ if (!out->a2dp_muted && !out->standby) {
+ ALOGD("%s: selecting speaker and muting stream", __func__);
+ assign_devices(&devices, &out->device_list);
+ reassign_device_list(&out->device_list, AUDIO_DEVICE_OUT_SPEAKER, "");
+ left_p = out->volume_l;
+ right_p = out->volume_r;
+ out->a2dp_muted = true;
+ if (is_offload_usecase(out->usecase)) {
if (out->offload_state == OFFLOAD_STATE_PLAYING)
compress_pause(out->compr);
out_set_compr_volume(&out->stream, (float)0, (float)0);
- out->a2dp_compress_mute = true;
- select_devices(adev, out->usecase);
+ } else if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP) {
+ out_set_voip_volume(&out->stream, (float)0, (float)0);
+ } else {
+ out_set_pcm_volume(&out->stream, (float)0, (float)0);
+ /* wait for stale pcm drained before switching to speaker */
+ uint32_t latency =
+ (out->config.period_count * out->config.period_size * 1000) /
+ (out->config.rate);
+ usleep(latency * 1000);
+ }
+ select_devices(adev, out->usecase);
+ if (is_offload_usecase(out->usecase)) {
if (out->offload_state == OFFLOAD_STATE_PLAYING)
compress_resume(out->compr);
- assign_devices(&out->device_list, &devices);
- out->volume_l = left_p;
- out->volume_r = right_p;
}
- } else {
- // mute for non offloaded streams
- if (audio_extn_a2dp_source_is_suspended()) {
- out->muted = true;
- }
+ assign_devices(&out->device_list, &devices);
+ out->volume_l = left_p;
+ out->volume_r = right_p;
}
pthread_mutex_unlock(&out->latch_lock);
}
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index f1e8672..32271bb 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -442,7 +442,7 @@
qahwi_stream_out_t qahwi_out;
bool is_iec61937_info_available;
- bool a2dp_compress_mute;
+ bool a2dp_muted;
float volume_l;
float volume_r;
bool apply_volume;