提交 b7dbea64 authored 作者: Anthony Minessale's avatar Anthony Minessale

add pelim say stuff, module framework, xml parser, dialplan app, and add new…

add pelim say stuff, module framework, xml parser, dialplan app, and add new channel var called sound_prefix for audio files

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3766 d0543943-73ff-0310-b7d9-9358b9ac24b2
上级 9db9fae8
...@@ -632,6 +632,43 @@ ...@@ -632,6 +632,43 @@
</user> </user>
</domain> </domain>
</section> </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> </document>
...@@ -626,6 +626,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_stack_xml_add_custom(switch_ivr_ ...@@ -626,6 +626,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_stack_xml_add_custom(switch_ivr_
*/ */
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_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 SWITCH_END_EXTERN_C
......
...@@ -75,6 +75,8 @@ struct switch_loadable_module_interface { ...@@ -75,6 +75,8 @@ struct switch_loadable_module_interface {
const switch_directory_interface_t *directory_interface; const switch_directory_interface_t *directory_interface;
/*! the table of chat interfaces the module has implmented */ /*! the table of chat interfaces the module has implmented */
const switch_chat_interface_t *chat_interface; 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 */ /*! the table of asr interfaces the module has implmented */
const switch_asr_interface_t *asr_interface; const switch_asr_interface_t *asr_interface;
}; };
...@@ -181,6 +183,13 @@ SWITCH_DECLARE(switch_directory_interface_t *) switch_loadable_module_get_direct ...@@ -181,6 +183,13 @@ SWITCH_DECLARE(switch_directory_interface_t *) switch_loadable_module_get_direct
*/ */
SWITCH_DECLARE(switch_chat_interface_t *) switch_loadable_module_get_chat_interface(char *name); 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);
/*! /*!
\brief Retrieve the list of loaded codecs into an array \brief Retrieve the list of loaded codecs into an array
......
...@@ -412,6 +412,20 @@ struct switch_speech_handle { ...@@ -412,6 +412,20 @@ struct switch_speech_handle {
void *private_info; 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 */ /*! \brief Abstract interface to a chat module */
struct switch_chat_interface { struct switch_chat_interface {
......
...@@ -93,6 +93,33 @@ SWITCH_BEGIN_EXTERN_C ...@@ -93,6 +93,33 @@ SWITCH_BEGIN_EXTERN_C
#define SWITCH_BITS_PER_BYTE 8 #define SWITCH_BITS_PER_BYTE 8
typedef uint8_t switch_byte_t; 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 { typedef enum {
SMF_NONE = 0, SMF_NONE = 0,
SMF_REBRIDGE = (1 << 0), SMF_REBRIDGE = (1 << 0),
...@@ -172,7 +199,8 @@ typedef enum { ...@@ -172,7 +199,8 @@ typedef enum {
SWITCH_XML_SECTION_RESULT = 0, SWITCH_XML_SECTION_RESULT = 0,
SWITCH_XML_SECTION_CONFIG = (1 << 0), SWITCH_XML_SECTION_CONFIG = (1 << 0),
SWITCH_XML_SECTION_DIRECTORY = (1 << 1), 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; } switch_xml_section_t;
/*! /*!
...@@ -863,6 +891,7 @@ typedef struct switch_speech_interface switch_speech_interface_t; ...@@ -863,6 +891,7 @@ typedef struct switch_speech_interface switch_speech_interface_t;
typedef struct switch_asr_interface switch_asr_interface_t; typedef struct switch_asr_interface switch_asr_interface_t;
typedef struct switch_directory_interface switch_directory_interface_t; typedef struct switch_directory_interface switch_directory_interface_t;
typedef struct switch_chat_interface switch_chat_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_core_port_allocator switch_core_port_allocator_t;
typedef struct switch_media_bug switch_media_bug_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); typedef void (*switch_media_bug_callback_t)(switch_media_bug_t *, void *, switch_abc_type_t);
......
...@@ -102,6 +102,32 @@ static void eval_function(switch_core_session_t *session, char *data) ...@@ -102,6 +102,32 @@ static void eval_function(switch_core_session_t *session, char *data)
return; 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) static void answer_function(switch_core_session_t *session, char *data)
{ {
switch_channel_t *channel; switch_channel_t *channel;
...@@ -462,13 +488,23 @@ static const switch_application_interface_t eval_application_interface = { ...@@ -462,13 +488,23 @@ static const switch_application_interface_t eval_application_interface = {
}; };
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 = { static const switch_application_interface_t strftime_application_interface = {
/*.interface_name */ "strftime", /*.interface_name */ "strftime",
/*.application_function */ strftime_function, /*.application_function */ strftime_function,
/* long_desc */ NULL, /* long_desc */ NULL,
/* short_desc */ NULL, /* short_desc */ NULL,
/* syntax */ NULL, /* syntax */ NULL,
/*.next */ &eval_application_interface /*.next */ &phrase_application_interface
}; };
......
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005/2006, Anthony Minessale II <anthmct@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@yahoo.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Anthony Minessale II <anthmct@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;
}
差异被折叠。
...@@ -54,6 +54,7 @@ struct switch_loadable_module_container { ...@@ -54,6 +54,7 @@ struct switch_loadable_module_container {
switch_hash_t *asr_hash; switch_hash_t *asr_hash;
switch_hash_t *directory_hash; switch_hash_t *directory_hash;
switch_hash_t *chat_hash; switch_hash_t *chat_hash;
switch_hash_t *say_hash;
switch_memory_pool_t *pool; switch_memory_pool_t *pool;
}; };
...@@ -260,6 +261,20 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable ...@@ -260,6 +261,20 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
switch_core_hash_insert(loadable_modules.chat_hash, (char *) ptr->interface_name, (void *) ptr); 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; return SWITCH_STATUS_SUCCESS;
...@@ -506,6 +521,7 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init() ...@@ -506,6 +521,7 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init()
switch_core_hash_init(&loadable_modules.asr_hash, loadable_modules.pool); 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.directory_hash, loadable_modules.pool);
switch_core_hash_init(&loadable_modules.chat_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); switch_core_hash_init(&loadable_modules.dialplan_hash, loadable_modules.pool);
if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) { if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
...@@ -683,6 +699,11 @@ SWITCH_DECLARE(switch_chat_interface_t *) switch_loadable_module_get_chat_interf ...@@ -683,6 +699,11 @@ SWITCH_DECLARE(switch_chat_interface_t *) switch_loadable_module_get_chat_interf
return switch_core_hash_find(loadable_modules.chat_hash, 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, SWITCH_DECLARE(int) switch_loadable_module_get_codecs(switch_memory_pool_t *pool, const switch_codec_implementation_t **array,
int arraylen) int arraylen)
{ {
......
...@@ -107,6 +107,7 @@ static struct xml_section_t SECTIONS[] = { ...@@ -107,6 +107,7 @@ static struct xml_section_t SECTIONS[] = {
{ "config", SWITCH_XML_SECTION_CONFIG}, { "config", SWITCH_XML_SECTION_CONFIG},
{ "directory", SWITCH_XML_SECTION_DIRECTORY}, { "directory", SWITCH_XML_SECTION_DIRECTORY},
{ "dialplan", SWITCH_XML_SECTION_DIALPLAN}, { "dialplan", SWITCH_XML_SECTION_DIALPLAN},
{ "phrases", SWITCH_XML_SECTION_PHRASES},
{ NULL, 0} { NULL, 0}
}; };
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论