Пример #1
0
/* Use this function to set the current channel state without locking the 
 * speech channel.  Do this if you already have the speech channel locked.
 */
void speech_channel_set_state_unlocked(speech_channel_t *schannel, speech_channel_state_t state)
{
	if (schannel != NULL) {
		/* Wake anyone waiting for audio data. */
		if ((schannel->state == SPEECH_CHANNEL_PROCESSING) && (state != SPEECH_CHANNEL_PROCESSING))
			audio_queue_clear(schannel->audio_queue);

		ast_log(LOG_DEBUG, "(%s) %s ==> %s\n", schannel->name, speech_channel_state_to_string(schannel->state), speech_channel_state_to_string(state));
		schannel->state = state;

		if (schannel->cond != NULL)
			apr_thread_cond_signal(schannel->cond);
	}
}
Пример #2
0
/* Receive a command from the client and execute it. */
static void handle_command (const int client_id)
{
	int cmd;
	int err = 0;
	struct client *cli = &clients[client_id];

	if (!get_int(cli->socket, &cmd)) {
		logit ("Failed to get command from the client");
		close (cli->socket);
		del_client (cli);
		return;
	}

	switch (cmd) {
		case CMD_QUIT:
			logit ("Exit request from the client");
			close (cli->socket);
			del_client (cli);
			server_quit = 1;
			break;
		case CMD_LIST_CLEAR:
			logit ("Clearing the list");
			audio_plist_clear ();
			break;
		case CMD_LIST_ADD:
			if (!req_list_add(cli))
				err = 1;
			break;
		case CMD_PLAY:
			if (!req_play(cli))
				err = 1;
			break;
		case CMD_DISCONNECT:
			logit ("Client disconnected");
			close (cli->socket);
			del_client (cli);
			break;
		case CMD_PAUSE:
			audio_pause ();
			break;
		case CMD_UNPAUSE:
			audio_unpause ();
			break;
		case CMD_STOP:
			audio_stop ();
			break;
		case CMD_GET_CTIME:
			if (!send_data_int(cli, MAX(0, audio_get_time())))
				err = 1;
			break;
		case CMD_SEEK:
			if (!req_seek(cli))
				err = 1;
			break;
		case CMD_JUMP_TO:
			if (!req_jump_to(cli))
				err = 1;
			break;
		case CMD_GET_SNAME:
			if (!send_sname(cli))
				err = 1;
			break;
		case CMD_GET_STATE:
			if (!send_data_int(cli, audio_get_state()))
				err = 1;
			break;
		case CMD_GET_BITRATE:
			if (!send_data_int(cli, sound_info.bitrate))
				err = 1;
			break;
		case CMD_GET_AVG_BITRATE:
			if (!send_data_int(cli, sound_info.avg_bitrate))
				err = 1;
			break;
		case CMD_GET_RATE:
			if (!send_data_int(cli, sound_info.rate))
				err = 1;
			break;
		case CMD_GET_CHANNELS:
			if (!send_data_int(cli, sound_info.channels))
				err = 1;
			break;
		case CMD_NEXT:
			audio_next ();
			break;
		case CMD_PREV:
			audio_prev ();
			break;
		case CMD_PING:
			if (!send_int(cli->socket, EV_PONG))
				err = 1;
			break;
		case CMD_GET_OPTION:
			if (!send_option(cli))
				err = 1;
			break;
		case CMD_SET_OPTION:
			if (!get_set_option(cli))
				err = 1;
			break;
		case CMD_GET_MIXER:
			if (!send_data_int(cli, audio_get_mixer()))
				err = 1;
			break;
		case CMD_SET_MIXER:
			if (!set_mixer(cli))
				err = 1;
			break;
		case CMD_DELETE:
			if (!delete_item(cli))
				err = 1;
			break;
		case CMD_SEND_PLIST_EVENTS:
			cli->wants_plist_events = 1;
			logit ("Request for events");
			break;
		case CMD_GET_PLIST:
			if (!get_client_plist(cli))
				err = 1;
			break;
		case CMD_SEND_PLIST:
			if (!req_send_plist(cli))
				err = 1;
			break;
		case CMD_CAN_SEND_PLIST:
			cli->can_send_plist = 1;
			break;
		case CMD_CLI_PLIST_ADD:
		case CMD_CLI_PLIST_DEL:
		case CMD_CLI_PLIST_CLEAR:
		case CMD_CLI_PLIST_MOVE:
			if (!plist_sync_cmd(cli, cmd))
				err = 1;
			break;
		case CMD_LOCK:
			if (!client_lock(cli))
				err = 1;
			break;
		case CMD_UNLOCK:
			if (!client_unlock(cli))
				err = 1;
			break;
		case CMD_GET_SERIAL:
			if (!send_serial(cli))
				err = 1;
			break;
		case CMD_PLIST_GET_SERIAL:
			if (!req_plist_get_serial(cli))
				err = 1;
			break;
		case CMD_PLIST_SET_SERIAL:
			if (!req_plist_set_serial(cli))
				err = 1;
			break;
		case CMD_GET_TAGS:
			if (!req_get_tags(cli))
				err = 1;
			break;
		case CMD_TOGGLE_MIXER_CHANNEL:
			req_toggle_mixer_channel ();
			break;
		case CMD_TOGGLE_SOFTMIXER:
			req_toggle_softmixer ();
			break;
		case CMD_GET_MIXER_CHANNEL_NAME:
			if (!req_get_mixer_channel_name(cli))
				err = 1;
			break;
		case CMD_GET_FILE_TAGS:
			if (!get_file_tags(client_id))
				err = 1;
			break;
		case CMD_ABORT_TAGS_REQUESTS:
			if (!abort_tags_requests(client_id))
				err = 1;
			break;
		case CMD_LIST_MOVE:
			if (!req_list_move(cli))
				err = 1;
			break;
		case CMD_TOGGLE_EQUALIZER:
			req_toggle_equalizer();
			break;
		case CMD_EQUALIZER_REFRESH:
			req_equalizer_refresh();
			break;
		case CMD_EQUALIZER_PREV:
			req_equalizer_prev();
			break;
		case CMD_EQUALIZER_NEXT:
			req_equalizer_next();
			break;
		case CMD_TOGGLE_MAKE_MONO:
			req_toggle_make_mono();
			break;
		case CMD_QUEUE_ADD:
			if (!req_queue_add(cli))
				err = 1;
			break;
		case CMD_QUEUE_DEL:
			if (!req_queue_del(cli))
				err = 1;
			break;
		case CMD_QUEUE_CLEAR:
			logit ("Clearing the queue");
			audio_queue_clear ();
			add_event_all (EV_QUEUE_CLEAR, NULL);
			break;
		case CMD_QUEUE_MOVE:
			if (!req_queue_move(cli))
				err = 1;
			break;
		case CMD_GET_QUEUE:
			if (!req_send_queue(cli))
				err = 1;
			break;
		default:
			logit ("Bad command (0x%x) from the client", cmd);
			err = 1;
	}

	if (err) {
		logit ("Closing client connection due to error");
		close (cli->socket);
		del_client (cli);
	}
}
Пример #3
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;
}