/** \brief Change an engine specific setting */ static int uni_recog_change(struct ast_speech *speech, ast_compat_const char *name, const char *value) { uni_speech_t *uni_speech = speech->data; if(uni_speech->is_inprogress) { uni_recog_stop(speech); } ast_log(LOG_NOTICE, "Change setting '%s'\n",uni_speech_id_get(uni_speech)); return 0; }
/** \brief Change the type of results we want back */ static int uni_recog_change_results_type(struct ast_speech *speech,enum ast_speech_results_type results_type) { uni_speech_t *uni_speech = speech->data; if(uni_speech->is_inprogress) { uni_recog_stop(speech); } ast_log(LOG_NOTICE, "Change result type '%s'\n",uni_speech_id_get(uni_speech)); return -1; }
/** \brief Change an engine specific setting */ static int uni_recog_change(struct ast_speech *speech, ast_compat_const char *name, const char *value) { uni_speech_t *uni_speech = speech->data; if(uni_speech->is_inprogress) { uni_recog_stop(speech); } ast_log(LOG_NOTICE, "(%s) Change setting name: %s value:%s\n",uni_speech->name,name,value); return 0; }
/** \brief Deactivate a loaded grammar */ static int uni_recog_deactivate_grammar(struct ast_speech *speech, ast_compat_const char *grammar_name) { uni_speech_t *uni_speech = speech->data; if(uni_speech->is_inprogress) { uni_recog_stop(speech); } ast_log(LOG_NOTICE, "(%s) Deactivate grammar name: %s\n",uni_speech->name,grammar_name); apr_hash_set(uni_speech->active_grammars,grammar_name,APR_HASH_KEY_STRING,NULL); return 0; }
/** \brief Unload a local grammar */ static int uni_recog_unload_grammar(struct ast_speech *speech, ast_compat_const char *grammar_name) { uni_speech_t *uni_speech = speech->data; mrcp_message_t *mrcp_message; mrcp_generic_header_t *generic_header; if(uni_speech->is_inprogress) { uni_recog_stop(speech); } ast_log(LOG_NOTICE, "Unload grammar name:%s '%s'\n", grammar_name, uni_speech_id_get(uni_speech)); apr_hash_set(uni_speech->active_grammars,grammar_name,APR_HASH_KEY_STRING,NULL); mrcp_message = mrcp_application_message_create( uni_speech->session, uni_speech->channel, RECOGNIZER_DEFINE_GRAMMAR); if(!mrcp_message) { ast_log(LOG_WARNING, "Failed to create MRCP message\n"); return -1; } /* Get/allocate generic header */ generic_header = mrcp_generic_header_prepare(mrcp_message); if(generic_header) { /* Set generic header fields */ apt_string_assign(&generic_header->content_id,grammar_name,mrcp_message->pool); mrcp_generic_header_property_add(mrcp_message,GENERIC_HEADER_CONTENT_ID); } /* Send MRCP request and wait for response */ if(uni_recog_mrcp_request_send(uni_speech,mrcp_message) != TRUE) { ast_log(LOG_WARNING, "Failed to send MRCP message\n"); return -1; } /* Check received response */ if(!uni_speech->mrcp_response || uni_speech->mrcp_response->start_line.status_code != MRCP_STATUS_CODE_SUCCESS) { ast_log(LOG_WARNING, "Received failure response\n"); return -1; } return 0; }
/** \brief Try to get result */ struct ast_speech_result* uni_recog_get(struct ast_speech *speech) { struct ast_speech_result *result; mrcp_recog_header_t *recog_header; uni_speech_t *uni_speech = speech->data; if(uni_speech->is_inprogress) { uni_recog_stop(speech); } if(!uni_speech->mrcp_event) { ast_log(LOG_WARNING, "(%s) No RECOGNITION-COMPLETE message received\n",uni_speech->name); return NULL; } /* Get recognizer header */ recog_header = mrcp_resource_header_get(uni_speech->mrcp_event); if(!recog_header || mrcp_resource_header_property_check(uni_speech->mrcp_event,RECOGNIZER_HEADER_COMPLETION_CAUSE) != TRUE) { ast_log(LOG_WARNING, "(%s) Missing completion cause in RECOGNITION-COMPLETE message\n",uni_speech->name); return NULL; } ast_log(LOG_NOTICE, "(%s) Get result completion cause: %03d reason: %s\n", uni_speech->name, recog_header->completion_cause, recog_header->completion_reason.buf ? recog_header->completion_reason.buf : "none"); if(recog_header->completion_cause != RECOGNIZER_COMPLETION_CAUSE_SUCCESS) { ast_log(LOG_WARNING, "(%s) Recognition completed abnormally cause: %03d reason: %s\n", uni_speech->name, recog_header->completion_cause, recog_header->completion_reason.buf ? recog_header->completion_reason.buf : "none"); return NULL; } result = uni_recog_speech_result_build( uni_speech, &uni_speech->mrcp_event->body, uni_speech->mrcp_event->start_line.version); if(result) ast_set_flag(speech,AST_SPEECH_HAVE_RESULTS); return result; }
/** \brief Try to get result */ struct ast_speech_result* uni_recog_get(struct ast_speech *speech) { mrcp_recog_header_t *recog_header; uni_speech_t *uni_speech = speech->data; if(uni_speech->is_inprogress) { uni_recog_stop(speech); } ast_log(LOG_NOTICE, "Get result '%s'\n",uni_speech_id_get(uni_speech)); if(!uni_speech->mrcp_event) { ast_log(LOG_WARNING, "No RECOGNITION-COMPLETE message received\n"); return NULL; } /* Get recognizer header */ recog_header = mrcp_resource_header_get(uni_speech->mrcp_event); if(!recog_header || mrcp_resource_header_property_check(uni_speech->mrcp_event,RECOGNIZER_HEADER_COMPLETION_CAUSE) != TRUE) { ast_log(LOG_WARNING, "Missing Completion-Cause in RECOGNITION-COMPLETE message\n"); return NULL; } if(recog_header->completion_cause != RECOGNIZER_COMPLETION_CAUSE_SUCCESS) { ast_log(LOG_WARNING, "Unsuccessful completion cause:%d reason:%s\n", recog_header->completion_cause, recog_header->completion_reason.buf ? recog_header->completion_reason.buf : "none"); return NULL; } if(speech->results) { ast_speech_results_free(speech->results); } speech->results = uni_recog_speech_result_build( &uni_speech->mrcp_event->body, uni_speech->mrcp_event->start_line.version, mrcp_application_session_pool_get(uni_speech->session)); if(speech->results) { ast_set_flag(speech,AST_SPEECH_HAVE_RESULTS); } return speech->results; }
/** brief Prepare engine to accept audio */ static int uni_recog_start(struct ast_speech *speech) { uni_speech_t *uni_speech = speech->data; mrcp_message_t *mrcp_message; mrcp_generic_header_t *generic_header; mrcp_recog_header_t *recog_header; if(uni_speech->is_inprogress) { uni_recog_stop(speech); } ast_log(LOG_NOTICE, "Start audio '%s'\n",uni_speech_id_get(uni_speech)); mrcp_message = mrcp_application_message_create( uni_speech->session, uni_speech->channel, RECOGNIZER_RECOGNIZE); if(!mrcp_message) { ast_log(LOG_WARNING, "Failed to create MRCP message\n"); return -1; } /* Get/allocate generic header */ generic_header = mrcp_generic_header_prepare(mrcp_message); if(generic_header) { apr_hash_index_t *it; void *val; const char *grammar_name; const char *content = NULL; /* Set generic header fields */ apt_string_assign(&generic_header->content_type,"text/uri-list",mrcp_message->pool); mrcp_generic_header_property_add(mrcp_message,GENERIC_HEADER_CONTENT_TYPE); /* Construct and set message body */ it = apr_hash_first(mrcp_message->pool,uni_speech->active_grammars); if(it) { apr_hash_this(it,NULL,NULL,&val); grammar_name = val; content = apr_pstrcat(mrcp_message->pool,"session:",grammar_name,NULL); it = apr_hash_next(it); } for(; it; it = apr_hash_next(it)) { apr_hash_this(it,NULL,NULL,&val); grammar_name = val; content = apr_pstrcat(mrcp_message->pool,content,"\nsession:",grammar_name,NULL); } if(content) { apt_string_set(&mrcp_message->body,content); } } /* Get/allocate recognizer header */ recog_header = (mrcp_recog_header_t*) mrcp_resource_header_prepare(mrcp_message); if(recog_header) { /* Set recognizer header fields */ if(mrcp_message->start_line.version == MRCP_VERSION_2) { recog_header->cancel_if_queue = FALSE; mrcp_resource_header_property_add(mrcp_message,RECOGNIZER_HEADER_CANCEL_IF_QUEUE); } recog_header->start_input_timers = TRUE; mrcp_resource_header_property_add(mrcp_message,RECOGNIZER_HEADER_START_INPUT_TIMERS); } /* Reset last event (if any) */ uni_speech->mrcp_event = NULL; /* Send MRCP request and wait for response */ if(uni_recog_mrcp_request_send(uni_speech,mrcp_message) != TRUE) { ast_log(LOG_WARNING, "Failed to send MRCP message\n"); return -1; } /* Check received response */ if(!uni_speech->mrcp_response || uni_speech->mrcp_response->start_line.status_code != MRCP_STATUS_CODE_SUCCESS) { ast_log(LOG_WARNING, "Received failure response\n"); return -1; } /* Reset media buffer */ mpf_frame_buffer_restart(uni_speech->media_buffer); ast_speech_change_state(speech, AST_SPEECH_STATE_READY); uni_speech->is_inprogress = TRUE; return 0; }