Support query microphones information.
Add query list of all/currently active microphones in hal layer.
Bug: 64038649
Bug: 75041465
Test: Manual Testing and Cts test
Change-Id: Id82300e83d2314f1102f2e5b5481df26d76002c8
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index f586865..115181a 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -3714,6 +3714,36 @@
return ret;
}
+static int in_get_active_microphones(const struct audio_stream_in *stream,
+ struct audio_microphone_characteristic_t *mic_array,
+ size_t *mic_count) {
+ struct stream_in *in = (struct stream_in *)stream;
+ struct audio_device *adev = in->dev;
+ ALOGVV("%s", __func__);
+
+ lock_input_stream(in);
+ pthread_mutex_lock(&adev->lock);
+ int ret = platform_get_active_microphones(adev->platform, in->device,
+ audio_channel_count_from_in_mask(in->channel_mask),
+ in->source, in->usecase, mic_array, mic_count);
+ pthread_mutex_unlock(&adev->lock);
+ pthread_mutex_unlock(&in->lock);
+
+ return ret;
+}
+
+static int adev_get_microphones(const struct audio_hw_device *dev,
+ struct audio_microphone_characteristic_t *mic_array,
+ size_t *mic_count) {
+ struct audio_device *adev = (struct audio_device *)dev;
+ ALOGVV("%s", __func__);
+
+ pthread_mutex_lock(&adev->lock);
+ int ret = platform_get_microphones(adev->platform, mic_array, mic_count);
+ pthread_mutex_unlock(&adev->lock);
+
+ return ret;
+}
static int adev_open_output_stream(struct audio_hw_device *dev,
audio_io_handle_t handle,
@@ -4555,6 +4585,7 @@
in->stream.read = in_read;
in->stream.get_input_frames_lost = in_get_input_frames_lost;
in->stream.get_capture_position = in_get_capture_position;
+ in->stream.get_active_microphones = in_get_active_microphones;
in->device = devices;
in->source = source;
@@ -5026,6 +5057,7 @@
adev->device.close_input_stream = adev_close_input_stream;
adev->device.dump = adev_dump;
+ adev->device.get_microphones = adev_get_microphones;
/* Set the default route before the PCM stream is opened */
pthread_mutex_lock(&adev->lock);
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 66803bc..a0a7442 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -2466,3 +2466,23 @@
bool platform_snd_device_has_speaker(snd_device_t dev __unused) {
return false;
}
+
+bool platform_set_microphone_characteristic(void *platform __unused,
+ struct audio_microphone_characteristic_t mic __unused) {
+ return -ENOSYS;
+}
+
+int platform_get_microphones(void *platform __unused,
+ struct audio_microphone_characteristic_t *mic_array __unused,
+ size_t *mic_count __unused) {
+ return -ENOSYS;
+}
+
+int platform_get_active_microphones(void *platform __unused,
+ audio_devices_t device __unused,
+ unsigned int channels __unused,
+ int source __unused, audio_usecase_t usecase __unused,
+ struct audio_microphone_characteristic_t *mic_array __unused,
+ size_t *mic_count __unused) {
+ return -ENOSYS;
+}
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index e8bdc92..937cfc4 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -243,6 +243,8 @@
#define AFE_PROXY_PLAYBACK_PCM_DEVICE 7
#define AFE_PROXY_RECORD_PCM_DEVICE 8
+#define AUDIO_MAKE_STRING_FROM_ENUM(X) { #X, X }
+
#define LIB_CSD_CLIENT "libcsd-client.so"
/* CSD-CLIENT related functions */
typedef int (*init_t)();
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index 580f230..8e8350b 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -1335,3 +1335,23 @@
bool platform_snd_device_has_speaker(snd_device_t dev __unused) {
return false;
}
+
+bool platform_set_microphone_characteristic(void *platform __unused,
+ struct audio_microphone_characteristic_t mic __unused) {
+ return -ENOSYS;
+}
+
+int platform_get_microphones(void *platform __unused,
+ struct audio_microphone_characteristic_t *mic_array __unused,
+ size_t *mic_count __unused) {
+ return -ENOSYS;
+}
+
+int platform_get_active_microphones(void *platform __unused,
+ audio_devices_t device __unused,
+ unsigned int channels __unused,
+ int source __unused, audio_usecase_t usecase __unused,
+ struct audio_microphone_characteristic_t *mic_array __unused,
+ size_t *mic_count __unused) {
+ return -ENOSYS;
+}
diff --git a/hal/msm8960/platform.h b/hal/msm8960/platform.h
index ebb4b1d..974b369 100644
--- a/hal/msm8960/platform.h
+++ b/hal/msm8960/platform.h
@@ -145,5 +145,7 @@
#define DEVICE_NAME_MAX_SIZE 128
+#define AUDIO_MAKE_STRING_FROM_ENUM(X) { #X, X }
+
#endif // QCOM_AUDIO_PLATFORM_H
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 92f534f..fea0d06 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -145,6 +145,9 @@
int max_mic_count;
void *hw_info;
+
+ uint32_t declared_mic_count;
+ struct audio_microphone_characteristic_t microphones[AUDIO_MICROPHONE_MAX_COUNT];
};
static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
@@ -1345,6 +1348,7 @@
audio_extn_utils_get_platform_info(snd_card_name, platform_info_file);
+ my_data->declared_mic_count = 0;
/* Initialize platform specific ids and/or backends*/
platform_info_init(platform_info_file, my_data);
@@ -4205,3 +4209,79 @@
}
return false;
}
+
+bool platform_set_microphone_characteristic(void *platform,
+ struct audio_microphone_characteristic_t mic) {
+ struct platform_data *my_data = (struct platform_data *)platform;
+ if (my_data->declared_mic_count >= AUDIO_MICROPHONE_MAX_COUNT) {
+ ALOGE("mic number is more than maximum number");
+ return false;
+ }
+ for (size_t ch = 0; ch < AUDIO_CHANNEL_COUNT_MAX; ch++) {
+ mic.channel_mapping[ch] = AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
+ }
+ my_data->microphones[my_data->declared_mic_count++] = mic;
+ return true;
+}
+
+int platform_get_microphones(void *platform,
+ struct audio_microphone_characteristic_t *mic_array,
+ size_t *mic_count) {
+ struct platform_data *my_data = (struct platform_data *)platform;
+ if (mic_count == NULL) {
+ return -EINVAL;
+ }
+ if (mic_array == NULL) {
+ return -EINVAL;
+ }
+
+ if (*mic_count == 0) {
+ *mic_count = my_data->declared_mic_count;
+ return 0;
+ }
+
+ size_t max_mic_count = *mic_count;
+ size_t actual_mic_count = 0;
+ for (size_t i = 0; i < max_mic_count && i < my_data->declared_mic_count; i++) {
+ mic_array[i] = my_data->microphones[i];
+ actual_mic_count++;
+ }
+ *mic_count = actual_mic_count;
+ return 0;
+}
+
+int platform_get_active_microphones(void *platform, audio_devices_t device, unsigned int channels,
+ int source __unused, audio_usecase_t usecase __unused,
+ struct audio_microphone_characteristic_t *mic_array,
+ size_t *mic_count) {
+ struct platform_data *my_data = (struct platform_data *)platform;
+ if (mic_count == 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 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;
+ }
+ actual_mic_count++;
+ }
+ }
+ *mic_count = actual_mic_count;
+ return 0;
+}
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index aebd667..3e31639 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -201,7 +201,6 @@
MAX_CODEC_BACKENDS
};
-
#define DEVICE_NAME_MAX_SIZE 128
#define HW_INFO_ARRAY_MAX_SIZE 32
@@ -336,6 +335,8 @@
#define PLATFORM_CONFIG_KEY_MAX_MIC_COUNT "input_mic_max_count"
#define PLATFORM_DEFAULT_MIC_COUNT 2
+#define AUDIO_MAKE_STRING_FROM_ENUM(X) { #X, X }
+
/* CSD-CLIENT related functions */
typedef int (*init_t)(bool);
typedef int (*deinit_t)();
diff --git a/hal/platform_api.h b/hal/platform_api.h
index be1c653..e2120b7 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -152,4 +152,14 @@
int *fd, uint32_t *size);
bool platform_sound_trigger_usecase_needs_event(audio_usecase_t uc_id);
bool platform_snd_device_has_speaker(snd_device_t dev);
+
+bool platform_set_microphone_characteristic(void *platform,
+ struct audio_microphone_characteristic_t mic);
+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,
+ struct audio_microphone_characteristic_t *mic_array,
+ size_t *mic_count);
#endif // AUDIO_PLATFORM_API_H
diff --git a/hal/platform_info.c b/hal/platform_info.c
index 1232ee3..ace57ea 100644
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -35,6 +35,7 @@
OPERATOR_SPECIFIC,
GAIN_LEVEL_MAPPING,
APP_TYPE,
+ MICROPHONE_CHARACTERISTIC,
} section_t;
typedef void (* section_process_fn)(const XML_Char **attr);
@@ -47,6 +48,7 @@
static void process_operator_specific(const XML_Char **attr);
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 section_process_fn section_table[] = {
[ROOT] = process_root,
@@ -57,6 +59,7 @@
[OPERATOR_SPECIFIC] = process_operator_specific,
[GAIN_LEVEL_MAPPING] = process_gain_db_to_level_map,
[APP_TYPE] = process_app_type,
+ [MICROPHONE_CHARACTERISTIC] = process_microphone_characteristic,
};
static set_parameters_fn set_parameters = &platform_set_parameters;
@@ -71,6 +74,79 @@
static struct platform_info my_data = {true, NULL, NULL};
+struct audio_string_to_enum {
+ const char* name;
+ unsigned int value;
+};
+
+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),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_LOCATION_MAINBODY_MOVABLE),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_LOCATION_PERIPHERAL),
+};
+
+static const struct audio_string_to_enum mic_directionalities[AUDIO_MICROPHONE_DIRECTIONALITY_CNT] = {
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_OMNI),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_BI_DIRECTIONAL),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_UNKNOWN),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_CARDIOID),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_HYPER_CARDIOID),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_SUPER_CARDIOID),
+};
+
+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),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_HDMI),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_VOICE_CALL),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_TELEPHONY_RX),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BACK_MIC),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_USB_DEVICE),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_FM_TUNER),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_TV_TUNER),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_LINE),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_SPDIF),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_A2DP),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_LOOPBACK),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_IP),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BUS),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_PROXY),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_USB_HEADSET),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_BLE),
+ AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_DEFAULT),
+};
+
+static bool find_enum_by_string(const struct audio_string_to_enum * table, const char * name,
+ int32_t len, unsigned int *value)
+{
+ if (table == NULL) {
+ ALOGE("%s: table is NULL", __func__);
+ return false;
+ }
+
+ if (name == NULL) {
+ ALOGE("null key");
+ return false;
+ }
+
+ for (int i = 0; i < len; i++) {
+ if (!strcmp(table[i].name, name)) {
+ *value = table[i].value;
+ return true;
+ }
+ }
+ return false;
+}
+
/*
* <audio_platform_info>
* <acdb_ids>
@@ -349,6 +425,230 @@
return;
}
+static void process_microphone_characteristic(const XML_Char **attr) {
+ struct audio_microphone_characteristic_t microphone;
+ uint32_t curIdx = 0;
+
+ if (strcmp(attr[curIdx++], "valid_mask")) {
+ ALOGE("%s: valid_mask not found", __func__);
+ goto done;
+ }
+ microphone.valid_mask = atoi(attr[curIdx++]);
+
+ if (strcmp(attr[curIdx++], "device_id")) {
+ ALOGE("%s: device_id not found", __func__);
+ goto done;
+ }
+ if (strlen(attr[curIdx]) > AUDIO_MICROPHONE_ID_MAX_LEN) {
+ ALOGE("%s: device_id %s is too long", __func__, attr[curIdx]);
+ goto done;
+ }
+ strcpy(microphone.device_id, attr[curIdx++]);
+
+ if (strcmp(attr[curIdx++], "type")) {
+ ALOGE("%s: device not found", __func__);
+ goto done;
+ }
+ if (!find_enum_by_string(device_in_types, (char*)attr[curIdx++],
+ ARRAY_SIZE(device_in_types), µphone.device)) {
+ ALOGE("%s: type %s in %s not found!",
+ __func__, attr[--curIdx], PLATFORM_INFO_XML_PATH);
+ goto done;
+ }
+
+ if (strcmp(attr[curIdx++], "address")) {
+ ALOGE("%s: address not found", __func__);
+ goto done;
+ }
+ if (strlen(attr[curIdx]) > AUDIO_DEVICE_MAX_ADDRESS_LEN) {
+ ALOGE("%s, address %s is too long", __func__, attr[curIdx]);
+ goto done;
+ }
+ strcpy(microphone.address, attr[curIdx++]);
+ if (strlen(microphone.address) == 0) {
+ // If the address is empty, populate the address according to device type.
+ if (microphone.device == AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ strcpy(microphone.address, AUDIO_BOTTOM_MICROPHONE_ADDRESS);
+ } else if (microphone.device == AUDIO_DEVICE_IN_BACK_MIC) {
+ strcpy(microphone.address, AUDIO_BACK_MICROPHONE_ADDRESS);
+ }
+ }
+
+ if (strcmp(attr[curIdx++], "location")) {
+ ALOGE("%s: location not found", __func__);
+ goto done;
+ }
+ if (!find_enum_by_string(mic_locations, (char*)attr[curIdx++],
+ AUDIO_MICROPHONE_LOCATION_CNT, µphone.location)) {
+ ALOGE("%s: location %s in %s not found!",
+ __func__, attr[--curIdx], PLATFORM_INFO_XML_PATH);
+ goto done;
+ }
+
+ if (strcmp(attr[curIdx++], "group")) {
+ ALOGE("%s: group not found", __func__);
+ goto done;
+ }
+ microphone.group = atoi(attr[curIdx++]);
+
+ if (strcmp(attr[curIdx++], "index_in_the_group")) {
+ ALOGE("%s: index_in_the_group not found", __func__);
+ goto done;
+ }
+ microphone.index_in_the_group = atoi(attr[curIdx++]);
+
+ if (strcmp(attr[curIdx++], "directionality")) {
+ ALOGE("%s: directionality not found", __func__);
+ goto done;
+ }
+ if (!find_enum_by_string(mic_directionalities, (char*)attr[curIdx++],
+ AUDIO_MICROPHONE_DIRECTIONALITY_CNT, µphone.directionality)) {
+ ALOGE("%s: directionality %s in %s not found!",
+ __func__, attr[--curIdx], PLATFORM_INFO_XML_PATH);
+ goto done;
+ }
+
+ if (strcmp(attr[curIdx++], "num_frequency_responses")) {
+ ALOGE("%s: num_frequency_responses not found", __func__);
+ goto done;
+ }
+ microphone.num_frequency_responses = atoi(attr[curIdx++]);
+ if (microphone.num_frequency_responses > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
+ ALOGE("%s: num_frequency_responses is too large", __func__);
+ goto done;
+ }
+ if (microphone.num_frequency_responses > 0) {
+ if (strcmp(attr[curIdx++], "frequencies")) {
+ ALOGE("%s: frequencies not found", __func__);
+ goto done;
+ }
+ char *token = strtok((char *)attr[curIdx++], ",");
+ uint32_t num_frequencies = 0;
+ while (token) {
+ microphone.frequency_responses[0][num_frequencies++] = atof(token);
+ if (num_frequencies > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
+ ALOGE("%s: num %u of frequency is too large", __func__, num_frequencies);
+ goto done;
+ }
+ token = strtok(NULL, ",");
+ }
+
+ if (strcmp(attr[curIdx++], "responses")) {
+ ALOGE("%s: responses not found", __func__);
+ goto done;
+ }
+ token = strtok((char *)attr[curIdx++], ",");
+ uint32_t num_responses = 0;
+ while (token) {
+ microphone.frequency_responses[1][num_responses++] = atof(token);
+ if (num_responses > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
+ ALOGE("%s: num %u of response is too large", __func__, num_responses);
+ goto done;
+ }
+ token = strtok(NULL, ",");
+ }
+
+ if (num_frequencies != num_responses
+ || num_frequencies != microphone.num_frequency_responses) {
+ ALOGE("%s: num of frequency and response not match: %u, %u, %u",
+ __func__, num_frequencies, num_responses, microphone.num_frequency_responses);
+ goto done;
+ }
+ }
+
+ if (microphone.valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_SENSITIVITY) {
+ if (strcmp(attr[curIdx++], "sensitivity")) {
+ ALOGE("%s: sensitivity not found", __func__);
+ goto done;
+ }
+ microphone.sensitivity = atof(attr[curIdx++]);
+ } else {
+ microphone.sensitivity = AUDIO_MICROPHONE_SENSITIVITY_UNKNOWN;
+ }
+
+ if (microphone.valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_MAX_SPL) {
+ if (strcmp(attr[curIdx++], "max_spl")) {
+ ALOGE("%s: max_spl not found", __func__);
+ goto done;
+ }
+ microphone.max_spl = atof(attr[curIdx++]);
+ } else {
+ microphone.max_spl = AUDIO_MICROPHONE_SPL_UNKNOWN;
+ }
+
+ if (microphone.valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_MIN_SPL) {
+ if (strcmp(attr[curIdx++], "min_spl")) {
+ ALOGE("%s: min_spl not found", __func__);
+ goto done;
+ }
+ microphone.min_spl = atof(attr[curIdx++]);
+ } else {
+ microphone.min_spl = AUDIO_MICROPHONE_SPL_UNKNOWN;
+ }
+
+ if (microphone.valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_ORIENTATION) {
+ if (strcmp(attr[curIdx++], "orientation")) {
+ ALOGE("%s: orientation not found", __func__);
+ goto done;
+ }
+ char *token = strtok((char *)attr[curIdx++], ",");
+ float orientation[3];
+ uint32_t idx = 0;
+ while (token) {
+ orientation[idx++] = atof(token);
+ if (idx > 3) {
+ ALOGE("%s: orientation invalid", __func__);
+ goto done;
+ }
+ token = strtok(NULL, ",");
+ }
+ if (idx != 3) {
+ ALOGE("%s: orientation invalid", __func__);
+ goto done;
+ }
+ microphone.orientation.x = orientation[0];
+ microphone.orientation.y = orientation[1];
+ microphone.orientation.z = orientation[2];
+ } else {
+ microphone.orientation.x = 0.0f;
+ microphone.orientation.y = 0.0f;
+ microphone.orientation.z = 0.0f;
+ }
+
+ if (microphone.valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_GEOMETRIC_LOCATION) {
+ if (strcmp(attr[curIdx++], "geometric_location")) {
+ ALOGE("%s: geometric_location not found", __func__);
+ goto done;
+ }
+ char *token = strtok((char *)attr[curIdx++], ",");
+ float geometric_location[3];
+ uint32_t idx = 0;
+ while (token) {
+ geometric_location[idx++] = atof(token);
+ if (idx > 3) {
+ ALOGE("%s: geometric_location invalid", __func__);
+ goto done;
+ }
+ token = strtok(NULL, ",");
+ }
+ if (idx != 3) {
+ ALOGE("%s: geometric_location invalid", __func__);
+ goto done;
+ }
+ microphone.geometric_location.x = geometric_location[0];
+ microphone.geometric_location.y = geometric_location[1];
+ microphone.geometric_location.z = geometric_location[2];
+ } else {
+ microphone.geometric_location.x = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
+ microphone.geometric_location.y = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
+ microphone.geometric_location.z = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
+ }
+
+ platform_set_microphone_characteristic(my_data.platform, microphone);
+done:
+ return;
+}
+
static void start_tag(void *userdata __unused, const XML_Char *tag_name,
const XML_Char **attr)
{
@@ -372,6 +672,8 @@
section = GAIN_LEVEL_MAPPING;
} else if (strcmp(tag_name, "app_types") == 0) {
section = APP_TYPE;
+ } else if (strcmp(tag_name, "microphone_characteristics") == 0) {
+ section = MICROPHONE_CHARACTERISTIC;
} 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");
@@ -399,7 +701,7 @@
fn(attr);
} else if (strcmp(tag_name, "gain_level_map") == 0) {
if (section != GAIN_LEVEL_MAPPING) {
- ALOGE("usecase tag only supported with GAIN_LEVEL_MAPPING section");
+ ALOGE("gain_level_map tag only supported with GAIN_LEVEL_MAPPING section");
return;
}
@@ -413,6 +715,13 @@
section_process_fn fn = section_table[APP_TYPE];
fn(attr);
+ } else if (strcmp(tag_name, "microphone") == 0) {
+ if (section != MICROPHONE_CHARACTERISTIC) {
+ ALOGE("microphone tag only supported with MICROPHONE_CHARACTERISTIC section");
+ return;
+ }
+ section_process_fn fn = section_table[MICROPHONE_CHARACTERISTIC];
+ fn(attr);
}
} else {
if(strcmp(tag_name, "config_params") == 0) {
@@ -447,6 +756,8 @@
section = ROOT;
} else if (strcmp(tag_name, "app_types") == 0) {
section = ROOT;
+ } else if (strcmp(tag_name, "microphone_characteristics") == 0) {
+ section = ROOT;
}
}