[Freeswitch-svn] [commit] r3766 - in freeswitch/trunk: conf src src/include src/mod/applications/mod_dptools src/mod/say src/mod/say/mod_say_en
Freeswitch SVN
anthm at freeswitch.org
Wed Dec 20 16:25:15 EST 2006
Author: anthm
Date: Wed Dec 20 16:25:14 2006
New Revision: 3766
Added:
freeswitch/trunk/src/mod/say/
freeswitch/trunk/src/mod/say/mod_say_en/
freeswitch/trunk/src/mod/say/mod_say_en/mod_say_en.c
Modified:
freeswitch/trunk/conf/freeswitch.xml
freeswitch/trunk/src/include/switch_ivr.h
freeswitch/trunk/src/include/switch_loadable_module.h
freeswitch/trunk/src/include/switch_module_interfaces.h
freeswitch/trunk/src/include/switch_types.h
freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c
freeswitch/trunk/src/switch_ivr.c
freeswitch/trunk/src/switch_loadable_module.c
freeswitch/trunk/src/switch_xml.c
Log:
add pelim say stuff, module framework, xml parser, dialplan app, and add new channel var called sound_prefix for audio files
Modified: freeswitch/trunk/conf/freeswitch.xml
==============================================================================
--- freeswitch/trunk/conf/freeswitch.xml (original)
+++ freeswitch/trunk/conf/freeswitch.xml Wed Dec 20 16:25:14 2006
@@ -632,6 +632,43 @@
</user>
</domain>
</section>
+
+ <!-- phrases section (under development still) -->
+ <section name="phrases" description="Speech Phrase Management">
+ <macros>
+ <language name="en" sound_path="/snds" tts_engine="cepstral" tts_voice="david">
+ <macro name="msgcount">
+ <input pattern="(.*)">
+ <action function="execute" data="sleep(1000)"/>
+ <action function="play-file" data="vm-youhave.wav"/>
+ <action function="say" data="$1" method="pronounced" type="items"/>
+ <action function="play-file" data="vm-messages.wav"/>
+ <!-- or -->
+ <!--<action function="speak-text" data="you have $1 messages"/>-->
+ </input>
+ </macro>
+ <macro name="timeleft">
+ <input pattern="(\d+):(\d+)">
+ <action function="speak-text" data="You have $1 minutes, $2 seconds remaining"/>
+ </input>
+ </macro>
+ </language>
+ <language name="fr" sound_path="/var/sounds/lang/fr/jean" tts_engine="cepstral" tts_voice="jean-pierre">
+ <macro name="msgcount">
+ <input pattern="(.*)">
+ <action function="play-file" data="tuas.wav"/>
+ <action function="say" data="$1" method="pronounced" type="items"/>
+ <action function="play-file" data="messages.wav"/>
+ </input>
+ </macro>
+ <macro name="timeleft">
+ <input pattern="(\d+):(\d+)">
+ <action function="speak-text" data="il y a $1 minutes et de $2 secondes de restant"/>
+ </input>
+ </macro>
+ </language>
+ </macros>
+ </section>
</document>
Modified: freeswitch/trunk/src/include/switch_ivr.h
==============================================================================
--- freeswitch/trunk/src/include/switch_ivr.h (original)
+++ freeswitch/trunk/src/include/switch_ivr.h Wed Dec 20 16:25:14 2006
@@ -626,6 +626,13 @@
*/
SWITCH_DECLARE(switch_status_t) switch_ivr_menu_stack_xml_init(switch_ivr_menu_xml_ctx_t **xml_menu_ctx, switch_memory_pool_t *pool);
+SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro(switch_core_session_t *session,
+ char *macro_name,
+ char *data,
+ char *lang,
+ switch_input_callback_function_t input_callback,
+ void *buf,
+ uint32_t buflen);
/** @} */
SWITCH_END_EXTERN_C
Modified: freeswitch/trunk/src/include/switch_loadable_module.h
==============================================================================
--- freeswitch/trunk/src/include/switch_loadable_module.h (original)
+++ freeswitch/trunk/src/include/switch_loadable_module.h Wed Dec 20 16:25:14 2006
@@ -75,6 +75,8 @@
const switch_directory_interface_t *directory_interface;
/*! the table of chat interfaces the module has implmented */
const switch_chat_interface_t *chat_interface;
+ /*! the table of say interfaces the module has implmented */
+ const switch_say_interface_t *say_interface;
/*! the table of asr interfaces the module has implmented */
const switch_asr_interface_t *asr_interface;
};
@@ -180,6 +182,13 @@
\return the desired chat interface
*/
SWITCH_DECLARE(switch_chat_interface_t *) switch_loadable_module_get_chat_interface(char *name);
+
+/*!
+ \brief Retrieve the say interface by it's registered name
+ \param name the name of the say interface
+ \return the desired say interface
+ */
+SWITCH_DECLARE(switch_say_interface_t *) switch_loadable_module_get_say_interface(char *name);
/*!
Modified: freeswitch/trunk/src/include/switch_module_interfaces.h
==============================================================================
--- freeswitch/trunk/src/include/switch_module_interfaces.h (original)
+++ freeswitch/trunk/src/include/switch_module_interfaces.h Wed Dec 20 16:25:14 2006
@@ -412,6 +412,20 @@
void *private_info;
};
+/*! \brief Abstract interface to a say module */
+struct switch_say_interface {
+ /*! the name of the interface */
+ const char *interface_name;
+ /*! function to pass down to the module */
+ switch_status_t (*say_function)(switch_core_session_t *session,
+ char *tosay,
+ switch_say_type_t type,
+ switch_say_method_t method,
+ switch_input_callback_function_t dtmf_callback,
+ void *buf,
+ uint32_t buflen);
+ const struct switch_say_interface *next;
+};
/*! \brief Abstract interface to a chat module */
struct switch_chat_interface {
Modified: freeswitch/trunk/src/include/switch_types.h
==============================================================================
--- freeswitch/trunk/src/include/switch_types.h (original)
+++ freeswitch/trunk/src/include/switch_types.h Wed Dec 20 16:25:14 2006
@@ -94,6 +94,33 @@
typedef uint8_t switch_byte_t;
typedef enum {
+ SSM_NA,
+ SSM_PRONOUNCED,
+ SSM_ITERATED
+} switch_say_method_t;
+
+typedef enum {
+ SST_NUMBER,
+ SST_ITEMS,
+ SST_PERSONS,
+ SST_MESSAGES,
+ SST_CURRENCY,
+ SST_TIME_MEASUREMENT,
+ SST_CURRENT_DATE,
+ SST_CURRENT_TIME,
+ SST_CURRENT_DATE_TIME,
+ SST_TELEPHONE_NUMBER,
+ SST_TELEPHONE_EXTENSION,
+ SST_URL,
+ SST_EMAIL_ADDRESS,
+ SST_POSTAL_ADDRESS,
+ SST_ACCOUNT_NUMBER,
+ SST_NAME_SPELLED,
+ SST_NAME_PHONETIC,
+} switch_say_type_t;
+
+
+typedef enum {
SMF_NONE = 0,
SMF_REBRIDGE = (1 << 0),
SMF_ECHO_ALEG = (1 << 1),
@@ -172,7 +199,8 @@
SWITCH_XML_SECTION_RESULT = 0,
SWITCH_XML_SECTION_CONFIG = (1 << 0),
SWITCH_XML_SECTION_DIRECTORY = (1 << 1),
- SWITCH_XML_SECTION_DIALPLAN = (1 << 2)
+ SWITCH_XML_SECTION_DIALPLAN = (1 << 2),
+ SWITCH_XML_SECTION_PHRASES = (1 << 3)
} switch_xml_section_t;
/*!
@@ -863,6 +891,7 @@
typedef struct switch_asr_interface switch_asr_interface_t;
typedef struct switch_directory_interface switch_directory_interface_t;
typedef struct switch_chat_interface switch_chat_interface_t;
+typedef struct switch_say_interface switch_say_interface_t;
typedef struct switch_core_port_allocator switch_core_port_allocator_t;
typedef struct switch_media_bug switch_media_bug_t;
typedef void (*switch_media_bug_callback_t)(switch_media_bug_t *, void *, switch_abc_type_t);
Modified: freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c Wed Dec 20 16:25:14 2006
@@ -102,6 +102,32 @@
return;
}
+static void phrase_function(switch_core_session_t *session, char *data)
+{
+ switch_channel_t *channel;
+ char *mydata = NULL;
+
+ channel = switch_core_session_get_channel(session);
+ assert(channel != NULL);
+
+ if ((mydata = switch_core_session_strdup(session, data))) {
+ char *lang;
+ char *macro = mydata;
+ char *mdata = NULL;
+
+ if ((mdata = strchr(macro, ','))) {
+ *mdata++ = '\0';
+ }
+ if (!(lang = switch_channel_get_variable(channel, "language"))) {
+ lang = "en";
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Execute %s(%s) lang %s\n", macro, mdata, lang);
+ switch_ivr_phrase_macro(session, macro, mdata, lang, NULL, NULL, 0);
+ }
+
+}
+
static void answer_function(switch_core_session_t *session, char *data)
{
switch_channel_t *channel;
@@ -462,13 +488,23 @@
};
+static const switch_application_interface_t phrase_application_interface = {
+ /*.interface_name */ "phrase",
+ /*.application_function */ phrase_function,
+ /* long_desc */ "Say a Phrase",
+ /* short_desc */ "Say a Phrase",
+ /* syntax */ "<macro_name>,<data>",
+ /*.next */ &eval_application_interface
+
+};
+
static const switch_application_interface_t strftime_application_interface = {
/*.interface_name */ "strftime",
/*.application_function */ strftime_function,
/* long_desc */ NULL,
/* short_desc */ NULL,
/* syntax */ NULL,
- /*.next */ &eval_application_interface
+ /*.next */ &phrase_application_interface
};
Added: freeswitch/trunk/src/mod/say/mod_say_en/mod_say_en.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/say/mod_say_en/mod_say_en.c Wed Dec 20 16:25:14 2006
@@ -0,0 +1,178 @@
+/*
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005/2006, Anthony Minessale II <anthmct at yahoo.com>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ *
+ * The Initial Developer of the Original Code is
+ * Anthony Minessale II <anthmct at yahoo.com>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Anthony Minessale II <anthmct at yahoo.com>
+ *
+ * mod_say_en.c -- Say for English
+ *
+ */
+#include <switch.h>
+#include <math.h>
+
+static const char modname[] = "mod_say_en";
+
+static switch_status_t en_say(switch_core_session_t *session,
+ char *tosay,
+ switch_say_type_t type,
+ switch_say_method_t method,
+ switch_input_callback_function_t input_callback,
+ void *buf,
+ uint32_t buflen)
+{
+ switch_channel_t *channel;
+
+ assert(session != NULL);
+ channel = switch_core_session_get_channel(session);
+ assert(channel != NULL);
+
+ switch(type) {
+ case SST_NUMBER:
+ case SST_ITEMS:
+ case SST_PERSONS:
+ case SST_MESSAGES:
+ {
+ int in;
+ int x, places[7] = {0};
+ char tmp[25];
+
+ in = atoi(tosay);
+
+ for(x = 6; x >= 0; x--) {
+ int num = pow(10, x);
+ if ((places[x] = in / num)) {
+ in -= places[x] * num;
+ }
+ }
+
+ switch (method) {
+ case SSM_PRONOUNCED:
+ if (places[6]) {
+ snprintf(tmp, sizeof(tmp), "digits/%d.wav", places[6]);
+ switch_ivr_play_file(session, NULL, tmp, NULL, input_callback, buf, buflen);
+ switch_ivr_play_file(session, NULL, "digits/million.wav", NULL, input_callback, buf, buflen);
+ }
+
+ if (places[5]) {
+ snprintf(tmp, sizeof(tmp), "digits/%d.wav", places[5]);
+ switch_ivr_play_file(session, NULL, tmp, NULL, input_callback, buf, buflen);
+ switch_ivr_play_file(session, NULL, "digits/hundred.wav", NULL, input_callback, buf, buflen);
+ }
+
+ if (places[4]) {
+ if (places[4] > 1) {
+ snprintf(tmp, sizeof(tmp), "digits/%d0.wav", places[4]);
+ switch_ivr_play_file(session, NULL, tmp, NULL, input_callback, buf, buflen);
+ } else {
+ snprintf(tmp, sizeof(tmp), "digits/%d%d.wav", places[4], places[3]);
+ switch_ivr_play_file(session, NULL, tmp, NULL, input_callback, buf, buflen);
+ places[3] = 0;
+ }
+ }
+
+ if (places[3]) {
+ snprintf(tmp, sizeof(tmp), "digits/%d.wav", places[3]);
+ switch_ivr_play_file(session, NULL, tmp, NULL, input_callback, buf, buflen);
+ }
+
+ if (places[4] || places[3]) {
+ switch_ivr_play_file(session, NULL, "digits/thousand.wav", NULL, input_callback, buf, buflen);
+ }
+
+ if (places[2]) {
+ snprintf(tmp, sizeof(tmp), "digits/%d.wav", places[2]);
+ switch_ivr_play_file(session, NULL, tmp, NULL, input_callback, buf, buflen);
+ switch_ivr_play_file(session, NULL, "digits/hundred.wav", NULL, input_callback, buf, buflen);
+ }
+
+ if (places[1]) {
+ if (places[1] > 1) {
+ snprintf(tmp, sizeof(tmp), "digits/%d0.wav", places[1]);
+ switch_ivr_play_file(session, NULL, tmp, NULL, input_callback, buf, buflen);
+ } else {
+ snprintf(tmp, sizeof(tmp), "digits/%d%d.wav", places[1], places[0]);
+ switch_ivr_play_file(session, NULL, tmp, NULL, input_callback, buf, buflen);
+ places[0] = 0;
+ }
+ }
+
+ if (places[0]) {
+ snprintf(tmp, sizeof(tmp), "digits/%d.wav", places[0]);
+ switch_ivr_play_file(session, NULL, tmp, NULL, input_callback, buf, buflen);
+ }
+
+ break;
+ case SSM_ITERATED:
+ for(x = 7; x >= 0; x--) {
+ if (places[x]) {
+ snprintf(tmp, sizeof(tmp), "digits/%d.wav", places[x]);
+ switch_ivr_play_file(session, NULL, tmp, NULL, input_callback, buf, buflen);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ default:
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Finish ME!\n");
+ break;
+ }
+
+
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static const switch_chat_interface_t en_say_interface= {
+ /*.name */ "en",
+ /*.say_function */ en_say,
+};
+
+static switch_loadable_module_interface_t say_en_module_interface = {
+ /*.module_name */ modname,
+ /*.endpoint_interface */ NULL,
+ /*.timer_interface */ NULL,
+ /*.dialplan_interface */ NULL,
+ /*.codec_interface */ NULL,
+ /*.application_interface */ NULL,
+ /*.api_interface */ NULL,
+ /*.file_interface */ NULL,
+ /*.speech_interface */ NULL,
+ /*.directory_interface */ NULL,
+ /*.chat_interface */ NULL,
+ /*.say_inteface*/ &en_say_interface,
+ /*.asr_interface*/ NULL
+};
+
+SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename)
+{
+ /* connect my internal structure to the blank pointer passed to me */
+ *module_interface = &say_en_module_interface;
+
+ /* indicate that the module should continue to be loaded */
+ return SWITCH_STATUS_SUCCESS;
+}
+
Modified: freeswitch/trunk/src/switch_ivr.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr.c (original)
+++ freeswitch/trunk/src/switch_ivr.c Wed Dec 20 16:25:14 2006
@@ -977,8 +977,23 @@
char *title = "", *copyright = "", *software = "", *artist = "", *comment = "", *date = "";
uint8_t asis = 0;
char *ext;
+ char *prefix;
+
+ channel = switch_core_session_get_channel(session);
+ assert(channel != NULL);
+
+ prefix = switch_channel_get_variable(channel, "sound_prefix");
if (file) {
+ if (prefix && *file != '/' && *file != '\\' && *(file+1) != ':') {
+ char *new_file;
+ uint32_t len;
+ len = (uint32_t)strlen(file) + (uint32_t)strlen(prefix) + 10;
+ new_file = switch_core_session_alloc(session, len);
+ snprintf(new_file, len, "%s/%s", prefix, file);
+ file = new_file;
+ }
+
if ((ext = strrchr(file, '.'))) {
ext++;
} else {
@@ -1004,10 +1019,6 @@
fh->samples = 0;
}
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
if (switch_core_file_open(fh,
file,
SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,
@@ -1054,7 +1065,7 @@
date = (char *) switch_core_session_strdup(session, (char *)p);
switch_channel_set_variable(channel, "RECORD_DATE", (char *)p);
}
-
+#if 0
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"OPEN FILE %s %uhz %u channels\n"
"TITLE=%s\n"
@@ -1069,6 +1080,7 @@
artist,
comment,
date);
+#endif
assert(read_codec != NULL);
interval = read_codec->implementation->microseconds_per_frame / 1000;
@@ -4335,6 +4347,230 @@
return status;
}
+
+
+static char *SAY_METHOD_NAMES[] = {
+ "N/A",
+ "PRONOUNCED",
+ "ITERATED",
+ NULL
+};
+
+static char *SAY_TYPE_NAMES[] = {
+ "NUMBER",
+ "ITEMS",
+ "PERSONS",
+ "MESSAGES",
+ "CURRENCY",
+ "TIME_MEASUREMENT",
+ "CURRENT_DATE",
+ "CURRENT_TIME",
+ "CURRENT_DATE_TIME",
+ "TELEPHONE_NUMBER",
+ "TELEPHONE_EXTENSION",
+ "URL",
+ "EMAIL_ADDRESS",
+ "POSTAL_ADDRESS",
+ "ACCOUNT_NUMBER",
+ "NAME_SPELLED",
+ "NAME_PHONETIC",
+ NULL
+};
+
+
+static switch_say_method_t get_say_method_by_name(char *name)
+{
+ int x = 0;
+ for (x = 0; SAY_METHOD_NAMES[x]; x++) {
+ if (!strcasecmp(SAY_METHOD_NAMES[x], name)) {
+ break;
+ }
+ }
+
+ return (switch_say_method_t) x;
+}
+
+static switch_say_method_t get_say_type_by_name(char *name)
+{
+ int x = 0;
+ for (x = 0; SAY_TYPE_NAMES[x]; x++) {
+ if (!strcasecmp(SAY_TYPE_NAMES[x], name)) {
+ break;
+ }
+ }
+
+ return (switch_say_method_t) x;
+}
+
+
+SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro(switch_core_session_t *session,
+ char *macro_name,
+ char *data,
+ char *lang,
+ switch_input_callback_function_t input_callback,
+ void *buf,
+ uint32_t buflen)
+{
+ switch_xml_t cfg, xml = NULL, language, macros, macro, input, action;
+ char *lname = NULL, *mname = NULL, hint_data[1024] = "", enc_hint[1024] = "";
+ switch_status_t status = SWITCH_STATUS_GENERR;
+ char *old_sound_prefix, *sound_path = NULL, *tts_engine = NULL, *tts_voice = NULL;
+ switch_channel_t *channel;
+
+ channel = switch_core_session_get_channel(session);
+ assert(channel != NULL);
+
+ switch_url_encode(data, enc_hint, sizeof(enc_hint));
+ snprintf(hint_data, sizeof(hint_data), "macro_name=%s&lang=%s&data=%s", macro_name, lang, enc_hint);
+
+ if (switch_xml_locate("phrases", NULL, NULL, NULL, &xml, &cfg, hint_data) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of phrases failed.\n");
+ goto done;
+ }
+
+ if (!(macros = switch_xml_child(cfg, "macros"))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "can't find macros tag.\n");
+ goto done;
+ }
+
+ if (!(language = switch_xml_child(macros, "language"))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "can't find language tag.\n");
+ goto done;
+ }
+
+ while(language) {
+ if ((lname = switch_xml_attr(language, "name")) && !strcasecmp(lname, lang)) {
+ break;
+ }
+ language = language->next;
+ }
+
+ if (!language) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "can't find language %s.\n", lang);
+ goto done;
+ }
+
+ sound_path = switch_xml_attr_soft(language, "sound_path");
+ tts_engine = switch_xml_attr_soft(language, "tts_engine");
+ tts_voice = switch_xml_attr_soft(language, "tts_voice");
+
+ old_sound_prefix = switch_channel_get_variable(channel, "sound_prefix");
+ switch_channel_set_variable(channel, "sound_prefix", sound_path);
+
+ if (!(macro = switch_xml_child(language, "macro"))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "can't find any macro tags.\n");
+ goto done;
+ }
+
+ while(macro) {
+ if ((mname = switch_xml_attr(macro, "name")) && !strcasecmp(mname, macro_name)) {
+ break;
+ }
+ macro = macro->next;
+ }
+
+ if (!macro) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "can't find macro %s.\n", macro_name);
+ goto done;
+ }
+
+ if (!(input = switch_xml_child(macro, "input"))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "can't find any input tags.\n");
+ goto done;
+ }
+
+ switch_channel_pre_answer(channel);
+
+ while(input) {
+ char *pattern = switch_xml_attr(input, "pattern");
+
+ if (pattern) {
+ pcre *re = NULL;
+ int proceed = 0, ovector[30];
+ char substituted[1024] = "";
+ char *odata = NULL;
+
+ if ((proceed = switch_perform_regex(data, pattern, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
+ for (action = switch_xml_child(input, "action"); action; action = action->next) {
+ char *adata = switch_xml_attr_soft(action, "data");
+ char *func = switch_xml_attr_soft(action, "function");
+
+ if (strchr(pattern, '(') && strchr(adata, '$')) {
+ switch_perform_substitution(re, proceed, adata, data, substituted, sizeof(substituted), ovector);
+ odata = substituted;
+ } else {
+ odata = adata;
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Handle %s:[%s] (%s)\n", func, odata, lang);
+
+ if (!strcasecmp(func, "play-file")) {
+ switch_ivr_play_file(session, NULL, odata, NULL, input_callback, buf, buflen);
+ } else if (!strcasecmp(func, "execute")) {
+ const switch_application_interface_t *application_interface;
+ char *app_name = NULL;
+ char *app_arg = NULL;
+
+ if ((app_name = strdup(odata))) {
+ char *e = NULL;
+ if ((app_arg = strchr(app_name, '('))) {
+ *app_arg++ = '\0';
+ if ((e = strchr(app_arg, ')'))) {
+ *e = '\0';
+ }
+ if (app_name && app_arg && e && (application_interface = switch_loadable_module_get_application_interface(app_name))) {
+ if (application_interface->application_function) {
+ application_interface->application_function(session, app_arg);
+ }
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Application!\n");
+ }
+ }
+ switch_safe_free(app_name);
+ }
+ } else if (!strcasecmp(func, "say")) {
+ switch_say_interface_t *si;
+ if ((si = switch_loadable_module_get_say_interface(lang))) {
+ char *say_type = switch_xml_attr_soft(action, "type");
+ char *say_method = switch_xml_attr_soft(action, "method");
+
+ si->say_function(session, odata, get_say_type_by_name(say_type), get_say_method_by_name(say_method), input_callback, buf, buflen);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invaid SAY Interface [%s]!\n", lang);
+ }
+ } else if (!strcasecmp(func, "speak-text")) {
+ switch_codec_t *read_codec;
+ if ((read_codec = switch_core_session_get_read_codec(session))) {
+ switch_ivr_speak_text(session,
+ tts_engine,
+ tts_voice,
+ NULL,
+ read_codec->implementation->samples_per_second,
+ input_callback,
+ odata,
+ buf,
+ buflen);
+ }
+ }
+ }
+ }
+
+ switch_clean_re(re);
+ }
+
+ input = input->next;
+ }
+
+ done:
+
+ switch_channel_set_variable(channel, "sound_prefix", old_sound_prefix);
+
+ if (xml) {
+ switch_xml_free(xml);
+ }
+ return status;
+}
+
/* For Emacs:
* Local Variables:
Modified: freeswitch/trunk/src/switch_loadable_module.c
==============================================================================
--- freeswitch/trunk/src/switch_loadable_module.c (original)
+++ freeswitch/trunk/src/switch_loadable_module.c Wed Dec 20 16:25:14 2006
@@ -54,6 +54,7 @@
switch_hash_t *asr_hash;
switch_hash_t *directory_hash;
switch_hash_t *chat_hash;
+ switch_hash_t *say_hash;
switch_memory_pool_t *pool;
};
@@ -260,6 +261,20 @@
switch_core_hash_insert(loadable_modules.chat_hash, (char *) ptr->interface_name, (void *) ptr);
}
}
+
+ if (new_module->module_interface->say_interface) {
+ const switch_say_interface_t *ptr;
+
+ for (ptr = new_module->module_interface->say_interface; ptr; ptr = ptr->next) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Say interface '%s'\n", ptr->interface_name);
+ if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "type", "say");
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "name", "%s", ptr->interface_name);
+ switch_event_fire(&event);
+ }
+ switch_core_hash_insert(loadable_modules.say_hash, (char *) ptr->interface_name, (void *) ptr);
+ }
+ }
return SWITCH_STATUS_SUCCESS;
@@ -506,6 +521,7 @@
switch_core_hash_init(&loadable_modules.asr_hash, loadable_modules.pool);
switch_core_hash_init(&loadable_modules.directory_hash, loadable_modules.pool);
switch_core_hash_init(&loadable_modules.chat_hash, loadable_modules.pool);
+ switch_core_hash_init(&loadable_modules.say_hash, loadable_modules.pool);
switch_core_hash_init(&loadable_modules.dialplan_hash, loadable_modules.pool);
if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
@@ -681,6 +697,11 @@
SWITCH_DECLARE(switch_chat_interface_t *) switch_loadable_module_get_chat_interface(char *name)
{
return switch_core_hash_find(loadable_modules.chat_hash, name);
+}
+
+SWITCH_DECLARE(switch_say_interface_t *) switch_loadable_module_get_say_interface(char *name)
+{
+ return switch_core_hash_find(loadable_modules.say_hash, name);
}
SWITCH_DECLARE(int) switch_loadable_module_get_codecs(switch_memory_pool_t *pool, const switch_codec_implementation_t **array,
Modified: freeswitch/trunk/src/switch_xml.c
==============================================================================
--- freeswitch/trunk/src/switch_xml.c (original)
+++ freeswitch/trunk/src/switch_xml.c Wed Dec 20 16:25:14 2006
@@ -107,6 +107,7 @@
{ "config", SWITCH_XML_SECTION_CONFIG},
{ "directory", SWITCH_XML_SECTION_DIRECTORY},
{ "dialplan", SWITCH_XML_SECTION_DIALPLAN},
+ { "phrases", SWITCH_XML_SECTION_PHRASES},
{ NULL, 0}
};
More information about the Freeswitch-svn
mailing list