Add SayPhonetic and SayAlpha applications (bug #793)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2864 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.0
Mark Spencer 21 years ago
parent 09eeb42315
commit 73b389da6c

@ -273,6 +273,24 @@ datafiles: all
exit 1; \
fi; \
done
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds/letters
for x in sounds/letters/*.gsm; do \
if grep -q "^%`basename $$x`%" sounds.txt; then \
install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds/letters ; \
else \
echo "No description for $$x"; \
exit 1; \
fi; \
done
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds/phonetic
for x in sounds/phonetic/*.gsm; do \
if grep -q "^%`basename $$x`%" sounds.txt; then \
install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds/phonetic ; \
else \
echo "No description for $$x"; \
exit 1; \
fi; \
done
for x in sounds/vm-* sounds/transfer* sounds/pbx-* sounds/ss-* sounds/beep* sounds/dir-* sounds/conf-* sounds/agent-* sounds/invalid* sounds/tt-* sounds/auth-* sounds/privacy-* sounds/queue-*; do \
if grep -q "^%`basename $$x`%" sounds.txt; then \
install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds ; \

@ -385,10 +385,12 @@ static int handle_saydigits(struct ast_channel *chan, AGI *agi, int argc, char *
{
int res;
int num;
if (argc != 4)
return RESULT_SHOWUSAGE;
if (sscanf(argv[2], "%i", &num) != 1)
return RESULT_SHOWUSAGE;
res = ast_say_digit_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
if (res == 1) /* New command */
return RESULT_SUCCESS;
@ -417,6 +419,23 @@ static int handle_saytime(struct ast_channel *chan, AGI *agi, int argc, char *ar
return RESULT_FAILURE;
}
static int handle_sayphonetic(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
{
int res;
if (argc != 4)
return RESULT_SHOWUSAGE;
res = ast_say_phonetic_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
if (res == 1) /* New command */
return RESULT_SUCCESS;
fdprintf(agi->fd, "200 result=%d\n", res);
if (res >= 0)
return RESULT_SUCCESS;
else
return RESULT_FAILURE;
}
static int handle_getdata(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
{
int res;
@ -1031,6 +1050,13 @@ static char usage_saytime[] =
" completes without a digit being pressed, or the ASCII numerical value of the\n"
" digit if one was pressed or -1 on error/hangup.\n";
static char usage_sayphonetic[] =
" Usage: SAY PHONETIC <string> <escape digits>\n"
" Say a given character string with phonetics, returning early if any of the given DTMF digits\n"
" are received on the channel. Returns 0 if playback completes without a digit\n"
" being pressed, or the ASCII numerical value of the digit if one was pressed or\n"
" -1 on error/hangup.\n";
static char usage_getdata[] =
" Usage: GET DATA <file to be streamed> [timeout] [max digits]\n"
" Stream the given file, and recieve DTMF data. Returns the digits recieved\n"
@ -1080,6 +1106,7 @@ static agi_command commands[] = {
{ { "send", "image", NULL }, handle_sendimage, "Sends images to channels supporting it", usage_sendimage },
{ { "say", "digits", NULL }, handle_saydigits, "Says a given digit string", usage_saydigits },
{ { "say", "number", NULL }, handle_saynumber, "Says a given number", usage_saynumber },
{ { "say", "phonetic", NULL }, handle_sayphonetic, "Says a given character string with phonetics", usage_sayphonetic },
{ { "say", "time", NULL }, handle_saytime, "Says a given time", usage_saytime },
{ { "get", "data", NULL }, handle_getdata, "Gets data on a channel", usage_getdata },
{ { "set", "context", NULL }, handle_setcontext, "Sets channel context", usage_setcontext },

@ -896,7 +896,6 @@ static char *cli_prompt(EditLine *el)
int i;
struct timeval tv;
struct tm tm;
time_t curtime;
FILE *LOADAVG;
int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;

@ -29,6 +29,11 @@ console => notice,warning,error
;console => notice,warning,error,debug
messages => notice,warning,error
;full => notice,warning,error,debug,verbose
;
; Uncomment the following line (with *no* events) if you want the
; queue log to automatically rotate.
;
;queue_log =>
;syslog keyword : This special keyword logs to syslog facility
;

@ -61,6 +61,10 @@ int ast_say_digits_full(struct ast_channel *chan, int num, char *ints, char *lan
*/
int ast_say_digit_str(struct ast_channel *chan, char *num, char *ints, char *lang);
int ast_say_digit_str_full(struct ast_channel *chan, char *num, char *ints, char *lang, int audiofd, int ctrlfd);
int ast_say_character_str(struct ast_channel *chan, char *num, char *ints, char *lang);
int ast_say_character_str_full(struct ast_channel *chan, char *num, char *ints, char *lang, int audiofd, int ctrlfd);
int ast_say_phonetic_str(struct ast_channel *chan, char *num, char *ints, char *lang);
int ast_say_phonetic_str_full(struct ast_channel *chan, char *num, char *ints, char *lang, int audiofd, int ctrlfd);
int ast_say_datetime(struct ast_channel *chan, time_t t, char *ints, char *lang);

26
pbx.c

@ -169,6 +169,8 @@ static int pbx_builtin_gotoif(struct ast_channel *, void *);
static int pbx_builtin_gotoiftime(struct ast_channel *, void *);
static int pbx_builtin_saynumber(struct ast_channel *, void *);
static int pbx_builtin_saydigits(struct ast_channel *, void *);
static int pbx_builtin_saycharacters(struct ast_channel *, void *);
static int pbx_builtin_sayphonetic(struct ast_channel *, void *);
int pbx_builtin_setvar(struct ast_channel *, void *);
void pbx_builtin_setvar_helper(struct ast_channel *chan, char *name, char *value);
char *pbx_builtin_getvar_helper(struct ast_channel *chan, char *name);
@ -293,6 +295,14 @@ static struct pbx_builtin {
"Say Digits",
" SayDigits(digits): Says the passed digits\n" },
{ "SayAlpha", pbx_builtin_saycharacters,
"Say Alpha",
" SayAlpha(string): Spells the passed string\n" },
{ "SayPhonetic", pbx_builtin_sayphonetic,
"Say Phonetic",
" SayPhonetic(string): Spells the passed string with phonetic alphabet\n" },
{ "SetAccount", pbx_builtin_setaccount,
"Sets account code",
" SetAccount([account]): Set the channel account code for billing\n"
@ -4601,6 +4611,22 @@ static int pbx_builtin_saydigits(struct ast_channel *chan, void *data)
return res;
}
static int pbx_builtin_saycharacters(struct ast_channel *chan, void *data)
{
int res = 0;
if (data)
res = ast_say_character_str(chan, (char *)data, "", chan->language);
return res;
}
static int pbx_builtin_sayphonetic(struct ast_channel *chan, void *data)
{
int res = 0;
if (data)
res = ast_say_phonetic_str(chan, (char *)data, "", chan->language);
return res;
}
int load_pbx(void)
{
int x;

314
say.c

@ -16,6 +16,7 @@
#include <stdlib.h>
#include <netinet/in.h>
#include <time.h>
#include <ctype.h>
#include <asterisk/file.h>
#include <asterisk/channel.h>
#include <asterisk/logger.h>
@ -45,13 +46,13 @@ int ast_say_digit_str(struct ast_channel *chan, char *fn2, char *ints, char *lan
snprintf(fn, sizeof(fn), "digits/pound");
break;
default:
if((fn2[num] >= '0') && (fn2[num] <= '9')){ /* Must be in {0-9} */
if((fn2[num] >= '0') && (fn2[num] <= '9')){ /* Must be in {0-9} */
snprintf(fn, sizeof(fn), "digits/%c", fn2[num]);
}
}
}
if(strlen(fn)){ /* if length == 0, then skip this digit as it is invalid */
res = ast_streamfile(chan, fn, lang);
if (!res)
if (!res)
res = ast_waitstream(chan, ints);
ast_stopstream(chan);
}
@ -60,6 +61,178 @@ int ast_say_digit_str(struct ast_channel *chan, char *fn2, char *ints, char *lan
return res;
}
int ast_say_character_str(struct ast_channel *chan, char *fn2, char *ints, char *lang)
{
/* XXX Merge with full version? XXX */
char fn[256] = "";
char ltr;
int num = 0;
int res = 0;
while(fn2[num] && !res) {
fn[0] = '\0';
switch (fn2[num]) {
case ('*'):
snprintf(fn, sizeof(fn), "digits/star");
break;
case ('#'):
snprintf(fn, sizeof(fn), "digits/pound");
break;
case ('0'):
case ('1'):
case ('2'):
case ('3'):
case ('4'):
case ('5'):
case ('6'):
case ('7'):
case ('8'):
case ('9'):
snprintf(fn, sizeof(fn), "digits/%c", fn2[num]);
break;
case ('!'):
strncpy(fn, "letters/exclaimation-point", sizeof(fn));
break;
case ('@'):
strncpy(fn, "letters/at", sizeof(fn));
break;
case ('$'):
strncpy(fn, "letters/dollar", sizeof(fn));
break;
case ('-'):
strncpy(fn, "letters/dash", sizeof(fn));
break;
case ('.'):
strncpy(fn, "letters/dot", sizeof(fn));
break;
case ('='):
strncpy(fn, "letters/equals", sizeof(fn));
break;
case ('+'):
strncpy(fn, "letters/plus", sizeof(fn));
break;
case ('/'):
strncpy(fn, "letters/slash", sizeof(fn));
break;
case (' '):
strncpy(fn, "letters/space", sizeof(fn));
break;
default:
ltr = fn2[num];
if ('A' <= ltr && ltr <= 'Z') ltr += 'a' - 'A'; /* file names are all lower-case */
snprintf(fn, sizeof(fn), "letters/%c", ltr);
}
if(strlen(fn)){ /* if length == 0, then skip this digit as it is invalid */
res = ast_streamfile(chan, fn, lang);
if (!res)
res = ast_waitstream(chan, ints);
} ast_stopstream(chan);
num++;
}
return res;
}
int ast_say_phonetic_str(struct ast_channel *chan, char *fn2, char *ints, char *lang)
{
/* XXX Merge with full version? XXX */
char fn[256] = "";
char ltr;
int num = 0;
int res = 0;
int temp;
int play;
char hex[3];
/* while(fn2[num] && !res) { */
while(fn2[num]) {
play=1;
switch (fn2[num]) {
case ('*'):
snprintf(fn, sizeof(fn), "digits/star");
break;
case ('#'):
snprintf(fn, sizeof(fn), "digits/pound");
break;
case ('0'):
case ('1'):
case ('2'):
case ('3'):
case ('4'):
case ('5'):
case ('6'):
case ('7'):
case ('8'):
snprintf(fn, sizeof(fn), "digits/%c", fn2[num]);
break;
case ('!'):
strncpy(fn, "exclaimation-point", sizeof(fn));
break;
case ('@'):
strncpy(fn, "at", sizeof(fn));
break;
case ('$'):
strncpy(fn, "dollar", sizeof(fn));
break;
case ('-'):
strncpy(fn, "dash", sizeof(fn));
break;
case ('.'):
strncpy(fn, "dot", sizeof(fn));
break;
case ('='):
strncpy(fn, "equals", sizeof(fn));
break;
case ('+'):
strncpy(fn, "plus", sizeof(fn));
break;
case ('/'):
strncpy(fn, "slash", sizeof(fn));
break;
case (' '):
strncpy(fn, "space", sizeof(fn));
break;
case ('%'):
play=0;
/* check if we have 2 chars after the % */
if (strlen(fn2)>num+2)
{
hex[0]=fn2[num+1];
hex[1]=fn2[num+2];
hex[2]='\0';
if (sscanf(hex,"%x", &temp))
{ /* Hex to char convertion successfull */
fn2[num+2]=temp;
num++;
if (temp==37)
{ /* If it is a percent, play it now */
strncpy(fn, "percent", sizeof(fn));
num++;
play=1;
}
/* check for invalid characters */
if ((temp<32) || (temp>126))
{
num++;
}
}
}
else
num++;
break;
default: /* '9' falls through to here, too */
ltr = tolower(fn2[num]);
snprintf(fn, sizeof(fn), "phonetic/%c_p", ltr);
}
if (play)
{
res = ast_streamfile(chan, fn, lang);
if (!res)
res = ast_waitstream(chan, ints);
ast_stopstream(chan);
}
num++;
}
return res;
}
int ast_say_digit_str_full(struct ast_channel *chan, char *fn2, char *ints, char *lang, int audiofd, int ctrlfd)
{
char fn[256] = "";
@ -76,6 +249,141 @@ int ast_say_digit_str_full(struct ast_channel *chan, char *fn2, char *ints, char
return res;
}
int ast_say_character_str_full(struct ast_channel *chan, char *fn2, char *ints, char *lang, int audiofd, int ctrlfd)
{
char fn[256] = "";
char ltr;
int num = 0;
int res = 0;
while(fn2[num] && !res) {
switch (fn2[num]) {
case ('*'):
snprintf(fn, sizeof(fn), "digits/star");
break;
case ('#'):
snprintf(fn, sizeof(fn), "digits/pound");
break;
case ('0'):
case ('1'):
case ('2'):
case ('3'):
case ('4'):
case ('5'):
case ('6'):
case ('7'):
case ('8'):
case ('9'):
snprintf(fn, sizeof(fn), "digits/%c", fn2[num]);
break;
case ('!'):
strncpy(fn, "exclaimation-point", sizeof(fn));
break;
case ('@'):
strncpy(fn, "at", sizeof(fn));
break;
case ('$'):
strncpy(fn, "dollar", sizeof(fn));
break;
case ('-'):
strncpy(fn, "dash", sizeof(fn));
break;
case ('.'):
strncpy(fn, "dot", sizeof(fn));
break;
case ('='):
strncpy(fn, "equals", sizeof(fn));
break;
case ('+'):
strncpy(fn, "plus", sizeof(fn));
break;
case ('/'):
strncpy(fn, "slash", sizeof(fn));
break;
case (' '):
strncpy(fn, "space", sizeof(fn));
break;
default:
ltr = fn2[num];
if ('A' <= ltr && ltr <= 'Z') ltr += 'a' - 'A'; /* file names are all lower-case */
snprintf(fn, sizeof(fn), "letters/%c", ltr);
}
/* snprintf(fn, sizeof(fn), "digits/%c", fn2[num]); */
res = ast_streamfile(chan, fn, lang);
if (!res)
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
ast_stopstream(chan);
num++;
}
return res;
}
int ast_say_phonetic_str_full(struct ast_channel *chan, char *fn2, char *ints, char *lang, int audiofd, int ctrlfd)
{
char fn[256] = "";
char ltr;
int num = 0;
int res = 0;
while(fn2[num] && !res) {
switch (fn2[num]) {
case ('*'):
snprintf(fn, sizeof(fn), "digits/star");
break;
case ('#'):
snprintf(fn, sizeof(fn), "digits/pound");
break;
case ('0'):
case ('1'):
case ('2'):
case ('3'):
case ('4'):
case ('5'):
case ('6'):
case ('7'):
case ('8'):
snprintf(fn, sizeof(fn), "digits/%c", fn2[num]);
break;
case ('!'):
strncpy(fn, "exclaimation-point", sizeof(fn));
break;
case ('@'):
strncpy(fn, "at", sizeof(fn));
break;
case ('$'):
strncpy(fn, "dollar", sizeof(fn));
break;
case ('-'):
strncpy(fn, "dash", sizeof(fn));
break;
case ('.'):
strncpy(fn, "dot", sizeof(fn));
break;
case ('='):
strncpy(fn, "equals", sizeof(fn));
break;
case ('+'):
strncpy(fn, "plus", sizeof(fn));
break;
case ('/'):
strncpy(fn, "slash", sizeof(fn));
break;
case (' '):
strncpy(fn, "space", sizeof(fn));
break;
default: /* '9' falls here... */
ltr = fn2[num];
if ('A' <= ltr && ltr <= 'Z') ltr += 'a' - 'A'; /* file names are all lower-case */
snprintf(fn, sizeof(fn), "phonetic/%c", ltr);
}
/* snprintf(fn, sizeof(fn), "digits/%c", fn2[num]); */
res = ast_streamfile(chan, fn, lang);
if (!res)
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
ast_stopstream(chan);
num++;
}
return res;
}
int ast_say_digits(struct ast_channel *chan, int num, char *ints, char *lang)
{
/* XXX Should I be merged with say_digits_full XXX */

@ -478,3 +478,137 @@
%vm-reachoper.gsm%press 0 to reach an operator
%vm-tooshort.gsm%your message is too short
%9_p.gsm%niner
%a.gsm%a
%b.gsm%b
%c.gsm%c
%d.gsm%d
%e.gsm%e
%f.gsm%f
%g.gsm%g
%h.gsm%h
%i.gsm%i
%j.gsm%j
%k.gsm%k
%l.gsm%l
%m.gsm%m
%n.gsm%n
%o.gsm%o
%p.gsm%p
%q.gsm%q
%r.gsm%r
%s.gsm%s
%t.gsm%t
%u.gsm%u
%v.gsm%v
%w.gsm%w
%x.gsm%x
%y.gsm%y
%z.gsm%z
%zed.gsm%zed
%a_p.gsm%alpha
%b_p.gsm%bravo
%c_p.gsm%charlie
%d_p.gsm%delta
%e_p.gsm%echo
%f_p.gsm%foxtrot
%g_p.gsm%golf
%h_p.gsm%hotel
%i_p.gsm%india
%j_p.gsm%juliet
%k_p.gsm%kilo
%l_p.gsm%lima
%m_p.gsm%mike
%n_p.gsm%november
%o_p.gsm%oscar
%p_p.gsm%papa
%q_p.gsm%quebec
%r_p.gsm%romeo
%s_p.gsm%sierra
%t_p.gsm%tango
%u_p.gsm%uniform
%v_p.gsm%victor
%w_p.gsm%wiskey
%x_p.gsm%xray
%y_p.gsm%yankee
%z_p.gsm%zulu
%niner.gsm%niner
; Misc
%percent.gsm%percent [%]
%plus.gsm%plus [+]
%exclaimation-point.gsm%exclaimation-point [!]
%at.gsm%at [@]
%dollar.gsm%dollar [$]
%dash.gsm%dash [-]
%dot.gsm%dot [.]
%slash.gsm%slash [/]
%space.gsm%space [ ]
%plus.gsm%plus [+]
%equals.gsm%equals [=]

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,2 @@
Ô÷ƒsP VìµéeUñÉ$dyeVѹ[#[#P²JäBÉ#Ôx\zIâ®ØãØÜ˜ÌFÐËVëäŠT<C5A0>çÖóç 6rÕÛÔ·j©ÐçI"³v.Õ›*¤{u¬£ÆL3:I“<49>j1]–ÙÔ7Z¥IŸ¦dÛkˆÓQF‡¤¶ºÕñEÖz—ñ:ï»#Ô¶<,ƒ¡§H1Š˜êQ<12>=ÎÜ¡#!<21>]iñ²Ý^[TÓóCá
ñC€ìò¼¡£fÏ‘ÇQDùîZ£¡À-=ÊÛÓ±KeCñd±îY#£D”¹ÒL«QæÊ3YISD0;¾K%Ó­RiÂSe¦5¬ÚSÂ2„«²pSd˜ÓÙ\¥f¶Ð¹æäÓ*j^™U(8¢]JÞSFÇ©[¦ÅÔ¨ ó¬Væt&OÓæjÖ™¨Ç<C2A8>KŒ¥ÜXÅÕ±QW^äNufF)ºÃ»Öµdâ×çI ½öÚ<C3B6>»'S馄V‡.Dë¬Âqy©S0Øê¥ ÛÖB‰Sáœâ"sµ¾ÐàÂèãî÷»n³zîÙ¯¤ÕJªâ(M“N³Z´i>*dƒÂIŠS`qD Ø1é]ØîÅ™h㎣V[}®Æ<1F>/͹q&_iG24bÆ×qJ¼×²Íaî§¹e6"Âã>1¤“°A£ ˜A¹6²ÝþÖëa…ÚÜo·ºÙ,ì@|=.“lÚ@²êm²âä@HéfBÛÕ¢QÐÙ¸ J܉ÀbÆàZãQÉ%„ I3<å¸@7cn&ÜØ³<C398>ÖÕÛåÈãm·qèÆ}4¥h†I<E280A0>rÆ#¸$𤌢š×©b†îE'ÍæBµ£r.d¯Âç<C382>y£kzÄ´·þËÔ ]—ÒYj"Ö)$PÈ6×2·»¨§ÆÛHŸ[E! hþsÔ¢U<C2A2>Y·Ixc-Ÿd]¥dmB×]'¸ßqTй.<2E>9+ÔäEa¿(¥8uêžcHFLÐôùÇ& …)¹Ôƨ¹[éœÔçE È‡õb•NÓgz­º£ÎǦ™oÉmh)"<22>¶úÕ(Ké©kdFµSÄàkÅ„lÒG"o'¸âMf»mÄúo2òÕª:eêl£½ âþLmG5×2IÛDpcs\¥ÚĮ۩4PÔç4¥aÜÆxëqÇ"Ý#Åhr¸œàƒÙcm*5bÂÈnSåÖ,àèåD¼±¹+yCXÒJÖwB6©v<C2A9>Òxå3z±HäÖk:¥àvÃØM íñc©TÒQñ$D:ñ®­ ¤Î¯Ö«B!©šÂªÛ¾ñCk”ózÈ(4´<>ƒb­×2NÚðÄ&¼’-xáÖØˆYð<> k¯Çð¢6œ£·×q3M©€ÂFÓ‰Dü~Á¥“T|¡%<12>º«ðá7Ùm4ž×´KiîÀ©'^£ÈØ<C388>5%rWœnÁ(ÂQ:¤Ø ¸BR×µsPêÎ@ÊÞrÉ#ð`ePl· Ð@$ã+ v@'¢<>¶Û

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.
Loading…
Cancel
Save