在MRCP 开始语音识别后会调用recog_channel_start()函数
static switch_status_t recog_channel_start(speech_channel_t *schannel)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_hash_index_t *egk;
mrcp_message_t *mrcp_message;
mrcp_recog_header_t *recog_header;
mrcp_generic_header_t *generic_header;
recognizer_data_t *r;
char *start_input_timers;
const char *mime_type;
char *key = NULL;
switch_size_t len;
grammar_t *grammar = NULL;
switch_size_t grammar_uri_count = 0;
switch_size_t grammar_uri_list_len = 0;
char *grammar_uri_list = NULL;
int warned = 0;
switch_mutex_lock(schannel->mutex);
if (schannel->state != SPEECH_CHANNEL_READY) {
status = SWITCH_STATUS_FALSE;
goto done;
}
if (schannel->data == NULL) {
status = SWITCH_STATUS_FALSE;
goto done;
}
r = (recognizer_data_t *) schannel->data;
r->result = NULL;
if (r->result_headers) {
switch_event_destroy(&r->result_headers);
}
r->start_of_input = 0;
/* input timers are started by default unless the start-input-timers=false param is set */
start_input_timers = (char *) switch_core_hash_find(schannel->params, "start-input-timers");
r->timers_started = zstr(start_input_timers) || strcasecmp(start_input_timers, "false");
/* count enabled grammars */
for (egk = switch_core_hash_first(r->enabled_grammars); egk; egk = switch_core_hash_next(&egk)) {
// NOTE: This postponed type check is necessary to allow a non-URI-list grammar to execute alone
if (grammar_uri_count == 1 && grammar->type != GRAMMAR_TYPE_URI)
goto no_grammar_alone;
++grammar_uri_count;
switch_core_hash_this(egk, (void *) &key, NULL, (void *) &grammar);
if (grammar->type != GRAMMAR_TYPE_URI && grammar_uri_count != 1) {
no_grammar_alone:
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(schannel->session_uuid), SWITCH_LOG_ERROR, "(%s) Grammar '%s' can only be used alone (not a URI list)\n", schannel->name, key);
status = SWITCH_STATUS_FALSE;
switch_safe_free(egk);
goto done;
}
len = strlen(grammar->data);
if (!len)
continue;
grammar_uri_list_len += len;
if (grammar->data[len - 1] != '\n')
grammar_uri_list_len += 2;
}
switch (grammar_uri_count) {
case 0:
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(schannel->session_uuid), SWITCH_LOG_ERROR, "(%s) No grammar specified\n", schannel->name);
status = SWITCH_STATUS_FALSE;
goto done;
case 1:
/* grammar should already be the unique grammar */
break;
default:
/* get the enabled grammars list */
grammar_uri_list = switch_core_alloc(schannel->memory_pool, grammar_uri_list_len + 1);
grammar_uri_list_len = 0;
for (egk = switch_core_hash_first(r->enabled_grammars); egk; egk = switch_core_hash_next(&egk)) {
switch_core_hash_this(egk, (void *) &key, NULL, (void *) &grammar);
len = strlen(grammar->data);
if (!len)
continue;
memcpy(&(grammar_uri_list[grammar_uri_list_len]), grammar->data, len);
grammar_uri_list_len += len;
if (grammar_uri_list[grammar_uri_list_len - 1] != '\n')
{
grammar_uri_list_len += 2;
grammar_uri_list[grammar_uri_list_len - 2] = '\r';
grammar_uri_list[grammar_uri_list_len - 1] = '\n';
}
}
grammar_uri_list[grammar_uri_list_len++] = '\0';
grammar = NULL;
}
/* create MRCP message */
mrcp_message = mrcp_application_message_create(schannel->unimrcp_session, schannel->unimrcp_channel, RECOGNIZER_RECOGNIZE);
if (mrcp_message == NULL) {
status = SWITCH_STATUS_FALSE;
goto done;
}
/* allocate generic header */
generic_header = (mrcp_generic_header_t *) mrcp_generic_header_prepare(mrcp_message);
if (generic_header == NULL) {
status = SWITCH_STATUS_FALSE;
goto done;