audio HAL: support multiple active input streams
Implement support for more than one active input streams.
New implementation is limited to one active stream per capture use
case as there is one PCM ALSA device per front end and use case.
Note that the number of active sound trigger sessions is limited by the
soundtrigger implementation, not the number of PCM ALSA devices.
We do not enforce a max number of open streams per use case as this is
done by the audio_polcy_configuration file.
Bug: 111438757
Test: manual audio smoke tests for capture.
Change-Id: I1a372bca154d1ee034526f2b6b3ddeeae93a71f2
(cherry picked from commit d1b7a9b6b516e3313d65560a4b8004cfa3ae9a19)
Signed-off-by: Aniket Kumar Lata <alata@codeaurora.org>
diff --git a/hal/audio_extn/hw_loopback.c b/hal/audio_extn/hw_loopback.c
index 76c8873..afc029b 100644
--- a/hal/audio_extn/hw_loopback.c
+++ b/hal/audio_extn/hw_loopback.c
@@ -329,8 +329,6 @@
list_remove(&uc_info_rx->list);
free(uc_info_rx);
- adev->active_input = get_next_active_input(adev);
-
if (inout->ip_hdlr_handle) {
ret = audio_extn_ip_hdlr_intf_close(inout->ip_hdlr_handle, true, inout);
if (ret < 0)
@@ -522,7 +520,6 @@
memcpy(&loopback_source_stream.usecase, uc_info_rx,
sizeof(struct audio_usecase));
- adev->active_input = &loopback_source_stream;
select_devices(adev, uc_info_rx->id);
select_devices(adev, uc_info_tx->id);
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 9691ce8..9b7bd1f 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -917,7 +917,7 @@
char mixer_ctl_name[] = "Audio Effect";
struct mixer_ctl *ctl;
long set_values[6];
- struct stream_in *in = adev->active_input;
+ struct stream_in *in = adev_get_active_input(adev);
ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
if (!ctl) {
@@ -945,7 +945,7 @@
int ret = 0;
struct audio_effect_config other_effect_config;
struct audio_usecase *usecase = NULL;
- struct stream_in *in = adev->active_input;
+ struct stream_in *in = adev_get_active_input(adev);
usecase = get_usecase_from_list(adev, in->usecase);
if (!usecase)
@@ -975,7 +975,7 @@
struct audio_usecase *usecase = NULL;
int ret = 0;
unsigned int param_value = 0;
- struct stream_in *in = adev->active_input;
+ struct stream_in *in = adev_get_active_input(adev);
if(!voice_extn_is_dynamic_ecns_enabled())
return ENOSYS;
@@ -1024,13 +1024,16 @@
if(!voice_extn_is_dynamic_ecns_enabled())
return;
- if (adev->active_input->enable_aec) {
- enable_disable_effect(adev, EFFECT_AEC, true);
- }
+ struct stream_in *in = adev_get_active_input(adev);
- if (adev->active_input->enable_ns &&
- adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
- enable_disable_effect(adev, EFFECT_NS, true);
+ if (in != NULL && !in->standby) {
+ if (in->enable_aec)
+ enable_disable_effect(adev, EFFECT_AEC, true);
+
+ if (in->enable_ns &&
+ in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
+ enable_disable_effect(adev, EFFECT_NS, true);
+ }
}
}
@@ -1237,7 +1240,7 @@
}
if (((snd_device == SND_DEVICE_IN_HANDSET_6MIC) ||
(snd_device == SND_DEVICE_IN_HANDSET_QMIC)) &&
- (audio_extn_ffv_get_stream() == adev->active_input)) {
+ (audio_extn_ffv_get_stream() == adev_get_active_input(adev))) {
ALOGD("%s: init ec ref loopback", __func__);
audio_extn_ffv_init_ec_ref_loopback(adev, snd_device);
}
@@ -1319,7 +1322,7 @@
audio_route_apply_and_update_path(adev->audio_route, "hph-lowpower-mode");
} else if (((snd_device == SND_DEVICE_IN_HANDSET_6MIC) ||
(snd_device == SND_DEVICE_IN_HANDSET_QMIC)) &&
- (audio_extn_ffv_get_stream() == adev->active_input)) {
+ (audio_extn_ffv_get_stream() == adev_get_active_input(adev))) {
ALOGD("%s: deinit ec ref loopback", __func__);
audio_extn_ffv_deinit_ec_ref_loopback(adev, snd_device);
}
@@ -1612,8 +1615,10 @@
/* Update voc calibration before enabling VoIP route */
if (usecase->type == VOIP_CALL)
status = platform_switch_voice_call_device_post(adev->platform,
- usecase->out_snd_device,
- platform_get_input_snd_device(adev->platform, uc_info->devices));
+ usecase->out_snd_device,
+ platform_get_input_snd_device(
+ adev->platform, NULL,
+ uc_info->devices));
enable_audio_route(adev, usecase);
if (usecase->stream.out && usecase->id == USECASE_AUDIO_PLAYBACK_VOIP) {
out_set_voip_volume(&usecase->stream.out->stream,
@@ -1968,19 +1973,6 @@
return NULL;
}
-struct stream_in *get_next_active_input(const struct audio_device *adev)
-{
- struct audio_usecase *usecase;
- struct listnode *node;
-
- list_for_each_reverse(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->type == PCM_CAPTURE)
- return usecase->stream.in;
- }
- return NULL;
-}
-
/*
* is a true native playback active
*/
@@ -2214,6 +2206,42 @@
int out_standby_l(struct audio_stream *stream);
+struct stream_in *adev_get_active_input(const struct audio_device *adev)
+{
+ struct listnode *node;
+ struct stream_in *last_active_in = NULL;
+
+ /* Get last added active input.
+ * TODO: We may use a priority mechanism to pick highest priority active source */
+ list_for_each(node, &adev->usecase_list)
+ {
+ struct audio_usecase *usecase = node_to_item(node, struct audio_usecase, list);
+ if (usecase->type == PCM_CAPTURE && usecase->stream.in != NULL)
+ last_active_in = usecase->stream.in;
+ }
+
+ return last_active_in;
+}
+
+struct stream_in *get_voice_communication_input(const struct audio_device *adev)
+{
+ struct listnode *node;
+
+ /* First check active inputs with voice communication source and then
+ * any input if audio mode is in communication */
+ list_for_each(node, &adev->usecase_list)
+ {
+ struct audio_usecase *usecase = node_to_item(node, struct audio_usecase, list);
+ if (usecase->type == PCM_CAPTURE && usecase->stream.in != NULL &&
+ usecase->stream.in->source == AUDIO_SOURCE_VOICE_COMMUNICATION)
+ return usecase->stream.in;
+ }
+ if (adev->mode == AUDIO_MODE_IN_COMMUNICATION)
+ return adev_get_active_input(adev);
+
+ return NULL;
+}
+
int select_devices(struct audio_device *adev, audio_usecase_t uc_id)
{
snd_device_t out_snd_device = SND_DEVICE_NONE;
@@ -2243,7 +2271,9 @@
}
out_snd_device = platform_get_output_snd_device(adev->platform,
usecase->stream.out);
- in_snd_device = platform_get_input_snd_device(adev->platform, usecase->stream.out->devices);
+ in_snd_device = platform_get_input_snd_device(adev->platform,
+ NULL,
+ usecase->stream.out->devices);
usecase->devices = usecase->stream.out->devices;
} else if (usecase->type == TRANSCODE_LOOPBACK_RX) {
if (usecase->stream.inout == NULL) {
@@ -2262,7 +2292,7 @@
ALOGE("%s: stream.inout is NULL", __func__);
return -EINVAL;
}
- in_snd_device = platform_get_input_snd_device(adev->platform, AUDIO_DEVICE_NONE);
+ in_snd_device = platform_get_input_snd_device(adev->platform, NULL, AUDIO_DEVICE_NONE);
usecase->devices = in_snd_device;
} else {
/*
@@ -2322,21 +2352,17 @@
usecase->devices = usecase->stream.out->devices;
in_snd_device = SND_DEVICE_NONE;
if (out_snd_device == SND_DEVICE_NONE) {
+ struct stream_out *voip_out = adev->primary_output;
+ struct stream_in *voip_in = get_voice_communication_input(adev);
out_snd_device = platform_get_output_snd_device(adev->platform,
- usecase->stream.out);
+ usecase->stream.out);
voip_usecase = get_usecase_from_list(adev, USECASE_AUDIO_PLAYBACK_VOIP);
- if (voip_usecase == NULL && adev->primary_output && !adev->primary_output->standby)
- voip_usecase = get_usecase_from_list(adev, adev->primary_output->usecase);
- if ((usecase->stream.out != NULL &&
- voip_usecase != NULL &&
- usecase->stream.out->usecase == voip_usecase->id) &&
- adev->active_input &&
- (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
- adev->mode == AUDIO_MODE_IN_COMMUNICATION) &&
- out_snd_device != usecase->out_snd_device) {
- select_devices(adev, adev->active_input->usecase);
- }
+ if (voip_usecase)
+ voip_out = voip_usecase->stream.out;
+
+ if (usecase->stream.out == voip_out && voip_in != NULL)
+ select_devices(adev, voip_in->usecase);
}
} else if (usecase->type == PCM_CAPTURE) {
if (usecase->stream.in == NULL) {
@@ -2347,24 +2373,30 @@
out_snd_device = SND_DEVICE_NONE;
if (in_snd_device == SND_DEVICE_NONE) {
audio_devices_t out_device = AUDIO_DEVICE_NONE;
- if (adev->active_input &&
- (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
- (adev->mode == AUDIO_MODE_IN_COMMUNICATION &&
- adev->active_input->source == AUDIO_SOURCE_MIC))) {
- voip_usecase = get_usecase_from_list(adev, USECASE_AUDIO_PLAYBACK_VOIP);
- if (voip_usecase != NULL && voip_usecase->stream.out != NULL)
- out_device = voip_usecase->stream.out->devices;
- else if (adev->primary_output && !adev->primary_output->standby)
- out_device = adev->primary_output->devices;
+ struct stream_in *voip_in = get_voice_communication_input(adev);
+
+ if (voip_in != NULL) {
+
+ struct audio_usecase *voip_usecase = get_usecase_from_list(adev,
+ USECASE_AUDIO_PLAYBACK_VOIP);
+
platform_set_echo_reference(adev, false, AUDIO_DEVICE_NONE);
- } else if (usecase->id == USECASE_AUDIO_RECORD_AFE_PROXY) {
- out_device = AUDIO_DEVICE_OUT_TELEPHONY_TX;
- } else {
- /* forcing speaker o/p device to get matching i/p pair
- in case o/p is not routed from same primary HAL */
- out_device = AUDIO_DEVICE_OUT_SPEAKER;
+ if (usecase->id == USECASE_AUDIO_RECORD_AFE_PROXY) {
+ out_device = AUDIO_DEVICE_OUT_TELEPHONY_TX;
+ } else if (voip_usecase) {
+ out_device = voip_usecase->stream.out->devices;
+ } else if (adev->primary_output &&
+ !adev->primary_output->standby) {
+ out_device = adev->primary_output->devices;
+ } else {
+ /* forcing speaker o/p device to get matching i/p pair
+ in case o/p is not routed from same primary HAL */
+ out_device = AUDIO_DEVICE_OUT_SPEAKER;
+ }
}
- in_snd_device = platform_get_input_snd_device(adev->platform, out_device);
+ in_snd_device = platform_get_input_snd_device(adev->platform,
+ usecase->stream.in,
+ out_device);
}
}
}
@@ -2532,8 +2564,7 @@
/* If input stream is already running then effect needs to be
applied on the new input device that's being enabled here. */
- if ((in_snd_device != SND_DEVICE_NONE) && (adev->active_input != NULL) &&
- (!adev->active_input->standby))
+ if (in_snd_device != SND_DEVICE_NONE)
check_and_enable_effect(adev);
if (usecase->type == VOICE_CALL || usecase->type == VOIP_CALL) {
@@ -2557,14 +2588,13 @@
in_snd_device);
if (is_btsco_device(out_snd_device, in_snd_device) || is_a2dp_device(out_snd_device)) {
-
+ struct stream_in *in = adev_get_active_input(adev);
if (usecase->type == VOIP_CALL) {
- if (adev->active_input != NULL &&
- !adev->active_input->standby) {
+ if (in != NULL && !in->standby) {
if (is_bt_soc_on(adev) == false){
ALOGD("BT SCO MIC disconnected while in connection");
- if (adev->active_input->pcm != NULL)
- pcm_stop(adev->active_input->pcm);
+ if (in->pcm != NULL)
+ pcm_stop(in->pcm);
}
}
if ((usecase->stream.out != NULL) && (usecase->stream.out != adev->primary_output)
@@ -2634,7 +2664,6 @@
list_remove(&uc_info->list);
free(uc_info);
- adev->active_input = get_next_active_input(adev);
enable_gcov();
ALOGV("%s: exit: status(%d)", __func__, ret);
return ret;
@@ -2696,7 +2725,6 @@
goto error_config;
}
- adev->active_input = in;
uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
if (!uc_info) {
@@ -2827,7 +2855,6 @@
stop_input_stream(in);
error_config:
- adev->active_input = get_next_active_input(adev);
/*
* sleep 50ms to allow sufficient time for kernel
* drivers to recover incases like SSR.
@@ -8650,7 +8677,7 @@
/* Disable echo reference if there are no active input, hfp call
* and sound trigger while closing input stream
*/
- if (!adev->active_input &&
+ if (adev_get_active_input(adev) == NULL &&
!audio_extn_hfp_is_active(adev) &&
!audio_extn_sound_trigger_check_ec_ref_enable())
platform_set_echo_reference(adev, false, AUDIO_DEVICE_NONE);
@@ -8798,13 +8825,10 @@
uc_info.id = audio_usecase;
uc_info.type = usecase_type;
if (dir) {
- adev->active_input = ∈
memset(&in, 0, sizeof(in));
in.device = audio_device;
in.source = AUDIO_SOURCE_VOICE_COMMUNICATION;
uc_info.stream.in = ∈
- } else {
- adev->active_input = NULL;
}
memset(&out, 0, sizeof(out));
out.devices = audio_device; /* only field needed in select_devices */
@@ -8839,7 +8863,6 @@
list_remove(&uc_info.list);
}
}
- adev->active_input = NULL; /* restore adev state */
return 0;
}
@@ -9153,7 +9176,6 @@
/* Set the default route before the PCM stream is opened */
adev->mode = AUDIO_MODE_NORMAL;
- adev->active_input = NULL;
adev->primary_output = NULL;
adev->out_device = AUDIO_DEVICE_NONE;
adev->bluetooth_nrec = true;
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 9a93ed7..09e8568 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -541,7 +541,6 @@
struct mixer *mixer;
audio_mode_t mode;
audio_devices_t out_device;
- struct stream_in *active_input;
struct stream_out *primary_output;
struct stream_out *voice_tx_output;
struct stream_out *current_call_output;
@@ -660,8 +659,6 @@
struct audio_usecase *get_usecase_from_list(const struct audio_device *adev,
audio_usecase_t uc_id);
-struct stream_in *get_next_active_input(const struct audio_device *adev);
-
bool is_offload_usecase(audio_usecase_t uc_id);
bool audio_is_true_native_stream_active(struct audio_device *adev);
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 80a52c7..99ba137 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -4153,6 +4153,7 @@
bool use_voip_out_devices = false;
bool prop_rec_play_enabled = false;
char recConcPropValue[PROPERTY_VALUE_MAX];
+ struct stream_in *in = adev_get_active_input(adev);
if (property_get("vendor.audio.rec.playback.conc.disabled", recConcPropValue, NULL)) {
prop_rec_play_enabled = atoi(recConcPropValue) || !strncmp("true", recConcPropValue, 4);
@@ -4161,8 +4162,8 @@
(my_data->rec_play_conc_set || adev->mode == AUDIO_MODE_IN_COMMUNICATION);
ALOGV("platform_get_output_snd_device use_voip_out_devices : %d",use_voip_out_devices);
- audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
- AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
+ audio_channel_mask_t channel_mask = (in == NULL) ?
+ AUDIO_CHANNEL_IN_MONO : in->channel_mask;
int channel_count = popcount(channel_mask);
ALOGV("%s: enter: output devices(%#x)", __func__, devices);
@@ -4503,9 +4504,9 @@
{
struct audio_device *adev = my_data->adev;
snd_device_t snd_device = SND_DEVICE_NONE;
+ struct stream_in *in = adev_get_active_input(adev);
- if (adev->active_input->enable_aec &&
- adev->active_input->enable_ns) {
+ if (in != NULL && in->enable_aec && in->enable_ns) {
if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
if (my_data->fluence_in_spkr_mode) {
if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
@@ -4537,7 +4538,7 @@
snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
}
platform_set_echo_reference(adev, true, out_device);
- } else if (adev->active_input->enable_aec) {
+ } else if (in != NULL && in->enable_aec) {
if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
if (my_data->fluence_in_spkr_mode) {
if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
@@ -4569,7 +4570,7 @@
snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
}
platform_set_echo_reference(adev, true, out_device);
- } else if (adev->active_input->enable_ns) {
+ } else if (in != NULL && in->enable_ns) {
if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
if (my_data->fluence_in_spkr_mode) {
if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
@@ -4615,27 +4616,27 @@
return get_snd_device_for_voice_comm_ecns_disabled(my_data, out_device, in_device);
}
-snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
+snd_device_t platform_get_input_snd_device(void *platform,
+ struct stream_in *in,
+ audio_devices_t out_device)
{
struct platform_data *my_data = (struct platform_data *)platform;
struct audio_device *adev = my_data->adev;
- /*
- * TODO: active_input always points to last opened input. Source returned will
- * be wrong if more than one active inputs are present.
- */
- audio_source_t source = (adev->active_input == NULL) ?
- AUDIO_SOURCE_DEFAULT : adev->active_input->source;
-
- audio_mode_t mode = adev->mode;
- audio_devices_t in_device = ((adev->active_input == NULL) ?
- AUDIO_DEVICE_NONE : adev->active_input->device)
- & ~AUDIO_DEVICE_BIT_IN;
- audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
- AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
+ audio_mode_t mode = adev->mode;
snd_device_t snd_device = SND_DEVICE_NONE;
- int channel_count = popcount(channel_mask);
- int str_bitwidth = (adev->active_input == NULL) ?
- CODEC_BACKEND_DEFAULT_BIT_WIDTH : adev->active_input->bit_width;
+
+ if (in == NULL) {
+ in = adev_get_active_input(adev);
+ }
+
+ audio_source_t source = (in == NULL) ? AUDIO_SOURCE_DEFAULT : in->source;
+ audio_devices_t in_device =
+ ((in == NULL) ? AUDIO_DEVICE_NONE : in->device) & ~AUDIO_DEVICE_BIT_IN;
+ audio_channel_mask_t channel_mask = (in == NULL) ? AUDIO_CHANNEL_IN_MONO : in->channel_mask;
+ int channel_count = audio_channel_count_from_in_mask(channel_mask);
+
+ int str_bitwidth = (in == NULL) ?
+ CODEC_BACKEND_DEFAULT_BIT_WIDTH : in->bit_width;
ALOGV("%s: enter: out_device(%#x) in_device(%#x) channel_count (%d) channel_mask (0x%x)",
__func__, out_device, in_device, channel_count, channel_mask);
@@ -4824,7 +4825,7 @@
snd_device = SND_DEVICE_IN_QUAD_MIC;
}
if (snd_device == SND_DEVICE_NONE) {
- if (adev->active_input->enable_ns)
+ if (in != NULL && in->enable_ns)
snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
else
snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
@@ -4866,16 +4867,15 @@
in_device = ((out_device == AUDIO_DEVICE_NONE) ?
AUDIO_DEVICE_IN_BUILTIN_MIC : in_device) & ~AUDIO_DEVICE_BIT_IN;
- if (adev->active_input) {
+ if (in)
snd_device = get_snd_device_for_voice_comm(my_data, out_device, in_device);
- }
} else if (source == AUDIO_SOURCE_MIC) {
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC &&
channel_count == 1) {
if(my_data->fluence_in_audio_rec) {
if ((my_data->fluence_type & FLUENCE_HEX_MIC) &&
(my_data->source_mic_type & SOURCE_HEX_MIC) &&
- (audio_extn_ffv_get_stream() == adev->active_input)) {
+ (audio_extn_ffv_get_stream() == in)) {
snd_device = audio_extn_ffv_get_capture_snd_device();
} else if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
@@ -4897,7 +4897,7 @@
goto exit;
}
- if (adev->active_input && (audio_extn_ssr_get_stream() == adev->active_input))
+ if (in && (audio_extn_ssr_get_stream() == in))
snd_device = SND_DEVICE_IN_THREE_MIC;
if (snd_device != SND_DEVICE_NONE) {
@@ -4908,7 +4908,7 @@
!(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
!(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (adev->active_input && (audio_extn_ssr_get_stream() == adev->active_input))
+ if (in && (audio_extn_ssr_get_stream() == in))
snd_device = SND_DEVICE_IN_QUAD_MIC;
else if ((my_data->fluence_type & (FLUENCE_DUAL_MIC | FLUENCE_TRI_MIC | FLUENCE_QUAD_MIC)) &&
(channel_count == 2) && (my_data->source_mic_type & SOURCE_DUAL_MIC))
@@ -5233,9 +5233,9 @@
goto done_key_audcal;
}
- if(cal.dev_id) {
- if(audio_is_input_device(cal.dev_id)) {
- cal.snd_dev_id = platform_get_input_snd_device(platform, cal.dev_id);
+ if (cal.dev_id) {
+ if (audio_is_input_device(cal.dev_id)) {
+ cal.snd_dev_id = platform_get_input_snd_device(platform, NULL, cal.dev_id);
} else {
out.devices = cal.dev_id;
out.sample_rate = cal.sampling_rate;
@@ -5559,7 +5559,7 @@
}
if(cal.dev_id & AUDIO_DEVICE_BIT_IN) {
- cal.snd_dev_id = platform_get_input_snd_device(platform, cal.dev_id);
+ cal.snd_dev_id = platform_get_input_snd_device(platform, NULL, cal.dev_id);
} else if(cal.dev_id) {
out.devices = cal.dev_id;
out.sample_rate = cal.sampling_rate;
@@ -8520,7 +8520,7 @@
size_t actual_mic_count = 0;
snd_device_t active_input_snd_device =
- platform_get_input_snd_device(platform, usecase->stream.in->device);
+ platform_get_input_snd_device(platform, usecase->stream.in, AUDIO_DEVICE_NONE);
if (active_input_snd_device == SND_DEVICE_NONE) {
ALOGI("%s: No active microphones found", __func__);
goto end;
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index e16d20a..acab0c6 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -536,7 +536,7 @@
voice_is_in_call_rec_stream(usecase->stream.in))
snd_device = voice_get_incall_rec_snd_device(usecase->in_snd_device);
else if ((usecase->type == PCM_HFP_CALL) || (usecase->type == PCM_CAPTURE))
- snd_device = platform_get_input_snd_device(adev->platform,
+ snd_device = platform_get_input_snd_device(adev->platform, NULL,
adev->primary_output->devices);
acdb_dev_id = acdb_device_table[snd_device];
if (acdb_dev_id < 0) {
@@ -794,21 +794,23 @@
return snd_device;
}
-snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
+snd_device_t platform_get_input_snd_device(void *platform,
+ struct stream_in *in,
+ audio_devices_t out_device)
{
struct platform_data *my_data = (struct platform_data *)platform;
struct audio_device *adev = my_data->adev;
- audio_source_t source = (adev->active_input == NULL) ?
- AUDIO_SOURCE_DEFAULT : adev->active_input->source;
-
- audio_mode_t mode = adev->mode;
- audio_devices_t in_device = ((adev->active_input == NULL) ?
- AUDIO_DEVICE_NONE : adev->active_input->device)
- & ~AUDIO_DEVICE_BIT_IN;
- audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
- AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
+ audio_mode_t mode = adev->mode;
snd_device_t snd_device = SND_DEVICE_NONE;
+ if (in == NULL)
+ in = adev_get_active_input(adev);
+
+ audio_source_t source = (in == NULL) ? AUDIO_SOURCE_DEFAULT : in->source;
+ audio_devices_t in_device =
+ ((in == NULL) ? AUDIO_DEVICE_NONE : in->device) & ~AUDIO_DEVICE_BIT_IN;
+ audio_channel_mask_t channel_mask = (in == NULL) ? AUDIO_CHANNEL_IN_MONO : in->channel_mask;
+
ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
__func__, out_device, in_device);
if ((out_device != AUDIO_DEVICE_NONE) && (mode == AUDIO_MODE_IN_CALL)) {
@@ -882,8 +884,8 @@
} else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
in_device = AUDIO_DEVICE_IN_BACK_MIC;
- if (adev->active_input) {
- if (adev->active_input->enable_aec) {
+ if (in) {
+ if (in->enable_aec) {
if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
} else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 7fd2019..4827981 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1652,12 +1652,12 @@
{
struct platform_data *my_data = (struct platform_data *)platform;
struct audio_device *adev = my_data->adev;
- if (adev->active_input == NULL) {
+ struct stream_in *in = adev_get_active_input(adev);
+ if (in == NULL)
return base;
- }
- unsigned int sr = adev->active_input->sample_rate;
- unsigned int ch = popcount(adev->active_input->channel_mask);
- unsigned int bit_width = adev->active_input->bit_width;
+ unsigned int sr = in->sample_rate;
+ unsigned int ch = popcount(in->channel_mask);
+ unsigned int bit_width = in->bit_width;
if (audio_extn_usb_is_config_supported(&bit_width, &sr, &ch, false)
&& ((ch == 6) || (ch == 8))) {
return other;
@@ -5409,9 +5409,10 @@
audio_devices_t devices = out->devices;
unsigned int sample_rate = out->sample_rate;
int na_mode = platform_get_native_support();
+ struct stream_in *in = adev_get_active_input(adev);
- audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
- AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
+ audio_channel_mask_t channel_mask = (in == NULL) ?
+ AUDIO_CHANNEL_IN_MONO : in->channel_mask;
int channel_count = popcount(channel_mask);
ALOGV("%s: enter: output devices(%#x)", __func__, devices);
@@ -5863,9 +5864,9 @@
{
struct audio_device *adev = my_data->adev;
snd_device_t snd_device = SND_DEVICE_NONE;
+ struct stream_in *in = adev_get_active_input(adev);
- if (adev->active_input->enable_aec &&
- adev->active_input->enable_ns) {
+ if (in != NULL && in->enable_aec && in->enable_ns) {
if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
if (my_data->fluence_in_spkr_mode) {
if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
@@ -5911,7 +5912,7 @@
snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
}
platform_set_echo_reference(adev, true, out_device);
- } else if (adev->active_input->enable_aec) {
+ } else if (in != NULL && in->enable_aec) {
if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
if (my_data->fluence_in_spkr_mode) {
if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
@@ -5955,7 +5956,7 @@
snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
}
platform_set_echo_reference(adev, true, out_device);
- } else if (adev->active_input->enable_ns) {
+ } else if (in != NULL && in->enable_ns) {
if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
if (my_data->fluence_in_spkr_mode) {
if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
@@ -6013,27 +6014,24 @@
return get_snd_device_for_voice_comm_ecns_disabled(my_data, out_device, in_device);
}
-snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
+snd_device_t platform_get_input_snd_device(void *platform,
+ struct stream_in *in,
+ audio_devices_t out_device)
{
struct platform_data *my_data = (struct platform_data *)platform;
struct audio_device *adev = my_data->adev;
- /*
- * TODO: active_input always points to last opened input. Source returned will
- * be wrong if more than one active inputs are present.
- */
- audio_source_t source = (adev->active_input == NULL) ?
- AUDIO_SOURCE_DEFAULT : adev->active_input->source;
-
- audio_mode_t mode = adev->mode;
- audio_devices_t in_device = ((adev->active_input == NULL) ?
- AUDIO_DEVICE_NONE : adev->active_input->device)
- & ~AUDIO_DEVICE_BIT_IN;
- audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
- AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
+ audio_mode_t mode = adev->mode;
snd_device_t snd_device = SND_DEVICE_NONE;
- int channel_count = popcount(channel_mask);
- int str_bitwidth = (adev->active_input == NULL) ?
- CODEC_BACKEND_DEFAULT_BIT_WIDTH : adev->active_input->bit_width;
+
+ if (in == NULL)
+ in = adev_get_active_input(adev);
+
+ audio_source_t source = (in == NULL) ? AUDIO_SOURCE_DEFAULT : in->source;
+ audio_devices_t in_device =
+ ((in == NULL) ? AUDIO_DEVICE_NONE : in->device) & ~AUDIO_DEVICE_BIT_IN;
+ audio_channel_mask_t channel_mask = (in == NULL) ? AUDIO_CHANNEL_IN_MONO : in->channel_mask;
+ int channel_count = audio_channel_count_from_in_mask(channel_mask);
+ int str_bitwidth = (in == NULL) ? CODEC_BACKEND_DEFAULT_BIT_WIDTH : in->bit_width;
ALOGV("%s: enter: out_device(%#x) in_device(%#x) channel_count (%d) channel_mask (0x%x)",
__func__, out_device, in_device, channel_count, channel_mask);
@@ -6249,18 +6247,18 @@
/* Below check is true only in LA build to set
ambisonic profile. In LE hal client will set profile
*/
- if (my_data->ambisonic_profile == true) {
- strlcpy(adev->active_input->profile, "record_ambisonic",
- sizeof(adev->active_input->profile));
- }
+ if (my_data->ambisonic_profile == true &&
+ in != NULL)
+ strlcpy(in->profile, "record_ambisonic",
+ sizeof(in->profile));
- if (!strncmp(adev->active_input->profile, "record_ambisonic",
- strlen("record_ambisonic"))) {
+ if (in != NULL && !strncmp(in->profile, "record_ambisonic",
+ strlen("record_ambisonic"))) {
/* Validate input stream configuration for
Ambisonic capture.
*/
if (((int)channel_mask != (int)AUDIO_CHANNEL_INDEX_MASK_4) ||
- (adev->active_input->sample_rate != 48000)) {
+ (in->sample_rate != 48000)) {
snd_device = SND_DEVICE_NONE;
ALOGW("Unsupported Input configuration for ambisonic capture");
goto exit;
@@ -6326,19 +6324,19 @@
if (my_data->fluence_in_voice_rec && channel_count == 1) {
if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
- if (adev->active_input->enable_aec)
+ if (in != NULL && in->enable_aec)
snd_device = SND_DEVICE_IN_HANDSET_QMIC_AEC;
else
snd_device = SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE;
} else if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
(my_data->source_mic_type & SOURCE_THREE_MIC)) {
- if (adev->active_input->enable_aec)
+ if (in != NULL && in->enable_aec)
snd_device = SND_DEVICE_IN_HANDSET_TMIC_AEC;
else
snd_device = SND_DEVICE_IN_VOICE_REC_TMIC;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
(my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- if (adev->active_input->enable_aec)
+ if (in != NULL && in->enable_aec)
snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
else
snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
@@ -6356,14 +6354,14 @@
snd_device = SND_DEVICE_IN_QUAD_MIC;
}
if (snd_device == SND_DEVICE_NONE) {
- if (adev->active_input->enable_aec) {
- if (adev->active_input->enable_ns) {
+ if (in != NULL && in->enable_aec) {
+ if (in->enable_ns) {
snd_device = SND_DEVICE_IN_VOICE_REC_MIC_AEC_NS;
} else {
snd_device = SND_DEVICE_IN_VOICE_REC_MIC_AEC;
}
platform_set_echo_reference(adev, true, out_device);
- } else if (adev->active_input->enable_ns)
+ } else if (in != NULL && in->enable_ns)
snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
else
snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
@@ -6414,9 +6412,8 @@
in_device = ((out_device == AUDIO_DEVICE_NONE) ?
AUDIO_DEVICE_IN_BUILTIN_MIC : in_device) & ~AUDIO_DEVICE_BIT_IN;
- if (adev->active_input) {
+ if (in)
snd_device = get_snd_device_for_voice_comm(my_data, out_device, in_device);
- }
} else if (source == AUDIO_SOURCE_MIC) {
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC &&
channel_count == 1 ) {
@@ -6444,7 +6441,7 @@
goto exit;
}
- if (adev->active_input && (audio_extn_ssr_get_stream() == adev->active_input))
+ if (in && (audio_extn_ssr_get_stream() == in))
snd_device = SND_DEVICE_IN_THREE_MIC;
if (snd_device != SND_DEVICE_NONE) {
@@ -6455,7 +6452,7 @@
!(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
!(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if ((adev->active_input && (audio_extn_ssr_get_stream() == adev->active_input)) ||
+ if ((in && (audio_extn_ssr_get_stream() == in)) ||
((my_data->source_mic_type & SOURCE_QUAD_MIC) &&
channel_mask == AUDIO_CHANNEL_INDEX_MASK_4))
snd_device = SND_DEVICE_IN_QUAD_MIC;
@@ -6858,9 +6855,11 @@
goto done_key_audcal;
}
- if(cal.dev_id) {
- if(audio_is_input_device(cal.dev_id)) {
- cal.snd_dev_id = platform_get_input_snd_device(platform, cal.dev_id);
+ if (cal.dev_id) {
+ if (audio_is_input_device(cal.dev_id)) {
+ // FIXME: why pass an input device whereas
+ // platform_get_input_snd_device() expects as an output device?
+ cal.snd_dev_id = platform_get_input_snd_device(platform, NULL, cal.dev_id);
} else {
out.devices = cal.dev_id;
out.sample_rate = cal.sampling_rate;
@@ -7415,8 +7414,8 @@
goto done;
}
- if(cal.dev_id & AUDIO_DEVICE_BIT_IN) {
- cal.snd_dev_id = platform_get_input_snd_device(platform, cal.dev_id);
+ if (cal.dev_id & AUDIO_DEVICE_BIT_IN) {
+ cal.snd_dev_id = platform_get_input_snd_device(platform, NULL, cal.dev_id);
} else if(cal.dev_id) {
out.devices = cal.dev_id;
out.sample_rate = cal.sampling_rate;
@@ -8575,6 +8574,7 @@
unsigned int channels;
unsigned int format;
struct platform_data *my_data = (struct platform_data *)adev->platform;
+ struct stream_in *in = adev_get_active_input(adev);
bit_width = backend_cfg->bit_width;
sample_rate = backend_cfg->sample_rate;
@@ -8598,7 +8598,7 @@
} else if (my_data->is_internal_codec && !audio_is_usb_in_device(snd_device)) {
sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
channels = CODEC_BACKEND_DEFAULT_TX_CHANNELS;
- if (adev->active_input && adev->active_input->bit_width == 24)
+ if (in && in->bit_width == 24)
bit_width = platform_get_snd_device_bit_width(snd_device);
} else {
struct listnode *node;
@@ -10493,7 +10493,7 @@
size_t actual_mic_count = 0;
snd_device_t active_input_snd_device =
- platform_get_input_snd_device(platform, usecase->stream.in->device);
+ platform_get_input_snd_device(platform, usecase->stream.in, AUDIO_DEVICE_NONE);
if (active_input_snd_device == SND_DEVICE_NONE) {
ALOGI("%s: No active microphones found", __func__);
goto end;
diff --git a/hal/platform_api.h b/hal/platform_api.h
index f43aa88..3125f63 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -178,7 +178,9 @@
int platform_get_sample_rate(void *platform, uint32_t *rate);
int platform_set_device_mute(void *platform, bool state, char *dir);
snd_device_t platform_get_output_snd_device(void *platform, struct stream_out *out);
-snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device);
+snd_device_t platform_get_input_snd_device(void *platform,
+ struct stream_in *in,
+ audio_devices_t out_device);
int platform_set_hdmi_channels(void *platform, int channel_count);
int platform_edid_get_max_channels(void *platform);
void platform_add_operator_specific_device(snd_device_t snd_device,
@@ -355,4 +357,7 @@
struct audio_custom_mtmx_params_info *info);
int platform_add_custom_mtmx_params(void *platform,
struct audio_custom_mtmx_params_info *info);
+/* callback functions from platform to common audio HAL */
+struct stream_in *adev_get_active_input(const struct audio_device *adev);
+
#endif // AUDIO_PLATFORM_API_H
diff --git a/hal/voice_extn/compress_voip.c b/hal/voice_extn/compress_voip.c
index e4bc210..fbd6d6f 100644
--- a/hal/voice_extn/compress_voip.c
+++ b/hal/voice_extn/compress_voip.c
@@ -501,7 +501,6 @@
if (!voip_data.in_stream_count)
ret = compress_voip_open_input_stream(in);
- adev->active_input = in;
ret = voip_start_call(adev, &in->config);
in->pcm = voip_data.pcm_tx;
@@ -539,7 +538,6 @@
if(voip_data.in_stream_count > 0) {
voip_data.in_stream_count--;
status = voip_stop_call(adev);
- adev->active_input = get_next_active_input(adev);
in->pcm = NULL;
}