|
|
|
@ -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 */
|
|
|
|
|