Example #1
0
/*! \brief Stop the in-progress recognition */
static int uni_recog_stop(struct ast_speech *speech)
{
	uni_speech_t *uni_speech = speech->data;
	mrcp_message_t *mrcp_message;
	
	if(!uni_speech->is_inprogress) {
		return 0;
	}

	ast_log(LOG_NOTICE, "Stop recognition '%s'\n",uni_speech_id_get(uni_speech));
	mrcp_message = mrcp_application_message_create(
								uni_speech->session,
								uni_speech->channel,
								RECOGNIZER_STOP);
	if(!mrcp_message) {
		ast_log(LOG_WARNING, "Failed to create MRCP message\n");
		return -1;
	}
	
	/* 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_NOT_READY);
	
	uni_speech->is_inprogress = FALSE;
	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, "(%s) Unload grammar name: %s\n",
				uni_speech->name,
				grammar_name);

	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, "(%s) Failed to create MRCP message\n",uni_speech->name);
		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, "(%s) Failed to unload grammar\n",uni_speech->name);
		return -1;
	}

	return 0;
}
Example #3
0
/** Create demo MRCP message (RECOGNIZE request) */
mrcp_message_t* demo_recognize_message_create(mrcp_session_t *session, mrcp_channel_t *channel, const apt_dir_layout_t *dir_layout)
{
	const char text[] = "session:[email protected]";

	/* create MRCP message */
	mrcp_message_t *mrcp_message = mrcp_application_message_create(session,channel,RECOGNIZER_RECOGNIZE);
	if(mrcp_message) {
		mrcp_recog_header_t *recog_header;
		mrcp_generic_header_t *generic_header;
		/* 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_type,"text/uri-list",mrcp_message->pool);
			mrcp_generic_header_property_add(mrcp_message,GENERIC_HEADER_CONTENT_TYPE);
		}
		/* get/allocate recognizer header */
		recog_header = mrcp_resource_header_prepare(mrcp_message);
		if(recog_header) {
			if(mrcp_message->start_line.version == MRCP_VERSION_2) {
				/* set recognizer header fields */
				recog_header->cancel_if_queue = FALSE;
				mrcp_resource_header_property_add(mrcp_message,RECOGNIZER_HEADER_CANCEL_IF_QUEUE);
			}
			recog_header->no_input_timeout = 5000;
			mrcp_resource_header_property_add(mrcp_message,RECOGNIZER_HEADER_NO_INPUT_TIMEOUT);
			recog_header->recognition_timeout = 10000;
			mrcp_resource_header_property_add(mrcp_message,RECOGNIZER_HEADER_RECOGNITION_TIMEOUT);
			recog_header->start_input_timers = TRUE;
			mrcp_resource_header_property_add(mrcp_message,RECOGNIZER_HEADER_START_INPUT_TIMERS);
			recog_header->confidence_threshold = 0.87f;
			mrcp_resource_header_property_add(mrcp_message,RECOGNIZER_HEADER_CONFIDENCE_THRESHOLD);
		}
		/* set message body */
		apt_string_assign(&mrcp_message->body,text,mrcp_message->pool);
	}
	return mrcp_message;
}
/** \brief Set properties */
static apt_bool_t uni_recog_properties_set(uni_speech_t *uni_speech)
{
	mrcp_message_t *mrcp_message;
	mrcp_message_header_t *properties;
	ast_log(LOG_DEBUG, "(%s) Set properties\n",uni_speech->name);
	mrcp_message = mrcp_application_message_create(
								uni_speech->session,
								uni_speech->channel,
								RECOGNIZER_SET_PARAMS);
	if(!mrcp_message) {
		ast_log(LOG_WARNING, "(%s) Failed to create MRCP message\n",uni_speech->name);
		return FALSE;
	}

	/* Inherit properties loaded from config */
	if(mrcp_message->start_line.version == MRCP_VERSION_2) {
		properties = uni_engine.v2_properties;
	}
	else {
		properties = uni_engine.v1_properties;
	}

	if(properties) {
#if defined(TRANSPARENT_HEADER_FIELDS_SUPPORT)
		mrcp_header_fields_inherit(&mrcp_message->header,properties,mrcp_message->pool);
#else
		mrcp_message_header_inherit(&mrcp_message->header,properties,mrcp_message->pool);
#endif
	}

	/* Send MRCP request and wait for response */
	if(uni_recog_mrcp_request_send(uni_speech,mrcp_message) != TRUE) {
		ast_log(LOG_WARNING, "(%s) Failed to set properties\n",uni_speech->name);
		return FALSE;
	}

	return TRUE;
}
/*! \brief Stop the in-progress recognition */
static int uni_recog_stop(struct ast_speech *speech)
{
	uni_speech_t *uni_speech = speech->data;
	mrcp_message_t *mrcp_message;

	if(!uni_speech->is_inprogress) {
		return 0;
	}

	ast_log(LOG_NOTICE, "(%s) Stop recognition\n",uni_speech->name);
	mrcp_message = mrcp_application_message_create(
								uni_speech->session,
								uni_speech->channel,
								RECOGNIZER_STOP);
	if(!mrcp_message) {
		ast_log(LOG_WARNING, "(%s) Failed to create MRCP message\n",uni_speech->name);
		return -1;
	}

	/* 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, "(%s) Failed to stop recognition\n",uni_speech->name);
		return -1;
	}

	/* Reset media buffer */
	mpf_frame_buffer_restart(uni_speech->media_buffer);

	ast_speech_change_state(speech, AST_SPEECH_STATE_NOT_READY);

	uni_speech->is_inprogress = FALSE;
	return 0;
}
/* Send SPEAK request to synthesizer. */
static int synth_channel_speak(speech_channel_t *schannel, const char *content, const char *content_type, apr_hash_t *header_fields)
{
	int status = 0;
	mrcp_message_t *mrcp_message = NULL;
	mrcp_generic_header_t *generic_header = NULL;
	mrcp_synth_header_t *synth_header = NULL;

	if (!schannel || !content || !content_type) {
		ast_log(LOG_ERROR, "synth_channel_speak: unknown channel error!\n");
		return -1;
	}

	apr_thread_mutex_lock(schannel->mutex);

	if (schannel->state != SPEECH_CHANNEL_READY) {
		apr_thread_mutex_unlock(schannel->mutex);
		return -1;
	}

	if ((mrcp_message = mrcp_application_message_create(schannel->unimrcp_session, schannel->unimrcp_channel, SYNTHESIZER_SPEAK)) == NULL) {
		ast_log(LOG_ERROR, "(%s) Failed to create SPEAK message\n", schannel->name);

		apr_thread_mutex_unlock(schannel->mutex);
		return -1;
	}

	/* Set generic header fields (content-type). */
	if ((generic_header = (mrcp_generic_header_t *)mrcp_generic_header_prepare(mrcp_message)) == NULL) {	
		apr_thread_mutex_unlock(schannel->mutex);
		return -1;
	}

	apt_string_assign(&generic_header->content_type, content_type, mrcp_message->pool);
	mrcp_generic_header_property_add(mrcp_message, GENERIC_HEADER_CONTENT_TYPE);

	/* Set synthesizer header fields (voice, rate, etc.). */
	if ((synth_header = (mrcp_synth_header_t *)mrcp_resource_header_prepare(mrcp_message)) == NULL) {
		apr_thread_mutex_unlock(schannel->mutex);
		return -1;
	}

	/* Add params to MRCP message. */
	speech_channel_set_params(schannel, mrcp_message, header_fields);

	/* Set body (plain text or SSML). */
	apt_string_assign(&mrcp_message->body, content, schannel->pool);

	/* Empty audio queue and send SPEAK to MRCP server. */
	audio_queue_clear(schannel->audio_queue);

	if (!mrcp_application_message_send(schannel->unimrcp_session, schannel->unimrcp_channel, mrcp_message)) {
		ast_log(LOG_ERROR,"(%s) Failed to send SPEAK message", schannel->name);

		apr_thread_mutex_unlock(schannel->mutex);
		return -1;
	}

	/* Wait for IN PROGRESS. */
	apr_thread_cond_timedwait(schannel->cond, schannel->mutex, SPEECH_CHANNEL_TIMEOUT_USEC);

	if (schannel->state != SPEECH_CHANNEL_PROCESSING) {
		apr_thread_mutex_unlock(schannel->mutex);
		return -1;
	}

	apr_thread_mutex_unlock(schannel->mutex);
	return status;
}
Example #7
0
/** 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;
}
Example #8
0
/*! \brief Load a local grammar on the speech structure */
static int uni_recog_load_grammar(struct ast_speech *speech, ast_compat_const char *grammar_name, ast_compat_const char *grammar_path)
{
	uni_speech_t *uni_speech = speech->data;
	mrcp_message_t *mrcp_message;
	mrcp_generic_header_t *generic_header;
	const char *content_type = NULL;
	apt_bool_t inline_content = FALSE;
	char *tmp;
	apr_file_t *file;
	apt_str_t *body = 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;
	}

	/* 
	 * Grammar name and path are mandatory attributes, 
	 * grammar type can be optionally specified with path.
	 *
	 * SpeechLoadGrammar(name|path)
	 * SpeechLoadGrammar(name|type:path)
	 * SpeechLoadGrammar(name|uri:path)
	 * SpeechLoadGrammar(name|builtin:grammar/digits)
	 */

	tmp = strchr(grammar_path,':');
	if(tmp) {
		const char builtin_token[] = "builtin";
		const char uri_token[] = "uri";
		if(strncmp(grammar_path,builtin_token,sizeof(builtin_token)-1) == 0) {
			content_type = "text/uri-list";
			inline_content = TRUE;
		}
		else if(strncmp(grammar_path,uri_token,sizeof(uri_token)-1) == 0) {
			content_type = "text/uri-list";
			inline_content = TRUE;
			grammar_path = tmp+1;
		}
		else {
			*tmp = '\0';
			content_type = grammar_path;
			grammar_path = tmp+1;
		}
	}

	if(inline_content == TRUE) {
		body = &mrcp_message->body;
		apt_string_assign(body,grammar_path,mrcp_message->pool);
	}
	else {
		if(apr_file_open(&file,grammar_path,APR_FOPEN_READ|APR_FOPEN_BINARY,0,mrcp_message->pool) == APR_SUCCESS) {
			apr_finfo_t finfo;
			if(apr_file_info_get(&finfo,APR_FINFO_SIZE,file) == APR_SUCCESS) {
				/* Read message body */
				body = &mrcp_message->body;
				body->buf = apr_palloc(mrcp_message->pool,finfo.size+1);
				body->length = (apr_size_t)finfo.size;
				if(apr_file_read(file,body->buf,&body->length) != APR_SUCCESS) {
					ast_log(LOG_WARNING, "Failed to read the content of grammar file: %s\n",grammar_path);
				}
				body->buf[body->length] = '\0';
			}
			apr_file_close(file);
		}
		else {
			ast_log(LOG_WARNING, "No such grammar file available: %s\n",grammar_path);
			return -1;
		}
	}

	if(!body || !body->buf) {
		ast_log(LOG_WARNING, "No content available: %s\n",grammar_path);
		return -1;
	}

	/* Try to implicitly detect content type, if it's not specified */
	if(!content_type) {
		if(strstr(body->buf,"#JSGF")) {
			content_type = "application/x-jsgf";
		}
		else if(strstr(body->buf,"#ABNF")) {
			content_type = "application/srgs";
		}
		else {
			content_type = "application/srgs+xml";
		}
	}

	ast_log(LOG_NOTICE, "Load grammar name:%s type:%s path:%s '%s'\n",
				grammar_name,
				content_type,
				grammar_path,
				uni_speech_id_get(uni_speech));
	/* 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_type,content_type,mrcp_message->pool);
		mrcp_generic_header_property_add(mrcp_message,GENERIC_HEADER_CONTENT_TYPE);
		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;
}
Example #9
0
mrcp_message_t* UmcSession::CreateMrcpMessage(
    mrcp_channel_t* pMrcpChannel,
    mrcp_method_id method_id)
{
    return mrcp_application_message_create(m_pMrcpSession,pMrcpChannel,method_id);
}