Ejemplo n.º 1
0
bool UmcScenario::InitCapabilities(mpf_stream_capabilities_t* pCapabilities) const
{
    if(m_pCapabilities)
    {
        int i;
        mpf_codec_attribs_t *pAttribs;
        for(i=0; i<m_pCapabilities->attrib_arr->nelts; i++)
        {
            pAttribs = &APR_ARRAY_IDX(m_pCapabilities->attrib_arr,i,mpf_codec_attribs_t);
            mpf_codec_capabilities_add(
                &pCapabilities->codecs,
                pAttribs->sample_rates,
                pAttribs->name.buf);
        }
    }
    else
    {
        /* add default codec capabilities (Linear PCM) */
        mpf_codec_capabilities_add(
            &pCapabilities->codecs,
            MPF_SAMPLE_RATE_8000 | MPF_SAMPLE_RATE_16000,
            "LPCM");
    }

    return true;
}
Ejemplo n.º 2
0
bool UmcScenario::LoadCapabilities(const apr_xml_elem* pElem, apr_pool_t* pool)
{
    const apr_xml_elem* pChildElem;
    /* Load Child Elements */
    m_pCapabilities = (mpf_codec_capabilities_t*) apr_palloc(pool,sizeof(mpf_codec_capabilities_t));
    mpf_codec_capabilities_init(m_pCapabilities,1,pool);
    for(pChildElem = pElem->first_child; pChildElem; pChildElem = pChildElem->next)
    {
        if(strcasecmp(pChildElem->name,"codec") != 0)
            continue;

        const char* pName = NULL;
        const char* pRates = NULL;
        const apr_xml_attr* pAttr;
        for(pAttr = pChildElem->attr; pAttr; pAttr = pAttr->next)
        {
            if(strcasecmp(pAttr->name,"name") == 0)
            {
                pName = pAttr->value;
            }
            else if(strcasecmp(pAttr->name,"rates") == 0)
            {
                pRates = pAttr->value;
            }
        }

        if(pName)
        {
            int rates = ParseRates(pRates,pool);
            mpf_codec_capabilities_add(m_pCapabilities,rates,pName);
        }
    }
    return true;
}
Ejemplo n.º 3
0
static mpf_termination_t *speech_channel_create_mpf_termination(speech_channel_t *schannel)
{   
	mpf_termination_t *termination = NULL;
	mpf_stream_capabilities_t *capabilities = NULL;
	int sample_rates;

	if (schannel->type == SPEECH_CHANNEL_SYNTHESIZER)
		capabilities = mpf_sink_stream_capabilities_create(schannel->unimrcp_session->pool);
	else
		capabilities = mpf_source_stream_capabilities_create(schannel->unimrcp_session->pool);

	if (capabilities == NULL)
		ast_log(LOG_ERROR, "(%s) Unable to create capabilities\n", schannel->name);

	/* UniMRCP should transcode whatever the MRCP server wants to use into LPCM
	 * (host-byte ordered L16) for us. Asterisk may not support all of these.
	 */
	if (schannel->rate == 16000)
		sample_rates = MPF_SAMPLE_RATE_8000 | MPF_SAMPLE_RATE_16000;
	else if (schannel->rate == 32000)
		sample_rates = MPF_SAMPLE_RATE_8000 | MPF_SAMPLE_RATE_16000 | MPF_SAMPLE_RATE_32000;
	else if (schannel->rate == 48000)
		sample_rates = MPF_SAMPLE_RATE_8000 | MPF_SAMPLE_RATE_16000 | MPF_SAMPLE_RATE_48000;
	else
		sample_rates = MPF_SAMPLE_RATE_8000;

	/* TO DO : Check if all of these are supported on Asterisk for all codecs. */
	if (strcasecmp(schannel->codec, "L16") == 0)
		mpf_codec_capabilities_add(&capabilities->codecs, sample_rates, "LPCM");
	else
		mpf_codec_capabilities_add(&capabilities->codecs, sample_rates, schannel->codec);

	termination = mrcp_application_audio_termination_create(
					schannel->unimrcp_session,                        /* Session, termination belongs to. */
					&schannel->application->audio_stream_vtable,      /* Virtual methods table of audio stream. */
					capabilities,                                     /* Capabilities of audio stream. */
					schannel);                                        /* Object to associate. */

	if (termination == NULL)
		ast_log(LOG_ERROR, "(%s) Unable to create termination\n", schannel->name);

	return termination;
}
Ejemplo n.º 4
0
/** Create demo recognizer channel */
static mrcp_channel_t* recog_application_channel_create(mrcp_session_t *session)
{
	mrcp_channel_t *channel;
	mpf_termination_t *termination;
	mpf_stream_capabilities_t *capabilities;

	/* create channel */
	recog_app_channel_t *recog_channel = apr_palloc(session->pool,sizeof(recog_app_channel_t));
	recog_channel->streaming = FALSE;
	recog_channel->audio_in = NULL;
	recog_channel->time_to_complete = 0;

	/* create source stream capabilities */
	capabilities = mpf_source_stream_capabilities_create(session->pool);

	/* add codec capabilities (Linear PCM) */
	mpf_codec_capabilities_add(
			&capabilities->codecs,
			MPF_SAMPLE_RATE_8000 | MPF_SAMPLE_RATE_16000,
			"LPCM");

#if 0
	/* more capabilities can be added or replaced */
	mpf_codec_capabilities_add(
			&capabilities->codecs,
			MPF_SAMPLE_RATE_8000 | MPF_SAMPLE_RATE_16000,
			"PCMU");
#endif

	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 */
			recog_channel);            /* 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) */
			recog_channel);            /* object to associate */
	return channel;
}
/** Create demo synthesizer channel */
static mrcp_channel_t* synth_application_channel_create(mrcp_session_t *session)
{
	mrcp_channel_t *channel;
	mpf_termination_t *termination;
	mpf_stream_capabilities_t *capabilities;
	apr_pool_t *pool = mrcp_application_session_pool_get(session);

	/* create channel */
	synth_app_channel_t *synth_channel = apr_palloc(pool,sizeof(synth_app_channel_t));
	synth_channel->audio_out = NULL;

	/* create sink stream capabilities */
	capabilities = mpf_sink_stream_capabilities_create(pool);

	/* add codec capabilities (Linear PCM) */
	mpf_codec_capabilities_add(
			&capabilities->codecs,
			MPF_SAMPLE_RATE_8000 | MPF_SAMPLE_RATE_16000,
			"LPCM");

#if 0
	/* more capabilities can be added or replaced */
	mpf_codec_capabilities_add(
			&capabilities->codecs,
			MPF_SAMPLE_RATE_8000 | MPF_SAMPLE_RATE_16000,
			"PCMU");
#endif

	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 */
			synth_channel);            /* object to associate */
	
	channel = mrcp_application_channel_create(
			session,                   /* session, channel belongs to */
			MRCP_SYNTHESIZER_RESOURCE, /* MRCP resource identifier */
			termination,               /* media termination, used to terminate audio stream */
			NULL,                      /* RTP descriptor, used to create RTP termination (NULL by default) */
			synth_channel);            /* object to associate */
	return channel;
}
Ejemplo n.º 6
0
/** Create engine channel and sink media termination */
mrcp_engine_channel_t* mrcp_engine_sink_channel_create(
							mrcp_engine_t *engine,
							const mrcp_engine_channel_method_vtable_t *channel_vtable,
							const mpf_audio_stream_vtable_t *stream_vtable,
							void *method_obj,
							mpf_codec_descriptor_t *codec_descriptor,
							apr_pool_t *pool)
{
	mpf_stream_capabilities_t *capabilities;
	mpf_audio_stream_t *audio_stream;
	mpf_termination_t *termination;

	capabilities = mpf_sink_stream_capabilities_create(pool);
	if(codec_descriptor) {
		mpf_codec_capabilities_add(
						&capabilities->codecs,
						mpf_sample_rate_mask_get(codec_descriptor->sampling_rate),
						codec_descriptor->name.buf);
	}
	else {
		mpf_codec_default_capabilities_add(&capabilities->codecs);
	}

	/* create audio stream */
	audio_stream = mpf_audio_stream_create(
			method_obj,             /* object to associate */
			stream_vtable,          /* virtual methods table of audio stream */
			capabilities,           /* stream capabilities */
			pool);                  /* pool to allocate memory from */

	if(!audio_stream) {
		return NULL;
	}

	audio_stream->tx_descriptor = codec_descriptor;
	
	/* create media termination */
	termination = mpf_raw_termination_create(
			NULL,            /* no object to associate */
			audio_stream,    /* audio stream */
			NULL,            /* no video stream */
			pool);           /* pool to allocate memory from */

	/* create engine channel base */
	return mrcp_engine_channel_create(
			engine,          /* engine */
			channel_vtable,  /* virtual methods table of engine channel */
			method_obj,      /* object to associate */
			termination,     /* media termination, used to terminate audio stream */
			pool);           /* pool to allocate memory from */
}
Ejemplo n.º 7
0
/** Create demo synthesizer channel derived from engine channel base */
static mrcp_engine_channel_t* mrcp_swift_engine_channel_create(mrcp_engine_t *engine, apr_pool_t *pool)
{
	mrcp_swift_engine_t *synth_engine = engine->obj;

	mpf_stream_capabilities_t *capabilities;
	mpf_termination_t *termination; 
	mrcp_engine_channel_t *channel;

	/* create swift synth channel */
	mrcp_swift_channel_t *synth_channel = apr_palloc(pool,sizeof(mrcp_swift_channel_t));
	synth_channel->port = NULL;
	synth_channel->tts_stream = 0;
	synth_channel->channel = NULL;
	synth_channel->audio_buffer = NULL;
	synth_channel->speak_request = NULL;
	synth_channel->stop_response = NULL;
	synth_channel->paused = FALSE;

	capabilities = mpf_source_stream_capabilities_create(pool);
	mpf_codec_capabilities_add(
			&capabilities->codecs,
			synth_engine->sample_rates,
			"LPCM");

	/* create media termination */
	termination = mrcp_engine_audio_termination_create(
			synth_channel,        /* object to associate */
			&audio_stream_vtable, /* virtual methods table of audio stream */
			capabilities,         /* stream capabilities */
			pool);                /* pool to allocate memory from */

	/* create engine channel base */
	channel = mrcp_engine_channel_create(
			engine,               /* engine */
			&channel_vtable,      /* virtual methods table of engine channel */
			synth_channel,        /* object to associate */
			termination,          /* associated media termination */
			pool);                /* pool to allocate memory from */

	if(channel) {
		synth_channel->audio_buffer = mpf_buffer_create(pool);
	}
	synth_channel->channel = channel;
	return channel;
}
Ejemplo n.º 8
0
/** Create source media termination */
MRCP_DECLARE(mpf_termination_t*) mrcp_application_source_termination_create(
										mrcp_session_t *session,
										const mpf_audio_stream_vtable_t *stream_vtable,
										mpf_codec_descriptor_t *codec_descriptor,
										void *obj)
{
	mpf_stream_capabilities_t *capabilities;
	mpf_audio_stream_t *audio_stream;

	capabilities = mpf_source_stream_capabilities_create(session->pool);
	if(codec_descriptor) {
		mpf_codec_capabilities_add(
						&capabilities->codecs,
						mpf_sample_rate_mask_get(codec_descriptor->sampling_rate),
						codec_descriptor->name.buf);
	}
	else {
		mpf_codec_default_capabilities_add(&capabilities->codecs);
	}

	/* create audio stream */
	audio_stream = mpf_audio_stream_create(
			obj,                  /* object to associate */
			stream_vtable,        /* virtual methods table of audio stream */
			capabilities,         /* stream capabilities */
			session->pool);       /* memory pool to allocate memory from */

	if(!audio_stream) {
		return NULL;
	}

	audio_stream->rx_descriptor = codec_descriptor;

	/* create raw termination */
	return mpf_raw_termination_create(
			NULL,                 /* no object to associate */
			audio_stream,         /* audio stream */
			NULL,                 /* no video stream */
			session->pool);       /* memory pool to allocate memory from */
}
Ejemplo n.º 9
0
static mrcp_engine_channel_t* recorder_engine_channel_create(mrcp_engine_t *engine, apr_pool_t *pool)
{
	mpf_stream_capabilities_t *capabilities;
	mpf_termination_t *termination; 

	/* create recorder channel */
	recorder_channel_t *recorder_channel = apr_palloc(pool,sizeof(recorder_channel_t));
	recorder_channel->record_request = NULL;
	recorder_channel->stop_response = NULL;
	recorder_channel->detector = mpf_activity_detector_create(pool);
	recorder_channel->max_time = 0;
	recorder_channel->cur_time = 0;
	recorder_channel->cur_size = 0;
	recorder_channel->file_name = NULL;
	recorder_channel->audio_out = NULL;

	capabilities = mpf_sink_stream_capabilities_create(pool);
	mpf_codec_capabilities_add(
			&capabilities->codecs,
			MPF_SAMPLE_RATE_8000 | MPF_SAMPLE_RATE_16000,
			"LPCM");

	/* create media termination */
	termination = mrcp_engine_audio_termination_create(
			recorder_channel,     /* object to associate */
			&audio_stream_vtable, /* virtual methods table of audio stream */
			capabilities,         /* stream capabilities */
			pool);                /* pool to allocate memory from */

	/* create engine channel base */
	recorder_channel->channel = mrcp_engine_channel_create(
			engine,               /* engine */
			&channel_vtable,      /* virtual methods table of engine channel */
			recorder_channel,     /* object to associate */
			termination,          /* associated media termination */
			pool);                /* pool to allocate memory from */

	return recorder_channel->channel;
}
Ejemplo n.º 10
0
/** Create demo synthesizer channel derived from engine channel base */
static mrcp_engine_channel_t* demo_synth_engine_channel_create(mrcp_engine_t *engine, apr_pool_t *pool)
{
	mpf_stream_capabilities_t *capabilities;
	mpf_termination_t *termination; 

	/* create demo synth channel */
	demo_synth_channel_t *synth_channel = apr_palloc(pool,sizeof(demo_synth_channel_t));
	synth_channel->demo_engine = engine->obj;
	synth_channel->speak_request = NULL;
	synth_channel->stop_response = NULL;
	synth_channel->time_to_complete = 0;
	synth_channel->paused = FALSE;
	synth_channel->audio_file = NULL;
	
	capabilities = mpf_source_stream_capabilities_create(pool);
	mpf_codec_capabilities_add(
			&capabilities->codecs,
			MPF_SAMPLE_RATE_8000 | MPF_SAMPLE_RATE_16000,
			"LPCM");

	/* create media termination */
	termination = mrcp_engine_audio_termination_create(
			synth_channel,        /* object to associate */
			&audio_stream_vtable, /* virtual methods table of audio stream */
			capabilities,         /* stream capabilities */
			pool);                /* pool to allocate memory from */

	/* create engine channel base */
	synth_channel->channel = mrcp_engine_channel_create(
			engine,               /* engine */
			&channel_vtable,      /* virtual methods table of engine channel */
			synth_channel,        /* object to associate */
			termination,          /* associated media termination */
			pool);                /* pool to allocate memory from */

	return synth_channel->channel;
}
Ejemplo n.º 11
0
/** \brief Create recognition channel */
static apt_bool_t uni_recog_channel_create(uni_speech_t *uni_speech, ast_format_compat *format)
{
	mrcp_channel_t *channel;
	mpf_termination_t *termination;
	mpf_stream_capabilities_t *capabilities;
	apr_pool_t *pool = mrcp_application_session_pool_get(uni_speech->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");

	/* Create media termination */
	termination = mrcp_application_audio_termination_create(
			uni_speech->session,      /* session, termination belongs to */
			&audio_stream_vtable,     /* virtual methods table of audio stream */
			capabilities,             /* stream capabilities */
			uni_speech);              /* object to associate */
	
	/* Create MRCP channel */
	channel = mrcp_application_channel_create(
			uni_speech->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) */
			uni_speech);              /* object to associate */

	if(!channel) {
		return FALSE;
	}
	uni_speech->channel = channel;
	return TRUE;
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
0
/** Add default (liear PCM) capabilities */
MPF_DECLARE(apt_bool_t) mpf_codec_default_capabilities_add(mpf_codec_capabilities_t *capabilities)
{
    return mpf_codec_capabilities_add(capabilities,MPF_SAMPLE_RATE_8000,lpcm_attribs.name.buf);
}
Ejemplo n.º 14
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;
}