Merge "ma_listener: correct bounds of array" into pi-dev
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 34cb938..8a2562f 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -4086,9 +4086,9 @@
lock_input_stream(in);
pthread_mutex_lock(&adev->lock);
- int ret = platform_get_active_microphones(adev->platform, in->device,
+ int ret = platform_get_active_microphones(adev->platform,
audio_channel_count_from_in_mask(in->channel_mask),
- in->source, in->usecase, mic_array, mic_count);
+ in->usecase, mic_array, mic_count);
pthread_mutex_unlock(&adev->lock);
pthread_mutex_unlock(&in->lock);
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 7f46b58..38c4f49 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -2504,6 +2504,11 @@
return -ENOSYS;
}
+bool platform_set_microphone_map(void *platform __unused, snd_device_t in_snd_device __unused,
+ const struct mic_info *info __unused) {
+ return false;
+}
+
int platform_get_active_microphones(void *platform __unused,
audio_devices_t device __unused,
unsigned int channels __unused,
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index fbb166d..450e31c 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -105,6 +105,11 @@
char be_name[BE_DAI_NAME_MAX_LENGTH];
};
+struct snd_device_to_mic_map {
+ struct mic_info microphones[AUDIO_MICROPHONE_MAX_COUNT];
+ size_t mic_count;
+};
+
static struct listnode operator_info_list;
static struct listnode *operator_specific_device_table[SND_DEVICE_MAX];
@@ -167,6 +172,7 @@
uint32_t declared_mic_count;
struct audio_microphone_characteristic_t microphones[AUDIO_MICROPHONE_MAX_COUNT];
+ struct snd_device_to_mic_map mic_map[SND_DEVICE_MAX];
};
static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
@@ -4547,38 +4553,64 @@
return 0;
}
-int platform_get_active_microphones(void *platform, audio_devices_t device, unsigned int channels,
- int source __unused, audio_usecase_t usecase __unused,
+bool platform_set_microphone_map(void *platform, snd_device_t in_snd_device,
+ const struct mic_info *info) {
+ struct platform_data *my_data = (struct platform_data *)platform;
+ if (in_snd_device < SND_DEVICE_IN_BEGIN || in_snd_device >= SND_DEVICE_IN_END) {
+ ALOGE("%s: Sound device not valid", __func__);
+ return false;
+ }
+ size_t m_count = my_data->mic_map[in_snd_device].mic_count++;
+ if (m_count >= AUDIO_MICROPHONE_MAX_COUNT) {
+ ALOGE("%s: Microphone count is greater than max allowed value", __func__);
+ my_data->mic_map[in_snd_device].mic_count--;
+ return false;
+ }
+ my_data->mic_map[in_snd_device].microphones[m_count] = *info;
+ return true;
+}
+
+int platform_get_active_microphones(void *platform, unsigned int channels,
+ audio_usecase_t uc_id,
struct audio_microphone_characteristic_t *mic_array,
size_t *mic_count) {
struct platform_data *my_data = (struct platform_data *)platform;
- if (mic_count == NULL) {
+ struct audio_usecase *usecase = get_usecase_from_list(my_data->adev, uc_id);
+ if (mic_count == NULL || mic_array == NULL || usecase == NULL) {
return -EINVAL;
}
- if (mic_array == NULL) {
- return -EINVAL;
- }
-
- if (*mic_count == 0) {
- // TODO: return declared mic count as a preliminary implementation, the final
- // implementation will derive mic count and channel mapping from use case, source and device
- *mic_count = my_data->declared_mic_count;
- return 0;
- }
-
- size_t max_mic_count = *mic_count;
+ size_t max_mic_count = my_data->declared_mic_count;
size_t actual_mic_count = 0;
- for (size_t i = 0; i < max_mic_count && i < my_data->declared_mic_count; i++) {
- // TODO: get actual microphone and channel mapping type.
- if ((my_data->microphones[i].device & device) == device) {
- mic_array[actual_mic_count] = my_data->microphones[i];
- for (size_t ch = 0; ch < channels; ch++) {
- mic_array[actual_mic_count].channel_mapping[ch] =
- AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT;
+
+ snd_device_t active_input_snd_device =
+ platform_get_input_snd_device(platform, usecase->stream.in->device);
+ if (active_input_snd_device == SND_DEVICE_NONE) {
+ ALOGI("%s: No active microphones found", __func__);
+ goto end;
+ }
+
+ size_t active_mic_count = my_data->mic_map[active_input_snd_device].mic_count;
+ struct mic_info *m_info = my_data->mic_map[active_input_snd_device].microphones;
+
+ for (size_t i = 0; i < active_mic_count; i++) {
+ unsigned int channels_for_active_mic = channels;
+ if (channels_for_active_mic > m_info[i].channel_count) {
+ channels_for_active_mic = m_info[i].channel_count;
+ }
+ for (size_t j = 0; j < max_mic_count; j++) {
+ if (strcmp(my_data->microphones[j].device_id,
+ m_info[i].device_id) == 0) {
+ mic_array[actual_mic_count] = my_data->microphones[j];
+ for (size_t ch = 0; ch < channels_for_active_mic; ch++) {
+ mic_array[actual_mic_count].channel_mapping[ch] =
+ m_info[i].channel_mapping[ch];
+ }
+ actual_mic_count++;
+ break;
}
- actual_mic_count++;
}
}
+end:
*mic_count = actual_mic_count;
return 0;
}
diff --git a/hal/platform_api.h b/hal/platform_api.h
index e3dc5d1..5c7d81f 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -33,6 +33,12 @@
uint32_t level;
};
+struct mic_info {
+ char device_id[AUDIO_MICROPHONE_ID_MAX_LEN];
+ size_t channel_count;
+ audio_microphone_channel_mapping_t channel_mapping[AUDIO_CHANNEL_COUNT_MAX];
+};
+
enum card_status_t;
struct audio_usecase;
enum usecase_type_t;
@@ -156,11 +162,13 @@
bool platform_set_microphone_characteristic(void *platform,
struct audio_microphone_characteristic_t mic);
+bool platform_set_microphone_map(void *platform, snd_device_t in_snd_device,
+ const struct mic_info *info);
int platform_get_microphones(void *platform,
struct audio_microphone_characteristic_t *mic_array,
size_t *mic_count);
-int platform_get_active_microphones(void *platform, audio_devices_t device,
- unsigned int channels, int source, audio_usecase_t usecase,
+int platform_get_active_microphones(void *platform, unsigned int channels,
+ audio_usecase_t usecase,
struct audio_microphone_characteristic_t *mic_array,
size_t *mic_count);
int platform_set_usb_service_interval(void *platform,
diff --git a/hal/platform_info.c b/hal/platform_info.c
index 58631f2..181460e 100644
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -36,6 +36,11 @@
GAIN_LEVEL_MAPPING,
APP_TYPE,
MICROPHONE_CHARACTERISTIC,
+ SND_DEVICES,
+ INPUT_SND_DEVICE,
+ INPUT_SND_DEVICE_TO_MIC_MAPPING,
+ SND_DEV,
+ MIC_INFO,
} section_t;
typedef void (* section_process_fn)(const XML_Char **attr);
@@ -49,6 +54,8 @@
static void process_gain_db_to_level_map(const XML_Char **attr);
static void process_app_type(const XML_Char **attr);
static void process_microphone_characteristic(const XML_Char **attr);
+static void process_snd_dev(const XML_Char **attr);
+static void process_mic_info(const XML_Char **attr);
static section_process_fn section_table[] = {
[ROOT] = process_root,
@@ -60,6 +67,8 @@
[GAIN_LEVEL_MAPPING] = process_gain_db_to_level_map,
[APP_TYPE] = process_app_type,
[MICROPHONE_CHARACTERISTIC] = process_microphone_characteristic,
+ [SND_DEV] = process_snd_dev,
+ [MIC_INFO] = process_mic_info,
};
static set_parameters_fn set_parameters = &platform_set_parameters;
@@ -79,6 +88,8 @@
unsigned int value;
};
+static snd_device_t in_snd_device;
+
static const struct audio_string_to_enum mic_locations[AUDIO_MICROPHONE_LOCATION_CNT] = {
AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_LOCATION_UNKNOWN),
AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_LOCATION_MAINBODY),
@@ -95,6 +106,12 @@
AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_SUPER_CARDIOID),
};
+static const struct audio_string_to_enum mic_channel_mapping[AUDIO_MICROPHONE_CHANNEL_MAPPING_CNT] = {
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED),
+};
+
static const struct audio_string_to_enum device_in_types[] = {
AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_AMBIENT),
AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_COMMUNICATION),
@@ -660,6 +677,66 @@
return;
}
+static void process_snd_dev(const XML_Char **attr)
+{
+ uint32_t curIdx = 0;
+ in_snd_device = SND_DEVICE_NONE;
+
+ if (strcmp(attr[curIdx++], "in_snd_device")) {
+ ALOGE("%s: snd_device not found", __func__);
+ return;
+ }
+ in_snd_device = platform_get_snd_device_index((char *)attr[curIdx++]);
+ if (in_snd_device < SND_DEVICE_IN_BEGIN ||
+ in_snd_device >= SND_DEVICE_IN_END) {
+ ALOGE("%s: Sound device not valid", __func__);
+ in_snd_device = SND_DEVICE_NONE;
+ }
+
+ return;
+}
+
+static void process_mic_info(const XML_Char **attr)
+{
+ uint32_t curIdx = 0;
+ struct mic_info microphone;
+
+ memset(µphone.channel_mapping, AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED,
+ sizeof(microphone.channel_mapping));
+
+ if (strcmp(attr[curIdx++], "mic_device_id")) {
+ ALOGE("%s: mic_device_id not found", __func__);
+ goto on_error;
+ }
+ strlcpy(microphone.device_id,
+ (char *)attr[curIdx++], AUDIO_MICROPHONE_ID_MAX_LEN);
+
+ if (strcmp(attr[curIdx++], "channel_mapping")) {
+ ALOGE("%s: channel_mapping not found", __func__);
+ goto on_error;
+ }
+ const char *token = strtok((char *)attr[curIdx++], " ");
+ uint32_t idx = 0;
+ while (token) {
+ if (!find_enum_by_string(mic_channel_mapping, token,
+ AUDIO_MICROPHONE_CHANNEL_MAPPING_CNT,
+ µphone.channel_mapping[idx++])) {
+ ALOGE("%s: channel_mapping %s in %s not found!",
+ __func__, attr[--curIdx], PLATFORM_INFO_XML_PATH);
+ goto on_error;
+ }
+ token = strtok(NULL, " ");
+ }
+ microphone.channel_count = idx;
+
+ platform_set_microphone_map(my_data.platform, in_snd_device,
+ µphone);
+ return;
+on_error:
+ in_snd_device = SND_DEVICE_NONE;
+ return;
+}
+
static void start_tag(void *userdata __unused, const XML_Char *tag_name,
const XML_Char **attr)
{
@@ -685,6 +762,8 @@
section = APP_TYPE;
} else if (strcmp(tag_name, "microphone_characteristics") == 0) {
section = MICROPHONE_CHARACTERISTIC;
+ } else if (strcmp(tag_name, "snd_devices") == 0) {
+ section = SND_DEVICES;
} else if (strcmp(tag_name, "device") == 0) {
if ((section != ACDB) && (section != BACKEND_NAME) && (section != OPERATOR_SPECIFIC)) {
ALOGE("device tag only supported for acdb/backend names");
@@ -733,6 +812,36 @@
}
section_process_fn fn = section_table[MICROPHONE_CHARACTERISTIC];
fn(attr);
+ } else if (strcmp(tag_name, "input_snd_device") == 0) {
+ if (section != SND_DEVICES) {
+ ALOGE("input_snd_device tag only supported with SND_DEVICES section");
+ return;
+ }
+ section = INPUT_SND_DEVICE;
+ } else if (strcmp(tag_name, "input_snd_device_mic_mapping") == 0) {
+ if (section != INPUT_SND_DEVICE) {
+ ALOGE("input_snd_device_mic_mapping tag only supported with INPUT_SND_DEVICE section");
+ return;
+ }
+ section = INPUT_SND_DEVICE_TO_MIC_MAPPING;
+ } else if (strcmp(tag_name, "snd_dev") == 0) {
+ if (section != INPUT_SND_DEVICE_TO_MIC_MAPPING) {
+ ALOGE("snd_dev tag only supported with INPUT_SND_DEVICE_TO_MIC_MAPPING section");
+ return;
+ }
+ section_process_fn fn = section_table[SND_DEV];
+ fn(attr);
+ } else if (strcmp(tag_name, "mic_info") == 0) {
+ if (section != INPUT_SND_DEVICE_TO_MIC_MAPPING) {
+ ALOGE("mic_info tag only supported with INPUT_SND_DEVICE_TO_MIC_MAPPING section");
+ return;
+ }
+ if (in_snd_device == SND_DEVICE_NONE) {
+ ALOGE("%s: Error in previous tags, do not process mic info", __func__);
+ return;
+ }
+ section_process_fn fn = section_table[MIC_INFO];
+ fn(attr);
}
} else {
if(strcmp(tag_name, "config_params") == 0) {
@@ -769,6 +878,12 @@
section = ROOT;
} else if (strcmp(tag_name, "microphone_characteristics") == 0) {
section = ROOT;
+ } else if (strcmp(tag_name, "snd_devices") == 0) {
+ section = ROOT;
+ } else if (strcmp(tag_name, "input_snd_device") == 0) {
+ section = SND_DEVICES;
+ } else if (strcmp(tag_name, "input_snd_device_mic_mapping") == 0) {
+ section = INPUT_SND_DEVICE;
}
}