[Freeswitch-svn] [commit] r3333 - in freeswitch/branches/knhor/trunk: . src src/include src/mod/applications/mod_ivrtest

Freeswitch SVN knhor at freeswitch.org
Sun Nov 12 16:01:45 EST 2006


Author: knhor
Date: Sun Nov 12 16:01:45 2006
New Revision: 3333

Modified:
   freeswitch/branches/knhor/trunk/   (props changed)
   freeswitch/branches/knhor/trunk/src/include/switch_ivr.h
   freeswitch/branches/knhor/trunk/src/mod/applications/mod_ivrtest/mod_ivrtest.c
   freeswitch/branches/knhor/trunk/src/switch_ivr.c

Log:
Merged revisions 3326-3332 via svnmerge from trunk


Modified: freeswitch/branches/knhor/trunk/src/include/switch_ivr.h
==============================================================================
--- freeswitch/branches/knhor/trunk/src/include/switch_ivr.h	(original)
+++ freeswitch/branches/knhor/trunk/src/include/switch_ivr.h	Sun Nov 12 16:01:45 2006
@@ -480,6 +480,7 @@
 	SWITCH_IVR_ACTION_EXECMENU,	/* Goto another menu in the stack. */
 	SWITCH_IVR_ACTION_EXECAPP,		/* Execute an application.         */
 	SWITCH_IVR_ACTION_PLAYSOUND,	/* Play a sound.                   */
+	SWITCH_IVR_ACTION_SAYTEXT,	/* say text.                   */
 	SWITCH_IVR_ACTION_BACK,		/* Go back 1 menu.                 */
 	SWITCH_IVR_ACTION_TOMAIN,		/* Go back to the top level menu.  */
 	SWITCH_IVR_ACTION_TRANSFER,	/* Transfer caller to another ext. */
@@ -500,7 +501,6 @@
  *\param invalid_sound Optional pointer to a sound to play after invalid input.
  *\param timeout A number of milliseconds to pause before looping.
  *\param max_failures Maximum number of failures to withstand before hangingup This resets everytime you enter the menu.
- *\param inlen The max len of the input (1 for 1 digit menu opts, 2 for 2 digit etc.)
  *\param pool memory pool (NULL to create one)
  *\return SWUTCH_STATUS_SUCCESS if the menu was created
  */
@@ -510,9 +510,10 @@
 													 char *greeting_sound, 
 													 char *short_greeting_sound,
 													 char *invalid_sound, 
+													 char *tts_engine,
+													 char *tts_voice,
 													 int timeout,
 													 int max_failures, 
-													 int inlen,
 													 switch_memory_pool_t *pool);
 
 /*!

Modified: freeswitch/branches/knhor/trunk/src/mod/applications/mod_ivrtest/mod_ivrtest.c
==============================================================================
--- freeswitch/branches/knhor/trunk/src/mod/applications/mod_ivrtest/mod_ivrtest.c	(original)
+++ freeswitch/branches/knhor/trunk/src/mod/applications/mod_ivrtest/mod_ivrtest.c	Sun Nov 12 16:01:45 2006
@@ -81,6 +81,65 @@
 }
 
 
+static void ivr_application_function(switch_core_session_t *session, char *data)
+{
+	switch_channel_t *channel = switch_core_session_get_channel(session);
+	char *params = switch_core_session_strdup(session,data);
+
+	if (channel != NULL && params != NULL) {
+		switch_ivr_menu_t *menu = NULL, *sub_menu = NULL;
+		switch_status_t status;
+
+		// answer the channel if need be
+		switch_channel_answer(channel);
+
+		status = switch_ivr_menu_init(&menu,
+									  NULL,
+									  "main",
+									  "please enter some numbers so i can figure out if I have any bugs or not",
+									  "enter some numbers",
+									  "I have no idea what that is",
+									  "cepstral",
+									  "david",
+									  15000, 10, NULL);
+
+
+		status = switch_ivr_menu_init(&sub_menu,
+									  menu,
+									  "sub",
+									  "/ram/congrats.wav",
+									  "/ram/extension.wav",
+									  "/ram/invalid.wav",
+									  NULL,
+									  NULL,
+									  15000, 10, NULL);
+
+		if (status == SWITCH_STATUS_SUCCESS) {
+			// build the menu
+			switch_ivr_menu_bind_action(menu, SWITCH_IVR_ACTION_PLAYSOUND, "/ram/swimp.raw", "1");
+			switch_ivr_menu_bind_action(menu, SWITCH_IVR_ACTION_PLAYSOUND, "/ram/congrats.wav", "2");
+			switch_ivr_menu_bind_action(menu, SWITCH_IVR_ACTION_EXECMENU, "sub", "3");
+			//switch_ivr_menu_bind_action(menu, SWITCH_IVR_ACTION_PLAYSOUND, "/usr/local/freeswitch/sounds/3.wav", "3");
+
+			
+			switch_ivr_menu_bind_action(sub_menu, SWITCH_IVR_ACTION_PLAYSOUND, "/ram/swimp.raw", "1");
+			switch_ivr_menu_bind_action(sub_menu, SWITCH_IVR_ACTION_BACK, NULL, "2");
+			
+
+			// start the menu
+			status = switch_ivr_menu_execute(session, menu, "main", NULL);
+
+			// cleaup the menu
+			switch_ivr_menu_free_stack(menu);
+		} else {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unable to build menu %s\n",params);
+		}
+			
+
+		switch_ivr_play_file(session, NULL,"/ram/goodbye.wav",NULL,NULL,NULL,0);
+	}
+}
+
 static void dirtest_function(switch_core_session_t *session, char *data)
 {
 	char *var, *val;
@@ -354,11 +413,19 @@
 };
 
 
+
+static const switch_application_interface_t ivr_application_interface = {
+	/*.interface_name */ "ivrmenu",
+	/*.application_function */ ivr_application_function,
+	NULL, NULL, NULL,
+	/*.next*/ NULL
+};
+
 static const switch_application_interface_t xml_application_interface = {
 	/*.interface_name */ "xml",
 	/*.application_function */ xml_function,
 	NULL, NULL, NULL,
-	/*.next*/ NULL
+	/*.next*/ &ivr_application_interface
 };
 
 static const switch_application_interface_t disast_application_interface = {

Modified: freeswitch/branches/knhor/trunk/src/switch_ivr.c
==============================================================================
--- freeswitch/branches/knhor/trunk/src/switch_ivr.c	(original)
+++ freeswitch/branches/knhor/trunk/src/switch_ivr.c	Sun Nov 12 16:01:45 2006
@@ -431,12 +431,16 @@
 			switch_event_destroy(&event);
 		}
 
-		if (input_callback || buf) {
+		if (input_callback || buf || buflen) {
 			/*
 			  dtmf handler function you can hook up to be executed when a digit is dialed during playback 
 			  if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
 			*/
 			if (switch_channel_has_dtmf(channel)) {
+				if (!input_callback && !buf) {
+					status = SWITCH_STATUS_BREAK;
+					break;
+				}
 				switch_channel_dequeue_dtmf(channel, dtmf, sizeof(dtmf));
 				if (input_callback) {
 					status = input_callback(session, dtmf, SWITCH_INPUT_TYPE_DTMF, buf, buflen);
@@ -1094,12 +1098,17 @@
 			switch_event_destroy(&event);
 		}
 
-		if (input_callback || buf) {
+		if (input_callback || buf || buflen) {
 			/*
 			  dtmf handler function you can hook up to be executed when a digit is dialed during playback 
 			  if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
 			*/
 			if (switch_channel_has_dtmf(channel)) {
+				if (!input_callback && !buf) {
+					status = SWITCH_STATUS_BREAK;
+					done = 1;
+					break;
+				}
 				switch_channel_dequeue_dtmf(channel, dtmf, sizeof(dtmf));
 				if (input_callback) {
 					status = input_callback(session, dtmf, SWITCH_INPUT_TYPE_DTMF, buf, buflen);
@@ -1390,7 +1399,7 @@
 				if (switch_regex_match(digit_buffer, digits_regex) == SWITCH_STATUS_SUCCESS) {
 					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Match found!\n");
 					//Jobs done
-					return switch_channel_get_state(channel);
+					return SWITCH_STATUS_SUCCESS;
 				} else {
 					//See if a bad input prompt was specified, if so, play it
 					if (strlen(bad_input_audio_file) > 0) {
@@ -1405,14 +1414,14 @@
 				}
 			} else {
 				//Jobs done
-				return switch_channel_get_state(channel);
+				return SWITCH_STATUS_SUCCESS;
 			}
 		}
 	}
 
 	//if we got here, we got no digits or lost the channel
 	digit_buffer = "\0";
-	return switch_channel_get_state(channel);
+	return SWITCH_STATUS_FALSE;
 }
 
 
@@ -1485,12 +1494,17 @@
 			switch_event_destroy(&event);
 		}
 
-		if (input_callback || buf) {
+		if (input_callback || buf || buflen) {
 			/*
 			dtmf handler function you can hook up to be executed when a digit is dialed during playback 
 			if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
 			*/
 			if (switch_channel_has_dtmf(channel)) {
+				if (!input_callback && !buf) {
+					status = SWITCH_STATUS_BREAK;
+					done = 1;
+					break;
+				}
 				if (buf && !strcasecmp(buf, "_break_")) {
 					status = SWITCH_STATUS_BREAK;
 				} else {
@@ -1630,11 +1644,15 @@
 	switch_status_t status = SWITCH_STATUS_SUCCESS;
 	switch_speech_handle_t sh;
 	switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE;
+	switch_codec_t *read_codec;
 
-
 	channel = switch_core_session_get_channel(session);
 	assert(channel != NULL);
 
+	if (rate == 0) {
+		read_codec = switch_core_session_get_read_codec(session);
+		rate = read_codec->implementation->samples_per_second;
+	}
 
 	memset(&sh, 0, sizeof(sh));
 	if (switch_core_speech_open(&sh,
@@ -3406,6 +3424,10 @@
 	char *greeting_sound;
 	char *short_greeting_sound;
 	char *invalid_sound;
+	char *tts_engine;
+	char *tts_voice;
+	char *buf;
+	char *ptr;
 	int max_failures;
 	int timeout;
 	int inlen;
@@ -3454,9 +3476,10 @@
 													 char *greeting_sound, 
 													 char *short_greeting_sound,
 													 char *invalid_sound, 
+													 char *tts_engine,
+													 char *tts_voice,
 													 int timeout,
 													 int max_failures, 
-													 int inlen,
 													 switch_memory_pool_t *pool)
 {
 	switch_ivr_menu_t *menu;
@@ -3477,25 +3500,47 @@
 			return SWITCH_STATUS_MEMERR;
 		}
 	}
+
 	menu->pool = pool;
 
-	menu->name = switch_core_strdup(menu->pool, name);
-	menu->greeting_sound = switch_core_strdup(menu->pool, greeting_sound);
-	menu->short_greeting_sound = switch_core_strdup(menu->pool, short_greeting_sound);
-	menu->invalid_sound = switch_core_strdup(menu->pool, invalid_sound);
+	if (name) {
+		menu->name = switch_core_strdup(menu->pool, name);
+	}
+
+	if (greeting_sound) {
+		menu->greeting_sound = switch_core_strdup(menu->pool, greeting_sound);
+	}
+
+	if (short_greeting_sound) {
+		menu->short_greeting_sound = switch_core_strdup(menu->pool, short_greeting_sound);
+	}
+
+	if (invalid_sound) {
+		menu->invalid_sound = switch_core_strdup(menu->pool, invalid_sound);
+	}
+
+	if (tts_engine) {
+		menu->tts_engine = switch_core_strdup(menu->pool, tts_engine);
+	}
+
+	if (tts_voice) {
+		menu->tts_voice = switch_core_strdup(menu->pool, tts_voice);
+	}
+
 	menu->max_failures = max_failures;
+
 	menu->timeout = timeout;
+
 	menu->actions = NULL;
-	menu->inlen = inlen;
+
 	if (newpool) {
 		menu->flags |= SWITCH_IVR_MENU_FLAG_FREEPOOL;
 	}
 
-	if (menu->timeout <= 0)
+	if (menu->timeout <= 0) {
 		menu->timeout = 10000;
-	if (menu->inlen <= 0)
-		menu->inlen = 1;
-	
+	}
+
 	if (main) {
 		switch_ivr_menu_stack(&main, menu);
 	} else {
@@ -3511,11 +3556,15 @@
 SWITCH_DECLARE(switch_status_t) switch_ivr_menu_bind_action(switch_ivr_menu_t *menu, switch_ivr_action_t ivr_action, char *arg, char *bind)
 {
 	switch_ivr_menu_action_t *action;
-
+	switch_size_t len;
 	if ((action = switch_core_alloc(menu->pool, sizeof(*action)))) {
-		action->bind = bind;
+		action->bind = switch_core_strdup(menu->pool, bind);
 		action->next = menu->actions;
-		action->arg = arg;
+		action->arg = switch_core_strdup(menu->pool, arg);
+		len = strlen(action->bind);
+		if (len > menu->inlen) {
+			menu->inlen = (uint32_t)len;
+		}
 		action->ivr_action = ivr_action;
 		menu->actions = action;
 		return SWITCH_STATUS_SUCCESS;
@@ -3557,11 +3606,50 @@
 
 }
 
+static switch_status_t play_or_say(switch_core_session_t *session, switch_ivr_menu_t *menu, char *sound, uint32_t need)
+{
+	memset(menu->buf, 0, menu->inlen);
+	menu->ptr = menu->buf;
+	char terminator;
+	uint32_t len;
+	char *ptr;
+
+	switch_status_t status = SWITCH_STATUS_SUCCESS;
+
+	menu->ptr = menu->buf;
+
+	if (!need) {
+		len = 1;
+		ptr = NULL;
+	} else {
+		len = menu->inlen + 1;
+		ptr = menu->ptr;
+	}
+
+	if (*sound == '/' || *sound == '\\') {
+		switch_ivr_play_file(session, NULL, sound, NULL, NULL, ptr, len);
+	} else {
+		if (menu->tts_engine && menu->tts_voice) {
+			switch_ivr_speak_text(session, menu->tts_engine, menu->tts_voice, NULL, 0, NULL, sound, ptr, len);
+		}
+	}
+
+	if (need) {
+		menu->ptr += strlen(menu->buf);
+		if (strlen(menu->buf) < need) {
+			status = switch_ivr_collect_digits_count(session, menu->ptr, menu->inlen - strlen(menu->buf), need, "#", &terminator, menu->timeout);
+		}
+	}
+
+	return status;
+	
+}
+
 SWITCH_DECLARE(switch_status_t) switch_ivr_menu_execute(switch_core_session_t *session, switch_ivr_menu_t *stack, char *name, void *obj)
 {
 	int reps = 0, errs = 0, match = 0, running = 1;
 	char *greeting_sound = NULL, *aptr;
-	char *buf, arg[512];
+	char arg[512];
 	switch_ivr_action_t todo = SWITCH_IVR_ACTION_DIE;
 	switch_ivr_menu_action_t *ap;
 	switch_ivr_menu_t *menu;
@@ -3577,7 +3665,7 @@
 		return -1;
 	}
 	
-	if (!(buf = malloc(menu->inlen))) {
+	if (!(menu->buf = malloc(menu->inlen))) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Memory!\n");
 		return -1;
 	}
@@ -3585,12 +3673,10 @@
 	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Executing IVR menu %s\n", menu->name);
 
 	for (reps = 0 ; (running && status == SWITCH_STATUS_SUCCESS && errs < menu->max_failures) ; reps++) {
-
 		if (!switch_channel_ready(channel)) {
 			break;
 		}
 
-
 		if (reps > 0 && menu->short_greeting_sound) {
 			greeting_sound = menu->short_greeting_sound;
 		} else {
@@ -3599,28 +3685,19 @@
 
 		match = 0;
 		aptr = NULL;
-		memset(buf, 0, menu->inlen);
+
 		memset(arg, 0, sizeof(arg));
 
-		if (switch_play_and_get_digits(session,
-									   menu->inlen,
-									   menu->inlen,
-									   1,
-									   menu->timeout, "#",
-									   greeting_sound,
-									   NULL,
-									   buf,
-									   menu->inlen,
-									   NULL) != SWITCH_STATUS_SUCCESS) {
-			break;
-		}
+
+		play_or_say(session, menu, greeting_sound, menu->inlen);
 		
-		if (!switch_strlen_zero(buf)) {
+
+		if (!switch_strlen_zero(menu->buf)) {
 			for(ap = menu->actions; ap ; ap = ap->next) {
-				if (!strcmp(buf, ap->bind)) {
+				if (!strcmp(menu->buf, ap->bind)) {
 					char *membuf;
 
-					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IVR menu %s matched %s\n", menu->name, buf);
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IVR menu %s matched %s\n", menu->name, menu->buf);
 					match++;
 					errs = 0;
 					if (ap->function) {
@@ -3638,6 +3715,11 @@
 					case SWITCH_IVR_ACTION_PLAYSOUND:
 						status = switch_ivr_play_file(session, NULL, aptr, NULL, NULL, NULL, 0);
 						break;
+					case SWITCH_IVR_ACTION_SAYTEXT:
+						if (menu->tts_engine &&  menu->tts_voice) {
+							switch_ivr_speak_text(session, menu->tts_engine, menu->tts_voice, NULL, 0, NULL, aptr, NULL, 0);
+						}
+						break;
 					case SWITCH_IVR_ACTION_TRANSFER:
 						switch_ivr_session_transfer(session, aptr, NULL, NULL);
 						running = 0;
@@ -3693,10 +3775,10 @@
 			}
 		}
 		if (!match) {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IVR menu %s caught invalid input %s\n", menu->name, buf);
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IVR menu %s caught invalid input %s\n", menu->name, menu->buf);
 
 			if (menu->invalid_sound) {
-				status = switch_ivr_play_file(session, NULL, aptr, NULL, NULL, NULL, 0);
+				play_or_say(session, menu, menu->invalid_sound, 0);
 			}
 			errs++;
 
@@ -3707,7 +3789,7 @@
 		
 	}
 
-	switch_safe_free(buf);
+	switch_safe_free(menu->buf);
 
 	return status;
 }



More information about the Freeswitch-svn mailing list