Esempio n. 1
0
/* Create the audio queue. */
int audio_queue_create(audio_queue_t **audio_queue, const char *name)
{
	int status = 0;
	audio_queue_t *laudio_queue = NULL;
	char *lname = "";
	apr_pool_t *pool;

	if (audio_queue == NULL)
		return -1;
	else
		*audio_queue = NULL;

	if ((pool = apt_pool_create()) == NULL)
		return -1;

	if ((name == NULL) || (strlen(name) == 0))
		lname = "";
	else
		lname = apr_pstrdup(pool, name);
	if (lname == NULL)
		lname = "";

	if ((laudio_queue = (audio_queue_t *)apr_palloc(pool, sizeof(audio_queue_t))) == NULL) {
		ast_log(LOG_ERROR, "(%s) Unable to create audio queue\n", lname);
		return -1;
	} else {
		laudio_queue->buffer = NULL;
		laudio_queue->cond = NULL;
		laudio_queue->mutex = NULL;
		laudio_queue->name = lname;
		laudio_queue->pool = pool;
		laudio_queue->read_bytes = 0;
		laudio_queue->waiting = 0;
		laudio_queue->write_bytes = 0;

		if (audio_buffer_create(&laudio_queue->buffer, AUDIO_QUEUE_SIZE) != 0) {
			ast_log(LOG_ERROR, "(%s) Unable to create audio queue buffer\n", laudio_queue->name);
			status = -1;
		} else if (apr_thread_mutex_create(&laudio_queue->mutex, APR_THREAD_MUTEX_UNNESTED, pool) != APR_SUCCESS) {
			ast_log(LOG_ERROR, "(%s) Unable to create audio queue mutex\n", laudio_queue->name);
			status = -1;
		} else if (apr_thread_cond_create(&laudio_queue->cond, pool) != APR_SUCCESS) {
			ast_log(LOG_ERROR, "(%s) Unable to create audio queue condition variable\n", laudio_queue->name);
			status = -1;
		} else {
			*audio_queue = laudio_queue;
			ast_log(LOG_DEBUG, "(%s) Audio queue created\n", laudio_queue->name);
		}
	}

	if (status != 0)
		audio_queue_destroy(laudio_queue);

	return status;
}
Esempio n. 2
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;
}
Esempio n. 3
0
speech_channel_t *speech_channel_create(apr_pool_t *pool, const char *name, speech_channel_type_t type, ast_mrcp_application_t *app, const char *codec, apr_uint16_t rate, struct ast_channel *chan)
{
	speech_channel_t *schan = NULL;
	int status = 0;

	if (app == NULL) {
		ast_log(LOG_ERROR, "MRCP application is NULL\n");
		status = -1;
	} else if (pool == NULL) {
		ast_log(LOG_ERROR, "Memory pool is NULL\n");
		status = -1;
	} else if ((schan = (speech_channel_t *)apr_palloc(pool, sizeof(speech_channel_t))) == NULL) {
		ast_log(LOG_ERROR, "Unable to allocate speech channel structure\n");
		status = -1;
	} else {
		if ((name == NULL) || (strlen(name) == 0)) {
			ast_log(LOG_WARNING, "No name specified, assuming \"TTS\"\n");
			schan->name = "TTS";
		} else
			schan->name = apr_pstrdup(pool, name);
		if ((schan->name == NULL) || (strlen(schan->name) == 0)) {
			ast_log(LOG_WARNING, "Unable to allocate name for channel, using \"TTS\"\n");
			schan->name = "TTS";
		}

		if ((codec == NULL) || (strlen(codec) == 0)) {
			ast_log(LOG_WARNING, "(%s) No codec specified, assuming \"L16\"\n", schan->name);
			schan->codec = "L16";
		} else
			schan->codec = apr_pstrdup(pool, codec);
		if ((schan->codec == NULL) || (strlen(schan->codec) == 0)) {
			ast_log(LOG_WARNING, "(%s) Unable to allocate codec for channel, using \"L16\"\n", schan->name);
			schan->codec = "L16";
		}

		schan->profile = NULL;
		schan->type = type;
		schan->application = app;
		schan->unimrcp_session = NULL;
		schan->unimrcp_channel = NULL;
		schan->stream = NULL;
		schan->dtmf_generator = NULL;
		schan->pool = pool;
		schan->mutex = NULL;
		schan->cond = NULL;
		schan->state = SPEECH_CHANNEL_CLOSED;
		schan->audio_queue = NULL;
		schan->rate = rate;
		schan->data = NULL;
		schan->chan = chan;

		if (strstr("L16", schan->codec)) {
			schan->silence = 0;
		} else {
			/* 8-bit PCMU, PCMA. */
			schan->silence = 128;
		}

		if ((apr_thread_mutex_create(&schan->mutex, APR_THREAD_MUTEX_UNNESTED, pool) != APR_SUCCESS) || (schan->mutex == NULL)) {
			ast_log(LOG_ERROR, "(%s) Unable to create channel mutex\n", schan->name);
			status = -1;
		} else if ((apr_thread_cond_create(&schan->cond, pool) != APR_SUCCESS) || (schan->cond == NULL)) {
			ast_log(LOG_ERROR, "(%s) Unable to create channel condition variable\n",schan->name);
			status = -1;
		} else if ((audio_queue_create(&schan->audio_queue, name) != 0) || (schan->audio_queue == NULL)) {
			ast_log(LOG_ERROR, "(%s) Unable to create audio queue for channel\n",schan->name);
			status = -1;
		} else {
			ast_log(LOG_DEBUG, "Created speech channel: Name=%s, Type=%s, Codec=%s, Rate=%u\n", schan->name, speech_channel_type_to_string(schan->type), schan->codec, schan->rate);
		}
	}

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

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

				schan->cond = NULL;
			}

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

			schan = NULL;
		}
	}

#if SPEECH_CHANNEL_DUMP
	if(schan) {
		const char *stream_in_filename = apr_psprintf(pool,"%s/%s-%s-in.raw", SPEECH_CHANNEL_DUMP_DIR, schan->name, schan->codec);
		const char *stream_out_filename = apr_psprintf(pool,"%s/%s-%s-out.raw", SPEECH_CHANNEL_DUMP_DIR, schan->name, schan->codec);

		schan->stream_in = fopen(stream_in_filename,"wb");
		if(!schan->stream_in) {
			ast_log(LOG_WARNING, "(%s) Unable to open input stream file for writing\n", schan->name);
		}

		schan->stream_out = fopen(stream_out_filename,"wb");
		if(!schan->stream_out) {
			ast_log(LOG_WARNING, "(%s) Unable to open output stream file for writing\n", schan->name);
		}
	}
#endif

	return schan;
}