Add support for French, Danish, Portuguese, Spanish, Italian, and Dutch numbers

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2809 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.0
Mark Spencer 21 years ago
parent 7e79c52808
commit 5192a1a054

@ -621,7 +621,7 @@ static int count_exec(struct ast_channel *chan, void *data)
} else {
if (chan->_state != AST_STATE_UP)
ast_answer(chan);
res = ast_say_number(chan, count, "", chan->language);
res = ast_say_number(chan, count, "", chan->language, (char *) NULL); /* Needs gender */
}
LOCAL_USER_REMOVE(u);
return res;

@ -370,7 +370,7 @@ static int say_position(struct queue_ent *qe)
goto posout;
} else {
res += play_file(qe->chan, qe->parent->sound_thereare);
res += ast_say_number(qe->chan, qe->pos, AST_DIGIT_ANY, qe->chan->language);
res += ast_say_number(qe->chan, qe->pos, AST_DIGIT_ANY, qe->chan->language, (char *) NULL); /* Needs gender */
res += play_file(qe->chan, qe->parent->sound_calls);
}
@ -383,7 +383,7 @@ static int say_position(struct queue_ent *qe)
supposed to be only once and we have already said it, say it */
if (avgholdmins > 1 && (qe->parent->announceholdtime) && (!(qe->parent->announceholdtime==1 && qe->last_pos)) ) {
res += play_file(qe->chan, qe->parent->sound_holdtime);
res += ast_say_number(qe->chan, avgholdmins, AST_DIGIT_ANY, qe->chan->language);
res += ast_say_number(qe->chan, avgholdmins, AST_DIGIT_ANY, qe->chan->language, (char*) NULL);
res += play_file(qe->chan, qe->parent->sound_minutes);
}

@ -1706,7 +1706,7 @@ static int count_messages(char *dir)
static int say_and_wait(struct ast_channel *chan, int num)
{
int d;
d = ast_say_number(chan, num, AST_DIGIT_ANY, chan->language);
d = ast_say_number(chan, num, AST_DIGIT_ANY, chan->language, (char *) NULL);
return d;
}
@ -2270,7 +2270,7 @@ static int get_folder(struct ast_channel *chan, int start)
if (d)
return d;
for (x = start; x< 5; x++) {
if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language)))
if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, (char *) NULL)))
return d;
d = play_and_wait(chan, "vm-for");
if (d)
@ -2634,7 +2634,7 @@ static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struc
res = wait_file2(chan, vms, "vm-message");
if (msg && (msg != vms->lastmsg)) {
if (!res)
res = ast_say_number(chan, msg + 1, AST_DIGIT_ANY, chan->language);
res = ast_say_number(chan, msg + 1, AST_DIGIT_ANY, chan->language, (char *) NULL);
}
}

@ -322,7 +322,7 @@ static int conf_exec(struct ast_channel *chan, void *data)
}
confno = atoi(strchr(confstr,'/') + 1);
ast_stopstream(chan);
ast_say_number(chan, confno, AST_DIGIT_ANY, chan->language);
ast_say_number(chan, confno, AST_DIGIT_ANY, chan->language, (char *) NULL);
res = conf_run(chan, confno, confflags);
if (res<0) break;
input = res;

@ -2350,12 +2350,12 @@ static void bridge_playfile(struct ast_channel *chan,char *sound,int remain) {
res=ast_streamfile(chan,"vm-youhave",chan->language);
res = ast_waitstream(chan, "");
if(min) {
res = ast_say_number(chan,min, AST_DIGIT_ANY, chan->language);
res = ast_say_number(chan,min, AST_DIGIT_ANY, chan->language, (char *) NULL);
res=ast_streamfile(chan,"minutes",chan->language);
res = ast_waitstream(chan, "");
}
if(sec) {
res = ast_say_number(chan,sec, AST_DIGIT_ANY, chan->language);
res = ast_say_number(chan,sec, AST_DIGIT_ANY, chan->language, (char *) NULL);
res=ast_streamfile(chan,"seconds",chan->language);
res = ast_waitstream(chan, "");
}

@ -0,0 +1,66 @@
; Test Internationalisation of SayNumber()
; #include this into a suitable context
; English
exten => 841,1,Answer
exten => 841,2,Wait,1 ; Allow VoIP sessions time to initialise
exten => 841,3,SetLanguage(en)
exten => 841,4,SayNumber(183) ; one hundred eighty three (NB This sounds wrong to me!)
; French
exten => 842,1,Answer
exten => 842,2,Wait,1 ; Allow VoIP sessions time to initialise
exten => 842,3,SetLanguage(fr)
exten => 842,4,SayNumber(183) ; hundred eighty three
exten => 842,5,SayNumber(283) ; two hundred eighty three
exten => 842,6,SayNumber(1063) ; thousand sixty three
exten => 842,7,SayNumber(2063) ; two thousand sixty three
; Spanish
exten => 843,1,Answer
exten => 843,2,Wait,1 ; Allow VoIP sessions time to initialise
exten => 843,3,SetLanguage(es)
exten => 843,4,SayNumber(21) ; "twentyone"
exten => 843,5,SayNumber(200) ; "twohundred"
exten => 843,6,SayNumber(1000000) ; one million
exten => 843,7,SayNumber(2000000) ; two millions
; Portuguese
exten => 844,1,Answer
exten => 844,2,Wait,1 ; Allow VoIP sessions time to initialise
exten => 844,3,SetLanguage(pt)
exten => 844,4,SayNumber(1) ; one
exten => 844,5,SayNumber(1,f) ; one (feminine)
exten => 844,6,SayNumber(2) ; two
exten => 844,7,SayNumber(2,f) ; two (feminine)
exten => 844,8,SayNumber(183) ; hundred& eighty three
; Italian
exten => 845,1,Answer
exten => 845,2,Wait,1 ; Allow VoIP sessions time to initialise
exten => 845,3,SetLanguage(it)
exten => 845,4,SayNumber(21) ; "twentyone"
exten => 845,5,SayNumber(183) ; hundred eighty three
exten => 845,6,SayNumber(283) ; two hundred eighty three
exten => 845,7,SayNumber(1063) ; thousand sixty three
exten => 845,8,SayNumber(2063) ; two thousands sixty three
; Dutch
exten => 846,1,Answer
exten => 846,2,Wait,1 ; Allow VoIP sessions time to initialise
exten => 846,3,SetLanguage(nl)
; Danish
exten => 847,1,Answer
exten => 847,2,Wait,1 ; Allow VoIP sessions time to initialise
exten => 847,3,SetLanguage(da)
exten => 847,4,SayNumber(68) ; eight-& sixty
exten => 847,5,SayNumber(2034) ; two thousand & four-& thirty
exten => 847,6,SayNumber(1000000) ; one million
exten => 847,7,SayNumber(2000000) ; two millions
; German (not yet implemented)
exten => 848,1,Answer
exten => 848,2,Wait,1 ; Allow VoIP sessions time to initialise
exten => 848,3,SetLanguage(de)
exten => 848,4,SayNumber(68) ; eight-& sixty
exten => 848,5,SayNumber(2034) ; two thousand & four-& thirty
exten => 848,6,SayNumber(1000000) ; one million
exten => 848,7,SayNumber(2000000) ; two millions
; Swedish
exten => 849,1,Answer
exten => 849,2,Wait,1 ; Allow VoIP sessions time to initialise
exten => 849,3,SetLanguage(se)

@ -29,10 +29,11 @@ extern "C" {
* \param num number to say on the channel
* \param ints which dtmf to interrupt on
* \param lang language to speak the number
* \param options set to 'f' for female, 'm' for masculine (used in portuguese)
* Vocally says a number on a given channel
* Returns 0 on success, DTMF digit on interrupt, -1 on failure
*/
int ast_say_number(struct ast_channel *chan, int num, char *ints, char *lang);
int ast_say_number(struct ast_channel *chan, int num, char *ints, char *lang, char *options);
/* Same as above with audiofd for received audio and returns 1 on ctrlfd being readable */
int ast_say_number_full(struct ast_channel *chan, int num, char *ints, char *lang, int audiofd, int ctrlfd);

28
pbx.c

@ -287,7 +287,7 @@ static struct pbx_builtin {
{ "SayNumber", pbx_builtin_saynumber,
"Say Number",
" SayNumber(digits): Says the passed number\n" },
" SayNumber(digits[,gender]): Says the passed number\n" },
{ "SayDigits", pbx_builtin_saydigits,
"Say Digits",
@ -4568,9 +4568,29 @@ static int pbx_builtin_gotoif(struct ast_channel *chan, void *data)
static int pbx_builtin_saynumber(struct ast_channel *chan, void *data)
{
int res = 0;
if (data && atoi((char *)data) )
res = ast_say_number(chan, atoi((char *)data), "", chan->language);
return res;
char tmp[256];
char *number = (char *) NULL;
char *options = (char *) NULL;
if (!data || !strlen((char *)data)) {
ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n");
return -1;
}
strncpy(tmp, (char *)data, sizeof(tmp)-1);
number=tmp;
strsep(&number, "|");
options = strsep(&number, "|");
if (options) {
if ( strcasecmp(options, "f") && strcasecmp(options,"m") &&
strcasecmp(options, "c") && strcasecmp(options, "n") ) {
ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n");
return -1;
}
}
return res = ast_say_number(chan, atoi((char *) tmp), "", chan->language, options);
}
static int pbx_builtin_saydigits(struct ast_channel *chan, void *data)

875
say.c

@ -25,6 +25,10 @@
#include "asterisk.h"
#include <stdio.h>
/* Forward declaration */
static int wait_file(struct ast_channel *chan, char *ints, char *file, char *lang);
int ast_say_digit_str(struct ast_channel *chan, char *fn2, char *ints, char *lang)
{
/* XXX Merge with full version? XXX */
@ -87,22 +91,95 @@ int ast_say_digits_full(struct ast_channel *chan, int num, char *ints, char *lan
return ast_say_digit_str_full(chan, fn2, ints, lang, audiofd, ctrlfd);
}
/* Forward declarations */
/* Syntaxes supported, not really language codes.
en - English, Swedish, Norwegian
fr - French
da - Danish (maybe German - please check)
pt - Portuguese
es - Spanish
it - Italian
nl - Dutch
For portuguese, we're using an option to saynumber() to indicate if the gender is male of female
This should also be implemented in _full version, really.
OEJ 2004-04-25
*/
static int ast_say_number_full_en(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd);
static int ast_say_number_full_fr(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd);
static int ast_say_number_full_de(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd);
static int ast_say_number_full_da(struct ast_channel *chan, int num, char *ints, char *language, char *options, int audiofd, int ctrlfd);
static int ast_say_number_full_pt(struct ast_channel *chan, int num, char *ints, char *language, char *options, int audiofd, int ctrlfd);
static int ast_say_number_full_it(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd);
static int ast_say_number_full_es(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd);
static int ast_say_number_full_nl(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd);
/*--- ast_say_number_full: call language-specific functions */
/* Called from AGI */
int ast_say_number_full(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd)
{
char *options=(char *) NULL; /* While waiting for a general hack for agi */
if (!strcasecmp(language, "no") || !strcasecmp(language,"se") || !strcasecmp(language,"en") ) {
return(ast_say_number_full_en(chan, num, ints, language, audiofd, ctrlfd));
} else if (!strcasecmp(language, "fr") ) { /* French syntax */
return(ast_say_number_full_fr(chan, num, ints, language, audiofd, ctrlfd));
} else if (!strcasecmp(language, "de") ) { /* German syntax */
return(ast_say_number_full_de(chan, num, ints, language, audiofd, ctrlfd));
} else if (!strcasecmp(language, "da") ) { /* Danish syntax */
return(ast_say_number_full_da(chan, num, ints, language, options, audiofd, ctrlfd));
} else if (!strcasecmp(language, "it") ) { /* Italian syntax */
return(ast_say_number_full_it(chan, num, ints, language, audiofd, ctrlfd));
} else if (!strcasecmp(language, "pt") ) { /* Portuguese syntax */
return(ast_say_number_full_pt(chan, num, ints, language, options, audiofd, ctrlfd));
} else if (!strcasecmp(language, "es") ) { /* Spanish syntax */
return(ast_say_number_full_es(chan, num, ints, language, audiofd, ctrlfd));
} else if (!strcasecmp(language, "nl") ) { /* Spanish syntax */
return(ast_say_number_full_nl(chan, num, ints, language, audiofd, ctrlfd));
}
/* Default to english */
return(ast_say_number_full_en(chan, num, ints, language, audiofd, ctrlfd));
}
/*--- ast_say_number: call language-specific functions without file descriptors */
int ast_say_number(struct ast_channel *chan, int num, char *ints, char *language, char *options)
{
if (!strcasecmp(language, "no") || !strcasecmp(language,"se") || !strcasecmp(language,"en") ) {
return(ast_say_number_full_en(chan, num, ints, language, -1, -1));
}
/* French */
if (!strcasecmp(language, "fr")) { /* French syntax */
return(ast_say_number_full_fr(chan, num, ints, language, -1, -1));
} else if (!strcasecmp(language, "da")) { /* Danish syntax */
return(ast_say_number_full_da(chan, num, ints, language, options, -1, -1));
} else if (!strcasecmp(language, "it")) { /* Italian syntax */
return(ast_say_number_full_it(chan, num, ints, language, -1, -1));
} else if (!strcasecmp(language, "pt")) { /* Portuguese syntax */
return(ast_say_number_full_pt(chan, num, ints, language, options, -1, -1));
} else if (!strcasecmp(language, "nl")) { /* Spanish syntax */
return(ast_say_number_full_nl(chan, num, ints, language, -1, -1));
} else if (!strcasecmp(language, "es")) { /* Spanish syntax */
return(ast_say_number_full_es(chan, num, ints, language, -1, -1));
}
/* Default to english */
return(ast_say_number_full_en(chan, num, ints, language, NULL, NULL));
}
/*--- ast_say_number_full_en: English syntax */
/* This is the default syntax, if no other syntax defined in this file is used */
static int ast_say_number_full_en(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd)
{
int res = 0;
int playh = 0;
char fn[256] = "";
if (!num)
return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
if (0) {
/* XXX Only works for english XXX */
} else {
/* Use english numbers if a given language is supported. */
/* As a special case, Norwegian has the same numerical grammar
as English */
if (strcasecmp(language, "no"))
language = "en";
while(!res && (num || playh)) {
while(!res && (num || playh)) {
if (playh) {
snprintf(fn, sizeof(fn), "digits/hundred");
playh = 0;
@ -121,14 +198,14 @@ int ast_say_number_full(struct ast_channel *chan, int num, char *ints, char *lan
num -= ((num / 100) * 100);
} else {
if (num < 1000000) { /* 1,000,000 */
res = ast_say_number_full(chan, num / 1000, ints, language, audiofd, ctrlfd);
res = ast_say_number_full_en(chan, num / 1000, ints, language, audiofd, ctrlfd);
if (res)
return res;
num = num % 1000;
snprintf(fn, sizeof(fn), "digits/thousand");
} else {
if (num < 1000000000) { /* 1,000,000,000 */
res = ast_say_number_full(chan, num / 1000000, ints, language, audiofd, ctrlfd);
res = ast_say_number_full_en(chan, num / 1000000, ints, language, audiofd, ctrlfd);
if (res)
return res;
num = num % 1000000;
@ -140,80 +217,723 @@ int ast_say_number_full(struct ast_channel *chan, int num, char *ints, char *lan
}
}
}
if (!res) {
res = ast_streamfile(chan, fn, language);
if (!res)
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
ast_stopstream(chan);
}
if (!res) {
if(!ast_streamfile(chan, fn, language)) {
if (audiofd && ctrlfd)
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
else
res = ast_waitstream(chan, ints);
}
ast_stopstream(chan);
}
}
}
return res;
}
int ast_say_number(struct ast_channel *chan, int num, char *ints, char *language)
/*--- ast_say_number_full_fr: French syntax */
static int ast_say_number_full_fr(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd)
{
/* XXX Should I be merged with ast_say_number_full XXX */
int res = 0;
int playh = 0;
int playa = 0; /* For french */
char fn[256] = "";
if (!num)
return ast_say_digits(chan, 0,ints, language);
if (0) {
/* XXX Only works for english XXX */
} else {
/* Use english numbers */
language = "en";
while(!res && (num || playh)) {
if (playh) {
snprintf(fn, sizeof(fn), "digits/hundred");
playh = 0;
} else
if (num < 20) {
snprintf(fn, sizeof(fn), "digits/%d", num);
return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
while(!res && (num || playh || playa)) {
if (playh) {
snprintf(fn, sizeof(fn), "digits/hundred");
playh = 0;
} else
if (playa) {
snprintf(fn, sizeof(fn), "digits/et");
playa = 0;
} else
if (num < 21) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num < 70) {
snprintf(fn, sizeof(fn), "digits/%d", (num/10)*10);
if ((num % 10) == 1) playa++;
num = num % 10;
} else
if (num < 80) {
snprintf(fn, sizeof(fn), "digits/60");
if ((num % 10) == 1) playa++;
num = num - 60;
} else
if (num < 100) {
snprintf(fn, sizeof(fn), "digits/80");
num = num - 80;
} else
if (num < 200) {
snprintf(fn, sizeof(fn), "digits/hundred");
num = num - 100;
} else
if (num < 1000) {
snprintf(fn, sizeof(fn), "digits/%d", (num/100));
playh++;
num = num % 100;
} else
if (num < 2000) {
snprintf(fn, sizeof(fn), "digits/thousand");
num = num - 1000;
} else
if (num < 1000000) {
res = ast_say_number_full_fr(chan, num / 1000, ints, language, audiofd, ctrlfd);
if (res) return res;
snprintf(fn, sizeof(fn), "digits/thousand");
num = num % 1000;
} else
if (num < 1000000000) {
res = ast_say_number_full_fr(chan, num / 1000000, ints, language, audiofd, ctrlfd);
if (res) return res;
snprintf(fn, sizeof(fn), "digits/million");
num = num % 1000000;
} else {
ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
res = -1;
}
if (!res) {
if(!ast_streamfile(chan, fn, language)) {
if (audiofd && ctrlfd)
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
else
res = ast_waitstream(chan, ints);
}
ast_stopstream(chan);
}
}
return res;
}
/*--- ast_say_number_full_da: Danish syntax */
/* New files:
In addition to English, the following sounds are required: "1N", "millions", "and" and "1-and" through "9-and"
*/
static int ast_say_number_full_da(struct ast_channel *chan, int num, char *ints, char *language, char *options, int audiofd, int ctrlfd)
{
int res = 0;
int playh = 0;
int playa = 0;
int cn = 1; /* +1 = Commune; -1 = Neutrum */
char fn[256] = "";
if (!num)
return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
if (options && !strncasecmp(options, "n",1)) cn = -1;
while(!res && (num || playh || playa )) {
/* The grammer for Danish numbers is the same as for English except
* for the following:
* - 1 exists in both commune ("en", file "1N") and neutrum ("et", file "1")
* - numbers 20 through 99 are said in reverse order, i.e. 21 is
* "one-and twenty" and 68 is "eight-and sixty".
* - "million" is different in singular and plural form
* - numbers > 1000 with zero as the third digit from last have an
* "and" before the last two digits, i.e. 2034 is "two thousand and
* four-and thirty" and 1000012 is "one million and twelve".
*/
if (playh) {
snprintf(fn, sizeof(fn), "digits/hundred");
playh = 0;
} else
if (playa) {
snprintf(fn, sizeof(fn), "digits/and");
playa = 0;
} else
if (num == 1 && cn == -1) {
snprintf(fn, sizeof(fn), "digits/1N");
num = 0;
} else
if (num < 100) {
snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
num -= ((num / 10) * 10);
} else {
if (num < 1000){
snprintf(fn, sizeof(fn), "digits/%d", (num/100));
playh++;
num -= ((num / 100) * 100);
} else {
if (num < 1000000) {
res = ast_say_number(chan, num / 1000, ints, language);
if (res)
return res;
num = num % 1000;
snprintf(fn, sizeof(fn), "digits/thousand");
} else
if (num < 20) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num < 100) {
int ones = num % 10;
if (ones) {
snprintf(fn, sizeof(fn), "digits/%d-and", ones);
num -= ones;
} else {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
}
} else {
if (num < 1000) {
int hundreds = num / 100;
if (hundreds == 1)
snprintf(fn, sizeof(fn), "digits/1N");
else
snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
playh++;
num -= 100 * hundreds;
if (num)
playa++;
} else {
if (num < 1000000) {
res = ast_say_number_full_da(chan, num / 1000, ints, language, "n", audiofd, ctrlfd);
if (res)
return res;
num = num % 1000;
snprintf(fn, sizeof(fn), "digits/thousand");
} else {
if (num < 1000000000) {
int millions = num / 1000000;
res = ast_say_number_full_da(chan, millions, ints, language, "c", audiofd, ctrlfd);
if (res)
return res;
if (millions == 1)
snprintf(fn, sizeof(fn), "digits/million");
else
snprintf(fn, sizeof(fn), "digits/millions");
num = num % 1000000;
} else {
if (num < 1000000000) {
res = ast_say_number(chan, num / 1000000, ints, language);
if (res)
return res;
num = num % 1000000;
snprintf(fn, sizeof(fn), "digits/million");
} else {
ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
res = -1;
}
}
ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
res = -1;
}
}
if (num && num < 100)
playa++;
}
}
if (!res) {
if(!ast_streamfile(chan, fn, language)) {
if (audiofd && ctrlfd)
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
else
res = ast_waitstream(chan, ints);
}
ast_stopstream(chan);
}
}
return res;
}
/*--- ast_say_number_full_de: German syntax */
/* New files:
In addition to English, the following sounds are required: "millions", "and" and "1-and" through "9-and"
*/
static int ast_say_number_full_de(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd)
{
int res = 0;
int playh = 0;
int playa = 0;
char fn[256] = "";
if (!num)
return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
while(!res && (num || playh || playa )) {
/* The grammer for German numbers is the same as for English except
* for the following:
* - numbers 20 through 99 are said in reverse order, i.e. 21 is
* "one-and twenty" and 68 is "eight-and sixty".
* - "million" is different in singular and plural form
* - numbers > 1000 with zero as the third digit from last have an
* "and" before the last two digits, i.e. 2034 is "two thousand and
* four-and thirty" and 1000012 is "one million and twelve".
*/
if (playh) {
snprintf(fn, sizeof(fn), "digits/hundred");
playh = 0;
} else
if (playa) {
snprintf(fn, sizeof(fn), "digits/and");
playa = 0;
} else
if (num < 20) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num < 100) {
int ones = num % 10;
if (ones) {
snprintf(fn, sizeof(fn), "digits/%d-and", ones);
num -= ones;
} else {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
}
} else {
if (num < 1000) {
int hundreds = num / 100;
if (hundreds == 1)
snprintf(fn, sizeof(fn), "digits/1N");
else
snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
playh++;
num -= 100 * hundreds;
if (num)
playa++;
} else {
if (num < 1000000) {
res = ast_say_number_full_da(chan, num / 1000, ints, language, "n", audiofd, ctrlfd);
if (res)
return res;
num = num % 1000;
snprintf(fn, sizeof(fn), "digits/thousand");
} else {
if (num < 1000000000) {
int millions = num / 1000000;
res = ast_say_number_full_da(chan, millions, ints, language, "c", audiofd, ctrlfd);
if (res)
return res;
if (millions == 1)
snprintf(fn, sizeof(fn), "digits/million");
else
snprintf(fn, sizeof(fn), "digits/millions");
num = num % 1000000;
} else {
ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
res = -1;
}
}
if (num && num < 100)
playa++;
}
}
if (!res) {
res = ast_streamfile(chan, fn, language);
if (!res)
res = ast_waitstream(chan, ints);
if(!ast_streamfile(chan, fn, language)) {
if (audiofd && ctrlfd)
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
else
res = ast_waitstream(chan, ints);
}
ast_stopstream(chan);
}
}
}
return res;
}
/*------------ Portuguese ----------------------*/
/* ast_say_number_full_pt: Portuguese syntax */
/* For feminin all sound files end with F */
/* 100E for 100+ something */
/* What is "pt-e" */
static int ast_say_number_full_pt(struct ast_channel *chan, int num, char *ints, char *language, char *options, int audiofd, int ctrlfd)
{
int res = 0;
int playh = 0;
int mf = 1; /* +1 = Masculin; -1 = Feminin */
char fn[256] = "";
if (!num)
return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
if (options && !strncasecmp(options, "f",1)) mf = -1;
while(!res && num ) {
if (num < 20) {
if ((num == 1 || num == 2) && (mf < 0))
snprintf(fn, sizeof(fn), "digits/%dF", num);
else
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num < 100) {
snprintf(fn, sizeof(fn), "digits/%d", (num / 10) * 10);
if (num % 10)
playh = 1;
num = num % 10;
} else
if (num < 1000) {
if (num == 100)
snprintf(fn, sizeof(fn), "digits/100");
else if (num < 200)
snprintf(fn, sizeof(fn), "digits/100E");
else {
if (mf < 0 && num > 199)
snprintf(fn, sizeof(fn), "digits/%dF", (num / 100) * 100);
else
snprintf(fn, sizeof(fn), "digits/%d", (num / 100) * 100);
if (num % 100)
playh = 1;
}
num = num % 100;
} else
if (num < 1000000) {
if (num > 1999) {
res = ast_say_number_full_pt(chan, (num / 1000) * mf, ints, language, options, audiofd, ctrlfd);
if (res)
return res;
}
snprintf(fn, sizeof(fn), "digits/1000");
if ((num % 1000) && ((num % 1000) < 100 || !(num % 100)))
playh = 1;
num = num % 1000;
} else
if (num < 1000000000) {
res = ast_say_number_full_pt(chan, (num / 1000000), ints, language, options, audiofd, ctrlfd );
if (res)
return res;
if (num < 2000000)
snprintf(fn, sizeof(fn), "digits/1000000");
else
snprintf(fn, sizeof(fn), "digits/1000000S");
if ((num % 1000000) &&
// no thousands
((!((num / 1000) % 1000) && ((num % 1000) < 100 || !(num % 100))) ||
// no hundreds and below
(!(num % 1000) && (((num / 1000) % 1000) < 100 || !((num / 1000) % 100))) ) )
playh = 1;
num = num % 1000000;
}
if (!res && playh) {
res = wait_file(chan, ints, "digits/pt-e", language);
ast_stopstream(chan);
playh = 0;
}
if (!res) {
if(!ast_streamfile(chan, fn, language)) {
if (audiofd && ctrlfd)
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
else
res = ast_waitstream(chan, ints);
}
ast_stopstream(chan);
}
}
return res;
}
/*--- ast_say_number_full_it: italian */
static int ast_say_number_full_it(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd)
{
int res = 0;
int playh = 0;
int tempnum = 0;
char fn[256] = "";
if (!num)
return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
/*
Italian support
Like english, numbers till 20 are a single 'word', and other
compound, but with exceptions.
For example 21 is not twenty-one, but is a single word in it.
Idem for 28 (ie when a the 2nd part of a compund number
starts with a wovel)
There're exceptions also for hundred, thounsand and million.
In english 100 = one hundred, 200 is two hundred.
In italian 100 = cento , like to say hundred (without one),
200 and more are like english.
Same apply for thousand:
1000 is one thousand in en, 2000 is two thousand.
In it we have 1000 = mille , 2000 = 2 mila
For million(s) we use the plural, if more than one
Also, one million is abbreviated in it, like on-million,
or 'un milione', not 'uno milione'.
So the right file is provided.
*/
while(!res && (num || playh)) {
if (playh) {
snprintf(fn, sizeof(fn), "digits/hundred");
playh = 0;
} else
if (num < 20) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num == 21) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num == 28) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num == 31) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num == 38) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num == 41) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num == 48) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num == 51) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num == 58) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num == 61) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num == 68) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num == 71) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num == 78) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num == 81) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num == 88) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num == 91) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num == 98) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num < 100) {
snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
num -= ((num / 10) * 10);
} else {
if (num < 1000){
if ((num / 100) > 1) {
snprintf(fn, sizeof(fn), "digits/%d", (num/100));
playh++;
}
else {
snprintf(fn, sizeof(fn), "digits/hundred");
}
num -= ((num / 100) * 100);
} else {
if (num < 1000000) { /* 1,000,000 */
if ((num/1000) > 1)
res = ast_say_number_full(chan, num / 1000, ints, language, audiofd, ctrlfd);
if (res)
return res;
tempnum = num;
num = num % 1000;
if ((tempnum / 1000) < 2)
snprintf(fn, sizeof(fn), "digits/thousand");
else /* for 1000 it says mille, for >1000 (eg 2000) says mila */
snprintf(fn, sizeof(fn), "digits/thousands");
} else {
if (num < 1000000000) { /* 1,000,000,000 */
if ((num / 1000000) > 1)
res = ast_say_number_full(chan, num / 1000000, ints, language, audiofd, ctrlfd);
if (res)
return res;
tempnum = num;
num = num % 1000000;
if ((tempnum / 1000000) < 2)
snprintf(fn, sizeof(fn), "digits/million");
else
snprintf(fn, sizeof(fn), "digits/millions");
} else {
ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
res = -1;
}
}
}
}
if (!res) {
if(!ast_streamfile(chan, fn, language)) {
if (audiofd && ctrlfd)
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
else
res = ast_waitstream(chan, ints);
}
ast_stopstream(chan);
}
}
return res;
}
/*--- ast_say_number_full_es: spanish syntax */
/* New files:
Requires a few new audios:
21.gsm thru 29.gsm, cien.gsm, mil.gsm, millon.gsm, millones.gsm, 100.gsm, 200.gsm, 300.gsm, 400.gsm, 500.gsm, 600.gsm, 700.gsm, 800.gsm, 900.gsm, y.gsm
*/
static int ast_say_number_full_es(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd)
{
int res = 0;
int playa = 0;
char fn[256] = "";
if (!num)
return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
while (!res && num) {
if (playa) {
snprintf(fn, sizeof(fn), "digits/y");
playa = 0;
} else
if (num < 31) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num < 100) {
snprintf(fn, sizeof(fn), "digits/%d", (num/10)*10);
num -= ((num/10)*10);
if (num)
playa++;
} else
if (num == 100) {
snprintf(fn, sizeof(fn), "digits/cien");
num = 0;
} else {
if (num < 1000) {
snprintf(fn, sizeof(fn), "digits/%d", (num/100)*100);
num -= ((num/100)*100);
} else {
if (num < 1000000) {
res = ast_say_number_full_es(chan, num / 1000, ints, language, audiofd, ctrlfd);
if (res)
return res;
num = num % 1000;
snprintf(fn, sizeof(fn), "digits/mil");
} else {
if (num < 2147483640) {
res = ast_say_number_full_es(chan, num / 1000000, ints, language, audiofd, ctrlfd);
if (res)
return res;
if ((num/1000000) == 1) {
snprintf(fn, sizeof(fn), "digits/millon");
} else {
snprintf(fn, sizeof(fn), "digits/millones");
}
num = num % 1000000;
} else {
ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
res = -1;
}
}
}
}
if (!res) {
if(!ast_streamfile(chan, fn, language)) {
if (audiofd && ctrlfd)
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
else
res = ast_waitstream(chan, ints);
}
ast_stopstream(chan);
}
}
return res;
}
/*--- ast_say_number_full_nl: dutch syntax */
/* New files: ???
*/
static int ast_say_number_full_nl(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd)
{
int res = 0;
int playh = 0;
int units = 0;
char fn[256] = "";
if (!num)
return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
while (!res && (num || playh )) {
if (playh) {
snprintf(fn, sizeof(fn), "digits/hundred");
playh = 0;
} else
if (num < 20) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else
if (num < 100) {
units = num % 10;
if (units > 0) {
res = ast_say_number_full_nl(chan, units, ints, language, audiofd, ctrlfd);
if (res)
return res;
num = num - units;
snprintf(fn, sizeof(fn), "digits/nl-en");
} else {
snprintf(fn, sizeof(fn), "digits/%d", num - units);
num = 0;
}
} else {
if (num < 1000){
snprintf(fn, sizeof(fn), "digits/%d", (num/100));
playh++;
num -= ((num / 100) * 100);
} else {
if (num < 1000000) { /* 1,000,000 */
res = ast_say_number_full_en(chan, num / 1000, ints, language, audiofd, ctrlfd);
if (res)
return res;
num = num % 1000;
snprintf(fn, sizeof(fn), "digits/thousand");
} else {
if (num < 1000000000) { /* 1,000,000,000 */
res = ast_say_number_full_en(chan, num / 1000000, ints, language, audiofd, ctrlfd);
if (res)
return res;
num = num % 1000000;
snprintf(fn, sizeof(fn), "digits/million");
} else {
ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
res = -1;
}
}
}
}
if (!res) {
if(!ast_streamfile(chan, fn, language)) {
if (audiofd && ctrlfd)
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
else
res = ast_waitstream(chan, ints);
}
ast_stopstream(chan);
}
}
return res;
}
int ast_say_date(struct ast_channel *chan, time_t t, char *ints, char *lang)
{
struct tm tm;
@ -233,12 +953,13 @@ int ast_say_date(struct ast_channel *chan, time_t t, char *ints, char *lang)
res = ast_waitstream(chan, ints);
}
if (!res)
res = ast_say_number(chan, tm.tm_mday, ints, lang);
res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
/* Should portuguese add a gender here? Defaults to masculin */
if (!res)
res = ast_waitstream(chan, ints);
if (!res)
res = ast_say_number(chan, tm.tm_year + 1900, ints, lang);
res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
return res;
}
@ -548,21 +1269,21 @@ int ast_say_time(struct ast_channel *chan, time_t t, char *ints, char *lang)
pm = 1;
}
if (!res)
res = ast_say_number(chan, hour, ints, lang);
res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
if (tm.tm_min > 9) {
if (!res)
res = ast_say_number(chan, tm.tm_min, ints, lang);
res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
} else if (tm.tm_min) {
if (!res)
res = ast_streamfile(chan, "digits/oh", lang);
res = ast_streamfile(chan, "digits/oh", lang); /* This is very english ! */
if (!res)
res = ast_waitstream(chan, ints);
if (!res)
res = ast_say_number(chan, tm.tm_min, ints, lang);
res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
} else {
if (!res)
res = ast_streamfile(chan, "digits/oclock", lang);
res = ast_streamfile(chan, "digits/oclock", lang); /* This is very english ! */
if (!res)
res = ast_waitstream(chan, ints);
}
@ -598,7 +1319,7 @@ int ast_say_datetime(struct ast_channel *chan, time_t t, char *ints, char *lang)
res = ast_waitstream(chan, ints);
}
if (!res)
res = ast_say_number(chan, tm.tm_mday, ints, lang);
res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
hour = tm.tm_hour;
if (!hour)
@ -610,18 +1331,18 @@ int ast_say_datetime(struct ast_channel *chan, time_t t, char *ints, char *lang)
pm = 1;
}
if (!res)
res = ast_say_number(chan, hour, ints, lang);
res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
if (tm.tm_min > 9) {
if (!res)
res = ast_say_number(chan, tm.tm_min, ints, lang);
res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
} else if (tm.tm_min) {
if (!res)
res = ast_streamfile(chan, "digits/oh", lang);
if (!res)
res = ast_waitstream(chan, ints);
if (!res)
res = ast_say_number(chan, tm.tm_min, ints, lang);
res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
} else {
if (!res)
res = ast_streamfile(chan, "digits/oclock", lang);
@ -638,7 +1359,7 @@ int ast_say_datetime(struct ast_channel *chan, time_t t, char *ints, char *lang)
if (!res)
res = ast_waitstream(chan, ints);
if (!res)
res = ast_say_number(chan, tm.tm_year + 1900, ints, lang);
res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
return res;
}
@ -665,7 +1386,7 @@ int ast_say_datetime_from_now(struct ast_channel *chan, time_t t, char *ints, ch
res = ast_waitstream(chan, ints);
}
if (!res)
res = ast_say_number(chan, tm.tm_mday, ints, lang);
res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
} else if (daydiff) {
/* Just what day of the week */

Loading…
Cancel
Save