Пример #1
0
/** Run demo synthesizer scenario */
static apt_bool_t synth_application_run(demo_application_t *demo_application, const char *profile)
{
	mrcp_channel_t *channel;
	/* create session */
	mrcp_session_t *session = mrcp_application_session_create(demo_application->application,profile,NULL);
	if(!session) {
		return FALSE;
	}
	
	/* create channel and associate all the required data */
	channel = synth_application_channel_create(session);
	if(!channel) {
		mrcp_application_session_destroy(session);
		return FALSE;
	}

	/* add channel to session (send asynchronous request) */
	if(mrcp_application_channel_add(session,channel) != TRUE) {
		/* session and channel are still not referenced 
		and both are allocated from session pool and will
		be freed with session destroy call */
		mrcp_application_session_destroy(session);
		return FALSE;
	}

	return TRUE;
}
Пример #2
0
bool UmcSession::AddMrcpChannel(mrcp_channel_t* pMrcpChannel)
{
    if(!m_Running)
        return false;

    return (mrcp_application_channel_add(m_pMrcpSession,pMrcpChannel) == TRUE);
}
Пример #3
0
/** \brief Send session management request to client stack and wait for async response */
static apt_bool_t uni_recog_sm_request_send(uni_speech_t *uni_speech, mrcp_sig_command_e sm_request)
{
	apt_bool_t res = FALSE;
	ast_log(LOG_DEBUG, "Send session request type:%d\n",sm_request);
	apr_thread_mutex_lock(uni_speech->mutex);
	uni_speech->is_sm_request = TRUE;
	uni_speech->sm_request = sm_request;
	switch(sm_request) {
		case MRCP_SIG_COMMAND_SESSION_UPDATE:
			res = mrcp_application_session_update(uni_speech->session);
			break;
		case MRCP_SIG_COMMAND_SESSION_TERMINATE:
			res = mrcp_application_session_terminate(uni_speech->session);
			break;
		case MRCP_SIG_COMMAND_CHANNEL_ADD:
			res = mrcp_application_channel_add(uni_speech->session,uni_speech->channel);
			break;
		case MRCP_SIG_COMMAND_CHANNEL_REMOVE:
    			res = mrcp_application_channel_remove(uni_speech->session,uni_speech->channel);
			break;
		case MRCP_SIG_COMMAND_RESOURCE_DISCOVER:
    			res = mrcp_application_resource_discover(uni_speech->session);
			break;
		default:
			break;
	}

	if(res == TRUE) {
		/* Wait for session response */
		ast_log(LOG_DEBUG, "Wait for session response\n");
		if(apr_thread_cond_timedwait(uni_speech->wait_object,uni_speech->mutex,MRCP_APP_REQUEST_TIMEOUT) != APR_SUCCESS) {
		    ast_log(LOG_ERROR, "Failed to get response, request timed out\n");
		    uni_speech->sm_response = MRCP_SIG_STATUS_CODE_FAILURE;
		}
		ast_log(LOG_DEBUG, "Waked up, status code: %d\n",uni_speech->sm_response);
	}
	
	uni_speech->is_sm_request = FALSE;
	apr_thread_mutex_unlock(uni_speech->mutex);
	return res;
}
Пример #4
0
/** Create ASR session */
ASR_CLIENT_DECLARE(asr_session_t*) asr_session_create(asr_engine_t *engine, const char *profile)
{
	mpf_termination_t *termination;
	mrcp_channel_t *channel;
	mrcp_session_t *session;
	const mrcp_app_message_t *app_message;
	apr_pool_t *pool;
	asr_session_t *asr_session;
	mpf_stream_capabilities_t *capabilities;

	/* create session */
	session = mrcp_application_session_create(engine->mrcp_app,profile,NULL);
	if(!session) {
		return NULL;
	}
	pool = mrcp_application_session_pool_get(session);

	asr_session = apr_palloc(pool,sizeof(asr_session_t));
	mrcp_application_session_object_set(session,asr_session);
	
	/* create source stream capabilities */
	capabilities = mpf_source_stream_capabilities_create(pool);
	/* add codec capabilities (Linear PCM) */
	mpf_codec_capabilities_add(
			&capabilities->codecs,
			MPF_SAMPLE_RATE_8000,
			"LPCM");

	termination = mrcp_application_audio_termination_create(
			session,                   /* session, termination belongs to */
			&audio_stream_vtable,      /* virtual methods table of audio stream */
			capabilities,              /* capabilities of audio stream */
			asr_session);            /* object to associate */

	channel = mrcp_application_channel_create(
			session,                   /* session, channel belongs to */
			MRCP_RECOGNIZER_RESOURCE,  /* MRCP resource identifier */
			termination,               /* media termination, used to terminate audio stream */
			NULL,                      /* RTP descriptor, used to create RTP termination (NULL by default) */
			asr_session);              /* object to associate */

	if(!channel) {
		mrcp_application_session_destroy(session);
		return NULL;
	}
	
	asr_session->engine = engine;
	asr_session->mrcp_session = session;
	asr_session->mrcp_channel = channel;
	asr_session->recog_complete = NULL;
	asr_session->input_mode = INPUT_MODE_NONE;
	asr_session->streaming = FALSE;
	asr_session->audio_in = NULL;
	asr_session->media_buffer = NULL;
	asr_session->mutex = NULL;
	asr_session->wait_object = NULL;
	asr_session->app_message = NULL;

	/* Create cond wait object and mutex */
	apr_thread_mutex_create(&asr_session->mutex,APR_THREAD_MUTEX_DEFAULT,pool);
	apr_thread_cond_create(&asr_session->wait_object,pool);

	/* Create media buffer */
	asr_session->media_buffer = mpf_frame_buffer_create(160,20,pool);

	/* Send add channel request and wait for the response */
	apr_thread_mutex_lock(asr_session->mutex);
	app_message = NULL;
	if(mrcp_application_channel_add(asr_session->mrcp_session,asr_session->mrcp_channel) == TRUE) {
		apr_thread_cond_wait(asr_session->wait_object,asr_session->mutex);
		app_message = asr_session->app_message;
		asr_session->app_message = NULL;
	}
	apr_thread_mutex_unlock(asr_session->mutex);

	if(sig_response_check(app_message) == FALSE) {
		asr_session_destroy_ex(asr_session,TRUE);
		return NULL;
	}
	return asr_session;
}
Пример #5
0
int main(int argc, char const* argv[])
{
	apr_pool_t* pool = NULL;
	apr_pool_t* spool = NULL;
	int i;
	struct iovec cattext[101];
	static char const SP = ' ';
	char const* outfile;
	apr_status_t status;
	apt_dir_layout_t* dirLayout = NULL;
	mrcp_client_t* client = NULL;
	mrcp_application_t* app = NULL;
	mrcp_session_t* sess = NULL;
	mpf_stream_capabilities_t* caps = NULL;
	mpf_termination_t* term = NULL;
	mrcp_channel_t* chan = NULL;
	struct stat info;

	if (argc < 2) {
		puts("Usage:");
		printf("\t%s \"This is a synthetic voice.\"", argv[0]);
		exit(1);
	}

	/* Just detect various directory layout constellations */
	if (stat(ROOT_DIR, &info))
		ROOT_DIR = ROOT_DIR2;
	if (stat(ROOT_DIR, &info))
		ROOT_DIR = ROOT_DIR3;

	/* Initialize platform first */
	if (apr_initialize() != APR_SUCCESS) FAIL("Cannot initialize APR platform");
	pool = apt_pool_create();
	if (!pool) FAIL("Not enough memory");
	for (i = 0; (i < argc - 2) && (i < 50); i += 2) {
		cattext[2 * i].iov_base = (void*) argv[i + 1];
		cattext[2 * i].iov_len = strlen(argv[i + 1]);
		cattext[2 * i + 1].iov_base = (void*) &SP;
		cattext[2 * i + 1].iov_len = 1;
	}
	cattext[2 * i].iov_base = (void*) argv[i + 1];
	cattext[2 * i].iov_len = strlen(argv[i + 1]);
	text = apr_pstrcatv(pool, cattext, 2 * i + 1, NULL);
	if (!text) FAIL("Not enough memory");
	outfile = apr_pstrcat(pool, ROOT_DIR, "/data/", PCM_OUT_FILE, NULL);
	
	printf("This is a sample C UniMRCP client synthesizer scenario.\n");
	printf("Use client configuration from %s/conf/unimrcpclient.xml\n", ROOT_DIR);
	printf("Use profile %s\n", MRCP_PROFILE);
	printf("Synthesize text: `%s'\n", text);
	printf("Write output to file: %s\n", outfile);
	printf("\n");
	printf("Press enter to start the session...\n");
	(void) getchar();

	apt_log_instance_create(APT_LOG_OUTPUT_NONE, APT_PRIO_DEBUG, pool);
	apt_log_ext_handler_set(UniSynth_logger);
	dirLayout = apt_default_dir_layout_create(ROOT_DIR, pool);

	/* Create and start the client in a root dir */
	client = unimrcp_client_create(dirLayout);
	if (!client) FAIL("Cannot create UniMRCP client");
	app = mrcp_application_create(UniSynthAppMsgHandler, NULL, mrcp_client_memory_pool_get(client));
	if (!app) FAIL("Cannot create MRCP application");
	if (!mrcp_client_application_register(client, app, "Sample C app"))
		FAIL("Cannot register MRCP application");
	if (!mrcp_client_start(client)) FAIL("Cannot start MRCP client");

	/* Create a session using MRCP profile MRCP_PROFILE */
	sess = mrcp_application_session_create(app, MRCP_PROFILE, NULL);
	if (!sess) FAIL("Cannot create session");
	spool = mrcp_application_session_pool_get(sess);
	/* Create audio termination with capabilities */
	caps = mpf_stream_capabilities_create(STREAM_DIRECTION_SEND, spool);
	if (!caps) FAIL("Error creating capabilities");
	if (!mpf_codec_capabilities_add(&caps->codecs, MPF_SAMPLE_RATE_8000, "LPCM"))
		FAIL("Error adding codec capabilities");
	term = mrcp_application_audio_termination_create(sess, &stream_vtable, caps, NULL);
	if (!term) FAIL("Cannot create audio termination");
	/* Add signaling channel (and start processing in OnAdd method */
	f = fopen(outfile, "wb");
	if (!f) FAIL("Cannot open output file");
	status = apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_DEFAULT, pool);
	if (status != APR_SUCCESS) FAIL("Cannot create mutex");
	status = apr_thread_cond_create(&cond, pool);
	if (status != APR_SUCCESS) FAIL("Cannot create condition variable");
	chan = mrcp_application_channel_create(sess, MRCP_SYNTHESIZER_RESOURCE, term, NULL, NULL);
	if (!chan) FAIL("Cannot create channel");
	if (!mrcp_application_channel_add(sess, chan))
		FAIL("Cannot add channel");

	/* Now wait until the processing finishes */
	apr_thread_mutex_lock(mutex);
	while (err < 0) apr_thread_cond_wait(cond, mutex);
	apr_thread_mutex_unlock(mutex);

cleanup:
	if (sess) mrcp_application_session_terminate(sess);
	if (f) fclose(f);
	if (client) mrcp_client_shutdown(client);
	if (app) mrcp_application_destroy(app);
	if (client) mrcp_client_destroy(client);
	apt_log_instance_destroy();
	if (pool) apr_pool_destroy(pool);
	apr_terminate();
	puts("Program finished, memory released. Press any key to exit.");
	(void) getchar();
	return err;
}
Пример #6
0
/* Open the speech channel. */
int speech_channel_open(speech_channel_t *schannel, ast_mrcp_profile_t *profile)
{
	int status = 0;
	mpf_termination_t *termination = NULL;
	mrcp_resource_type_e resource_type;

	if ((schannel == NULL) || (profile == NULL))
		return -1;

	if (schannel->mutex != NULL)
		apr_thread_mutex_lock(schannel->mutex);

	/* Make sure we can open channel. */
	if (schannel->state != SPEECH_CHANNEL_CLOSED) {
		if (schannel->mutex != NULL)
			apr_thread_mutex_unlock(schannel->mutex);

		return -1;
	}

	schannel->profile = profile;

	/* Create MRCP session. */
	if ((schannel->unimrcp_session = mrcp_application_session_create(schannel->application->app, profile->name, schannel)) == NULL) {
		/* Profile doesn't exist? */
		ast_log(LOG_ERROR, "(%s) Unable to create session with %s\n", schannel->name, profile->name);

		if (schannel->mutex != NULL)
			apr_thread_mutex_unlock(schannel->mutex);

		return 2;
	}
	
	/* Set session name for logging purposes. */
	mrcp_application_session_name_set(schannel->unimrcp_session, schannel->name);

	/* Create audio termination and add to channel. */
	if ((termination = speech_channel_create_mpf_termination(schannel)) == NULL) {
		ast_log(LOG_ERROR, "(%s) Unable to create termination with %s\n", schannel->name, profile->name);

		if (!mrcp_application_session_destroy(schannel->unimrcp_session))
			ast_log(LOG_WARNING, "(%s) Unable to destroy application session for %s\n", schannel->name, profile->name);

		if (schannel->mutex != NULL)
			apr_thread_mutex_unlock(schannel->mutex);

		return -1;
	}

	if (schannel->type == SPEECH_CHANNEL_SYNTHESIZER)
		resource_type = MRCP_SYNTHESIZER_RESOURCE;
	else
		resource_type = MRCP_RECOGNIZER_RESOURCE;

	if ((schannel->unimrcp_channel = mrcp_application_channel_create(schannel->unimrcp_session, resource_type, termination, NULL, schannel)) == NULL) {
		ast_log(LOG_ERROR, "(%s) Unable to create channel with %s\n", schannel->name, profile->name);

		if (!mrcp_application_session_destroy(schannel->unimrcp_session))
			ast_log(LOG_WARNING, "(%s) Unable to destroy application session for %s\n", schannel->name, profile->name);

		if (schannel->mutex != NULL)
			apr_thread_mutex_unlock(schannel->mutex);

		return -1;
	}

	/* Add channel to session. This establishes the connection to the MRCP server. */
	if (mrcp_application_channel_add(schannel->unimrcp_session, schannel->unimrcp_channel) != TRUE) {
		ast_log(LOG_ERROR, "(%s) Unable to add channel to session with %s\n", schannel->name, profile->name);

		if (!mrcp_application_session_destroy(schannel->unimrcp_session))
			ast_log(LOG_WARNING, "(%s) Unable to destroy application session for %s\n", schannel->name, profile->name);

		if (schannel->mutex != NULL)
			apr_thread_mutex_unlock(schannel->mutex);

		return -1;
	}

	/* Wait for channel to be ready. */
	while ((schannel->mutex != NULL) && (schannel->cond != NULL) && (schannel->state == SPEECH_CHANNEL_CLOSED))
		apr_thread_cond_timedwait(schannel->cond, schannel->mutex, SPEECH_CHANNEL_TIMEOUT_USEC);

	if (schannel->state == SPEECH_CHANNEL_READY) {
		ast_log(LOG_DEBUG, "(%s) channel is ready\n", schannel->name);
	} else if (schannel->state == SPEECH_CHANNEL_CLOSED) {
		ast_log(LOG_ERROR, "(%s) Timed out waiting for channel to be ready\n", schannel->name);
		/* Can't retry. */
		status = -1;
	} else if (schannel->state == SPEECH_CHANNEL_ERROR) {
		/* Wait for session to be cleaned up. */
		if (schannel->cond != NULL)
			apr_thread_cond_timedwait(schannel->cond, schannel->mutex, SPEECH_CHANNEL_TIMEOUT_USEC);

		if (schannel->state != SPEECH_CHANNEL_CLOSED) {
			/* Major issue. Can't retry. */
			status = -1;
		} else {
			/* Failed to open profile, retry is allowed. */
			status = 2;
		}
	}

	if (schannel->type == SPEECH_CHANNEL_RECOGNIZER) {
		recognizer_data_t *r = (recognizer_data_t *)apr_palloc(schannel->pool, sizeof(recognizer_data_t));

		if (r != NULL) {
			schannel->data = r;
			memset(r, 0, sizeof(recognizer_data_t));

			if ((r->grammars = apr_hash_make(schannel->pool)) == NULL) {
				ast_log(LOG_ERROR, "Unable to allocate hash for grammars\n");
				status = -1;
			}
		} else {
			ast_log(LOG_ERROR, "Unable to allocate recognizer data structure\n");
			status = -1;
		}
	}

	if (schannel->mutex != NULL)
		apr_thread_mutex_unlock(schannel->mutex);

	return status;
}