Exemple #1
0
/* Handle the UniMRCP responses sent to channel add requests. */
static apt_bool_t speech_on_channel_add(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_sig_status_code_e status)
{
	speech_channel_t *schannel;

	if (channel != NULL)
		schannel = (speech_channel_t *)mrcp_application_channel_object_get(channel);
	else
		schannel = NULL;

	ast_log(LOG_DEBUG, "(%s) speech_on_channel_add\n", schannel->name);

	if ((schannel != NULL) && (application != NULL) && (session != NULL) && (channel != NULL)) {
		if ((session != NULL) && (status == MRCP_SIG_STATUS_CODE_SUCCESS)) {
			const mpf_codec_descriptor_t *descriptor = descriptor = mrcp_application_sink_descriptor_get(channel);
			if (!descriptor) {
				ast_log(LOG_ERROR, "(%s) Unable to determine codec descriptor\n", schannel->name);
				speech_channel_set_state(schannel, SPEECH_CHANNEL_ERROR);
				ast_log(LOG_DEBUG, "(%s) Terminating MRCP session\n", schannel->name);
				if (!mrcp_application_session_terminate(session))
					ast_log(LOG_WARNING, "(%s) Unable to terminate application session\n", schannel->name);
				return FALSE;
			}

			schannel->rate = descriptor->sampling_rate;
			const char *codec_name = NULL;
			if (descriptor->name.length > 0)
				codec_name = descriptor->name.buf;
			else
				codec_name = "unknown";

			ast_log(LOG_NOTICE, "(%s) Channel ready, codec=%s, sample rate=%d\n",
				schannel->name,
				codec_name,
				schannel->rate);
			speech_channel_set_state(schannel, SPEECH_CHANNEL_READY);
		} else {
			ast_log(LOG_ERROR, "(%s) Channel error!\n", schannel->name);

			if (session != NULL) {
				ast_log(LOG_DEBUG, "(%s) Terminating MRCP session\n", schannel->name);
				speech_channel_set_state(schannel, SPEECH_CHANNEL_ERROR);

				if (!mrcp_application_session_terminate(session))
					ast_log(LOG_WARNING, "(%s) Unable to terminate application session\n", schannel->name);
			}
		}
	} else
		ast_log(LOG_ERROR, "(unknown) channel error!\n");

	return TRUE;
}
/** Destroy ASR session */
static apt_bool_t asr_session_destroy_ex(asr_session_t *asr_session, apt_bool_t terminate)
{
	if(terminate == TRUE) {
		apr_thread_mutex_lock(asr_session->mutex);
		if(mrcp_application_session_terminate(asr_session->mrcp_session) == TRUE) {
			apr_thread_cond_wait(asr_session->wait_object,asr_session->mutex);
			/* the response must be checked to be the valid one */
		}
		apr_thread_mutex_unlock(asr_session->mutex);
	}

	if(asr_session->audio_in) {
		fclose(asr_session->audio_in);
		asr_session->audio_in = NULL;
	}

	if(asr_session->mutex) {
		apr_thread_mutex_destroy(asr_session->mutex);
		asr_session->mutex = NULL;
	}
	if(asr_session->wait_object) {
		apr_thread_cond_destroy(asr_session->wait_object);
		asr_session->wait_object = NULL;
	}
	if(asr_session->media_buffer) {
		mpf_frame_buffer_destroy(asr_session->media_buffer);
		asr_session->media_buffer = NULL;
	}
	
	return mrcp_application_session_destroy(asr_session->mrcp_session);
}
/** Handle the responses sent to channel add requests */
static apt_bool_t synth_application_on_channel_add(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_sig_status_code_e status)
{
	synth_app_channel_t *synth_channel = mrcp_application_channel_object_get(channel);
	if(status == MRCP_SIG_STATUS_CODE_SUCCESS) {
		mrcp_message_t *mrcp_message;
		const apt_dir_layout_t *dir_layout = mrcp_application_dir_layout_get(application);
		/* create and send SPEAK request */
		mrcp_message = demo_speak_message_create(session,channel,dir_layout);
		if(mrcp_message) {
			mrcp_application_message_send(session,channel,mrcp_message);
		}

		if(synth_channel && session) {
			char *file_name = apr_pstrcat(session->pool,"synth-",session->id.buf,".pcm",NULL);
			char *file_path = apt_datadir_filepath_get(dir_layout,file_name,session->pool);
			if(file_path) {
				synth_channel->audio_out = fopen(file_path,"wb");
			}
		}
	}
	else {
		/* error case, just terminate the demo */
		mrcp_application_session_terminate(session);
	}
	return TRUE;
}
/** Handle the responses sent to channel add requests */
static apt_bool_t demo_application_on_channel_add(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_sig_status_code_e status)
{
	if(status == MRCP_SIG_STATUS_CODE_SUCCESS) {
		mpf_rtp_termination_descriptor_t *rtp_descriptor;
		mrcp_message_t *mrcp_message;
		const apt_dir_layout_t *dir_layout = mrcp_application_dir_layout_get(application);
		/* create and send SPEAK request */
		mrcp_message = demo_speak_message_create(session,channel,dir_layout);
		if(mrcp_message) {
			mrcp_application_message_send(session,channel,mrcp_message);
		}
		rtp_descriptor = mrcp_application_rtp_descriptor_get(channel);
		if(rtp_descriptor) {
			mpf_rtp_media_descriptor_t *local_media = rtp_descriptor->audio.local;
			mpf_rtp_media_descriptor_t *remote_media = rtp_descriptor->audio.remote;
			if(local_media && remote_media) {
				apt_log(APT_PRIO_INFO,"Media Attributes: L[%s/%d] R[%s/%d]",
					local_media->base.ip.buf,
					local_media->base.port,
					remote_media->base.ip.buf,
					remote_media->base.port);
			}
		}
	}
	else {
		/* error case, just terminate the demo */
		mrcp_application_session_terminate(session);
	}
	return TRUE;
}
Exemple #5
0
/* Handle the UniMRCP responses sent to channel remove requests. */
static apt_bool_t speech_on_channel_remove(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_sig_status_code_e status)
{
	speech_channel_t *schannel;

	if (channel != NULL)
		schannel = (speech_channel_t *)mrcp_application_channel_object_get(channel);
	else
		schannel = NULL;

	ast_log(LOG_DEBUG, "(%s) speech_on_channel_remove\n", schannel->name);

	if (schannel != NULL) {
		ast_log(LOG_NOTICE, "(%s) Channel removed\n", schannel->name);
		schannel->unimrcp_channel = NULL;

		if (session != NULL) {
			ast_log(LOG_DEBUG, "(%s) Terminating MRCP session\n", schannel->name);

			if (!mrcp_application_session_terminate(session))
				ast_log(LOG_WARNING, "(%s) Unable to terminate application session\n", schannel->name);
		}
	} else
		ast_log(LOG_ERROR, "(unknown) channel error!\n");

	return TRUE;
}
Exemple #6
0
bool UmcSession::Terminate()
{
    if(m_Terminating)
        return false;

    m_Running = false;
    m_Terminating = true;
    return (mrcp_application_session_terminate(m_pMrcpSession) == TRUE);
}
/** Handle the responses sent to channel add requests */
static apt_bool_t synth_application_on_channel_add(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_sig_status_code_e status)
{
	if(status == MRCP_SIG_STATUS_CODE_SUCCESS) {
		mrcp_message_t *mrcp_message;
		synth_app_channel_t *synth_channel = mrcp_application_channel_object_get(channel);
		apr_pool_t *pool = mrcp_application_session_pool_get(session);
		const apt_dir_layout_t *dir_layout = mrcp_application_dir_layout_get(application);
		const mpf_codec_descriptor_t *descriptor = mrcp_application_sink_descriptor_get(channel);
		if(!descriptor) {
			/* terminate the demo */
			apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Get Media Sink Descriptor");
			return mrcp_application_session_terminate(session);
		}

		/* create and send SPEAK request */
		mrcp_message = demo_speak_message_create(session,channel,dir_layout);
		if(mrcp_message) {
			mrcp_application_message_send(session,channel,mrcp_message);
		}

		if(synth_channel) {
			const apt_str_t *id = mrcp_application_session_id_get(session);
			char *file_name = apr_psprintf(pool,"synth-%dkHz-%s.pcm",
									descriptor->sampling_rate/1000,
									id->buf);
			char *file_path = apt_datadir_filepath_get(dir_layout,file_name,pool);
			if(file_path) {
				synth_channel->audio_out = fopen(file_path,"wb");
			}
		}
	}
	else {
		/* error case, just terminate the demo */
		mrcp_application_session_terminate(session);
	}
	return TRUE;
}
/** Handle the responses sent to channel remove requests */
static apt_bool_t synth_application_on_channel_remove(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_sig_status_code_e status)
{
	synth_app_channel_t *synth_channel = mrcp_application_channel_object_get(channel);

	/* terminate the demo */
	mrcp_application_session_terminate(session);

	if(synth_channel) {
		FILE *audio_out = synth_channel->audio_out;
		if(audio_out) {
			synth_channel->audio_out = NULL;
			fclose(audio_out);
		}
	}
	return TRUE;
}
static apt_bool_t recog_application_on_channel_remove(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_sig_status_code_e status)
{
	recog_app_channel_t *recog_channel = mrcp_application_channel_object_get(channel);

	/* terminate the demo */
	mrcp_application_session_terminate(session);

	if(recog_channel) {
		FILE *audio_in = recog_channel->audio_in;
		if(audio_in) {
			recog_channel->audio_in = NULL;
			fclose(audio_in);
		}
	}
	return TRUE;
}
/** Handle the responses sent to channel add requests */
static apt_bool_t recog_application_on_channel_add(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_sig_status_code_e status)
{
	if(status == MRCP_SIG_STATUS_CODE_SUCCESS) {
		mrcp_message_t *mrcp_message;
		const apt_dir_layout_t *dir_layout = mrcp_application_dir_layout_get(application);
		/* create and send DEFINE-GRAMMAR request */
		mrcp_message = demo_define_grammar_message_create(session,channel,dir_layout);
		if(mrcp_message) {
			mrcp_application_message_send(session,channel,mrcp_message);
		}
	}
	else {
		/* error case, just terminate the demo */
		mrcp_application_session_terminate(session);
	}
	return TRUE;
}
/** \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;
}
Exemple #12
0
/** Handle the responses sent to resource discover requests */
static apt_bool_t discover_application_on_resource_discover(mrcp_application_t *application, mrcp_session_t *session, mrcp_session_descriptor_t *descriptor, mrcp_sig_status_code_e status)
{
    if(descriptor && status == MRCP_SIG_STATUS_CODE_SUCCESS) {
        int i;
        int count = descriptor->control_media_arr->nelts;
        apt_log(APT_LOG_MARK,APT_PRIO_INFO,"On Resource Discover [%d]", count);

        for(i = 0; i < count; i++) {
            mrcp_control_descriptor_t *control_media = mrcp_session_control_media_get(descriptor,i);
            if(control_media) {
                apt_log(APT_LOG_MARK,APT_PRIO_INFO,"[%d] - %s", i,control_media->resource_name.buf);
            }
        }
    }
    else {
        apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Failed to Discover Resources");
    }

    mrcp_application_session_terminate(session);
    return TRUE;
}
Exemple #13
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;
}
/** Handle the responses sent to channel remove requests */
static apt_bool_t demo_application_on_channel_remove(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_sig_status_code_e status)
{
	/* terminate the demo */
	mrcp_application_session_terminate(session);
	return TRUE;
}
Exemple #15
0
/* Destroy the speech channel. */
int speech_channel_destroy(speech_channel_t *schannel)
{
	if (schannel == NULL) {
		ast_log(LOG_ERROR, "Speech channel structure pointer is NULL\n");
		return -1;
	}
	
	ast_log(LOG_DEBUG, "Destroy speech channel: Name=%s, Type=%s, Codec=%s, Rate=%u\n", schannel->name, speech_channel_type_to_string(schannel->type), schannel->codec, schannel->rate);

	if (schannel->mutex)
		apr_thread_mutex_lock(schannel->mutex);

#if SPEECH_CHANNEL_DUMP
	if(schannel->stream_out) {
		fclose(schannel->stream_out);
		schannel->stream_out = NULL;
	}
	if(schannel->stream_in) {
		fclose(schannel->stream_in);
		schannel->stream_in = NULL;
	}
#endif

	/* Destroy the channel and session if not already done. */
	if (schannel->state != SPEECH_CHANNEL_CLOSED) {
		int warned = 0;

		if ((schannel->unimrcp_session != NULL) && (schannel->unimrcp_channel != NULL)) {
			if (!mrcp_application_session_terminate(schannel->unimrcp_session))
				ast_log(LOG_WARNING, "(%s) Unable to terminate application session\n", schannel->name);
		}

		ast_log(LOG_DEBUG, "(%s) Waiting for MRCP session to terminate\n", schannel->name);
		while (schannel->state != SPEECH_CHANNEL_CLOSED) {
			if (schannel->cond != NULL) {
				if ((apr_thread_cond_timedwait(schannel->cond, schannel->mutex, SPEECH_CHANNEL_TIMEOUT_USEC) == APR_TIMEUP) && (!warned)) {
					warned = 1;
					ast_log(LOG_WARNING, "(%s) MRCP session has not terminated after %d ms\n", schannel->name, SPEECH_CHANNEL_TIMEOUT_USEC / 1000);
				}
			}
		}
	}

	if (schannel->state != SPEECH_CHANNEL_CLOSED) {
		ast_log(LOG_ERROR, "(%s) Failed to destroy channel.  Continuing\n", schannel->name);
	}

	if (schannel->dtmf_generator != NULL) {
		mpf_dtmf_generator_destroy(schannel->dtmf_generator);
		schannel->dtmf_generator = NULL;
		ast_log(LOG_DEBUG, "(%s) DTMF generator destroyed\n", schannel->name);
	}

	if (schannel->audio_queue != NULL) {
		if (audio_queue_destroy(schannel->audio_queue) != 0)
			ast_log(LOG_WARNING, "(%s) Unable to destroy channel audio queue\n",schannel->name);
	}

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

	if (schannel->cond != NULL) {
		if (apr_thread_cond_destroy(schannel->cond) != APR_SUCCESS)
			ast_log(LOG_WARNING, "(%s) Unable to destroy channel condition variable\n", schannel->name);
	}

	if (schannel->mutex != NULL) {
		if (apr_thread_mutex_destroy(schannel->mutex) != APR_SUCCESS)
			ast_log(LOG_WARNING, "(%s) Unable to destroy channel condition variable\n", schannel->name);
	}

	schannel->name = NULL;
	schannel->profile = NULL;
	schannel->application = NULL;
	schannel->unimrcp_session = NULL;
	schannel->unimrcp_channel = NULL;
	schannel->stream = NULL;
	schannel->dtmf_generator = NULL;
	schannel->pool = NULL;
	schannel->mutex = NULL;
	schannel->cond = NULL;
	schannel->audio_queue = NULL;
	schannel->codec = NULL;
	schannel->data = NULL;
	schannel->chan = NULL;

	return 0;
}