st-hal: Add support for first stage PDK5
This change adds support for PDK5 along with multi
sound models. These are the changes needed for first
stage only.
Change-Id: Ie846ffd148625913ffcb7e26edbf4ce866370869
diff --git a/st_session.c b/st_session.c
index 156bfb9..f62bbda 100644
--- a/st_session.c
+++ b/st_session.c
@@ -257,6 +257,46 @@
};
}
+static inline struct st_proxy_ses_sm_info_wrapper *get_sm_info_for_model_id
+(
+ st_proxy_session_t *st_ses,
+ uint32_t model_id
+)
+{
+ struct listnode *node = NULL;
+ struct st_proxy_ses_sm_info_wrapper *p_info = NULL;
+
+ list_for_each(node, &st_ses->sm_info_list) {
+ p_info = node_to_item(node, struct st_proxy_ses_sm_info_wrapper,
+ sm_list_node);
+
+ if (p_info->sm_info.model_id == model_id)
+ return p_info;
+ }
+
+ return NULL;
+}
+
+static inline struct st_hw_ses_config *get_sthw_cfg_for_model_id
+(
+ st_hw_session_t *hw_ses,
+ uint32_t model_id
+)
+{
+ struct listnode *node = NULL;
+ struct st_hw_ses_config *sthw_cfg = NULL;
+
+ list_for_each(node, &hw_ses->sthw_cfg_list) {
+ sthw_cfg = node_to_item(node, struct st_hw_ses_config,
+ sthw_cfg_list_node);
+
+ if (sthw_cfg->model_id == model_id)
+ return sthw_cfg;
+ }
+
+ return NULL;
+}
+
static inline void free_array_ptrs(char **arr, unsigned int arr_len)
{
int i = 0;
@@ -667,7 +707,8 @@
st_session_t *c_ses = NULL;
listen_model_type **in_models = NULL;
listen_model_type out_model = {0};
- struct sound_model_info sm_info = {0};
+ struct sound_model_info sm_info = {0};
+ struct st_proxy_ses_sm_info_wrapper *p_info = NULL;
int status = 0, num_models = 0;
ALOGV("%s:[c%d]", __func__, stc_ses->sm_handle);
@@ -675,13 +716,46 @@
ALOGD("%s:[c%d] Already added", __func__, stc_ses->sm_handle);
return 0;
}
- if (!st_ses->vendor_uuid_info->merge_fs_soundmodels) {
+ if (!st_ses->vendor_uuid_info->merge_fs_soundmodels ||
+ stc_ses->f_stage_version == ST_MODULE_TYPE_PDK5) {
stc_ses->sm_info.sm_data = sm_data;
stc_ses->sm_info.sm_size = sm_size;
- st_ses->sm_info.sm_data = sm_data;
- st_ses->sm_info.sm_size = sm_size;
- st_ses->sm_info.sm_type = stc_ses->sm_type;
- ALOGD("%s:[c%d] no merge", __func__, stc_ses->sm_handle);
+ stc_ses->sm_info.sm_type = stc_ses->sm_type;
+ stc_ses->sm_info.model_id =
+ (stc_ses->f_stage_version == ST_MODULE_TYPE_PDK5) ?
+ stc_ses->sm_handle : 0;
+
+ p_info = calloc(1, sizeof(struct st_proxy_ses_sm_info_wrapper));
+ if (!p_info) {
+ ALOGE("%s: failed to alloc struct st_proxy_ses_sm_info_wrapper",
+ __func__);
+ return -ENOMEM;
+ }
+
+ memcpy((uint8_t *)&p_info->sm_info, (uint8_t *)&stc_ses->sm_info,
+ sizeof(struct sound_model_info));
+
+ if (stc_ses->f_stage_version == ST_MODULE_TYPE_PDK5) {
+ st_ses->recognition_mode |= stc_ses->recognition_mode;
+ p_info->sm_info.cf_levels = calloc(1, 2 * MAX_MULTI_SM_CONF_LEVELS);
+ if (!p_info->sm_info.cf_levels) {
+ ALOGE("%s: failed to alloc cf_levels",
+ __func__);
+ free(p_info);
+ return -ENOMEM;
+ }
+ memset(p_info->sm_info.cf_levels, MAX_CONF_LEVEL_VALUE,
+ MAX_MULTI_SM_CONF_LEVELS);
+ p_info->sm_info.det_cf_levels = p_info->sm_info.cf_levels +
+ MAX_MULTI_SM_CONF_LEVELS;
+ memset(p_info->sm_info.det_cf_levels, 0,
+ MAX_MULTI_SM_CONF_LEVELS);
+ stc_ses->sm_info.cf_levels = p_info->sm_info.cf_levels;
+ stc_ses->sm_info.det_cf_levels = p_info->sm_info.det_cf_levels;
+ }
+ list_add_tail(&st_ses->sm_info_list, &p_info->sm_list_node);
+ if (stc_ses->f_stage_version == ST_MODULE_TYPE_GMM)
+ ALOGD("%s:[c%d] no merge", __func__, stc_ses->sm_handle);
return 0;
}
/* get sound model header information for client model */
@@ -703,15 +777,20 @@
num_models++;
}
if (!num_models) {
- if (st_ses->sm_info.sm_merged && st_ses->sm_info.sm_data) {
- free(st_ses->sm_info.sm_data);
+ p_info = calloc(1, sizeof(struct st_proxy_ses_sm_info_wrapper));
+ if (!p_info) {
+ ALOGE("%s: failed to alloc struct st_proxy_ses_sm_info_wrapper",
+ __func__);
+ return -ENOMEM;
}
- /* Only one current client model, just re-use it */
st_ses->recognition_mode = stc_ses->recognition_mode;
stc_ses->sm_info.sm_type = stc_ses->sm_type;
- st_ses->sm_info = stc_ses->sm_info;
- st_ses->sm_info.sm_merged = false;
- ALOGD("%s: re-use single client c%d model, size %d", __func__,
+ stc_ses->sm_info.model_id = 0;
+ memcpy((uint8_t *)&p_info->sm_info, (uint8_t *)&stc_ses->sm_info,
+ sizeof(struct sound_model_info));
+ st_ses->sm_merged = false;
+ list_add_tail(&st_ses->sm_info_list, &p_info->sm_list_node);
+ ALOGD("%s: Copy from single client c%d model, size %d", __func__,
stc_ses->sm_handle, stc_ses->sm_info.sm_size);
return 0;
}
@@ -720,19 +799,27 @@
* Merge this client model with already existing merged model due to other
* clients models.
*/
- if (!st_ses->sm_info.sm_data) {
+ p_info = get_sm_info_for_model_id(st_ses, 0);
+ if (!p_info) {
+ ALOGE("%s: Unexpected, no matching model_id in sm_info list,"
+ "num current models %d", __func__, num_models);
+ status = -EINVAL;
+ goto cleanup;
+ }
+
+ if (!p_info->sm_info.sm_data) {
if (num_models == 1) {
/*
- * Its not a merged model yet, but proxy ses sm_data is valid and
- * must be pointing to client sm_data
+ * Its not a merged model yet, but proxy ses sm_data is valid
+ * and must be pointing to client sm_data
*/
- ALOGE("%s: Unexpected, sm_info.sm_data NULL, num current"
+ ALOGE("%s: Unexpected, sm_data NULL, num current"
"models %d", __func__, num_models);
status = -EINVAL;
goto cleanup;
- } else if (!st_ses->sm_info.sm_merged) {
- ALOGE("%s: Unexpected, no pre-existing merged model, num current"
- "models %d", __func__, num_models);
+ } else if (!st_ses->sm_merged) {
+ ALOGE("%s: Unexpected, no pre-existing merged model,"
+ "num current models %d", __func__, num_models);
status = -EINVAL;
goto cleanup;
}
@@ -747,8 +834,8 @@
goto cleanup;
}
/* Add existing model */
- in_models[0]->data = st_ses->sm_info.sm_data;
- in_models[0]->size = st_ses->sm_info.sm_size;
+ in_models[0]->data = p_info->sm_info.sm_data;
+ in_models[0]->size = p_info->sm_info.sm_size;
/* Add this client model */
in_models[1]->data = sm_data;
in_models[1]->size = sm_size;
@@ -759,16 +846,16 @@
sm_info.sm_data = out_model.data;
sm_info.sm_size = out_model.size;
- sm_info.sm_merged = true;
+ sm_info.model_id = 0;
status = query_sound_model(st_ses->stdev, &sm_info,
out_model.data, out_model.size);
if (status)
goto cleanup;
- if (out_model.size < st_ses->sm_info.sm_size) {
+ if (out_model.size < p_info->sm_info.sm_size) {
ALOGE("%s: Unexpected, merged model sz %d < current sz %d",
- __func__, out_model.size, st_ses->sm_info.sm_size);
+ __func__, out_model.size, p_info->sm_info.sm_size);
release_sound_model_info(&sm_info);
status = -EINVAL;
goto cleanup;
@@ -777,13 +864,15 @@
in_models = NULL;
/* Update the new merged model */
- if (st_ses->sm_info.sm_merged && st_ses->sm_info.sm_data) {
- release_sound_model_info(&st_ses->sm_info);
- free(st_ses->sm_info.sm_data);
+ if (st_ses->sm_merged && p_info->sm_info.sm_data) {
+ release_sound_model_info(&p_info->sm_info);
+ free(p_info->sm_info.sm_data);
}
ALOGD("%s: Updated sound model: current size %d, new size %d", __func__,
- st_ses->sm_info.sm_size, out_model.size);
- st_ses->sm_info = sm_info;
+ p_info->sm_info.sm_size, out_model.size);
+ memcpy((uint8_t *)&p_info->sm_info, (uint8_t *)&sm_info,
+ sizeof(struct sound_model_info));
+ st_ses->sm_merged = true;
/*
* If any of the clients has user identificaiton enabled, underlying
@@ -815,6 +904,8 @@
listen_model_type in_model = {0};
listen_model_type out_model = {0};
struct sound_model_info sm_info = {0};
+ struct st_proxy_ses_sm_info_wrapper *p_info = NULL;
+ struct st_hw_ses_config *sthw_cfg = NULL;
int status = 0, num_models = 0;
unsigned int rec_mode = RECOGNITION_MODE_VOICE_TRIGGER;
@@ -823,14 +914,42 @@
ALOGD("%s:[c%d] Already deleted", __func__, stc_ses->sm_handle);
return 0;
}
- if (!st_ses->vendor_uuid_info->merge_fs_soundmodels) {
+
+ p_info = get_sm_info_for_model_id(st_ses, stc_ses->sm_info.model_id);
+ if (!p_info) {
+ ALOGE("%s: Unexpected, no matching sm_info" , __func__);
+ return -EINVAL;
+ }
+
+ if (!st_ses->vendor_uuid_info->merge_fs_soundmodels ||
+ stc_ses->f_stage_version == ST_MODULE_TYPE_PDK5) {
+ list_remove(&p_info->sm_list_node);
/*
- * As it directly points to client model, just set as NULL
- * without freeing
+ * As it directly points to client model, just set sm_data
+ * as NULL without freeing
*/
- st_ses->sm_info.sm_data = NULL;
+ if (stc_ses->f_stage_version == ST_MODULE_TYPE_PDK5) {
+ /* Update overall recogniton mode from remaining clients */
+ list_for_each(node, &st_ses->clients_list) {
+ c_ses = node_to_item(node, st_session_t, hw_list_node);
+ if ((c_ses != stc_ses) && c_ses->sm_info.sm_data) {
+ if (c_ses->recognition_mode &
+ RECOGNITION_MODE_USER_IDENTIFICATION)
+ rec_mode |= RECOGNITION_MODE_USER_IDENTIFICATION;
+ }
+ }
+ st_ses->recognition_mode = rec_mode;
+
+ if (p_info->sm_info.cf_levels) {
+ free(p_info->sm_info.cf_levels);
+ p_info->sm_info.cf_levels = NULL;
+ }
+ }
+ p_info->sm_info.sm_data = NULL;
+ free(p_info);
stc_ses->sm_info.sm_data = NULL;
- ALOGD("%s:[c%d] no merge", __func__, stc_ses->sm_handle);
+ if (stc_ses->f_stage_version == ST_MODULE_TYPE_GMM)
+ ALOGD("%s:[c%d] no merge", __func__, stc_ses->sm_handle);
return 0;
}
@@ -846,10 +965,14 @@
num_models++;
}
}
+
if (num_models == 0) {
ALOGD("%s: No remaining models", __func__);
/* Delete current client model */
- release_sound_model_info(&stc_ses->sm_info);
+ release_sound_model_info(&p_info->sm_info);
+ list_remove(&p_info->sm_list_node);
+ p_info->sm_info.sm_data = NULL;
+ free(p_info);
stc_ses->sm_info.sm_data = NULL;
return 0;
}
@@ -858,17 +981,24 @@
ALOGD("%s: reuse only remaining client model, size %d", __func__,
c_ses_rem->sm_info.sm_size);
/* If only one remaining client model exists, re-use it */
- if (st_ses->sm_info.sm_merged) {
- release_sound_model_info(&st_ses->sm_info);
- if (st_ses->sm_info.sm_data)
- free(st_ses->sm_info.sm_data);
+ if (st_ses->sm_merged) {
+ release_sound_model_info(&p_info->sm_info);
+ if (p_info->sm_info.sm_data)
+ free(p_info->sm_info.sm_data);
}
- st_ses->sm_info = c_ses_rem->sm_info;
- st_ses->sm_info.sm_merged = false;
- st_ses->hw_ses_current->sthw_cfg.conf_levels =
- st_ses->sm_info.cf_levels;
- st_ses->hw_ses_current->sthw_cfg.num_conf_levels =
- st_ses->sm_info.cf_levels_size;
+ memcpy((uint8_t *)&p_info->sm_info, (uint8_t *)&c_ses_rem->sm_info,
+ sizeof(struct sound_model_info));
+ st_ses->sm_merged = false;
+
+ sthw_cfg = get_sthw_cfg_for_model_id(st_ses->hw_ses_current, 0);
+ if (!sthw_cfg) {
+ ALOGE("%s: Unexpected, no matching sthw_cfg", __func__);
+ return -EINVAL;
+ }
+
+ sthw_cfg->conf_levels = p_info->sm_info.cf_levels;
+ sthw_cfg->num_conf_levels =
+ p_info->sm_info.cf_levels_size;
st_ses->recognition_mode = c_ses_rem->recognition_mode;
/* Delete current client model */
release_sound_model_info(&stc_ses->sm_info);
@@ -888,15 +1018,15 @@
* Delete this client model with already existing merged model due to other
* clients models.
*/
- if (!st_ses->sm_info.sm_merged || !st_ses->sm_info.sm_data) {
+ if (!st_ses->sm_merged || !p_info->sm_info.sm_data) {
ALOGE("%s: Unexpected, no pre-existing merged model to delete from,"
"num current models %d", __func__, num_models);
goto cleanup;
}
/* Existing merged model from which the current client model to be deleted */
- in_model.data = st_ses->sm_info.sm_data;
- in_model.size = st_ses->sm_info.sm_size;
+ in_model.data = p_info->sm_info.sm_data;
+ in_model.size = p_info->sm_info.sm_size;
status = delete_from_merged_sound_model(st_ses->stdev,
stc_ses->sm_info.keyphrases, stc_ses->sm_info.num_keyphrases,
@@ -907,7 +1037,7 @@
sm_info.sm_data = out_model.data;
sm_info.sm_size = out_model.size;
- sm_info.sm_merged = true;
+ sm_info.model_id = 0;
/* Update existing merged model info with new merged model */
status = query_sound_model(st_ses->stdev, &sm_info, out_model.data,
@@ -915,22 +1045,24 @@
if (status)
goto cleanup;
- if (out_model.size > st_ses->sm_info.sm_size) {
+ if (out_model.size > p_info->sm_info.sm_size) {
ALOGE("%s: Unexpected, merged model sz %d > current sz %d",
- __func__, out_model.size, st_ses->sm_info.sm_size);
+ __func__, out_model.size, p_info->sm_info.sm_size);
release_sound_model_info(&sm_info);
status = -EINVAL;
goto cleanup;
}
- if (st_ses->sm_info.sm_merged && st_ses->sm_info.sm_data) {
- release_sound_model_info(&st_ses->sm_info);
- free(st_ses->sm_info.sm_data);
+ if (st_ses->sm_merged && p_info->sm_info.sm_data) {
+ release_sound_model_info(&p_info->sm_info);
+ free(p_info->sm_info.sm_data);
}
ALOGD("%s: Updated sound model: current size %d, new size %d", __func__,
- st_ses->sm_info.sm_size, out_model.size);
- st_ses->sm_info = sm_info;
+ p_info->sm_info.sm_size, out_model.size);
+ memcpy((uint8_t *)&p_info->sm_info, (uint8_t *)&sm_info,
+ sizeof(struct sound_model_info));
+ st_ses->sm_merged = true;
/*
* If any of the remaining clients has user identificaiton enabled,
* underlying hw session has to operate with user identificaiton enabled.
@@ -989,19 +1121,26 @@
unsigned int src_size, bool set)
{
int i = 0, j = 0;
+ struct st_proxy_ses_sm_info_wrapper *p_info = NULL;
if (!st_ses || !src) {
ALOGE("%s: NULL pointer", __func__);
return -EINVAL;
}
- if (!st_ses->sm_info.sm_merged)
+ if (!st_ses->sm_merged)
return 0;
- if (src_size > st_ses->sm_info.cf_levels_size) {
+ p_info = get_sm_info_for_model_id(st_ses, 0);
+ if (!p_info) {
+ ALOGE("%s: Unexpected, no matching sm_info" , __func__);
+ return -EINVAL;
+ }
+
+ if (src_size > p_info->sm_info.cf_levels_size) {
ALOGE("%s:[%d] Unexpected, client conf levels %d > "
"merged conf levels %d", __func__, st_ses->sm_handle,
- src_size, st_ses->sm_info.cf_levels_size);
+ src_size, p_info->sm_info.cf_levels_size);
return -EINVAL;
}
@@ -1010,17 +1149,17 @@
/* Populate DSP merged sound model conf levels */
for (i = 0; i < src_size; i++) {
- for (j = 0; j < st_ses->sm_info.cf_levels_size; j++) {
- if (!strcmp(st_ses->sm_info.cf_levels_kw_users[j],
+ for (j = 0; j < p_info->sm_info.cf_levels_size; j++) {
+ if (!strcmp(p_info->sm_info.cf_levels_kw_users[j],
src_sm_info->cf_levels_kw_users[i])) {
if (set) {
- st_ses->sm_info.cf_levels[j] = src[i];
- ALOGV("%s: set: sm_info.cf_levels[%d]=%d", __func__,
- j, st_ses->sm_info.cf_levels[j]);
+ p_info->sm_info.cf_levels[j] = src[i];
+ ALOGV("%s: set: cf_levels[%d]=%d", __func__,
+ j, p_info->sm_info.cf_levels[j]);
} else {
- st_ses->sm_info.cf_levels[j] = MAX_CONF_LEVEL_VALUE;
- ALOGV("%s: reset: sm_info.cf_levels[%d]=%d", __func__,
- j, st_ses->sm_info.cf_levels[j]);
+ p_info->sm_info.cf_levels[j] = MAX_CONF_LEVEL_VALUE;
+ ALOGV("%s: reset: cf_levels[%d]=%d", __func__,
+ j, p_info->sm_info.cf_levels[j]);
}
}
}
@@ -1056,21 +1195,29 @@
unsigned char **dst, unsigned int *dst_size)
{
st_session_t *stc_ses = st_ses->det_stc_ses;
+ struct st_proxy_ses_sm_info_wrapper *p_info = NULL;
int i = 0, j = 0;
*dst = src;
*dst_size = src_size;
if (!st_ses->vendor_uuid_info->merge_fs_soundmodels ||
- !st_ses->sm_info.sm_merged) {
+ !st_ses->sm_merged ||
+ stc_ses->f_stage_version == ST_MODULE_TYPE_PDK5) {
ALOGV("%s:[%d] not merged", __func__, st_ses->sm_handle);
return;
}
- if (src_size < st_ses->sm_info.cf_levels_size) {
+ p_info = get_sm_info_for_model_id(st_ses, 0);
+ if (!p_info) {
+ ALOGE("%s: Unexpected, no matching sm_info" , __func__);
+ return;
+ }
+
+ if (src_size < p_info->sm_info.cf_levels_size) {
ALOGE("%s:[%d] Unexpected, detection conf payload size %d < %d",
__func__, st_ses->sm_handle, src_size,
- st_ses->sm_info.cf_levels_size);
+ p_info->sm_info.cf_levels_size);
return;
}
@@ -1078,12 +1225,12 @@
memset(stc_ses->sm_info.det_cf_levels, 0, stc_ses->sm_info.cf_levels_size);
/* Extract the client conf level values from DSP payload */
- for(i = 0; i < st_ses->sm_info.cf_levels_size; i++) {
+ for(i = 0; i < p_info->sm_info.cf_levels_size; i++) {
if (!src[i])
continue;
for(j = 0; j < stc_ses->sm_info.cf_levels_size; j++) {
if (!strcmp(stc_ses->sm_info.cf_levels_kw_users[j],
- st_ses->sm_info.cf_levels_kw_users[i])) {
+ p_info->sm_info.cf_levels_kw_users[i])) {
stc_ses->sm_info.det_cf_levels[j] = src[i];
}
}
@@ -1202,16 +1349,12 @@
st_session_t *stc_ses)
{
st_hw_session_t *hw_ses = st_ses->hw_ses_current;
- struct st_hw_ses_config *sthw_cfg = &hw_ses->sthw_cfg;
+ struct st_hw_ses_config *sthw_cfg = NULL;
struct listnode *node = NULL;
st_session_t *c_ses = NULL;
int hb_sz = 0, pr_sz = 0;
bool enable_lab = false;
- if (!st_ses->vendor_uuid_info->merge_fs_soundmodels ||
- !st_ses->sm_info.sm_merged)
- return;
-
/*
* Adjust history buffer and preroll durations to highest of
* all clients, including current restarting client.
@@ -1233,14 +1376,48 @@
}
}
- sthw_cfg->client_req_hist_buf = hb_sz;
- sthw_cfg->client_req_preroll = pr_sz;
- st_ses->lab_enabled = enable_lab;
+ sthw_cfg = get_sthw_cfg_for_model_id(hw_ses, stc_ses->sm_info.model_id);
+ if (!sthw_cfg) {
+ ALOGE("%s: Unexpected, no matching sthw_cfg", __func__);
+ return;
+ }
- update_merge_conf_levels_payload(st_ses, &stc_ses->sm_info,
- stc_ses->sm_info.cf_levels,
- stc_ses->sm_info.cf_levels_size,
- true);
+ if (st_ses->f_stage_version == ST_MODULE_TYPE_GMM) {
+ if (!st_ses->vendor_uuid_info->merge_fs_soundmodels ||
+ !st_ses->sm_merged)
+ return;
+
+ sthw_cfg->client_req_hist_buf = hb_sz;
+ hw_ses->max_hist_buf = hb_sz;
+ sthw_cfg->client_req_preroll = pr_sz;
+ hw_ses->max_preroll = pr_sz;
+ st_ses->lab_enabled = enable_lab;
+
+ update_merge_conf_levels_payload(st_ses, &stc_ses->sm_info,
+ stc_ses->sm_info.cf_levels,
+ stc_ses->sm_info.cf_levels_size,
+ true);
+ } else {
+ sthw_cfg->client_req_hist_buf = stc_ses->hist_buf_duration;
+ hw_ses->max_hist_buf = hb_sz;
+ sthw_cfg->client_req_preroll = stc_ses->preroll_duration;
+ hw_ses->max_preroll = pr_sz;
+ st_ses->lab_enabled = enable_lab;
+
+ /*
+ * During stop, the conf levels get set to the max value
+ * to prevent detections while its client state is loaded
+ * and another sound model's client state is active. So
+ * during restart, the conf levels need to be reset from
+ * the cached stc_values to enable detections again.
+ */
+ memset(sthw_cfg->conf_levels, MAX_CONF_LEVEL_VALUE,
+ MAX_MULTI_SM_CONF_LEVELS);
+ memcpy(sthw_cfg->conf_levels, stc_ses->sm_info.cf_levels,
+ stc_ses->sm_info.cf_levels_size);
+ sthw_cfg->num_conf_levels = stc_ses->sm_info.cf_levels_size;
+ }
+
hw_ses->sthw_cfg_updated = true;
ALOGV("%s:[%d] lab_enabled %d, hb_sz %d, pr_sz %d", __func__,
@@ -1252,13 +1429,21 @@
st_session_t *stc_ses)
{
st_hw_session_t *hw_ses = st_ses->hw_ses_current;
- struct st_hw_ses_config *sthw_cfg = &hw_ses->sthw_cfg;
+ struct st_hw_ses_config *sthw_cfg = NULL;
struct listnode *node = NULL;
st_session_t *c_ses = NULL;
int hb_sz = 0, pr_sz = 0;
bool active = false, enable_lab = false;
- if (!st_ses->vendor_uuid_info->merge_fs_soundmodels) {
+ sthw_cfg = get_sthw_cfg_for_model_id(hw_ses, stc_ses->sm_info.model_id);
+ if (!sthw_cfg) {
+ ALOGE("%s: Unexpected, no matching sthw_cfg", __func__);
+ return false;
+ }
+
+ if (!st_ses->vendor_uuid_info->merge_fs_soundmodels &&
+ stc_ses->f_stage_version == ST_MODULE_TYPE_GMM) {
+
if (sthw_cfg->conf_levels) {
ALOGV("%s: free hw conf_levels", __func__);
free(sthw_cfg->conf_levels);
@@ -1286,26 +1471,54 @@
!list_empty(&c_ses->second_stage_list);
}
}
- if (!active) {
+
+ if (st_ses->f_stage_version == ST_MODULE_TYPE_GMM) {
+ if (!active) {
+ sthw_cfg->client_req_hist_buf = 0;
+ hw_ses->max_hist_buf = 0;
+ sthw_cfg->client_req_preroll = 0;
+ hw_ses->max_preroll = 0;
+ st_ses->lab_enabled = false;
+ hw_ses->custom_data = NULL;
+ hw_ses->custom_data_size = 0;
+ hw_ses->sthw_cfg_updated = true;
+ ALOGV("%s:[%d] no active client hw cfg is reset", __func__,
+ st_ses->sm_handle);
+ return false;
+ }
+
+ sthw_cfg->client_req_hist_buf = hb_sz;
+ hw_ses->max_hist_buf = hb_sz;
+ sthw_cfg->client_req_preroll = pr_sz;
+ hw_ses->max_preroll = pr_sz;
+ st_ses->lab_enabled = enable_lab;
+
+ update_merge_conf_levels_payload(st_ses, &stc_ses->sm_info,
+ stc_ses->sm_info.cf_levels,
+ stc_ses->sm_info.cf_levels_size,
+ false);
+ } else {
+ if (!active) {
+ hw_ses->max_hist_buf = 0;
+ hw_ses->max_preroll = 0;
+ st_ses->lab_enabled = false;
+ hw_ses->custom_data = NULL;
+ hw_ses->custom_data_size = 0;
+ hw_ses->sthw_cfg_updated = true;
+ return false;
+ }
+
sthw_cfg->client_req_hist_buf = 0;
+ hw_ses->max_hist_buf = hb_sz;
sthw_cfg->client_req_preroll = 0;
- st_ses->lab_enabled = 0;
- sthw_cfg->custom_data = NULL;
- sthw_cfg->custom_data_size = 0;
- hw_ses->sthw_cfg_updated = true;
- ALOGV("%s:[%d] no active client hw cfg is reset", __func__,
- st_ses->sm_handle);
- return false;
+ hw_ses->max_preroll = pr_sz;
+ st_ses->lab_enabled = enable_lab;
+
+ memset(sthw_cfg->conf_levels, MAX_CONF_LEVEL_VALUE,
+ MAX_MULTI_SM_CONF_LEVELS);
+ sthw_cfg->num_conf_levels = 0;
}
- sthw_cfg->client_req_hist_buf = hb_sz;
- sthw_cfg->client_req_preroll = pr_sz;
- st_ses->lab_enabled = enable_lab;
-
- update_merge_conf_levels_payload(st_ses, &stc_ses->sm_info,
- stc_ses->sm_info.cf_levels,
- stc_ses->sm_info.cf_levels_size,
- false);
hw_ses->sthw_cfg_updated = true;
ALOGV("%s:[%d] lab_enabled %d, hb_sz %d, pr_sz %d", __func__,
@@ -1336,7 +1549,7 @@
break;
}
i += GENERIC_DET_EVENT_HEADER_SIZE + key_payload_size;
- payload += i;
+ payload += GENERIC_DET_EVENT_HEADER_SIZE + key_payload_size;
}
} else {
if (st_ses->exec_mode == ST_EXEC_MODE_CPE) {
@@ -1355,70 +1568,116 @@
struct listnode *node = NULL;
st_session_t *c_ses = NULL;
unsigned char *conf_levels = NULL;
- unsigned int conf_levels_size = 0;
+ unsigned int conf_levels_size = 0, key_id = 0, key_payload_size = 0;
int i = 0, j = 0;
+ struct st_proxy_ses_sm_info_wrapper *p_info = NULL;
+ multi_model_result_info_t *result_info = NULL;
- if (list_empty(&st_ses->clients_list)) {
- ALOGE("%s:[%d] no clients attached!!", __func__, st_ses->sm_handle);
- return NULL;
- }
- /*
- * If only single client exist, this detection is not for merged
- * sound model, hence return this as only available client
- */
- if (!check_for_multi_clients(st_ses)) {
- ALOGV("%s:[%d] single client detection", __func__, st_ses->sm_handle);
- node = list_head(&st_ses->clients_list);
- c_ses = node_to_item(node, st_session_t, hw_list_node);
- if (c_ses->state == ST_STATE_ACTIVE) {
- ALOGD("%s: detected c%d", __func__, c_ses->sm_handle);
- return c_ses;
- } else {
- ALOGE("%s: detected c%d is not active", __func__, c_ses->sm_handle);
+ if (st_ses->f_stage_version == ST_MODULE_TYPE_GMM) {
+ p_info = get_sm_info_for_model_id(st_ses, 0);
+ if (!p_info) {
+ ALOGE("%s: Unexpected, no matching sm_info" , __func__);
return NULL;
}
- }
- get_conf_levels_from_dsp_payload(st_ses, payload, payload_size,
- &conf_levels, &conf_levels_size);
- if (!conf_levels) {
- ALOGE("%s:[%d] no conf levels payload found!!", __func__,
- st_ses->sm_handle);
- return NULL;
- }
- if (conf_levels_size < st_ses->sm_info.num_keyphrases) {
- ALOGE("%s:[%d] detection conf levels size %d < num of keywords %d",
- __func__, st_ses->sm_handle, conf_levels_size,
- st_ses->sm_info.num_keyphrases);
- return NULL;
- }
-
- /*
- * The DSP payload contains the keyword conf levels from the beginning.
- * Only one keyword conf level is expected to be non-zero from keyword
- * detection. Find non-zero conf level up to number of keyphrases and if
- * one is found, match it to the corresponding keyphrase from list of
- * clients to obtain the detected client.
- */
- for (i = 0; i < st_ses->sm_info.num_keyphrases; i++) {
- if (!conf_levels[i])
- continue;
- list_for_each(node, &st_ses->clients_list) {
+ if (list_empty(&st_ses->clients_list)) {
+ ALOGE("%s:[%d] no clients attached!!", __func__,
+ st_ses->sm_handle);
+ return NULL;
+ }
+ /*
+ * If only single client exist, this detection is not for merged
+ * sound model, hence return this as only available client
+ */
+ if (!check_for_multi_clients(st_ses)) {
+ ALOGV("%s:[%d] single client detection", __func__,
+ st_ses->sm_handle);
+ node = list_head(&st_ses->clients_list);
c_ses = node_to_item(node, st_session_t, hw_list_node);
- for (j = 0; j < c_ses->sm_info.num_keyphrases; j++) {
- if (!strcmp(st_ses->sm_info.keyphrases[i],
- c_ses->sm_info.keyphrases[j])) {
- if (c_ses->state == ST_STATE_ACTIVE) {
- ALOGV("%s: detected c%d", __func__, c_ses->sm_handle);
- return c_ses;
- } else {
- ALOGE("%s: detected c%d is not active", __func__,
- c_ses->sm_handle);
- return NULL;
+ if (c_ses->state == ST_STATE_ACTIVE) {
+ ALOGD("%s: detected c%d", __func__, c_ses->sm_handle);
+ return c_ses;
+ } else {
+ ALOGE("%s: detected c%d is not active", __func__,
+ c_ses->sm_handle);
+ return NULL;
+ }
+ }
+
+ get_conf_levels_from_dsp_payload(st_ses, payload, payload_size,
+ &conf_levels, &conf_levels_size);
+ if (!conf_levels) {
+ ALOGE("%s:[%d] no conf levels payload found!!", __func__,
+ st_ses->sm_handle);
+ return NULL;
+ }
+ if (conf_levels_size < p_info->sm_info.num_keyphrases) {
+ ALOGE("%s:[%d] detection conf levels size %d < num of keywords %d",
+ __func__, st_ses->sm_handle, conf_levels_size,
+ p_info->sm_info.num_keyphrases);
+ return NULL;
+ }
+
+ /*
+ * The DSP payload contains the keyword conf levels from the beginning.
+ * Only one keyword conf level is expected to be non-zero from keyword
+ * detection. Find non-zero conf level up to number of keyphrases and
+ * if one is found, match it to the corresponding keyphrase from list
+ * of clients to obtain the detected client.
+ */
+ for (i = 0; i < p_info->sm_info.num_keyphrases; i++) {
+ if (!conf_levels[i])
+ continue;
+ list_for_each(node, &st_ses->clients_list) {
+ c_ses = node_to_item(node, st_session_t, hw_list_node);
+ for (j = 0; j < c_ses->sm_info.num_keyphrases; j++) {
+ if (!strcmp(p_info->sm_info.keyphrases[i],
+ c_ses->sm_info.keyphrases[j])) {
+ if (c_ses->state == ST_STATE_ACTIVE) {
+ ALOGV("%s: detected c%d", __func__,
+ c_ses->sm_handle);
+ return c_ses;
+ } else {
+ ALOGE("%s: detected c%d is not active", __func__,
+ c_ses->sm_handle);
+ return NULL;
+ }
}
}
}
}
+ } else {
+ while (i < payload_size) {
+ key_id = *(uint32_t *)payload;
+ key_payload_size = *((uint32_t *)payload + 1);
+
+ if (key_id == KEY_ID_MULTI_MODEL_RESULT_INFO) {
+ result_info = (multi_model_result_info_t *)(payload +
+ GENERIC_DET_EVENT_HEADER_SIZE);
+ list_for_each(node, &st_ses->clients_list) {
+ c_ses = node_to_item(node, st_session_t, hw_list_node);
+ if (c_ses->sm_info.model_id ==
+ result_info->detected_model_id) {
+ if (c_ses->state == ST_STATE_ACTIVE) {
+ ALOGV("%s: detected c%d", __func__,
+ c_ses->sm_handle);
+ return c_ses;
+ } else {
+ ALOGE("%s: detected c%d is not active", __func__,
+ c_ses->sm_handle);
+ return NULL;
+ }
+ }
+ }
+ break;
+ } else {
+ ALOGE("%s: Unexpected key id for PDK5 0x%x", __func__,
+ key_id);
+ break;
+ }
+ i += GENERIC_DET_EVENT_HEADER_SIZE + key_payload_size;
+ payload += GENERIC_DET_EVENT_HEADER_SIZE + key_payload_size;
+ }
}
return c_ses;
}
@@ -2201,6 +2460,7 @@
unsigned int opaque_size = 0, conf_levels_payload_size = 0;
int status = 0;
bool enable_lab = false;
+ struct st_proxy_ses_sm_info_wrapper *p_info = NULL;
if (st_ses->stdev->enable_debug_dumps) {
ST_DBG_DECLARE(FILE *rc_opaque_fd = NULL;
@@ -2324,100 +2584,152 @@
}
}
- sthw_cfg = &st_hw_ses->sthw_cfg;
enable_lab = stc_ses->rc_config->capture_requested ||
!list_empty(&stc_ses->second_stage_list);
- if (v_info->merge_fs_soundmodels) {
- /* merge_fs_soundmodels is true only for QC SVA UUID */
+ sthw_cfg = get_sthw_cfg_for_model_id(st_hw_ses,
+ stc_ses->sm_info.model_id);
+ if (!sthw_cfg) {
+ ALOGE("%s: Unexpected, no matching sthw_cfg", __func__);
+ return -EINVAL;
+ }
- /*
- * Note:
- * For ADSP case, the generated conf levles size must be equal to
- * SML queried conf levels.
- * For WDSP gcs case, there is additional payload for KW enable
- * fields in generated conf_levels. If merge sound model is supported
- * on WDSP case, update logic here accordingly.
- */
- if (num_conf_levels != stc_ses->sm_info.cf_levels_size) {
- ALOGE("%s: Unexpected, client cf levels %d != sm_info cf levels %d",
- __func__, num_conf_levels, stc_ses->sm_info.cf_levels_size);
- return -EINVAL;
+ if (stc_ses->f_stage_version == ST_MODULE_TYPE_GMM) {
+ if (v_info->merge_fs_soundmodels) {
+ /* merge_fs_soundmodels is true only for QC SVA UUID */
+
+ /*
+ * Note:
+ * For ADSP case, the generated conf levles size must be equal to
+ * SML queried conf levels.
+ * For WDSP gcs case, there is additional payload for KW enable
+ * fields in generated conf_levels. If merge sound model is supported
+ * on WDSP case, update logic here accordingly.
+ */
+ if (num_conf_levels != stc_ses->sm_info.cf_levels_size) {
+ ALOGE("%s: Unexpected, client cf levels %d != sm_info cf levels %d",
+ __func__, num_conf_levels, stc_ses->sm_info.cf_levels_size);
+ return -EINVAL;
+ }
+
+ /*
+ * If any of the active clients requested capture or enabled the
+ * second stage, the underlying hw session buffering needs to
+ * be enabled. Ignore if it is already enabled.
+ */
+ if (!st_ses->lab_enabled && enable_lab)
+ st_ses->lab_enabled = true;
+
+ /* Aggregate DSP configuration for highest client configuration */
+
+ /* SVA2.0 sound models */
+ if (!stc_ses->hist_buf_duration &&
+ stc_ses->rc_config->capture_requested &&
+ (stc_ses->rc_config->data_size > 0)) {
+ stc_ses->hist_buf_duration = st_ses->vendor_uuid_info->kw_duration;
+ stc_ses->preroll_duration = 0;
+ }
+
+ if (stc_ses->hist_buf_duration > sthw_cfg->client_req_hist_buf) {
+ sthw_cfg->client_req_hist_buf = stc_ses->hist_buf_duration;
+ st_hw_ses->max_hist_buf = stc_ses->hist_buf_duration;
+ }
+ if (stc_ses->preroll_duration > sthw_cfg->client_req_preroll) {
+ sthw_cfg->client_req_preroll = stc_ses->preroll_duration;
+ st_hw_ses->max_preroll = stc_ses->preroll_duration;
+ }
+
+ ALOGV("%s: client hb_sz %d pr_sz %d, sthw lab %d hb_sz %d "
+ "pr_sz %d", __func__, stc_ses->hist_buf_duration,
+ stc_ses->preroll_duration, st_ses->lab_enabled,
+ sthw_cfg->client_req_hist_buf, sthw_cfg->client_req_preroll);
+
+ /* Cache it to use when client restarts without config update or
+ * during only one remaining client model as there won't be a
+ * merged model yet.
+ */
+ memcpy(stc_ses->sm_info.cf_levels, conf_levels,
+ stc_ses->sm_info.cf_levels_size);
+
+ status = update_merge_conf_levels_payload(st_ses, &stc_ses->sm_info,
+ conf_levels, num_conf_levels, true);
+ free(conf_levels); /* Merged model conf levels will be used further */
+ if (status)
+ return status;
+
+ p_info = get_sm_info_for_model_id(st_ses, 0);
+ if (!p_info) {
+ ALOGE("%s: Unexpected, no matching sm_info" , __func__);
+ status = -EINVAL;
+ return status;
+ }
+
+ sthw_cfg->conf_levels = p_info->sm_info.cf_levels;
+ sthw_cfg->num_conf_levels = p_info->sm_info.cf_levels_size;
+ sthw_cfg->model_id = 0;
+ st_hw_ses->sthw_cfg_updated = true;
+
+ /*
+ * Merging further unknown custom data is not needed, as
+ * SVA doesn't support unkown custom data. if required in future,
+ * handle here.
+ * For now just copy the the current client data which is same
+ * across SVA engines.
+ * Update the custom data for the case in which one client session
+ * does not have custom data and another one does.
+ */
+ if (rc_config->data_size > st_hw_ses->custom_data_size) {
+ st_hw_ses->custom_data = (char *)rc_config + rc_config->data_offset;
+ st_hw_ses->custom_data_size = rc_config->data_size;
+ }
+ } else {
+ st_ses->recognition_mode = stc_ses->recognition_mode;
+ st_ses->lab_enabled = enable_lab;
+ sthw_cfg->client_req_hist_buf = stc_ses->hist_buf_duration;
+ st_hw_ses->max_hist_buf = stc_ses->hist_buf_duration;
+ sthw_cfg->client_req_preroll = stc_ses->preroll_duration;
+ st_hw_ses->max_preroll = stc_ses->preroll_duration;
+
+ if (sthw_cfg->conf_levels)
+ free(sthw_cfg->conf_levels);
+ sthw_cfg->conf_levels = conf_levels;
+ sthw_cfg->num_conf_levels = num_conf_levels;
+
+ st_hw_ses->custom_data = (char *)rc_config + rc_config->data_offset;
+ st_hw_ses->custom_data_size = rc_config->data_size;
}
- /*
- * If any of the active clients requested capture or enabled the
- * second stage, the underlying hw session buffering needs to
- * be enabled. Ignore if it is already enabled.
- */
+
+ } else {
if (!st_ses->lab_enabled && enable_lab)
st_ses->lab_enabled = true;
- /* Aggregate DSP configuration for highest client configuration */
+ sthw_cfg->client_req_hist_buf = stc_ses->hist_buf_duration;
+ if (st_hw_ses->max_hist_buf < stc_ses->hist_buf_duration)
+ st_hw_ses->max_hist_buf = stc_ses->hist_buf_duration;
- /* SVA2.0 sound models */
- if (!stc_ses->hist_buf_duration &&
- stc_ses->rc_config->capture_requested &&
- (stc_ses->rc_config->data_size > 0)) {
- stc_ses->hist_buf_duration = st_ses->vendor_uuid_info->kw_duration;
- stc_ses->preroll_duration = 0;
- }
-
- if (stc_ses->hist_buf_duration > sthw_cfg->client_req_hist_buf)
- sthw_cfg->client_req_hist_buf = stc_ses->hist_buf_duration;
- if (stc_ses->preroll_duration > sthw_cfg->client_req_preroll)
- sthw_cfg->client_req_preroll = stc_ses->preroll_duration;
-
- ALOGV("%s: client hb_sz %d pr_sz %d, sthw lab %d hb_sz %d "
- "pr_sz %d", __func__, stc_ses->hist_buf_duration,
- stc_ses->preroll_duration, st_ses->lab_enabled,
- sthw_cfg->client_req_hist_buf, sthw_cfg->client_req_preroll);
-
- /* Cache it to use when client restarts without config update or
- * during only one remaining client model as there won't be a
- * merged model yet.
- */
- memcpy(stc_ses->sm_info.cf_levels, conf_levels,
- stc_ses->sm_info.cf_levels_size);
-
- status = update_merge_conf_levels_payload(st_ses, &stc_ses->sm_info,
- conf_levels, num_conf_levels, true);
- free(conf_levels); /* Merged model conf levels will be used further */
- if (status)
- return status;
-
- sthw_cfg->conf_levels = st_ses->sm_info.cf_levels;
- sthw_cfg->num_conf_levels = st_ses->sm_info.cf_levels_size;
- st_hw_ses->sthw_cfg_updated = true;
+ sthw_cfg->client_req_preroll = stc_ses->preroll_duration;
+ if (st_hw_ses->max_preroll < stc_ses->preroll_duration)
+ st_hw_ses->max_preroll = stc_ses->preroll_duration;
/*
- * Merging further unknown custom data is not needed, as
- * SVA doesn't support unkown custom data. if required in future,
- * handle here.
- * For now just copy the the current client data which is same
- * across SVA engines.
- * Update the custom data for the case in which one client session
- * does not have custom data and another one does.
+ * Cache it to use when client restarts without
+ * config update
*/
- if (rc_config->data_size > sthw_cfg->custom_data_size) {
- sthw_cfg->custom_data = (char *)rc_config + rc_config->data_offset;
- sthw_cfg->custom_data_size = rc_config->data_size;
- }
+ memcpy(stc_ses->sm_info.cf_levels, conf_levels,
+ num_conf_levels);
+ stc_ses->sm_info.cf_levels_size = num_conf_levels;
- } else {
- st_ses->recognition_mode = stc_ses->recognition_mode;
- st_ses->lab_enabled = enable_lab;
-
- sthw_cfg->client_req_hist_buf = stc_ses->hist_buf_duration;
- sthw_cfg->client_req_preroll = stc_ses->preroll_duration;
-
- if (sthw_cfg->conf_levels)
- free(sthw_cfg->conf_levels);
- sthw_cfg->conf_levels = conf_levels;
+ memcpy(sthw_cfg->conf_levels, conf_levels,
+ num_conf_levels);
sthw_cfg->num_conf_levels = num_conf_levels;
+ free(conf_levels);
- sthw_cfg->custom_data = (char *)rc_config + rc_config->data_offset;
- sthw_cfg->custom_data_size = rc_config->data_size;
+ if (rc_config->data_size >= st_hw_ses->custom_data_size) {
+ st_hw_ses->custom_data = (char *)rc_config + rc_config->data_offset;
+ st_hw_ses->custom_data_size = rc_config->data_size;
+ }
+ st_hw_ses->sthw_cfg_updated = true;
}
ALOGD("%s:[%d] lab enabled %d", __func__, st_ses->sm_handle,
st_ses->lab_enabled);
@@ -2425,6 +2737,47 @@
return status;
}
+static int reg_all_sm(st_proxy_session_t *st_ses, st_hw_session_t *hw_ses)
+{
+ struct st_proxy_ses_sm_info_wrapper *p_info = NULL;
+ struct listnode *node = NULL;
+ int status = 0;
+
+ list_for_each(node, &st_ses->sm_info_list) {
+ p_info = node_to_item(node, struct st_proxy_ses_sm_info_wrapper,
+ sm_list_node);
+ status = hw_ses->fptrs->reg_sm(hw_ses, p_info->sm_info.sm_data,
+ p_info->sm_info.sm_size, p_info->sm_info.model_id);
+ if (status) {
+ ALOGE("%s:[%d] reg_sm failed, model_id = %d, status = %d", __func__,
+ st_ses->sm_handle, p_info->sm_info.model_id, status);
+ return status;
+ }
+ }
+
+ return 0;
+}
+
+static int dereg_all_sm(st_proxy_session_t *st_ses, st_hw_session_t *hw_ses)
+{
+ struct st_proxy_ses_sm_info_wrapper *p_info = NULL;
+ struct listnode *node = NULL;
+ int status = 0, ret = 0;
+
+ list_for_each(node, &st_ses->sm_info_list) {
+ p_info = node_to_item(node, struct st_proxy_ses_sm_info_wrapper,
+ sm_list_node);
+ status = hw_ses->fptrs->dereg_sm(hw_ses, p_info->sm_info.model_id);
+ if (status) {
+ ALOGE("%s:[%d] dereg_sm failed, model_id = %d, status = %d", __func__,
+ st_ses->sm_handle, p_info->sm_info.model_id, status);
+ ret = status;
+ }
+ }
+
+ return ret;
+}
+
static void do_hw_sess_cleanup(st_proxy_session_t *st_ses,
st_hw_session_t *hw_ses, enum hw_session_err_mask err)
{
@@ -2443,7 +2796,7 @@
hw_ses->fptrs->set_device(hw_ses, false);
if (err & HW_SES_ERR_MASK_REG_SM)
- hw_ses->fptrs->dereg_sm(hw_ses);
+ dereg_all_sm(st_ses, hw_ses);
}
static void reg_hal_event_session(st_session_t *stc_ses,
@@ -2564,7 +2917,7 @@
if (do_unload) {
if (!load_sm) {
load_sm = true;
- status = hw_ses->fptrs->dereg_sm(hw_ses);
+ status = dereg_all_sm(st_ses, hw_ses);
if (status)
ALOGW("%s:[%d] failed to dereg_sm err %d", __func__,
st_ses->sm_handle, status);
@@ -2572,8 +2925,7 @@
}
if (load_sm) {
- status = hw_ses->fptrs->reg_sm(hw_ses, st_ses->sm_info.sm_data,
- st_ses->sm_info.sm_size, st_ses->sm_info.sm_type);
+ status = reg_all_sm(st_ses, hw_ses);
if (status) {
ALOGE("%s:[%d] failed to reg_sm err %d", __func__,
st_ses->sm_handle, status);
@@ -2591,8 +2943,7 @@
err |= HW_SES_ERR_MASK_DEVICE_SET;
status = hw_ses->fptrs->reg_sm_params(hw_ses, st_ses->recognition_mode,
- st_ses->lab_enabled, st_ses->rc_config, st_ses->sm_info.sm_type,
- st_ses->sm_info.sm_data);
+ st_ses->lab_enabled, st_ses->rc_config);
if (status) {
ALOGE("%s:[%d] failed to reg_sm_params err %d", __func__,
st_ses->sm_handle, status);
@@ -2643,7 +2994,7 @@
rc = status;
}
if (unload_sm) {
- status = hw_ses->fptrs->dereg_sm(hw_ses);
+ status = dereg_all_sm(st_ses, hw_ses);
if (status) {
ALOGE("%s:[%d] failed to dereg_sm, err %d", __func__,
st_ses->sm_handle, status);
@@ -2679,8 +3030,7 @@
int status = 0;
status = hw_ses->fptrs->restart(hw_ses, st_ses->recognition_mode,
- st_ses->rc_config, st_ses->sm_info.sm_type,
- st_ses->sm_info.sm_data);
+ st_ses->rc_config);
if (status == 0) {
st_ses->hw_session_started = true;
} else {
@@ -2727,6 +3077,7 @@
st_arm_second_stage_t *st_sec_stage = NULL;
st_session_t *stc_ses = st_ses->det_stc_ses;
bool is_active_vop_session = false;
+ multi_model_result_info_t *result_info = NULL;
list_for_each(node, &stc_ses->second_stage_list) {
st_sec_stage = node_to_item(node, st_arm_second_stage_t, list_node);
@@ -2748,13 +3099,20 @@
key_payload_size = *((uint32_t *)payload_ptr + 1);
switch (key_id) {
+ case KEY_ID_MULTI_MODEL_RESULT_INFO:
+ result_info = (multi_model_result_info_t *)(payload_ptr +
+ GENERIC_DET_EVENT_HEADER_SIZE);
+ hw_ses->kw_start_idx = result_info->keyword_start_idx_bytes;
+ hw_ses->kw_end_idx = result_info->keyword_end_idx_bytes;
+ break;
+
case KEY_ID_CONFIDENCE_LEVELS:
if (is_active_vop_session) {
/*
* It is expected that VoP is supported with single KW/user
* SVA3.0 model, hence get it directly with hard offset.
*/
- if (!st_ses->sm_info.sm_merged) {
+ if (!st_ses->sm_merged) {
hw_ses->user_level = (int32_t)(*(payload_ptr +
GENERIC_DET_EVENT_USER_LEVEL_OFFSET));
} else {
@@ -2779,13 +3137,17 @@
GENERIC_DET_EVENT_KW_END_OFFSET);
break;
+ case KEY_ID_TIMESTAMP_INFO:
+ /* No op */
+ break;
+
default:
ALOGW("%s: Unsupported generic detection event key id",
__func__);
break;
}
count_size += GENERIC_DET_EVENT_HEADER_SIZE + key_payload_size;
- payload_ptr += count_size;
+ payload_ptr += GENERIC_DET_EVENT_HEADER_SIZE + key_payload_size;
}
} else {
/*
@@ -2796,9 +3158,9 @@
* duration from platform xml will be used.
*/
hw_ses->kw_start_idx = 0;
- if (hw_ses->sthw_cfg.client_req_hist_buf) {
+ if (hw_ses->max_hist_buf) {
hw_ses->kw_end_idx =
- convert_ms_to_bytes(hw_ses->sthw_cfg.client_req_hist_buf,
+ convert_ms_to_bytes(hw_ses->max_hist_buf,
&hw_ses->config);
} else {
hw_ses->kw_end_idx =
@@ -2935,6 +3297,22 @@
key_payload_size = *((uint32_t *)payload + 1);
switch (key_id) {
+ case KEY_ID_MULTI_MODEL_RESULT_INFO:
+ opaque_size += sizeof(struct st_param_header);
+ if (version != CONF_LEVELS_INTF_VERSION_0002) {
+ opaque_size +=
+ sizeof(struct st_confidence_levels_info);
+ } else {
+ opaque_size +=
+ sizeof(struct st_confidence_levels_info_v2);
+ }
+
+ opaque_size += sizeof(struct st_param_header) +
+ sizeof(struct st_keyword_indices_info);
+ opaque_size += sizeof(struct st_param_header) +
+ sizeof(struct st_timestamp_info);
+ break;
+
case KEY_ID_CONFIDENCE_LEVELS:
opaque_size += sizeof(struct st_param_header);
if (version != CONF_LEVELS_INTF_VERSION_0002) {
@@ -2944,25 +3322,26 @@
opaque_size +=
sizeof(struct st_confidence_levels_info_v2);
}
- count_size += GENERIC_DET_EVENT_HEADER_SIZE + key_payload_size;
- payload += count_size;
break;
case KEY_ID_KEYWORD_POSITION_STATS:
opaque_size += sizeof(struct st_param_header) +
sizeof(struct st_keyword_indices_info);
- count_size += GENERIC_DET_EVENT_HEADER_SIZE + key_payload_size;
- payload += count_size;
+ break;
+
+ case KEY_ID_TIMESTAMP_INFO:
+ opaque_size += sizeof(struct st_param_header) +
+ sizeof(struct st_timestamp_info);
break;
default:
ALOGE("%s: Unsupported generic detection event key id", __func__);
+ break;
}
+ count_size += GENERIC_DET_EVENT_HEADER_SIZE + key_payload_size;
+ payload += GENERIC_DET_EVENT_HEADER_SIZE + key_payload_size;
}
- opaque_size += sizeof(struct st_param_header) +
- sizeof(struct st_timestamp_info);
-
return opaque_size;
}
@@ -3139,6 +3518,7 @@
struct sound_trigger_phrase_recognition_event *local_event)
{
uint32_t key_id = 0, key_payload_size = 0;
+ uint32_t timestamp_msw = 0, timestamp_lsw = 0;
struct st_param_header *param_hdr = NULL;
struct st_keyword_indices_info *kw_indices = NULL;
struct st_timestamp_info *timestamps = NULL;
@@ -3149,15 +3529,91 @@
int status = 0;
unsigned char *cf_levels = NULL;
unsigned int cf_levels_size = 0;
+ multi_model_result_info_t *result_info = NULL;
while (count_size < payload_size) {
key_id = *(uint32_t *)payload;
key_payload_size = *((uint32_t *)payload + 1);
switch (key_id) {
+ case KEY_ID_MULTI_MODEL_RESULT_INFO:
+ if (st_ses->f_stage_version == ST_MODULE_TYPE_GMM) {
+ ALOGE("%s: Error. Multi sm result info supported on PDK5 only",
+ __func__);
+ status = -EINVAL;
+ goto exit;
+ }
+ /* Set confidence levels */
+ param_hdr = (struct st_param_header *)opaque_data;
+ param_hdr->key_id = ST_PARAM_KEY_CONFIDENCE_LEVELS;
+ opaque_data += sizeof(struct st_param_header);
+ if (stc_ses->conf_levels_intf_version !=
+ CONF_LEVELS_INTF_VERSION_0002) {
+ param_hdr->payload_size =
+ sizeof(struct st_confidence_levels_info);
+ } else {
+ param_hdr->payload_size =
+ sizeof(struct st_confidence_levels_info_v2);
+ }
+ result_info = (multi_model_result_info_t *)(payload +
+ GENERIC_DET_EVENT_HEADER_SIZE);
+
+ memset(stc_ses->sm_info.det_cf_levels, 0,
+ MAX_MULTI_SM_CONF_LEVELS);
+
+ cf_levels = stc_ses->sm_info.det_cf_levels;
+ cf_levels_size = stc_ses->sm_info.cf_levels_size;
+ memcpy(opaque_data, stc_ses->st_conf_levels,
+ param_hdr->payload_size);
+ *(cf_levels + result_info->detected_keyword_id) =
+ result_info->best_confidence_level;
+ pack_opaque_data_conf_levels(st_ses, opaque_data,
+ cf_levels, cf_levels_size);
+ pack_recognition_event_conf_levels(st_ses, cf_levels,
+ cf_levels_size, local_event);
+ opaque_data += param_hdr->payload_size;
+
+ /* Set keyword indices */
+ param_hdr = (struct st_param_header *)opaque_data;
+ param_hdr->key_id = ST_PARAM_KEY_KEYWORD_INDICES;
+ param_hdr->payload_size = sizeof(struct st_keyword_indices_info);
+ opaque_data += sizeof(struct st_param_header);
+ kw_indices = (struct st_keyword_indices_info *)opaque_data;
+ kw_indices->version = 0x1;
+ kw_indices->start_index = result_info->keyword_start_idx_bytes;
+ kw_indices->end_index = result_info->keyword_end_idx_bytes;
+
+ list_for_each(node, &stc_ses->second_stage_list) {
+ st_sec_stage = node_to_item(node, st_arm_second_stage_t,
+ list_node);
+ if (IS_KEYWORD_DETECTION_MODEL(st_sec_stage->ss_info->sm_id)) {
+ kw_indices->start_index =
+ st_sec_stage->ss_session->kw_start_idx;
+ kw_indices->end_index =
+ st_sec_stage->ss_session->kw_end_idx;
+ }
+ }
+ opaque_data += sizeof(struct st_keyword_indices_info);
+
+ /* Set timestamp */
+ param_hdr = (struct st_param_header *)opaque_data;
+ param_hdr->key_id = ST_PARAM_KEY_TIMESTAMP;
+ param_hdr->payload_size = sizeof(struct st_timestamp_info);
+ opaque_data += sizeof(struct st_param_header);
+ timestamps = (struct st_timestamp_info *)opaque_data;
+ timestamps->version = 0x1;
+ timestamps->first_stage_det_event_time =
+ (uint64_t)result_info->timestamp_msw_us << 32 |
+ result_info->timestamp_lsw_us;
+ if (!list_empty(&stc_ses->second_stage_list))
+ timestamps->second_stage_det_event_time =
+ st_ses->hw_ses_current->second_stage_det_event_time;
+ opaque_data += sizeof(struct st_timestamp_info);
+ break;
+
case KEY_ID_CONFIDENCE_LEVELS:
/* Pack the opaque data confidence levels structure */
- param_hdr = (struct st_param_header *)(opaque_data);
+ param_hdr = (struct st_param_header *)opaque_data;
param_hdr->key_id = ST_PARAM_KEY_CONFIDENCE_LEVELS;
opaque_data += sizeof(struct st_param_header);
if (stc_ses->conf_levels_intf_version !=
@@ -3186,11 +3642,11 @@
case KEY_ID_KEYWORD_POSITION_STATS:
/* Pack the opaque data keyword indices structure */
- param_hdr = (struct st_param_header *)(opaque_data);
+ param_hdr = (struct st_param_header *)opaque_data;
param_hdr->key_id = ST_PARAM_KEY_KEYWORD_INDICES;
param_hdr->payload_size = sizeof(struct st_keyword_indices_info);
opaque_data += sizeof(struct st_param_header);
- kw_indices = (struct st_keyword_indices_info *)(opaque_data);
+ kw_indices = (struct st_keyword_indices_info *)opaque_data;
kw_indices->version = 0x1;
kw_indices->start_index = *((uint32_t *)payload + 3);
kw_indices->end_index = *((uint32_t *)payload + 4);
@@ -3208,29 +3664,33 @@
opaque_data += sizeof(struct st_keyword_indices_info);
break;
+ case KEY_ID_TIMESTAMP_INFO:
+ /* Pack the opaque data detection timestamp structure */
+ param_hdr = (struct st_param_header *)opaque_data;
+ param_hdr->key_id = ST_PARAM_KEY_TIMESTAMP;
+ param_hdr->payload_size = sizeof(struct st_timestamp_info);
+ opaque_data += sizeof(struct st_param_header);
+ timestamp_lsw = *((uint32_t *)payload + 3);
+ timestamp_msw = *((uint32_t *)payload + 4);
+ timestamps = (struct st_timestamp_info *)opaque_data;
+ timestamps->version = 0x1;
+ timestamps->first_stage_det_event_time =
+ (uint64_t)timestamp_msw << 32 | timestamp_lsw;
+ if (!list_empty(&stc_ses->second_stage_list))
+ timestamps->second_stage_det_event_time =
+ st_ses->hw_ses_current->second_stage_det_event_time;
+ opaque_data += sizeof(struct st_timestamp_info);
+ break;
+
default:
ALOGE("%s: Unsupported generic detection event key id", __func__);
status = -EINVAL;
goto exit;
}
count_size += GENERIC_DET_EVENT_HEADER_SIZE + key_payload_size;
- payload += count_size;
+ payload += GENERIC_DET_EVENT_HEADER_SIZE + key_payload_size;
}
- /* Pack the opaque data detection timestamp structure */
- param_hdr = (struct st_param_header *)(opaque_data);
- param_hdr->key_id = ST_PARAM_KEY_TIMESTAMP;
- param_hdr->payload_size = sizeof(struct st_timestamp_info);
- opaque_data += sizeof(struct st_param_header);
- timestamps = (struct st_timestamp_info *)(opaque_data);
- timestamps->version = 0x1;
- timestamps->first_stage_det_event_time =
- st_ses->hw_ses_current->first_stage_det_event_time;
- if (!list_empty(&stc_ses->second_stage_list))
- timestamps->second_stage_det_event_time =
- st_ses->hw_ses_current->second_stage_det_event_time;
- opaque_data += sizeof(struct st_timestamp_info);
-
exit:
return status;
}
@@ -3243,7 +3703,7 @@
size_t count_size = 0;
int status = 0;
unsigned char *cf_levels = NULL;
- unsigned int cf_levels_size = 0;;
+ unsigned int cf_levels_size = 0;
while (count_size < payload_size) {
key_id = *(uint32_t *)payload;
@@ -3264,7 +3724,12 @@
case KEY_ID_KEYWORD_POSITION_STATS:
count_size += GENERIC_DET_EVENT_HEADER_SIZE + key_payload_size;
- payload += count_size;
+ payload += GENERIC_DET_EVENT_HEADER_SIZE + key_payload_size;
+ break;
+
+ case KEY_ID_TIMESTAMP_INFO:
+ count_size += GENERIC_DET_EVENT_HEADER_SIZE + key_payload_size;
+ payload += GENERIC_DET_EVENT_HEADER_SIZE + key_payload_size;
break;
default:
@@ -3682,7 +4147,7 @@
struct sound_trigger_phrase_recognition_event *phrase_event = NULL;
*event = NULL;
- if (st_ses->sm_info.sm_type == SOUND_MODEL_TYPE_KEYPHRASE) {
+ if (st_ses->det_stc_ses->sm_type == SOUND_MODEL_TYPE_KEYPHRASE) {
if (sthw_extn_check_process_det_ev_support())
ret = sthw_extn_process_detection_event_keyphrase(st_ses,
timestamp, detect_status, payload, payload_size, &phrase_event);
@@ -3977,11 +4442,74 @@
st_ses->aggregator_thread_created = false;
}
+static int init_st_hw_config(st_hw_session_t *hw_ses, uint32_t model_id)
+{
+ struct st_hw_ses_config *sthw_cfg = NULL;
+ int status;
+
+ sthw_cfg = calloc(1, sizeof(struct st_hw_ses_config));
+ if (!sthw_cfg) {
+ ALOGE("%s: Failed to allocate struct st_hw_ses_config, exiting",
+ __func__);
+ return -ENOMEM;
+ }
+ sthw_cfg->model_id = model_id;
+
+ if (hw_ses->f_stage_version == ST_MODULE_TYPE_PDK5) {
+ sthw_cfg->conf_levels = calloc(1, MAX_MULTI_SM_CONF_LEVELS);
+ if (!sthw_cfg->conf_levels) {
+ ALOGE("%s: Failed to allocate conf_levels, exiting",
+ __func__);
+ status = -ENOMEM;
+ goto exit;
+ }
+ memset(sthw_cfg->conf_levels, MAX_CONF_LEVEL_VALUE,
+ MAX_MULTI_SM_CONF_LEVELS);
+ }
+
+ list_add_tail(&hw_ses->sthw_cfg_list,
+ &sthw_cfg->sthw_cfg_list_node);
+
+ return 0;
+
+exit:
+ if (sthw_cfg) {
+ free(sthw_cfg);
+ sthw_cfg = NULL;
+ }
+ return status;
+}
+
+static int deinit_st_hw_config(st_hw_session_t *hw_ses, uint32_t model_id)
+{
+ struct st_hw_ses_config *sthw_cfg = NULL;
+
+ sthw_cfg = get_sthw_cfg_for_model_id(hw_ses, model_id);
+ if (!sthw_cfg) {
+ ALOGE("%s: Unexpected, no matching sthw_cfg", __func__);
+ return -EINVAL;
+ }
+
+ if (hw_ses->f_stage_version == ST_MODULE_TYPE_PDK5 &&
+ sthw_cfg->conf_levels) {
+ free(sthw_cfg->conf_levels);
+ sthw_cfg->conf_levels = NULL;
+ }
+
+ list_remove(&sthw_cfg->sthw_cfg_list_node);
+ free(sthw_cfg);
+ sthw_cfg = NULL;
+
+ return 0;
+}
+
/* This function is called for multi-client */
static int handle_load_sm(st_proxy_session_t *st_ses, st_session_t *stc_ses)
{
st_hw_session_t *hw_ses = st_ses->hw_ses_current;
st_proxy_session_state_fn_t curr_state = st_ses->current_state;
+ struct st_proxy_ses_sm_info_wrapper *p_info = NULL;
+ struct st_hw_ses_config *sthw_cfg = NULL;
int status = 0;
ALOGV("%s:[c%d-%d]", __func__, stc_ses->sm_handle, st_ses->sm_handle);
@@ -4010,10 +4538,12 @@
STATE_TRANSITION(st_ses, loaded_state_fn);
}
- status = hw_ses->fptrs->dereg_sm(hw_ses);
- if (status) {
- ALOGE("%s:[%d] dereg_sm failed %d", __func__,
- st_ses->sm_handle, status);
+ if (st_ses->f_stage_version == ST_MODULE_TYPE_GMM) {
+ status = hw_ses->fptrs->dereg_sm(hw_ses, 0);
+ if (status) {
+ ALOGE("%s:[%d] dereg_sm failed %d", __func__,
+ st_ses->sm_handle, status);
+ }
}
/* Continue updating sound model resulting in merged model */
status = update_sound_model(stc_ses, true);
@@ -4022,20 +4552,40 @@
stc_ses->sm_handle, status);
goto exit;
}
- hw_ses->sthw_cfg.conf_levels = st_ses->sm_info.cf_levels;
- hw_ses->sthw_cfg.num_conf_levels = st_ses->sm_info.cf_levels_size;
- hw_ses->sthw_cfg_updated = true;
- /*
- * Sound model merge would have changed the order of merge conf levels,
- * which need to be re-updated for all current active clients, if any.
- */
- status = update_merge_conf_levels_payload_with_active_clients(st_ses);
- if (status)
- goto exit_1;
- /* Load merged sound model */
- status = hw_ses->fptrs->reg_sm(hw_ses, st_ses->sm_info.sm_data,
- st_ses->sm_info.sm_size, st_ses->sm_info.sm_type);
+ p_info = get_sm_info_for_model_id(st_ses, stc_ses->sm_info.model_id);
+ if (!p_info) {
+ ALOGE("%s: Unexpected, no matching sm_info" , __func__);
+ status = -EINVAL;
+ goto exit_1;
+ }
+
+ if (st_ses->f_stage_version == ST_MODULE_TYPE_GMM) {
+ sthw_cfg = get_sthw_cfg_for_model_id(hw_ses, 0);
+ if (!sthw_cfg) {
+ ALOGE("%s: Unexpected, no matching sthw_cfg", __func__);
+ status = -EINVAL;
+ goto exit_1;
+ }
+
+ sthw_cfg->conf_levels = p_info->sm_info.cf_levels;
+ sthw_cfg->num_conf_levels = p_info->sm_info.cf_levels_size;
+ /*
+ * Sound model merge would have changed the order of merge conf levels,
+ * which need to be re-updated for all current active clients, if any.
+ */
+ status = update_merge_conf_levels_payload_with_active_clients(st_ses);
+ if (status)
+ goto exit_1;
+ } else {
+ status = init_st_hw_config(hw_ses, stc_ses->sm_info.model_id);
+ if (status)
+ goto exit_1;
+ }
+ hw_ses->sthw_cfg_updated = true;
+
+ status = hw_ses->fptrs->reg_sm(hw_ses, p_info->sm_info.sm_data,
+ p_info->sm_info.sm_size, p_info->sm_info.model_id);
if (status) {
ALOGE("%s:[%d] reg_sm failed %d", __func__,
st_ses->sm_handle, status);
@@ -4056,16 +4606,18 @@
exit_2:
if (!st_ses->stdev->ssr_offline_received)
- hw_ses->fptrs->dereg_sm(hw_ses);
+ hw_ses->fptrs->dereg_sm(hw_ses, p_info->sm_info.model_id);
exit_1:
if (!st_ses->stdev->ssr_offline_received) {
update_sound_model(stc_ses, false);
- update_merge_conf_levels_payload_with_active_clients(st_ses);
+ if (st_ses->f_stage_version == ST_MODULE_TYPE_GMM)
+ update_merge_conf_levels_payload_with_active_clients(st_ses);
}
exit:
if (st_ses->stdev->ssr_offline_received) {
+ dereg_all_sm(st_ses, hw_ses);
STATE_TRANSITION(st_ses, ssr_state_fn);
status = 0;
}
@@ -4077,6 +4629,8 @@
{
st_hw_session_t *hw_ses = st_ses->hw_ses_current;
st_proxy_session_state_fn_t curr_state = st_ses->current_state;
+ struct st_proxy_ses_sm_info_wrapper *p_info = NULL;
+ struct st_hw_ses_config *sthw_cfg = NULL;
int status = 0;
ALOGV("%s:[c%d-%d]", __func__, stc_ses->sm_handle, st_ses->sm_handle);
@@ -4100,7 +4654,7 @@
STATE_TRANSITION(st_ses, loaded_state_fn);
}
- status = hw_ses->fptrs->dereg_sm(hw_ses);
+ status = hw_ses->fptrs->dereg_sm(hw_ses, stc_ses->sm_info.model_id);
if (status)
ALOGE("%s:[%d] dereg_sm failed %d", __func__, st_ses->sm_handle, status);
@@ -4110,23 +4664,43 @@
ALOGE("%s:[c%d] update_sound_model delete failed %d", __func__,
stc_ses->sm_handle, status);
- hw_ses->sthw_cfg.conf_levels = st_ses->sm_info.cf_levels;
- hw_ses->sthw_cfg.num_conf_levels = st_ses->sm_info.cf_levels_size;
- hw_ses->sthw_cfg_updated = true;
- /*
- * Sound model merge would have changed the order of merge conf levels,
- * which need to be re-updated for all current active clients, if any.
- */
- update_merge_conf_levels_payload_with_active_clients(st_ses);
+ if (st_ses->f_stage_version == ST_MODULE_TYPE_GMM) {
+ p_info = get_sm_info_for_model_id(st_ses, 0);
+ if (!p_info) {
+ ALOGE("%s: Unexpected, no matching sm_info" , __func__);
+ status = -EINVAL;
+ goto exit;
+ }
- /* Load remaining merged sound model */
- status = hw_ses->fptrs->reg_sm(hw_ses, st_ses->sm_info.sm_data,
- st_ses->sm_info.sm_size, st_ses->sm_info.sm_type);
- if (status) {
- ALOGE("%s:[%d] reg_sm failed %d", __func__,
- st_ses->sm_handle, status);
- goto exit;
+ sthw_cfg = get_sthw_cfg_for_model_id(hw_ses, 0);
+ if (!sthw_cfg) {
+ ALOGE("%s: Unexpected, no matching sthw_cfg", __func__);
+ status = -EINVAL;
+ goto exit;
+ }
+
+ sthw_cfg->conf_levels = p_info->sm_info.cf_levels;
+ sthw_cfg->num_conf_levels = p_info->sm_info.cf_levels_size;
+ /*
+ * Sound model merge would have changed the order of merge conf levels,
+ * which need to be re-updated for all current active clients, if any.
+ */
+ update_merge_conf_levels_payload_with_active_clients(st_ses);
+
+ /* Load remaining merged sound model */
+ status = hw_ses->fptrs->reg_sm(hw_ses, p_info->sm_info.sm_data,
+ p_info->sm_info.sm_size, 0);
+ if (status) {
+ ALOGE("%s:[%d] reg_sm failed %d", __func__,
+ st_ses->sm_handle, status);
+ goto exit;
+ }
+ } else {
+ status = deinit_st_hw_config(hw_ses, stc_ses->sm_handle);
+ if (status)
+ goto exit;
}
+ hw_ses->sthw_cfg_updated = true;
if (curr_state == active_state_fn ||
curr_state == detected_state_fn ||
@@ -4141,6 +4715,8 @@
exit:
if (st_ses->stdev->ssr_offline_received) {
+ if (st_ses->f_stage_version == ST_MODULE_TYPE_PDK5)
+ dereg_all_sm(st_ses, hw_ses);
STATE_TRANSITION(st_ses, ssr_state_fn);
status = 0;
}
@@ -4153,6 +4729,7 @@
int ret = 0;
st_session_t *stc_ses = ev->stc_ses;
st_hw_session_t *hw_ses = st_ses->hw_ses_current;
+ struct st_proxy_ses_sm_info_wrapper *p_info = NULL;
/* skip parameter check as this is an internal funciton */
ALOGD("%s:[c%d-%d] handle event id %d", __func__, stc_ses->sm_handle,
@@ -4173,6 +4750,20 @@
break;
}
+ p_info = get_sm_info_for_model_id(st_ses, stc_ses->sm_info.model_id);
+ if (!p_info) {
+ ALOGE("%s: Unexpected, no matching sm_info" , __func__);
+ status = -EINVAL;
+ break;
+ }
+
+ status = init_st_hw_config(hw_ses, p_info->sm_info.model_id);
+ if (status) {
+ ALOGE("%s:[%d] failed to init sthw_cfg, exiting",
+ __func__, st_ses->sm_handle);
+ break;
+ }
+
/*
* Do retry to handle a corner case that when ADSP SSR ONLINE is
* received, sometimes ADSP is still not ready to receive cmd from HLOS
@@ -4180,8 +4771,8 @@
* state.
*/
for (int i = 0; i < REG_SM_RETRY_CNT; i++) {
- status = ret = hw_ses->fptrs->reg_sm(hw_ses, st_ses->sm_info.sm_data,
- st_ses->sm_info.sm_size, st_ses->sm_info.sm_type);
+ status = ret = hw_ses->fptrs->reg_sm(hw_ses, p_info->sm_info.sm_data,
+ p_info->sm_info.sm_size, p_info->sm_info.model_id);
if (ret) {
if (st_ses->stdev->ssr_offline_received) {
STATE_TRANSITION(st_ses, ssr_state_fn);
@@ -4196,6 +4787,7 @@
break;
}
}
+
if (ret)
break;
@@ -4258,6 +4850,7 @@
st_hw_session_t *hw_ses = st_ses->hw_ses_current;
st_hw_session_t *new_hw_ses = NULL;
st_exec_mode_t new_exec_mode = 0;
+ struct st_proxy_ses_sm_info_wrapper *p_info = NULL;
/* skip parameter check as this is an internal function */
ALOGD("%s:[c%d-%d] handle event id %d", __func__, stc_ses->sm_handle,
@@ -4275,7 +4868,7 @@
break;
}
- status = hw_ses->fptrs->dereg_sm(hw_ses);
+ status = hw_ses->fptrs->dereg_sm(hw_ses, stc_ses->sm_info.model_id);
if (status)
ALOGE("%s:[%d] dereg_sm failed %d", __func__,
st_ses->sm_handle, status);
@@ -4285,6 +4878,11 @@
ALOGE("%s:[c%d] update_sound_model failed %d", __func__,
stc_ses->sm_handle, status);
+ status = deinit_st_hw_config(hw_ses, stc_ses->sm_info.model_id);
+ if (status)
+ ALOGE("%s:[c%d] failed to deinit sthw_cfg",
+ __func__, stc_ses->sm_handle);
+
/* since this is a teardown scenario dont fail here */
status = 0;
STATE_TRANSITION(st_ses, idle_state_fn);
@@ -4304,18 +4902,18 @@
hw_ses->lpi_enable = hw_ses->stdev->lpi_enable;
hw_ses->barge_in_mode = hw_ses->stdev->barge_in_mode;
- status = hw_ses->fptrs->dereg_sm(hw_ses);
+ status = dereg_all_sm(st_ses, hw_ses);
if (status) {
ALOGE("%s:[%d] failed to dereg_sm err %d", __func__,
st_ses->sm_handle, status);
break;
}
- status = hw_ses->fptrs->reg_sm(hw_ses, st_ses->sm_info.sm_data,
- st_ses->sm_info.sm_size, st_ses->sm_info.sm_type);
+ status = reg_all_sm(st_ses, hw_ses);
if (status) {
ALOGE("%s:[%d] failed to reg_sm err %d", __func__,
st_ses->sm_handle, status);
+ dereg_all_sm(st_ses, hw_ses);
STATE_TRANSITION(st_ses, idle_state_fn);
}
}
@@ -4338,7 +4936,7 @@
status = start_session(st_ses, hw_ses, false);
if (status) {
if (st_ses->stdev->ssr_offline_received) {
- hw_ses->fptrs->dereg_sm(hw_ses);
+ dereg_all_sm(st_ses, hw_ses);
STATE_TRANSITION(st_ses, ssr_state_fn);
status = 0;
} else {
@@ -4362,7 +4960,7 @@
case ST_SES_EV_SSR_OFFLINE:
/* exec mode can be none if ssr occurs during a transition */
if (st_ses->exec_mode != ST_EXEC_MODE_NONE)
- hw_ses->fptrs->dereg_sm(hw_ses);
+ dereg_all_sm(st_ses, hw_ses);
STATE_TRANSITION(st_ses, ssr_state_fn);
break;
@@ -4385,7 +4983,7 @@
c_ses->exec_mode = ST_EXEC_MODE_NONE;
}
/* unload sm for current hw session */
- status = hw_ses->fptrs->dereg_sm(hw_ses);
+ status = hw_ses->fptrs->dereg_sm(hw_ses, 0);
if (status) {
ALOGE("%s:[%d] dereg_sm failed with err %d", __func__,
st_ses->sm_handle, status);
@@ -4408,9 +5006,15 @@
break;
}
+ p_info = get_sm_info_for_model_id(st_ses, 0);
+ if (!p_info) {
+ ALOGE("%s: Unexpected, no matching sm_info" , __func__);
+ status = -EINVAL;
+ break;
+ }
+
status = new_hw_ses->fptrs->reg_sm(new_hw_ses,
- st_ses->sm_info.sm_data, st_ses->sm_info.sm_size,
- st_ses->sm_info.sm_type);
+ p_info->sm_info.sm_data, p_info->sm_info.sm_size, 0);
if (status) {
ALOGE("%s:[%d] reg_sm failed with err %d", __func__,
st_ses->sm_handle, status);
@@ -4532,7 +5136,7 @@
st_ses->sm_handle, status);
}
if (status & st_ses->stdev->ssr_offline_received) {
- hw_ses->fptrs->dereg_sm(hw_ses);
+ dereg_all_sm(st_ses, hw_ses);
STATE_TRANSITION(st_ses, ssr_state_fn);
status = 0;
}
@@ -4618,7 +5222,7 @@
if (status) {
if (st_ses->stdev->ssr_offline_received) {
STATE_TRANSITION(st_ses, ssr_state_fn);
- hw_ses->fptrs->dereg_sm(hw_ses);
+ dereg_all_sm(st_ses, hw_ses);
status = 0;
} else {
ALOGE("%s:[%d] failed to stop session, err %d", __func__,
@@ -4661,7 +5265,7 @@
if (status) {
if (st_ses->stdev->ssr_offline_received) {
- hw_ses->fptrs->dereg_sm(hw_ses);
+ dereg_all_sm(st_ses, hw_ses);
STATE_TRANSITION(st_ses, ssr_state_fn);
status = 0;
} else {
@@ -4698,6 +5302,7 @@
st_ses->det_stc_ses = stc_ses;
st_ses->hw_ses_current->enable_second_stage = false; /* Initialize */
stc_ses->detection_sent = false;
+ hw_ses->detected_preroll = stc_ses->preroll_duration;
if (list_empty(&stc_ses->second_stage_list) ||
st_ses->detection_requested) {
@@ -5252,7 +5857,7 @@
if (status) {
if (st_ses->stdev->ssr_offline_received) {
- hw_ses->fptrs->dereg_sm(hw_ses);
+ dereg_all_sm(st_ses, hw_ses);
STATE_TRANSITION(st_ses, ssr_state_fn);
status = 0;
} else {
@@ -5987,7 +6592,7 @@
st_proxy_session_t *st_ses = stc_ses->hw_proxy_ses;
pthread_mutex_lock(&st_ses->lock);
- val = st_ses->hw_ses_current->sthw_cfg.client_req_preroll;
+ val = st_ses->hw_ses_current->max_preroll;
pthread_mutex_unlock(&st_ses->lock);
return val;
@@ -6242,45 +6847,71 @@
* Check for merge sound model support and return the existing hw
* session. If any other clients have already created it.
*/
- if (v_info->merge_fs_soundmodels) {
+ if (v_info->merge_fs_soundmodels &&
+ stc_ses->f_stage_version == ST_MODULE_TYPE_GMM) {
if (!v_info->is_qcva_uuid) {
- ALOGE("%s: merge sound model not supported for non SVA engines",
- __func__);
- status = -ENOSYS;
- goto cleanup;
+ ALOGE("%s: merge sound model not supported for non SVA engines",
+ __func__);
+ status = -ENOSYS;
+ goto cleanup;
}
list_for_each(node, &stdev->sound_model_list) {
c_ses = node_to_item(node, st_session_t, list_node);
if ((c_ses != stc_ses) &&
c_ses->vendor_uuid_info->is_qcva_uuid &&
- c_ses->vendor_uuid_info->merge_fs_soundmodels) {
+ c_ses->vendor_uuid_info->merge_fs_soundmodels &&
+ c_ses->f_stage_version == ST_MODULE_TYPE_GMM) {
stc_ses->hw_proxy_ses = c_ses->hw_proxy_ses;
list_add_tail(&stc_ses->hw_proxy_ses->clients_list,
&stc_ses->hw_list_node);
- ALOGD("%s: another client attached: h%d <-- c%d", __func__,
- stc_ses->hw_proxy_ses->sm_handle, sm_handle);
+ ALOGD("%s: another client attached, merge SM: h%d <-- c%d",
+ __func__, stc_ses->hw_proxy_ses->sm_handle, sm_handle);
free(st_ses);
st_ses = NULL;
break;
}
}
- }
- if (st_ses) { /* If no other client exist */
- st_ses->hw_ses_adsp =
- (st_hw_session_t *)calloc(1, sizeof(st_hw_session_lsm_t));
- if (!st_ses->hw_ses_adsp) {
- status = -ENOMEM;
- goto cleanup;
- }
- status = st_hw_sess_lsm_init(st_ses->hw_ses_adsp, hw_sess_cb,
- (void *)st_ses, exec_mode, v_info, sm_handle, stdev);
- if (status) {
- ALOGE("%s: initializing lsm hw session failed %d",
- __func__, status);
- goto cleanup;
- }
- st_ses->hw_ses_current = st_ses->hw_ses_adsp;
- }
+ } else if (stc_ses->f_stage_version == ST_MODULE_TYPE_PDK5) {
+ if (!v_info->is_qcva_uuid) {
+ ALOGE("%s: multi sound model not supported for non SVA engines",
+ __func__);
+ status = -ENOSYS;
+ goto cleanup;
+ }
+ list_for_each(node, &stdev->sound_model_list) {
+ c_ses = node_to_item(node, st_session_t, list_node);
+ if ((c_ses != stc_ses) &&
+ c_ses->vendor_uuid_info->is_qcva_uuid &&
+ c_ses->f_stage_version == ST_MODULE_TYPE_PDK5) {
+ stc_ses->hw_proxy_ses = c_ses->hw_proxy_ses;
+ list_add_tail(&stc_ses->hw_proxy_ses->clients_list,
+ &stc_ses->hw_list_node);
+ ALOGD("%s: another client attached, multi SM: h%d <-- c%d",
+ __func__, stc_ses->hw_proxy_ses->sm_handle, sm_handle);
+ free(st_ses);
+ st_ses = NULL;
+ break;
+ }
+ }
+ }
+ if (st_ses) { /* If no other client exist */
+ st_ses->hw_ses_adsp =
+ (st_hw_session_t *)calloc(1, sizeof(st_hw_session_lsm_t));
+ if (!st_ses->hw_ses_adsp) {
+ status = -ENOMEM;
+ goto cleanup;
+ }
+ status = st_hw_sess_lsm_init(st_ses->hw_ses_adsp, hw_sess_cb,
+ (void *)st_ses, exec_mode, v_info, sm_handle, stdev);
+ if (status) {
+ ALOGE("%s: initializing lsm hw session failed %d",
+ __func__, status);
+ goto cleanup;
+ }
+ st_ses->hw_ses_current = st_ses->hw_ses_adsp;
+ st_ses->f_stage_version = stc_ses->f_stage_version;
+ st_ses->hw_ses_current->f_stage_version = stc_ses->f_stage_version;
+ }
} else if (v_info && (EXEC_MODE_CFG_ARM == v_info->exec_mode_cfg)) {
st_ses->enable_trans = false;
st_ses->hw_ses_arm = calloc(1, sizeof(st_hw_session_pcm_t));
@@ -6330,6 +6961,7 @@
pthread_mutex_init(&st_ses->lock, (const pthread_mutexattr_t *)&attr);
stc_ses->hw_proxy_ses = st_ses;
+ list_init(&st_ses->sm_info_list);
list_init(&st_ses->clients_list);
list_add_tail(&st_ses->clients_list, &stc_ses->hw_list_node);
ALOGD("%s: client attached: h%d <-- c%d", __func__,