Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Macros | Functions
say.c File Reference

Say numbers and dates (maybe words one day too) More...

#include "asterisk.h"
#include <netinet/in.h>
#include <time.h>
#include <ctype.h>
#include <math.h>
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/say.h"
#include "asterisk/lock.h"
#include "asterisk/localtime.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/test.h"
#include "asterisk/cli.h"

Go to the source code of this file.

Data Structures

struct  odmiana
 

Macros

#define IL_DATE_STR   "AdBY"
 
#define IL_DATE_STR_FULL   IL_DATE_STR " 'digits/at' " IL_TIME_STR
 
#define IL_TIME_STR   "HM" /* NOTE: In Hebrew we do not support 12 hours, only 24. No AM or PM exists in the Hebrew language */
 
#define SAY_NUM_BUF_SIZE   256
 

Functions

static void __say_init (void)
 remap the 'say' functions to use those in this file
 
struct ast_strast_get_character_str (const char *str, const char *lang, enum ast_say_case_sensitivity sensitivity)
 Returns an ast_str of files for SayAlpha playback. More...
 
struct ast_strast_get_digit_str (const char *str, const char *lang)
 Returns an ast_str of files for SayDigits playback. More...
 
static struct ast_strast_get_money_en_dollars_str (const char *str, const char *lang)
 
struct ast_strast_get_money_str (const char *str, const char *lang)
 ast_get_money_str: call language-specific functions More...
 
struct ast_strast_get_number_str (int num, const char *lang)
 ast_get_number_str: call language-specific functions More...
 
struct ast_strast_get_ordinal_str (int num, const char *lang)
 ast_get_ordinal_str: call language-specific functions More...
 
struct ast_strast_get_phonetic_str (const char *str, const char *lang)
 Returns an ast_str of files for SayPhonetic playback. More...
 
int ast_say_counted_adjective (struct ast_channel *chan, int num, const char adjective[], const char gender[])
 
int ast_say_counted_noun (struct ast_channel *chan, int num, const char noun[])
 
static int ast_say_date_da (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Danish syntax.
 
static int ast_say_date_de (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 German syntax.
 
static int ast_say_date_en (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 English syntax.
 
static int ast_say_date_fr (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 French syntax.
 
static int ast_say_date_gr (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Greek support. More...
 
static int ast_say_date_he (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Hebrew syntax.
 
static int ast_say_date_hu (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Hungarian syntax.
 
static int ast_say_date_is (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 
static int ast_say_date_ja (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 
static int ast_say_date_ka (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Georgian syntax. e.g. "oriatas xuti tslis 5 noemberi". More...
 
static int ast_say_date_nl (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Dutch syntax.
 
static int ast_say_date_pt (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Portuguese syntax.
 
static int ast_say_date_th (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Thai syntax.
 
static int ast_say_date_with_format_da (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 Danish syntax.
 
static int ast_say_date_with_format_de (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 German syntax.
 
static int ast_say_date_with_format_en (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 English syntax.
 
static int ast_say_date_with_format_es (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 Spanish syntax.
 
static int ast_say_date_with_format_fr (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 French syntax oclock = heure.
 
static int ast_say_date_with_format_gr (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 Greek support.
 
static int ast_say_date_with_format_he (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 ast_say_date_with_format_he Say formatted date in Hebrew More...
 
static int ast_say_date_with_format_is (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 
static int ast_say_date_with_format_it (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 Italian syntax.
 
static int ast_say_date_with_format_ja (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 
static int ast_say_date_with_format_nl (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 Dutch syntax.
 
static int ast_say_date_with_format_pl (struct ast_channel *chan, time_t thetime, const char *ints, const char *lang, const char *format, const char *tzone)
 Polish syntax.
 
static int ast_say_date_with_format_pt (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 Portuguese syntax.
 
static int ast_say_date_with_format_th (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 Thai syntax.
 
static int ast_say_date_with_format_vi (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 Vietnamese syntax.
 
static int ast_say_date_with_format_zh (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 Taiwanese / Chinese syntax.
 
static int ast_say_datetime_de (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 German syntax.
 
static int ast_say_datetime_en (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 English syntax.
 
static int ast_say_datetime_fr (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 French syntax.
 
static int ast_say_datetime_from_now_en (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 English syntax.
 
static int ast_say_datetime_from_now_fr (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 French syntax.
 
static int ast_say_datetime_from_now_he (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Hebrew syntax.
 
static int ast_say_datetime_from_now_ka (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Georgian syntax.
 
static int ast_say_datetime_from_now_pt (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Portuguese syntax.
 
static int ast_say_datetime_gr (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Greek support.
 
static int ast_say_datetime_he (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Hebrew syntax.
 
static int ast_say_datetime_hu (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Hungarian syntax.
 
static int ast_say_datetime_ja (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 
static int ast_say_datetime_ka (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Georgian syntax. Say date, then say time.
 
static int ast_say_datetime_nl (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Dutch syntax.
 
static int ast_say_datetime_pt (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Portuguese syntax.
 
static int ast_say_datetime_pt_BR (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Brazilian Portuguese syntax.
 
static int ast_say_datetime_th (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Thai syntax.
 
static int ast_say_datetime_zh (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Taiwanese / Chinese syntax.
 
static int ast_say_enumeration_full_da (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_enumeration_full_da: Danish syntax
 
static int ast_say_enumeration_full_de (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_enumeration_full_de: German syntax
 
static int ast_say_enumeration_full_en (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 ast_say_enumeration_full_en: English syntax More...
 
static int ast_say_enumeration_full_he (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 
static int ast_say_enumeration_full_is (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_enumeration_full_is: Icelandic syntax
 
static int ast_say_enumeration_full_vi (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 
static int ast_say_number_full_cs (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full_cs: Czech syntax More...
 
static int ast_say_number_full_da (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full_da: Danish syntax New files: More...
 
static int ast_say_number_full_de (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full_de: German syntax More...
 
static int ast_say_number_full_en (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 ast_say_number_full_en: English syntax More...
 
static int ast_say_number_full_en_GB (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 ast_say_number_full_en_GB: British syntax New files: More...
 
static int ast_say_number_full_es (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full_es: Spanish syntax More...
 
static int ast_say_number_full_fr (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full_fr: French syntax Extra sounds needed: 1F: feminin 'une' et: 'and'
 
static int ast_say_number_full_gr (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 Greek support A list of the files that you need to create -> digits/xilia = "xilia" -> digits/myrio = "ekatomyrio" -> digits/thousands = "xiliades" -> digits/millions = "ektatomyria" -> digits/[1..12] :: A pronunciation of th digits form 1 to 12 e.g. "tria" -> digits/[10..100] :: A pronunciation of the tens from 10 to 90 e.g. 80 = "ogdonta" Here we must note that we use digits/tens/100 to utter "ekato" and digits/hundred-100 to utter "ekaton" -> digits/hundred-[100...1000] :: A pronunciation of hundreds from 100 to 1000 e.g 400 = "terakosia". Here again we use hundreds/1000 for "xilia" and digits/thousands for "xiliades".
 
static int ast_say_number_full_he (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 
static int ast_say_number_full_hu (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 ast_say_number_full_hu: Hungarian syntax More...
 
static int ast_say_number_full_is (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full_is: Icelandic syntax
 
static int ast_say_number_full_it (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 ast_say_number_full_it: Italian
 
static int ast_say_number_full_ja (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 
static int ast_say_number_full_ka (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full_ka: Georgian syntax
 
static int ast_say_number_full_nl (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 ast_say_number_full_nl: dutch syntax New files: digits/nl-en
 
static int ast_say_number_full_no (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full_no: Norwegian syntax New files: In addition to American English, the following sounds are required: "and", "1N" More...
 
static int ast_say_number_full_pl (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 
static int ast_say_number_full_pt (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 
static int ast_say_number_full_ru (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full_ru: Russian syntax More...
 
static int ast_say_number_full_se (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full_se: Swedish syntax More...
 
static int ast_say_number_full_th (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 Thai syntax.
 
static int ast_say_number_full_ur (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 
static int ast_say_number_full_vi (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 ast_say_number_full_vi: Vietnamese syntax
 
static int ast_say_number_full_zh (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 ast_say_number_full_zh: Taiwanese / Chinese syntax
 
static int ast_say_time_de (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 German syntax.
 
static int ast_say_time_en (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 English syntax.
 
static int ast_say_time_fr (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 French syntax.
 
static int ast_say_time_gr (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Greek support. More...
 
static int ast_say_time_he (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Hebrew syntax.
 
static int ast_say_time_hu (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Hungarian syntax.
 
static int ast_say_time_ja (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 
static int ast_say_time_ka (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Georgian syntax. e.g. "otxi saati da eqvsi tsuti".
 
static int ast_say_time_nl (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Dutch syntax.
 
static int ast_say_time_pt (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Portuguese syntax.
 
static int ast_say_time_pt_BR (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Brazilian Portuguese syntax.
 
static int ast_say_time_th (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Thai syntax.
 
static int ast_say_time_zh (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Taiwanese / Chinese syntax.
 
static char * ast_translate_number_ka (int num, char *res, int res_len)
 Georgian support. More...
 
static const char * counted_adjective_ending_ru (int num, const char gender[])
 In slavic languages such as Russian and Ukrainian the rules for declining adjectives are simpler than those for nouns. When counting we use only the singular (to which we give no suffix) and the genative plural (which we represent by adding an "x"). Oh, an in the singular gender matters so we append the supplied gender suffix ("m", "f", "n").
 
static const char * counted_noun_ending_en (int num)
 In English, we use the plural for everything but one. For example: More...
 
static const char * counted_noun_ending_slavic (int num)
 Counting of objects in slavic languages such as Russian and Ukrainian the rules are more complicated. There are two plural forms used in counting. They are the genative singular which we represent with the suffix "x1" and the genative plural which we represent with the suffix "x2". The base names of the soundfiles remain in English. For example: More...
 
static int exp10_int (int power)
 
static int get_lastdigits_ru (int num)
 determine last digits for thousands/millions (ru)
 
static struct ast_strget_number_str_en (int num, const char *lang)
 
static struct ast_strget_ordinal_str_en (int num, const char *lang)
 
static int gr_say_number_female (int num, struct ast_channel *chan, const char *ints, const char *lang)
 Greek digits/female-[1..4] : "Mia, dyo , treis, tessereis".
 
static char next_item (const char *format)
 
static char * pl_append (char *buffer, char *str)
 
static void pl_odtworz_plik (struct ast_channel *chan, const char *language, int audiofd, int ctrlfd, const char *ints, char *fn)
 
static char * pl_rzad_na_tekst (odmiana *odm, int i, int rzad)
 
static void powiedz (struct ast_channel *chan, const char *language, int audiofd, int ctrlfd, const char *ints, odmiana *odm, int rzad, int i)
 
static int say_character_str_full (struct ast_channel *chan, const char *str, const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity, int audiofd, int ctrlfd)
 
static int say_date (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 
static int say_date_with_format (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 
static int say_datetime (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 
static int say_datetime_from_now (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 
static int say_digit_str_full (struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
 
static int say_enumeration_full (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_enumeration_full: call language-specific functions More...
 
static int say_filenames (struct ast_channel *chan, const char *ints, const char *lang, int audiofd, int ctrlfd, struct ast_str *filenames)
 
static int say_money_str_full (struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
 
static int say_number_full (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full: call language-specific functions More...
 
static int say_ordinal_full (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 say_ordinal_full
 
static int say_phonetic_str_full (struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
 
static int say_time (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 
static int wait_file (struct ast_channel *chan, const char *ints, const char *file, const char *lang)
 

Detailed Description

Say numbers and dates (maybe words one day too)

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Note
12-16-2004 : Support for Greek added by InAccess Networks (work funded by HOL, www.hol.gr) George Konstantoulakis gkon@.nosp@m.inac.nosp@m.cessn.nosp@m.etwo.nosp@m.rks.c.nosp@m.om
2007-02-08 : Support for Georgian added by Alexander Shaduri ashad.nosp@m.uri@.nosp@m.gmail.nosp@m..com, Next Generation Networks (NGN).
2007-03-20 : Support for Thai added by Dome C. dome@.nosp@m.tel..nosp@m.co.th, IP Crossing Co., Ltd.
2021-07-26 : Refactoring to separate string buildup and playback by Naveen Albert aster.nosp@m.isk@.nosp@m.phrea.nosp@m.knet.nosp@m..org

Definition in file say.c.

Function Documentation

struct ast_str* ast_get_character_str ( const char *  str,
const char *  lang,
enum ast_say_case_sensitivity  sensitivity 
)

Returns an ast_str of files for SayAlpha playback.

Parameters
strText to be translated to the corresponding audio files.
langChannel language
sensitivityCase sensitivity

Computes the list of files to be played by SayAlpha.

Return values
ampersand-separatedstring of Asterisk sound files that can be played back.

Definition at line 64 of file say.c.

References ast_fileexists(), AST_SAY_CASE_ALL, AST_SAY_CASE_LOWER, AST_SAY_CASE_NONE, AST_SAY_CASE_UPPER, ast_str_append(), ast_str_create, ast_str_reset(), and ast_str_strlen().

64  {
65  const char *fn;
66  char fnbuf[10], asciibuf[20] = "letters/ascii";
67  char ltr;
68  int num = 0;
69  int res = 0;
70  int upper = 0;
71  int lower = 0;
72 
73  struct ast_str *filenames = ast_str_create(20);
74  if (!filenames) {
75  return NULL;
76  }
77  ast_str_reset(filenames);
78 
79  while (str[num] && !res) {
80  fn = NULL;
81  switch (str[num]) {
82  case ('*'):
83  fn = "digits/star";
84  break;
85  case ('#'):
86  fn = "digits/pound";
87  break;
88  case ('!'):
89  fn = "letters/exclaimation-point";
90  break;
91  case ('@'):
92  fn = "letters/at";
93  break;
94  case ('$'):
95  fn = "letters/dollar";
96  break;
97  case ('-'):
98  fn = "letters/dash";
99  break;
100  case ('.'):
101  fn = "letters/dot";
102  break;
103  case ('='):
104  fn = "letters/equals";
105  break;
106  case ('+'):
107  fn = "letters/plus";
108  break;
109  case ('/'):
110  fn = "letters/slash";
111  break;
112  case (' '):
113  fn = "letters/space";
114  break;
115  case ('0'):
116  case ('1'):
117  case ('2'):
118  case ('3'):
119  case ('4'):
120  case ('5'):
121  case ('6'):
122  case ('7'):
123  case ('8'):
124  case ('9'):
125  strcpy(fnbuf, "digits/X");
126  fnbuf[7] = str[num];
127  fn = fnbuf;
128  break;
129  default:
130  ltr = str[num];
131  if ('A' <= ltr && ltr <= 'Z') {
132  ltr += 'a' - 'A'; /* file names are all lower-case */
133  switch (sensitivity) {
134  case AST_SAY_CASE_UPPER:
135  case AST_SAY_CASE_ALL:
136  upper = !upper;
137  case AST_SAY_CASE_LOWER:
138  case AST_SAY_CASE_NONE:
139  break;
140  }
141  } else if ('a' <= ltr && ltr <= 'z') {
142  switch (sensitivity) {
143  case AST_SAY_CASE_LOWER:
144  case AST_SAY_CASE_ALL:
145  lower = !lower;
146  case AST_SAY_CASE_UPPER:
147  case AST_SAY_CASE_NONE:
148  break;
149  }
150  }
151 
152  if (upper) {
153  strcpy(fnbuf, "uppercase");
154  } else if (lower) {
155  strcpy(fnbuf, "lowercase");
156  } else {
157  strcpy(fnbuf, "letters/X");
158  fnbuf[8] = ltr;
159  }
160  fn = fnbuf;
161  }
162  if ((fn && ast_fileexists(fn, NULL, lang) > 0) ||
163  (snprintf(asciibuf + 13, sizeof(asciibuf) - 13, "%d", str[num]) > 0 && ast_fileexists(asciibuf, NULL, lang) > 0 && (fn = asciibuf))) {
164  ast_str_append(&filenames, 0, "%s%s", ast_str_strlen(filenames) ? "&" : "", fn);
165  }
166  if (upper || lower) {
167  continue;
168  }
169  num++;
170  }
171 
172  return filenames;
173 }
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
Support for dynamic strings.
Definition: strings.h:623
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:693
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:730
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1129
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
struct ast_str* ast_get_digit_str ( const char *  str,
const char *  lang 
)

Returns an ast_str of files for SayDigits playback.

Parameters
strText to be translated to the corresponding audio files.
langChannel language

Computes the list of files to be played by SayDigits.

Return values
ampersand-separatedstring of Asterisk sound files that can be played back.

Definition at line 300 of file say.c.

References ast_fileexists(), ast_str_append(), ast_str_create, ast_str_reset(), and ast_str_strlen().

301 {
302  const char *fn;
303  char fnbuf[256];
304  int num = 0;
305 
306  struct ast_str *filenames = ast_str_create(20);
307  if (!filenames) {
308  return NULL;
309  }
310  ast_str_reset(filenames);
311 
312  while (str[num]) {
313  fn = NULL;
314  switch (str[num]) {
315  case ('*'):
316  fn = "digits/star";
317  break;
318  case ('#'):
319  fn = "digits/pound";
320  break;
321  case ('-'):
322  fn = "digits/minus";
323  break;
324  case '0':
325  case '1':
326  case '2':
327  case '3':
328  case '4':
329  case '5':
330  case '6':
331  case '7':
332  case '8':
333  case '9':
334  strcpy(fnbuf, "digits/X");
335  fnbuf[7] = str[num];
336  fn = fnbuf;
337  break;
338  }
339  if (fn && ast_fileexists(fn, NULL, lang) > 0) {
340  ast_str_append(&filenames, 0, "%s%s", ast_str_strlen(filenames) ? "&" : "", fn);
341  }
342  num++;
343  }
344 
345  return filenames;
346 }
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
Support for dynamic strings.
Definition: strings.h:623
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:693
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:730
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1129
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
struct ast_str* ast_get_money_str ( const char *  str,
const char *  lang 
)

ast_get_money_str: call language-specific functions

Returns an ast_str of files for SayMoney playback.

Definition at line 449 of file say.c.

450 {
451  if (!strncasecmp(lang, "en", 2)) { /* English syntax */
452  return ast_get_money_en_dollars_str(str, lang);
453  }
454 
455  ast_log(LOG_WARNING, "Language %s not currently supported, defaulting to US Dollars\n", lang);
456  /* Default to english */
457  return ast_get_money_en_dollars_str(str, lang);
458 }
struct ast_str* ast_get_number_str ( int  num,
const char *  lang 
)

ast_get_number_str: call language-specific functions

Returns an ast_str of files for SayNumber playback.

Definition at line 566 of file say.c.

Referenced by ast_say_number_full_en().

567 {
568  if (!strncasecmp(lang, "en", 2)) { /* English syntax */
569  return get_number_str_en(num, lang);
570  }
571 
572  ast_log(LOG_WARNING, "Language %s not currently supported, defaulting to English\n", lang);
573  /* Default to english */
574  return get_number_str_en(num, lang);
575 }
struct ast_str* ast_get_ordinal_str ( int  num,
const char *  lang 
)

ast_get_ordinal_str: call language-specific functions

Returns an ast_str of files for SayOrdinal playback.

Definition at line 686 of file say.c.

Referenced by say_ordinal_full().

687 {
688  if (!strncasecmp(lang, "en", 2)) { /* English syntax */
689  return get_ordinal_str_en(num, lang);
690  }
691 
692  ast_log(LOG_WARNING, "Language %s not currently supported, defaulting to English\n", lang);
693  /* Default to english */
694  return get_ordinal_str_en(num, lang);
695 }
struct ast_str* ast_get_phonetic_str ( const char *  str,
const char *  lang 
)

Returns an ast_str of files for SayPhonetic playback.

Parameters
strText to be translated to the corresponding audio files.
langChannel language

Computes the list of files to be played by SayPhonetic.

Return values
ampersand-separatedstring of Asterisk sound files that can be played back.

Definition at line 216 of file say.c.

References ast_fileexists(), ast_str_append(), ast_str_create, ast_str_reset(), and ast_str_strlen().

217 {
218  const char *fn;
219  char fnbuf[256];
220  char ltr;
221  int num = 0;
222 
223  struct ast_str *filenames = ast_str_create(20);
224  if (!filenames) {
225  return NULL;
226  }
227  ast_str_reset(filenames);
228 
229  while (str[num]) {
230  fn = NULL;
231  switch (str[num]) {
232  case ('*'):
233  fn = "digits/star";
234  break;
235  case ('#'):
236  fn = "digits/pound";
237  break;
238  case ('!'):
239  fn = "letters/exclaimation-point";
240  break;
241  case ('@'):
242  fn = "letters/at";
243  break;
244  case ('$'):
245  fn = "letters/dollar";
246  break;
247  case ('-'):
248  fn = "letters/dash";
249  break;
250  case ('.'):
251  fn = "letters/dot";
252  break;
253  case ('='):
254  fn = "letters/equals";
255  break;
256  case ('+'):
257  fn = "letters/plus";
258  break;
259  case ('/'):
260  fn = "letters/slash";
261  break;
262  case (' '):
263  fn = "letters/space";
264  break;
265  case ('0'):
266  case ('1'):
267  case ('2'):
268  case ('3'):
269  case ('4'):
270  case ('5'):
271  case ('6'):
272  case ('7'):
273  case ('8'):
274  strcpy(fnbuf, "digits/X");
275  fnbuf[7] = str[num];
276  fn = fnbuf;
277  break;
278  default: /* '9' falls here... */
279  ltr = str[num];
280  if ('A' <= ltr && ltr <= 'Z') ltr += 'a' - 'A'; /* file names are all lower-case */
281  strcpy(fnbuf, "phonetic/X_p");
282  fnbuf[9] = ltr;
283  fn = fnbuf;
284  }
285  if (fn && ast_fileexists(fn, NULL, lang) > 0) {
286  ast_str_append(&filenames, 0, "%s%s", ast_str_strlen(filenames) ? "&" : "", fn);
287  }
288  num++;
289  }
290 
291  return filenames;
292 }
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
Support for dynamic strings.
Definition: strings.h:623
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:693
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:730
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1129
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
static int ast_say_date_gr ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang 
)
static

Greek support.

The format is weekday - day - month -year

A list of the files that you need to create digits/day-[1..7] : "Deytera .. Paraskeyh" digits/months/1..12 : "Ianouariou .. Dekembriou" Attention the months are in "gekinh klhsh"

Definition at line 8372 of file say.c.

References ast_localtime(), ast_say_number(), ast_streamfile(), ast_waitstream(), gr_say_number_female(), ast_tm::tm_mday, ast_tm::tm_mon, ast_tm::tm_wday, and ast_tm::tm_year.

8373 {
8374  struct ast_tm tm;
8375  struct timeval when = { t, 0 };
8376 
8377  char fn[256];
8378  int res = 0;
8379 
8380 
8381  ast_localtime(&when, &tm, NULL);
8382  /* W E E K - D A Y */
8383  if (!res) {
8384  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
8385  res = ast_streamfile(chan, fn, lang);
8386  if (!res)
8387  res = ast_waitstream(chan, ints);
8388  }
8389  /* D A Y */
8390  if (!res) {
8391  gr_say_number_female(tm.tm_mday, chan, ints, lang);
8392  }
8393  /* M O N T H */
8394  if (!res) {
8395  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
8396  res = ast_streamfile(chan, fn, lang);
8397  if (!res)
8398  res = ast_waitstream(chan, ints);
8399  }
8400  /* Y E A R */
8401  if (!res)
8402  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
8403  return res;
8404 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8235
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1840
static int gr_say_number_female(int num, struct ast_channel *chan, const char *ints, const char *lang)
Greek digits/female-[1..4] : "Mia, dyo , treis, tessereis".
Definition: say.c:8183
static int ast_say_date_ka ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang 
)
static

Georgian syntax. e.g. "oriatas xuti tslis 5 noemberi".

Georgian support for date/time requires the following files (*.gsm):

  • mon-1, mon-2, ... (ianvari, tebervali, ...)
  • day-1, day-2, ... (orshabati, samshabati, ...)
  • saati_da
  • tsuti
  • tslis

Definition at line 9540 of file say.c.

References ast_localtime(), ast_say_number(), ast_streamfile(), ast_waitstream(), ast_tm::tm_mday, ast_tm::tm_mon, ast_tm::tm_wday, and ast_tm::tm_year.

9541 {
9542  struct timeval when = { t, 0 };
9543  struct ast_tm tm;
9544  char fn[256];
9545  int res = 0;
9546  ast_localtime(&when, &tm, NULL);
9547 
9548  if (!res) {
9549  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
9550  }
9551 
9552  if (!res) {
9553  snprintf(fn, sizeof(fn), "digits/tslis %d", tm.tm_wday);
9554  res = ast_streamfile(chan, fn, lang);
9555  if (!res) {
9556  res = ast_waitstream(chan, ints);
9557  }
9558  }
9559 
9560  if (!res) {
9561  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
9562 /* if (!res)
9563  res = ast_waitstream(chan, ints);
9564 */
9565  }
9566 
9567  if (!res) {
9568  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
9569  res = ast_streamfile(chan, fn, lang);
9570  if (!res) {
9571  res = ast_waitstream(chan, ints);
9572  }
9573  }
9574  return res;
9575 
9576 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8235
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1840
int ast_say_date_with_format_he ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang,
const char *  format,
const char *  tzone 
)
static

ast_say_date_with_format_he Say formatted date in Hebrew

ast_say_date_with_format_en for the details of the options

Changes from the English version:

  • don't replicate in here the logic of ast_say_number_full_he
  • year is always 4-digit (because it's simpler)
  • added c, x, and X. Mainly for my tests
  • The standard "long" format used in Hebrew is AdBY, rather than ABdY
Todo:
  • A "ha" is missing in the standard date format, before the 'd'.
  • The numbers of 3000–19000 are not handled well

Definition at line 5482 of file say.c.

References ast_debug, ast_localtime(), ast_tvnow(), ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_wday, and ast_tm::tm_year.

5483 {
5484 #define IL_DATE_STR "AdBY"
5485 #define IL_TIME_STR "HM" /* NOTE: In Hebrew we do not support 12 hours, only 24. No AM or PM exists in the Hebrew language */
5486 #define IL_DATE_STR_FULL IL_DATE_STR " 'digits/at' " IL_TIME_STR
5487  /* TODO: This whole function is cut&paste from
5488  * ast_say_date_with_format_en . Is that considered acceptable?
5489  **/
5490  struct timeval when = { t, 0 };
5491  struct ast_tm tm;
5492  int res = 0, offset, sndoffset;
5493  char sndfile[256], nextmsg[256];
5494 
5495  if (!format) {
5496  format = IL_DATE_STR_FULL;
5497  }
5498 
5499  ast_localtime(&when, &tm, tzone);
5500 
5501  for (offset = 0; format[offset] != '\0'; offset++) {
5502  ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
5503  switch (format[offset]) {
5504  /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
5505  case '\'':
5506  /* Literal name of a sound file */
5507  for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
5508  sndfile[sndoffset] = format[offset];
5509  }
5510  sndfile[sndoffset] = '\0';
5511  res = wait_file(chan, ints, sndfile, lang);
5512  break;
5513  case 'A':
5514  case 'a':
5515  /* Sunday - Saturday */
5516  snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
5517  res = wait_file(chan, ints, nextmsg, lang);
5518  break;
5519  case 'B':
5520  case 'b':
5521  case 'h':
5522  /* January - December */
5523  snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
5524  res = wait_file(chan, ints, nextmsg, lang);
5525  break;
5526  case 'd':
5527  case 'e': /* Day of the month */
5528  /* I'm not sure exactly what the parameters
5529  * audiofd and ctrlfd to
5530  * ast_say_number_full_he mean, but it seems
5531  * safe to pass -1 there.
5532  *
5533  * At least in one of the paths :-(
5534  */
5535  res = ast_say_number_full_he(chan, tm.tm_mday, ints, lang, "m", -1, -1);
5536  break;
5537  case 'Y': /* Year */
5538  res = ast_say_number_full_he(chan, tm.tm_year + 1900, ints, lang, "f", -1, -1);
5539  break;
5540  case 'I':
5541  case 'l': /* 12-Hour -> we do not support 12 hour based languages in Hebrew */
5542  case 'H':
5543  case 'k': /* 24-Hour */
5544  res = ast_say_number_full_he(chan, tm.tm_hour, ints, lang, "f", -1, -1);
5545  break;
5546  case 'M': /* Minute */
5547  if (tm.tm_min >= 0 && tm.tm_min <= 9) /* say a leading zero if needed */
5548  res = ast_say_number_full_he(chan, 0, ints, lang, "f", -1, -1);
5549  res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1);
5550  break;
5551  case 'P':
5552  case 'p':
5553  /* AM/PM - There is no AM/PM in Hebrew... */
5554  break;
5555  case 'Q':
5556  /* Shorthand for "Today", "Yesterday", or "date" */
5557  case 'q':
5558  /* Shorthand for "" (today), "Yesterday", A
5559  * (weekday), or "date" */
5560  /* XXX As emphasized elsewhere, this should the native way in your
5561  * language to say the date, with changes in what you say, depending
5562  * upon how recent the date is. XXX */
5563  {
5564  struct timeval now = ast_tvnow();
5565  struct ast_tm tmnow;
5566  time_t beg_today;
5567  char todo = format[offset]; /* The letter to format*/
5568 
5569  ast_localtime(&now, &tmnow, tzone);
5570  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5571  /* In any case, it saves not having to do ast_mktime() */
5572  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5573  if (beg_today < t) {
5574  /* Today */
5575  if (todo == 'Q') {
5576  res = wait_file(chan, ints, "digits/today", lang);
5577  }
5578  } else if (beg_today - 86400 < t) {
5579  /* Yesterday */
5580  res = wait_file(chan, ints, "digits/yesterday", lang);
5581  } else if ((todo != 'Q') && (beg_today - 86400 * 6 < t)) {
5582  /* Within the last week */
5583  res = ast_say_date_with_format_he(chan, t, ints, lang, "A", tzone);
5584  } else {
5585  res = ast_say_date_with_format_he(chan, t, ints, lang, IL_DATE_STR, tzone);
5586  }
5587  }
5588  break;
5589  case 'R':
5590  res = ast_say_date_with_format_he(chan, t, ints, lang, "HM", tzone);
5591  break;
5592  case 'S': /* Seconds */
5593  res = ast_say_number_full_he(chan, tm.tm_sec,
5594  ints, lang, "f", -1, -1
5595  );
5596  break;
5597  case 'T':
5598  res = ast_say_date_with_format_he(chan, t, ints, lang, "HMS", tzone);
5599  break;
5600  /* c, x, and X seem useful for testing. Not sure
5601  * if they're good for the general public */
5602  case 'c':
5603  res = ast_say_date_with_format_he(chan, t, ints, lang, IL_DATE_STR_FULL, tzone);
5604  break;
5605  case 'x':
5606  res = ast_say_date_with_format_he(chan, t, ints, lang, IL_DATE_STR, tzone);
5607  break;
5608  case 'X': /* Currently not locale-dependent...*/
5609  res = ast_say_date_with_format_he(chan, t, ints, lang, IL_TIME_STR, tzone);
5610  break;
5611  case ' ':
5612  case ' ':
5613  /* Just ignore spaces and tabs */
5614  break;
5615  default:
5616  /* Unknown character */
5617  ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
5618  }
5619  /* Jump out on DTMF */
5620  if (res) {
5621  break;
5622  }
5623  }
5624  return res;
5625 }
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
static int ast_say_date_with_format_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
ast_say_date_with_format_he Say formatted date in Hebrew
Definition: say.c:5482
#define ast_debug(level,...)
Log a DEBUG message.
static int ast_say_enumeration_full_en ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
int  audiofd,
int  ctrlfd 
)
static

ast_say_enumeration_full_en: English syntax

Note
This is the default syntax, if no other syntax defined in this file is used

Definition at line 3251 of file say.c.

References ast_copy_string(), ast_debug, ast_say_number_full_en(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by say_enumeration_full().

3252 {
3253  int res = 0, t = 0;
3254  char fn[256] = "";
3255 
3256  while (!res && num) {
3257  if (num < 0) {
3258  ast_copy_string(fn, "digits/minus", sizeof(fn)); /* kind of senseless for enumerations, but our best effort for error checking */
3259  if ( num > INT_MIN ) {
3260  num = -num;
3261  } else {
3262  num = 0;
3263  }
3264  } else if (num < 20) {
3265  snprintf(fn, sizeof(fn), "digits/h-%d", num);
3266  num = 0;
3267  } else if (num < 100) {
3268  int tens = num / 10;
3269  num = num % 10;
3270  if (num == 0) {
3271  snprintf(fn, sizeof(fn), "digits/h-%d", (tens * 10));
3272  } else {
3273  snprintf(fn, sizeof(fn), "digits/%d", (tens * 10));
3274  }
3275  } else if (num < 1000) {
3276  int hundreds = num / 100;
3277  num = num % 100;
3278  if (hundreds > 1 || t == 1) {
3279  res = ast_say_number_full_en(chan, hundreds, ints, language, audiofd, ctrlfd);
3280  }
3281  if (res)
3282  return res;
3283  if (num) {
3284  ast_copy_string(fn, "digits/hundred", sizeof(fn));
3285  } else {
3286  ast_copy_string(fn, "digits/h-hundred", sizeof(fn));
3287  }
3288  } else if (num < 1000000) {
3289  int thousands = num / 1000;
3290  num = num % 1000;
3291  if (thousands > 1 || t == 1) {
3292  res = ast_say_number_full_en(chan, thousands, ints, language, audiofd, ctrlfd);
3293  }
3294  if (res)
3295  return res;
3296  if (num) {
3297  ast_copy_string(fn, "digits/thousand", sizeof(fn));
3298  } else {
3299  ast_copy_string(fn, "digits/h-thousand", sizeof(fn));
3300  }
3301  t = 1;
3302  } else if (num < 1000000000) {
3303  int millions = num / 1000000;
3304  num = num % 1000000;
3305  t = 1;
3306  res = ast_say_number_full_en(chan, millions, ints, language, audiofd, ctrlfd);
3307  if (res)
3308  return res;
3309  if (num) {
3310  ast_copy_string(fn, "digits/million", sizeof(fn));
3311  } else {
3312  ast_copy_string(fn, "digits/h-million", sizeof(fn));
3313  }
3314  } else if (num < INT_MAX) {
3315  int billions = num / 1000000000;
3316  num = num % 1000000000;
3317  t = 1;
3318  res = ast_say_number_full_en(chan, billions, ints, language, audiofd, ctrlfd);
3319  if (res)
3320  return res;
3321  if (num) {
3322  ast_copy_string(fn, "digits/billion", sizeof(fn));
3323  } else {
3324  ast_copy_string(fn, "digits/h-billion", sizeof(fn));
3325  }
3326  } else if (num == INT_MAX) {
3327  ast_copy_string(fn, "digits/h-last", sizeof(fn));
3328  num = 0;
3329  } else {
3330  ast_debug(1, "Number '%d' is too big for me\n", num);
3331  res = -1;
3332  }
3333 
3334  if (!res) {
3335  if (!ast_streamfile(chan, fn, language)) {
3336  if ((audiofd > -1) && (ctrlfd > -1)) {
3337  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
3338  } else {
3339  res = ast_waitstream(chan, ints);
3340  }
3341  }
3342  ast_stopstream(chan);
3343  }
3344  }
3345  return res;
3346 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
#define ast_debug(level,...)
Log a DEBUG message.
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1849
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1840
static int ast_say_number_full_en(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
ast_say_number_full_en: English syntax
Definition: say.c:933
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
static int ast_say_number_full_cs ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
const char *  options,
int  audiofd,
int  ctrlfd 
)
static

ast_say_number_full_cs: Czech syntax

files needed:

  • 1m,2m - gender male
  • 1w,2w - gender female
  • 3,4,...,20
  • 30,40,...,90
  • hundreds - 100 - sto, 200 - 2ste, 300,400 3,4sta, 500,600,...,900 5,6,...9set

for each number 10^(3n + 3) exist 3 files represented as: 1 thousand = jeden tisic = 1_E3 2,3,4 thousands = dva,tri,ctyri tisice = 2-3_E3 5,6,... thousands = pet,sest,... tisic = 5_E3

million = _E6 miliard = _E9 etc...

thousand, milion are gender male, so 1 and 2 is 1m 2m miliard is gender female, so 1 and 2 is 1w 2w

Definition at line 976 of file say.c.

References ast_copy_string(), ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by say_number_full().

977 {
978  int res = 0;
979  int playh = 0;
980  char fn[256] = "";
981 
982  int hundred = 0;
983  int left = 0;
984  int length = 0;
985 
986  /* options - w = woman, m = man, n = neutral. Defaultl is woman */
987  if (!options)
988  options = "w";
989 
990  if (!num)
991  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
992 
993  while (!res && (num || playh)) {
994  if (num < 0) {
995  ast_copy_string(fn, "digits/minus", sizeof(fn));
996  if ( num > INT_MIN ) {
997  num = -num;
998  } else {
999  num = 0;
1000  }
1001  } else if (num < 3 ) {
1002  snprintf(fn, sizeof(fn), "digits/%d%c", num, options[0]);
1003  playh = 0;
1004  num = 0;
1005  } else if (num < 20) {
1006  snprintf(fn, sizeof(fn), "digits/%d", num);
1007  playh = 0;
1008  num = 0;
1009  } else if (num < 100) {
1010  snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
1011  num %= 10;
1012  } else if (num < 1000) {
1013  hundred = num / 100;
1014  if ( hundred == 1 ) {
1015  ast_copy_string(fn, "digits/1sto", sizeof(fn));
1016  } else if ( hundred == 2 ) {
1017  ast_copy_string(fn, "digits/2ste", sizeof(fn));
1018  } else {
1019  res = ast_say_number_full_cs(chan, hundred, ints, language, options, audiofd, ctrlfd);
1020  if (res)
1021  return res;
1022  if (hundred == 3 || hundred == 4) {
1023  ast_copy_string(fn, "digits/sta", sizeof(fn));
1024  } else if ( hundred > 4 ) {
1025  ast_copy_string(fn, "digits/set", sizeof(fn));
1026  }
1027  }
1028  num -= (hundred * 100);
1029  } else { /* num > 1000 */
1030  length = (int)log10(num)+1;
1031  while ( (length % 3 ) != 1 ) {
1032  length--;
1033  }
1034  left = num / (exp10_int(length-1));
1035  if ( left == 2 ) {
1036  switch (length-1) {
1037  case 9: options = "w"; /* 1,000,000,000 gender female */
1038  break;
1039  default : options = "m"; /* others are male */
1040  }
1041  }
1042  if ( left > 1 ) { /* we don't say "one thousand" but only thousand */
1043  res = ast_say_number_full_cs(chan, left, ints, language, options, audiofd, ctrlfd);
1044  if (res)
1045  return res;
1046  }
1047  if ( left >= 5 ) { /* >= 5 have the same declension */
1048  snprintf(fn, sizeof(fn), "digits/5_E%d", length - 1);
1049  } else if ( left >= 2 && left <= 4 ) {
1050  snprintf(fn, sizeof(fn), "digits/2-4_E%d", length - 1);
1051  } else { /* left == 1 */
1052  snprintf(fn, sizeof(fn), "digits/1_E%d", length - 1);
1053  }
1054  num -= left * (exp10_int(length-1));
1055  }
1056  if (!res) {
1057  if (!ast_streamfile(chan, fn, language)) {
1058  if ((audiofd > -1) && (ctrlfd > -1)) {
1059  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
1060  } else {
1061  res = ast_waitstream(chan, ints);
1062  }
1063  }
1064  ast_stopstream(chan);
1065  }
1066  }
1067  return res;
1068 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8283
static int ast_say_number_full_cs(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_number_full_cs: Czech syntax
Definition: say.c:976
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1849
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1840
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
static int ast_say_number_full_da ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
const char *  options,
int  audiofd,
int  ctrlfd 
)
static

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"

Definition at line 1074 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by say_number_full().

1075 {
1076  int res = 0;
1077  int playh = 0;
1078  int playa = 0;
1079  int cn = 1; /* +1 = commune; -1 = neuter */
1080  char fn[256] = "";
1081  if (!num)
1082  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
1083 
1084  if (options && !strncasecmp(options, "n", 1)) cn = -1;
1085 
1086  while (!res && (num || playh || playa )) {
1087  /* The grammar for Danish numbers is the same as for English except
1088  * for the following:
1089  * - 1 exists in both commune ("en", file "1N") and neuter ("et", file "1")
1090  * - numbers 20 through 99 are said in reverse order, i.e. 21 is
1091  * "one-and twenty" and 68 is "eight-and sixty".
1092  * - "million" is different in singular and plural form
1093  * - numbers > 1000 with zero as the third digit from last have an
1094  * "and" before the last two digits, i.e. 2034 is "two thousand and
1095  * four-and thirty" and 1000012 is "one million and twelve".
1096  */
1097  if (num < 0) {
1098  ast_copy_string(fn, "digits/minus", sizeof(fn));
1099  if ( num > INT_MIN ) {
1100  num = -num;
1101  } else {
1102  num = 0;
1103  }
1104  } else if (playh) {
1105  ast_copy_string(fn, "digits/hundred", sizeof(fn));
1106  playh = 0;
1107  } else if (playa) {
1108  ast_copy_string(fn, "digits/and", sizeof(fn));
1109  playa = 0;
1110  } else if (num == 1 && cn == -1) {
1111  ast_copy_string(fn, "digits/1N", sizeof(fn));
1112  num = 0;
1113  } else if (num < 20) {
1114  snprintf(fn, sizeof(fn), "digits/%d", num);
1115  num = 0;
1116  } else if (num < 100) {
1117  int ones = num % 10;
1118  if (ones) {
1119  snprintf(fn, sizeof(fn), "digits/%d-and", ones);
1120  num -= ones;
1121  } else {
1122  snprintf(fn, sizeof(fn), "digits/%d", num);
1123  num = 0;
1124  }
1125  } else {
1126  if (num < 1000) {
1127  int hundreds = num / 100;
1128  if (hundreds == 1)
1129  ast_copy_string(fn, "digits/1N", sizeof(fn));
1130  else
1131  snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
1132 
1133  playh++;
1134  num -= 100 * hundreds;
1135  if (num)
1136  playa++;
1137 
1138  } else {
1139  if (num < 1000000) {
1140  res = ast_say_number_full_da(chan, num / 1000, ints, language, "n", audiofd, ctrlfd);
1141  if (res)
1142  return res;
1143  num = num % 1000;
1144  ast_copy_string(fn, "digits/thousand", sizeof(fn));
1145  } else {
1146  if (num < 1000000000) {
1147  int millions = num / 1000000;
1148  res = ast_say_number_full_da(chan, millions, ints, language, "c", audiofd, ctrlfd);
1149  if (res)
1150  return res;
1151  if (millions == 1)
1152  ast_copy_string(fn, "digits/million", sizeof(fn));
1153  else
1154  ast_copy_string(fn, "digits/millions", sizeof(fn));
1155  num = num % 1000000;
1156  } else {
1157  ast_debug(1, "Number '%d' is too big for me\n", num);
1158  res = -1;
1159  }
1160  }
1161  if (num && num < 100)
1162  playa++;
1163  }
1164  }
1165  if (!res) {
1166  if (!ast_streamfile(chan, fn, language)) {
1167  if ((audiofd > -1) && (ctrlfd > -1))
1168  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
1169  else
1170  res = ast_waitstream(chan, ints);
1171  }
1172  ast_stopstream(chan);
1173  }
1174  }
1175  return res;
1176 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8283
#define ast_debug(level,...)
Log a DEBUG message.
static int ast_say_number_full_da(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_number_full_da: Danish syntax New files:
Definition: say.c:1074
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1849
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1840
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
static int ast_say_number_full_de ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
const char *  options,
int  audiofd,
int  ctrlfd 
)
static

ast_say_number_full_de: German syntax

New files: In addition to English, the following sounds are required:

  • "millions"
  • "1-and" through "9-and"
  • "1F" (eine)
  • "1N" (ein)
  • NB "1" is recorded as 'eins'

Definition at line 1188 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), and say_number_full().

1189 {
1190  int res = 0, t = 0;
1191  int mf = 1; /* +1 = male and neuter; -1 = female */
1192  char fn[256] = "";
1193  char fna[256] = "";
1194  if (!num)
1195  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
1196 
1197  if (options && (!strncasecmp(options, "f", 1)))
1198  mf = -1;
1199 
1200  while (!res && num) {
1201  /* The grammar for German numbers is the same as for English except
1202  * for the following:
1203  * - numbers 20 through 99 are said in reverse order, i.e. 21 is
1204  * "one-and twenty" and 68 is "eight-and sixty".
1205  * - "one" varies according to gender
1206  * - 100 is 'hundert', however all other instances are 'ein hundert'
1207  * - 1000 is 'tausend', however all other instances are 'ein tausend'
1208  * - 1000000 is always 'eine million'
1209  * - "million" is different in singular and plural form
1210  * - 'and' should not go between a hundreds place value and any
1211  * tens/ones place values that follows it. i.e 136 is ein hundert
1212  * sechs und dreizig, not ein hundert und sechs und dreizig.
1213  */
1214  if (num < 0) {
1215  ast_copy_string(fn, "digits/minus", sizeof(fn));
1216  if ( num > INT_MIN ) {
1217  num = -num;
1218  } else {
1219  num = 0;
1220  }
1221  } else if (num == 1 && mf == -1) {
1222  snprintf(fn, sizeof(fn), "digits/%dF", num);
1223  num = 0;
1224  } else if (num < 20) {
1225  snprintf(fn, sizeof(fn), "digits/%d", num);
1226  num = 0;
1227  } else if (num < 100) {
1228  int ones = num % 10;
1229  if (ones) {
1230  snprintf(fn, sizeof(fn), "digits/%d-and", ones);
1231  num -= ones;
1232  } else {
1233  snprintf(fn, sizeof(fn), "digits/%d", num);
1234  num = 0;
1235  }
1236  } else if (num == 100 && t == 0) {
1237  ast_copy_string(fn, "digits/hundred", sizeof(fn));
1238  num = 0;
1239  } else if (num < 1000) {
1240  int hundreds = num / 100;
1241  num = num % 100;
1242  if (hundreds == 1) {
1243  ast_copy_string(fn, "digits/1N", sizeof(fn));
1244  } else {
1245  snprintf(fn, sizeof(fn), "digits/%d", hundreds);
1246  }
1247  ast_copy_string(fna, "digits/hundred", sizeof(fna));
1248  } else if (num == 1000 && t == 0) {
1249  ast_copy_string(fn, "digits/thousand", sizeof(fn));
1250  num = 0;
1251  } else if (num < 1000000) {
1252  int thousands = num / 1000;
1253  num = num % 1000;
1254  t = 1;
1255  if (thousands == 1) {
1256  ast_copy_string(fn, "digits/1N", sizeof(fn));
1257  ast_copy_string(fna, "digits/thousand", sizeof(fna));
1258  } else {
1259  res = ast_say_number_full_de(chan, thousands, ints, language, options, audiofd, ctrlfd);
1260  if (res)
1261  return res;
1262  ast_copy_string(fn, "digits/thousand", sizeof(fn));
1263  }
1264  } else if (num < 1000000000) {
1265  int millions = num / 1000000;
1266  num = num % 1000000;
1267  t = 1;
1268  if (millions == 1) {
1269  ast_copy_string(fn, "digits/1F", sizeof(fn));
1270  ast_copy_string(fna, "digits/million", sizeof(fna));
1271  } else {
1272  res = ast_say_number_full_de(chan, millions, ints, language, options, audiofd, ctrlfd);
1273  if (res)
1274  return res;
1275  ast_copy_string(fn, "digits/millions", sizeof(fn));
1276  }
1277  } else if (num <= INT_MAX) {
1278  int billions = num / 1000000000;
1279  num = num % 1000000000;
1280  t = 1;
1281  if (billions == 1) {
1282  ast_copy_string(fn, "digits/1F", sizeof(fn));
1283  ast_copy_string(fna, "digits/milliard", sizeof(fna));
1284  } else {
1285  res = ast_say_number_full_de(chan, billions, ints, language, options, audiofd, ctrlfd);
1286  if (res) {
1287  return res;
1288  }
1289  ast_copy_string(fn, "digits/milliards", sizeof(fn));
1290  }
1291  } else {
1292  ast_debug(1, "Number '%d' is too big for me\n", num);
1293  res = -1;
1294  }
1295  if (!res) {
1296  if (!ast_streamfile(chan, fn, language)) {
1297  if ((audiofd > -1) && (ctrlfd > -1))
1298  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
1299  else
1300  res = ast_waitstream(chan, ints);
1301  }
1302  ast_stopstream(chan);
1303  if (!res) {
1304  if (strlen(fna) != 0 && !ast_streamfile(chan, fna, language)) {
1305  if ((audiofd > -1) && (ctrlfd > -1))
1306  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
1307  else
1308  res = ast_waitstream(chan, ints);
1309  }
1310  ast_stopstream(chan);
1311  strcpy(fna, "");
1312  }
1313  }
1314  }
1315  return res;
1316 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8283
static int ast_say_number_full_de(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_number_full_de: German syntax
Definition: say.c:1188
#define ast_debug(level,...)
Log a DEBUG message.
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1849
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1840
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
static int ast_say_number_full_en ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
int  audiofd,
int  ctrlfd 
)
static

ast_say_number_full_en: English syntax

Note
This is the default syntax, if no other syntax defined in this file is used

Definition at line 933 of file say.c.

References ast_get_number_str().

Referenced by ast_say_enumeration_full_en(), and say_number_full().

934 {
935  struct ast_str *filenames = ast_get_number_str(num, language);
936  return say_filenames(chan, ints, language, audiofd, ctrlfd, filenames);
937 }
struct ast_str * ast_get_number_str(int num, const char *lang)
ast_get_number_str: call language-specific functions
Definition: say.c:566
Support for dynamic strings.
Definition: strings.h:623
static int ast_say_number_full_en_GB ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
int  audiofd,
int  ctrlfd 
)
static

ast_say_number_full_en_GB: British syntax New files:

  • In addition to American English, the following sounds are required: "vm-and"

Definition at line 1322 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by say_number_full().

1323 {
1324  int res = 0;
1325  int playh = 0;
1326  int playa = 0;
1327  char fn[256] = "";
1328  if (!num)
1329  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
1330 
1331  while (!res && (num || playh || playa )) {
1332  if (num < 0) {
1333  ast_copy_string(fn, "digits/minus", sizeof(fn));
1334  if ( num > INT_MIN ) {
1335  num = -num;
1336  } else {
1337  num = 0;
1338  }
1339  } else if (playh) {
1340  ast_copy_string(fn, "digits/hundred", sizeof(fn));
1341  playh = 0;
1342  } else if (playa) {
1343  ast_copy_string(fn, "vm-and", sizeof(fn));
1344  playa = 0;
1345  } else if (num < 20) {
1346  snprintf(fn, sizeof(fn), "digits/%d", num);
1347  num = 0;
1348  } else if (num < 100) {
1349  snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
1350  num %= 10;
1351  } else if (num < 1000) {
1352  int hundreds = num / 100;
1353  snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
1354 
1355  playh++;
1356  num -= 100 * hundreds;
1357  if (num)
1358  playa++;
1359  } else if (num < 1000000) {
1360  res = ast_say_number_full_en_GB(chan, num / 1000, ints, language, audiofd, ctrlfd);
1361  if (res)
1362  return res;
1363  ast_copy_string(fn, "digits/thousand", sizeof(fn));
1364  num %= 1000;
1365  if (num && num < 100)
1366  playa++;
1367  } else if (num < 1000000000) {
1368  int millions = num / 1000000;
1369  res = ast_say_number_full_en_GB(chan, millions, ints, language, audiofd, ctrlfd);
1370  if (res)
1371  return res;
1372  ast_copy_string(fn, "digits/million", sizeof(fn));
1373  num %= 1000000;
1374  if (num && num < 100)
1375  playa++;
1376  } else {
1377  ast_debug(1, "Number '%d' is too big for me\n", num);
1378  res = -1;
1379  }
1380 
1381  if (!res) {
1382  if (!ast_streamfile(chan, fn, language)) {
1383  if ((audiofd > -1) && (ctrlfd > -1))
1384  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
1385  else
1386  res = ast_waitstream(chan, ints);
1387  }
1388  ast_stopstream(chan);
1389  }
1390  }
1391  return res;
1392 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8283
#define ast_debug(level,...)
Log a DEBUG message.
static int ast_say_number_full_en_GB(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
ast_say_number_full_en_GB: British syntax New files:
Definition: say.c:1322
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1849
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1840
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
static int ast_say_number_full_es ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
const char *  options,
int  audiofd,
int  ctrlfd 
)
static

ast_say_number_full_es: Spanish syntax

New files: Requires a few new audios: 1F.gsm: feminine 'una' 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

Definition at line 1401 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by say_number_full().

1402 {
1403  int res = 0;
1404  int playa = 0;
1405  int mf = 0; /* +1 = male; -1 = female */
1406  char fn[256] = "";
1407  if (!num)
1408  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
1409 
1410  if (options) {
1411  if (!strncasecmp(options, "f", 1))
1412  mf = -1;
1413  else if (!strncasecmp(options, "m", 1))
1414  mf = 1;
1415  }
1416 
1417  while (!res && num) {
1418  if (num < 0) {
1419  ast_copy_string(fn, "digits/minus", sizeof(fn));
1420  if ( num > INT_MIN ) {
1421  num = -num;
1422  } else {
1423  num = 0;
1424  }
1425  } else if (playa) {
1426  ast_copy_string(fn, "digits/and", sizeof(fn));
1427  playa = 0;
1428  } else if (num == 1) {
1429  if (mf < 0)
1430  snprintf(fn, sizeof(fn), "digits/%dF", num);
1431  else if (mf > 0)
1432  snprintf(fn, sizeof(fn), "digits/%dM", num);
1433  else
1434  snprintf(fn, sizeof(fn), "digits/%d", num);
1435  num = 0;
1436  } else if (num < 31) {
1437  snprintf(fn, sizeof(fn), "digits/%d", num);
1438  num = 0;
1439  } else if (num < 100) {
1440  snprintf(fn, sizeof(fn), "digits/%d", (num/10)*10);
1441  num %= 10;
1442  if (num)
1443  playa++;
1444  } else if (num == 100) {
1445  ast_copy_string(fn, "digits/100", sizeof(fn));
1446  num = 0;
1447  } else if (num < 200) {
1448  ast_copy_string(fn, "digits/100-and", sizeof(fn));
1449  num -= 100;
1450  } else {
1451  if (num < 1000) {
1452  snprintf(fn, sizeof(fn), "digits/%d", (num/100)*100);
1453  num %= 100;
1454  } else if (num < 2000) {
1455  num %= 1000;
1456  ast_copy_string(fn, "digits/thousand", sizeof(fn));
1457  } else {
1458  if (num < 1000000) {
1459  res = ast_say_number_full_es(chan, num / 1000, ints, language, options, audiofd, ctrlfd);
1460  if (res)
1461  return res;
1462  num %= 1000;
1463  ast_copy_string(fn, "digits/thousand", sizeof(fn));
1464  } else {
1465  if (num < 2147483640) {
1466  if ((num/1000000) == 1) {
1467  res = ast_say_number_full_es(chan, num / 1000000, ints, language, "M", audiofd, ctrlfd);
1468  if (res)
1469  return res;
1470  ast_copy_string(fn, "digits/million", sizeof(fn));
1471  } else {
1472  res = ast_say_number_full_es(chan, num / 1000000, ints, language, options, audiofd, ctrlfd);
1473  if (res)
1474  return res;
1475  ast_copy_string(fn, "digits/millions", sizeof(fn));
1476  }
1477  num %= 1000000;
1478  } else {
1479  ast_debug(1, "Number '%d' is too big for me\n", num);
1480  res = -1;
1481  }
1482  }
1483  }
1484  }
1485 
1486  if (!res) {
1487  if (!ast_streamfile(chan, fn, language)) {
1488  if ((audiofd > -1) && (ctrlfd > -1))
1489  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
1490  else
1491  res = ast_waitstream(chan, ints);
1492  }
1493  ast_stopstream(chan);
1494 
1495  }
1496 
1497  }
1498  return res;
1499 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8283
#define ast_debug(level,...)
Log a DEBUG message.
static int ast_say_number_full_es(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_number_full_es: Spanish syntax
Definition: say.c:1401
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1849
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1840
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
static int ast_say_number_full_hu ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
int  audiofd,
int  ctrlfd 
)
static

ast_say_number_full_hu: Hungarian syntax

Extra sounds needed: 10en: "tizen" 20on: "huszon"

Definition at line 1769 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by say_number_full().

1770 {
1771  int res = 0;
1772  int playh = 0;
1773  char fn[256] = "";
1774  if (!num)
1775  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
1776 
1777  /*
1778  Hungarian support
1779  like english, except numbers up to 29 are from 2 words.
1780  10 and first word of 1[1-9] and 20 and first word of 2[1-9] are different.
1781  */
1782 
1783  while(!res && (num || playh)) {
1784  if (num < 0) {
1785  ast_copy_string(fn, "digits/minus", sizeof(fn));
1786  if ( num > INT_MIN ) {
1787  num = -num;
1788  } else {
1789  num = 0;
1790  }
1791  } else if (playh) {
1792  ast_copy_string(fn, "digits/hundred", sizeof(fn));
1793  playh = 0;
1794  } else if (num < 11 || num == 20) {
1795  snprintf(fn, sizeof(fn), "digits/%d", num);
1796  num = 0;
1797  } else if (num < 20) {
1798  ast_copy_string(fn, "digits/10en", sizeof(fn));
1799  num -= 10;
1800  } else if (num < 30) {
1801  ast_copy_string(fn, "digits/20on", sizeof(fn));
1802  num -= 20;
1803  } else if (num < 100) {
1804  snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
1805  num %= 10;
1806  } else {
1807  if (num < 1000){
1808  snprintf(fn, sizeof(fn), "digits/%d", (num/100));
1809  playh++;
1810  num %= 100;
1811  } else {
1812  if (num < 1000000) { /* 1,000,000 */
1813  res = ast_say_number_full_hu(chan, num / 1000, ints, language, audiofd, ctrlfd);
1814  if (res)
1815  return res;
1816  num %= 1000;
1817  ast_copy_string(fn, "digits/thousand", sizeof(fn));
1818  } else {
1819  if (num < 1000000000) { /* 1,000,000,000 */
1820  res = ast_say_number_full_hu(chan, num / 1000000, ints, language, audiofd, ctrlfd);
1821  if (res)
1822  return res;
1823  num %= 1000000;
1824  ast_copy_string(fn, "digits/million", sizeof(fn));
1825  } else {
1826  ast_debug(1, "Number '%d' is too big for me\n", num);
1827  res = -1;
1828  }
1829  }
1830  }
1831  }
1832  if (!res) {
1833  if(!ast_streamfile(chan, fn, language)) {
1834  if ((audiofd > -1) && (ctrlfd > -1))
1835  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
1836  else
1837  res = ast_waitstream(chan, ints);
1838  }
1839  ast_stopstream(chan);
1840  }
1841  }
1842  return res;
1843 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
static int ast_say_number_full_hu(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
ast_say_number_full_hu: Hungarian syntax
Definition: say.c:1769
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8283
#define ast_debug(level,...)
Log a DEBUG message.
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1849
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1840
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
static int ast_say_number_full_no ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
const char *  options,
int  audiofd,
int  ctrlfd 
)
static

ast_say_number_full_no: Norwegian syntax New files: In addition to American English, the following sounds are required: "and", "1N"

The grammar for Norwegian numbers is the same as for English except for the following:

  • 1 exists in both commune ("en", file "1") and neuter ("ett", file "1N") "and" before the last two digits, i.e. 2034 is "two thousand and thirty-four" and 1000012 is "one million and twelve".

Definition at line 2222 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by say_number_full().

2223 {
2224  int res = 0;
2225  int playh = 0;
2226  int playa = 0;
2227  int cn = 1; /* +1 = commune; -1 = neuter */
2228  char fn[256] = "";
2229 
2230  if (!num)
2231  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
2232 
2233  if (options && !strncasecmp(options, "n", 1)) cn = -1;
2234 
2235  while (!res && (num || playh || playa )) {
2236  if (num < 0) {
2237  ast_copy_string(fn, "digits/minus", sizeof(fn));
2238  if ( num > INT_MIN ) {
2239  num = -num;
2240  } else {
2241  num = 0;
2242  }
2243  } else if (playh) {
2244  ast_copy_string(fn, "digits/hundred", sizeof(fn));
2245  playh = 0;
2246  } else if (playa) {
2247  ast_copy_string(fn, "digits/and", sizeof(fn));
2248  playa = 0;
2249  } else if (num == 1 && cn == -1) {
2250  ast_copy_string(fn, "digits/1N", sizeof(fn));
2251  num = 0;
2252  } else if (num < 20) {
2253  snprintf(fn, sizeof(fn), "digits/%d", num);
2254  num = 0;
2255  } else if (num < 100) {
2256  snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
2257  num %= 10;
2258  } else if (num < 1000) {
2259  int hundreds = num / 100;
2260  if (hundreds == 1)
2261  ast_copy_string(fn, "digits/1N", sizeof(fn));
2262  else
2263  snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
2264 
2265  playh++;
2266  num -= 100 * hundreds;
2267  if (num)
2268  playa++;
2269  } else if (num < 1000000) {
2270  res = ast_say_number_full_no(chan, num / 1000, ints, language, "n", audiofd, ctrlfd);
2271  if (res)
2272  return res;
2273  ast_copy_string(fn, "digits/thousand", sizeof(fn));
2274  num %= 1000;
2275  if (num && num < 100)
2276  playa++;
2277  } else if (num < 1000000000) {
2278  int millions = num / 1000000;
2279  res = ast_say_number_full_no(chan, millions, ints, language, "c", audiofd, ctrlfd);
2280  if (res)
2281  return res;
2282  ast_copy_string(fn, "digits/million", sizeof(fn));
2283  num %= 1000000;
2284  if (num && num < 100)
2285  playa++;
2286  } else {
2287  ast_debug(1, "Number '%d' is too big for me\n", num);
2288  res = -1;
2289  }
2290 
2291  if (!res) {
2292  if (!ast_streamfile(chan, fn, language)) {
2293  if ((audiofd > -1) && (ctrlfd > -1))
2294  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
2295  else
2296  res = ast_waitstream(chan, ints);
2297  }
2298  ast_stopstream(chan);
2299  }
2300  }
2301  return res;
2302 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8283
static int ast_say_number_full_no(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_number_full_no: Norwegian syntax New files: In addition to American English, the following sounds are required: "and", "1N"
Definition: say.c:2222
#define ast_debug(level,...)
Log a DEBUG message.
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1849
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1840
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
static int ast_say_number_full_ru ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
const char *  options,
int  audiofd,
int  ctrlfd 
)
static

ast_say_number_full_ru: Russian syntax

additional files: n00.gsm (one hundred, two hundred, ...) thousand.gsm million.gsm thousands-i.gsm (tisyachi) million-a.gsm (milliona) thousands.gsm millions.gsm 1f.gsm (odna) 2f.gsm (dve)

where 'n' from 1 to 9

Definition at line 2984 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), ast_waitstream_full(), and get_lastdigits_ru().

Referenced by say_number_full().

2985 {
2986  int res = 0;
2987  int lastdigits = 0;
2988  char fn[256] = "";
2989  if (!num)
2990  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
2991 
2992  while (!res && (num)) {
2993  if (num < 0) {
2994  ast_copy_string(fn, "digits/minus", sizeof(fn));
2995  if ( num > INT_MIN ) {
2996  num = -num;
2997  } else {
2998  num = 0;
2999  }
3000  } else if (num < 20) {
3001  if (options && strlen(options) == 1 && num < 3) {
3002  snprintf(fn, sizeof(fn), "digits/%d%s", num, options);
3003  } else {
3004  snprintf(fn, sizeof(fn), "digits/%d", num);
3005  }
3006  num = 0;
3007  } else if (num < 100) {
3008  snprintf(fn, sizeof(fn), "digits/%d", num - (num % 10));
3009  num %= 10;
3010  } else if (num < 1000){
3011  snprintf(fn, sizeof(fn), "digits/%d", num - (num % 100));
3012  num %= 100;
3013  } else if (num < 1000000) { /* 1,000,000 */
3014  lastdigits = get_lastdigits_ru(num / 1000);
3015  /* say thousands */
3016  if (lastdigits < 3) {
3017  res = ast_say_number_full_ru(chan, num / 1000, ints, language, "f", audiofd, ctrlfd);
3018  } else {
3019  res = ast_say_number_full_ru(chan, num / 1000, ints, language, NULL, audiofd, ctrlfd);
3020  }
3021  if (res)
3022  return res;
3023  if (lastdigits == 1) {
3024  ast_copy_string(fn, "digits/thousand", sizeof(fn));
3025  } else if (lastdigits > 1 && lastdigits < 5) {
3026  ast_copy_string(fn, "digits/thousands-i", sizeof(fn));
3027  } else {
3028  ast_copy_string(fn, "digits/thousands", sizeof(fn));
3029  }
3030  num %= 1000;
3031  } else if (num < 1000000000) { /* 1,000,000,000 */
3032  lastdigits = get_lastdigits_ru(num / 1000000);
3033  /* say millions */
3034  res = ast_say_number_full_ru(chan, num / 1000000, ints, language, NULL, audiofd, ctrlfd);
3035  if (res)
3036  return res;
3037  if (lastdigits == 1) {
3038  ast_copy_string(fn, "digits/million", sizeof(fn));
3039  } else if (lastdigits > 1 && lastdigits < 5) {
3040  ast_copy_string(fn, "digits/million-a", sizeof(fn));
3041  } else {
3042  ast_copy_string(fn, "digits/millions", sizeof(fn));
3043  }
3044  num %= 1000000;
3045  } else {
3046  ast_debug(1, "Number '%d' is too big for me\n", num);
3047  res = -1;
3048  }
3049  if (!res) {
3050  if (!ast_streamfile(chan, fn, language)) {
3051  if ((audiofd > -1) && (ctrlfd > -1))
3052  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
3053  else
3054  res = ast_waitstream(chan, ints);
3055  }
3056  ast_stopstream(chan);
3057  }
3058  }
3059  return res;
3060 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
static int ast_say_number_full_ru(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_number_full_ru: Russian syntax
Definition: say.c:2984
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8283
#define ast_debug(level,...)
Log a DEBUG message.
static int get_lastdigits_ru(int num)
determine last digits for thousands/millions (ru)
Definition: say.c:2957
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1849
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1840
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
static int ast_say_number_full_se ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
const char *  options,
int  audiofd,
int  ctrlfd 
)
static

ast_say_number_full_se: Swedish syntax

Sound files needed

  • 1N

Definition at line 2705 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by say_number_full().

2706 {
2707  int playh = 0;
2708  int start = 1;
2709  char fn[256] = "";
2710  int cn = 1; /* +1 = commune; -1 = neuter */
2711  int res = 0;
2712 
2713  if (!num) {
2714  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
2715  }
2716  if (options && !strncasecmp(options, "n", 1)) cn = -1;
2717 
2718  while (num || playh) {
2719  if (num < 0) {
2720  ast_copy_string(fn, "digits/minus", sizeof(fn));
2721  if ( num > INT_MIN ) {
2722  num = -num;
2723  } else {
2724  num = 0;
2725  }
2726  } else if (playh) {
2727  ast_copy_string(fn, "digits/hundred", sizeof(fn));
2728  playh = 0;
2729  } else if (start && num < 200 && num > 99 && cn == -1) {
2730  /* Don't say "en hundra" just say "hundra". */
2731  snprintf(fn, sizeof(fn), "digits/hundred");
2732  num -= 100;
2733  } else if (num == 1 && cn == -1) { /* En eller ett? */
2734  ast_copy_string(fn, "digits/1N", sizeof(fn));
2735  num = 0;
2736  } else if (num < 20) {
2737  snprintf(fn, sizeof(fn), "digits/%d", num);
2738  num = 0;
2739  } else if (num < 100) { /* Below hundreds - teens and tens */
2740  snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
2741  num %= 10;
2742  } else if (num < 1000) {
2743  /* Hundreds */
2744  snprintf(fn, sizeof(fn), "digits/%d", (num/100));
2745  playh++;
2746  num %= 100;
2747  } else if (num < 1000000) { /* 1,000,000 */
2748  /* Always say "ett hundra tusen", not "en hundra tusen" */
2749  res = ast_say_number_full_se(chan, num / 1000, ints, language, "c", audiofd, ctrlfd);
2750  if (res) {
2751  return res;
2752  }
2753  num %= 1000;
2754  ast_copy_string(fn, "digits/thousand", sizeof(fn));
2755  } else if (num < 1000000000) { /* 1,000,000,000 */
2756  /* Always say "en miljon", not "ett miljon" */
2757  res = ast_say_number_full_se(chan, num / 1000000, ints, language, "n", audiofd, ctrlfd);
2758  if (res) {
2759  return res;
2760  }
2761  num %= 1000000;
2762  ast_copy_string(fn, "digits/million", sizeof(fn));
2763  } else { /* Miljarder - Billions */
2764  ast_debug(1, "Number '%d' is too big for me\n", num);
2765  return -1;
2766  }
2767 
2768  if (!ast_streamfile(chan, fn, language)) {
2769  if ((audiofd > -1) && (ctrlfd > -1)) {
2770  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
2771  } else {
2772  res = ast_waitstream(chan, ints);
2773  }
2774  ast_stopstream(chan);
2775  if (res) {
2776  return res;
2777  }
2778  }
2779  start = 0;
2780  }
2781  return 0;
2782 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
static int ast_say_number_full_se(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_number_full_se: Swedish syntax
Definition: say.c:2705
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8283
#define ast_debug(level,...)
Log a DEBUG message.
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1849
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1840
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
static int ast_say_time_gr ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang 
)
static

Greek support.

A list of the files that you need to create

  • digits/female/1..4 : "Mia, dyo , treis, tesseris "
  • digits/kai : "KAI"
  • digits : "h wra"
  • digits/p-m : "meta meshmbrias"
  • digits/a-m : "pro meshmbrias"

Definition at line 8452 of file say.c.

References ast_localtime(), ast_say_number(), ast_streamfile(), ast_waitstream(), gr_say_number_female(), ast_tm::tm_hour, and ast_tm::tm_min.

Referenced by ast_say_datetime_gr().

8453 {
8454 
8455  struct timeval when = { t, 0 };
8456  struct ast_tm tm;
8457  int res = 0;
8458  int hour, pm=0;
8459 
8460  ast_localtime(&when, &tm, NULL);
8461  hour = tm.tm_hour;
8462 
8463  if (!hour)
8464  hour = 12;
8465  else if (hour == 12)
8466  pm = 1;
8467  else if (hour > 12) {
8468  hour -= 12;
8469  pm = 1;
8470  }
8471 
8472  res = gr_say_number_female(hour, chan, ints, lang);
8473  if (tm.tm_min) {
8474  if (!res)
8475  res = ast_streamfile(chan, "digits/kai", lang);
8476  if (!res)
8477  res = ast_waitstream(chan, ints);
8478  if (!res)
8479  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
8480  } else {
8481  if (!res)
8482  res = ast_streamfile(chan, "digits/hwra", lang);
8483  if (!res)
8484  res = ast_waitstream(chan, ints);
8485  }
8486  if (pm) {
8487  if (!res)
8488  res = ast_streamfile(chan, "digits/p-m", lang);
8489  } else {
8490  if (!res)
8491  res = ast_streamfile(chan, "digits/a-m", lang);
8492  }
8493  if (!res)
8494  res = ast_waitstream(chan, ints);
8495  return res;
8496 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8235
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1840
static int gr_say_number_female(int num, struct ast_channel *chan, const char *ints, const char *lang)
Greek digits/female-[1..4] : "Mia, dyo , treis, tessereis".
Definition: say.c:8183
static char* ast_translate_number_ka ( int  num,
char *  res,
int  res_len 
)
static

Georgian support.

Convert a number into a semi-localized string. Only for Georgian. res must be of at least 256 bytes, preallocated. The output corresponds to Georgian spoken numbers, so it may be either converted to real words by applying a direct conversion table, or played just by substituting the entities with played files.

Output may consist of the following tokens (separated by spaces): 0, minus. 1-9, 1_-9_. (erti, ori, sami, otxi, ... . erti, or, sam, otx, ...). 10-19. 20, 40, 60, 80, 20_, 40_, 60_, 80_. (oci, ormoci, ..., ocda, ormocda, ...). 100, 100_, 200, 200_, ..., 900, 900_. (asi, as, orasi, oras, ...). 1000, 1000_. (atasi, atas). 1000000, 1000000_. (milioni, milion). 1000000000, 1000000000_. (miliardi, miliard).

To be able to play the sounds, each of the above tokens needs a corresponding sound file. (e.g. 200_.gsm).

Definition at line 9323 of file say.c.

Referenced by ast_say_number_full_ka().

9324 {
9325  char buf[256];
9326  int digit = 0;
9327  int remaining = 0;
9328 
9329 
9330  if (num < 0) {
9331  strncat(res, "minus ", res_len - strlen(res) - 1);
9332  if ( num > INT_MIN ) {
9333  num = -num;
9334  } else {
9335  num = 0;
9336  }
9337  }
9338 
9339 
9340  /* directly read the numbers */
9341  if (num <= 20 || num == 40 || num == 60 || num == 80 || num == 100) {
9342  snprintf(buf, sizeof(buf), "%d", num);
9343  strncat(res, buf, res_len - strlen(res) - 1);
9344  return res;
9345  }
9346 
9347 
9348  if (num < 40) { /* ocda... */
9349  strncat(res, "20_ ", res_len - strlen(res) - 1);
9350  return ast_translate_number_ka(num - 20, res, res_len);
9351  }
9352 
9353  if (num < 60) { /* ormocda... */
9354  strncat(res, "40_ ", res_len - strlen(res) - 1);
9355  return ast_translate_number_ka(num - 40, res, res_len);
9356  }
9357 
9358  if (num < 80) { /* samocda... */
9359  strncat(res, "60_ ", res_len - strlen(res) - 1);
9360  return ast_translate_number_ka(num - 60, res, res_len);
9361  }
9362 
9363  if (num < 100) { /* otxmocda... */
9364  strncat(res, "80_ ", res_len - strlen(res) - 1);
9365  return ast_translate_number_ka(num - 80, res, res_len);
9366  }
9367 
9368 
9369  if (num < 1000) { /* as, oras, samas, ..., cxraas. asi, orasi, ..., cxraasi. */
9370  remaining = num % 100;
9371  digit = (num - remaining) / 100;
9372 
9373  if (remaining == 0) {
9374  snprintf(buf, sizeof(buf), "%d", num);
9375  strncat(res, buf, res_len - strlen(res) - 1);
9376  return res;
9377  } else {
9378  snprintf(buf, sizeof(buf), "%d_ ", digit*100);
9379  strncat(res, buf, res_len - strlen(res) - 1);
9380  return ast_translate_number_ka(remaining, res, res_len);
9381  }
9382  }
9383 
9384 
9385  if (num == 1000) {
9386  strncat(res, "1000", res_len - strlen(res) - 1);
9387  return res;
9388  }
9389 
9390 
9391  if (num < 1000000) {
9392  remaining = num % 1000;
9393  digit = (num - remaining) / 1000;
9394 
9395  if (remaining == 0) {
9396  ast_translate_number_ka(digit, res, res_len);
9397  strncat(res, " 1000", res_len - strlen(res) - 1);
9398  return res;
9399  }
9400 
9401  if (digit == 1) {
9402  strncat(res, "1000_ ", res_len - strlen(res) - 1);
9403  return ast_translate_number_ka(remaining, res, res_len);
9404  }
9405 
9406  ast_translate_number_ka(digit, res, res_len);
9407  strncat(res, " 1000_ ", res_len - strlen(res) - 1);
9408  return ast_translate_number_ka(remaining, res, res_len);
9409  }
9410 
9411 
9412  if (num == 1000000) {
9413  strncat(res, "1 1000000", res_len - strlen(res) - 1);
9414  return res;
9415  }
9416 
9417 
9418  if (num < 1000000000) {
9419  remaining = num % 1000000;
9420  digit = (num - remaining) / 1000000;
9421 
9422  if (remaining == 0) {
9423  ast_translate_number_ka(digit, res, res_len);
9424  strncat(res, " 1000000", res_len - strlen(res) - 1);
9425  return res;
9426  }
9427 
9428  ast_translate_number_ka(digit, res, res_len);
9429  strncat(res, " 1000000_ ", res_len - strlen(res) - 1);
9430  return ast_translate_number_ka(remaining, res, res_len);
9431  }
9432 
9433 
9434  if (num == 1000000000) {
9435  strncat(res, "1 1000000000", res_len - strlen(res) - 1);
9436  return res;
9437  }
9438 
9439 
9440  if (num > 1000000000) {
9441  remaining = num % 1000000000;
9442  digit = (num - remaining) / 1000000000;
9443 
9444  if (remaining == 0) {
9445  ast_translate_number_ka(digit, res, res_len);
9446  strncat(res, " 1000000000", res_len - strlen(res) - 1);
9447  return res;
9448  }
9449 
9450  ast_translate_number_ka(digit, res, res_len);
9451  strncat(res, " 1000000000_ ", res_len - strlen(res) - 1);
9452  return ast_translate_number_ka(remaining, res, res_len);
9453  }
9454 
9455  return res;
9456 
9457 }
static char * ast_translate_number_ka(int num, char *res, int res_len)
Georgian support.
Definition: say.c:9323
static const char* counted_noun_ending_en ( int  num)
static

In English, we use the plural for everything but one. For example:

  • 1 degree
  • 2 degrees
  • 5 degrees The filename for the plural form is generated by appending "s". Note that purpose is to generate a unique filename, not to implement irregular declensions. Thus:
  • 1 man
  • 2 mans (the "mans" soundfile will of course say "men")

Definition at line 9689 of file say.c.

9690 {
9691  if (num == 1 || num == -1) {
9692  return "";
9693  } else {
9694  return "s";
9695  }
9696 }
static const char* counted_noun_ending_slavic ( int  num)
static

Counting of objects in slavic languages such as Russian and Ukrainian the rules are more complicated. There are two plural forms used in counting. They are the genative singular which we represent with the suffix "x1" and the genative plural which we represent with the suffix "x2". The base names of the soundfiles remain in English. For example:

  • 1 degree (soundfile says "gradus")
  • 2 degreex1 (soundfile says "gradusa")
  • 5 degreex2 (soundfile says "gradusov")

Definition at line 9708 of file say.c.

9709 {
9710  if (num < 0) {
9711  num *= -1;
9712  }
9713  num %= 100; /* never pay attention to more than two digits */
9714  if (num >= 20) { /* for numbers 20 and above, pay attention to only last digit */
9715  num %= 10;
9716  }
9717  if (num == 1) { /* singular */
9718  return "";
9719  }
9720  if (num > 0 && num < 5) { /* 2--4 get genative singular */
9721  return "x1";
9722  } else { /* 5--19 get genative plural */
9723  return "x2";
9724  }
9725 }
static int say_enumeration_full ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
const char *  options,
int  audiofd,
int  ctrlfd 
)
static

ast_say_enumeration_full: call language-specific functions

Note
Called from AGI

Definition at line 3229 of file say.c.

References ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), and ast_say_enumeration_full_is().

Referenced by __say_init(), and say_init_mode().

3230 {
3231  if (!strncasecmp(language, "en", 2)) { /* English syntax */
3232  return ast_say_enumeration_full_en(chan, num, ints, language, audiofd, ctrlfd);
3233  } else if (!strncasecmp(language, "da", 2)) { /* Danish syntax */
3234  return ast_say_enumeration_full_da(chan, num, ints, language, options, audiofd, ctrlfd);
3235  } else if (!strncasecmp(language, "de", 2)) { /* German syntax */
3236  return ast_say_enumeration_full_de(chan, num, ints, language, options, audiofd, ctrlfd);
3237  } else if (!strncasecmp(language, "he", 2)) { /* Hebrew syntax */
3238  return ast_say_enumeration_full_he(chan, num, ints, language, options, audiofd, ctrlfd);
3239  } else if (!strncasecmp(language, "is", 2)) { /* Icelandic syntax */
3240  return ast_say_enumeration_full_is(chan, num, ints, language, options, audiofd, ctrlfd);
3241  } else if (!strncasecmp(language, "vi", 2)) { /* Vietnamese syntax */
3242  return ast_say_enumeration_full_vi(chan, num, ints, language, audiofd, ctrlfd);
3243  }
3244 
3245  /* Default to english */
3246  return ast_say_enumeration_full_en(chan, num, ints, language, audiofd, ctrlfd);
3247 }
static int ast_say_enumeration_full_is(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_enumeration_full_is: Icelandic syntax
Definition: say.c:3782
static int ast_say_enumeration_full_en(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
ast_say_enumeration_full_en: English syntax
Definition: say.c:3251
static int ast_say_enumeration_full_da(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_enumeration_full_da: Danish syntax
Definition: say.c:3368
static int ast_say_enumeration_full_de(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_enumeration_full_de: German syntax
Definition: say.c:3531
static int say_number_full ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
const char *  options,
int  audiofd,
int  ctrlfd 
)
static

ast_say_number_full: call language-specific functions

Note
Called from AGI

Definition at line 874 of file say.c.

References ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_gr(), ast_say_number_full_hu(), ast_say_number_full_is(), ast_say_number_full_it(), ast_say_number_full_ka(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_th(), ast_say_number_full_vi(), ast_say_number_full_zh(), and ast_test_suite_event_notify.

Referenced by __say_init(), and say_init_mode().

875 {
876  ast_test_suite_event_notify("SAYNUM", "Message: saying number %d\r\nNumber: %d\r\nChannel: %s", num, num, ast_channel_name(chan));
877  if (!strncasecmp(language, "en_GB", 5)) { /* British syntax */
878  return ast_say_number_full_en_GB(chan, num, ints, language, audiofd, ctrlfd);
879  } else if (!strncasecmp(language, "en", 2)) { /* English syntax */
880  return ast_say_number_full_en(chan, num, ints, language, audiofd, ctrlfd);
881  } else if (!strncasecmp(language, "cs", 2)) { /* Czech syntax */
882  return ast_say_number_full_cs(chan, num, ints, language, options, audiofd, ctrlfd);
883  } else if (!strncasecmp(language, "da", 2)) { /* Danish syntax */
884  return ast_say_number_full_da(chan, num, ints, language, options, audiofd, ctrlfd);
885  } else if (!strncasecmp(language, "de", 2)) { /* German syntax */
886  return ast_say_number_full_de(chan, num, ints, language, options, audiofd, ctrlfd);
887  } else if (!strncasecmp(language, "es", 2)) { /* Spanish syntax */
888  return ast_say_number_full_es(chan, num, ints, language, options, audiofd, ctrlfd);
889  } else if (!strncasecmp(language, "fr", 2)) { /* French syntax */
890  return ast_say_number_full_fr(chan, num, ints, language, options, audiofd, ctrlfd);
891  } else if (!strncasecmp(language, "gr", 2)) { /* Greek syntax */
892  return ast_say_number_full_gr(chan, num, ints, language, audiofd, ctrlfd);
893  } else if (!strncasecmp(language, "ja", 2)) { /* Japanese syntax */
894  return ast_say_number_full_ja(chan, num, ints, language, audiofd, ctrlfd);
895  } else if (!strncasecmp(language, "he", 2)) { /* Hebrew syntax */
896  return ast_say_number_full_he(chan, num, ints, language, options, audiofd, ctrlfd);
897  } else if (!strncasecmp(language, "hu", 2)) { /* Hungarian syntax */
898  return ast_say_number_full_hu(chan, num, ints, language, audiofd, ctrlfd);
899  } else if (!strncasecmp(language, "is", 2)) { /* Icelandic syntax */
900  return ast_say_number_full_is(chan, num, ints, language, options, audiofd, ctrlfd);
901  } else if (!strncasecmp(language, "it", 2)) { /* Italian syntax */
902  return ast_say_number_full_it(chan, num, ints, language, audiofd, ctrlfd);
903  } else if (!strncasecmp(language, "ka", 2)) { /* Georgian syntax */
904  return ast_say_number_full_ka(chan, num, ints, language, options, audiofd, ctrlfd);
905  } else if (!strncasecmp(language, "nl", 2)) { /* Dutch syntax */
906  return ast_say_number_full_nl(chan, num, ints, language, audiofd, ctrlfd);
907  } else if (!strncasecmp(language, "no", 2)) { /* Norwegian syntax */
908  return ast_say_number_full_no(chan, num, ints, language, options, audiofd, ctrlfd);
909  } else if (!strncasecmp(language, "pl", 2)) { /* Polish syntax */
910  return ast_say_number_full_pl(chan, num, ints, language, options, audiofd, ctrlfd);
911  } else if (!strncasecmp(language, "pt", 2)) { /* Portuguese syntax */
912  return ast_say_number_full_pt(chan, num, ints, language, options, audiofd, ctrlfd);
913  } else if (!strncasecmp(language, "ru", 2)) { /* Russian syntax */
914  return ast_say_number_full_ru(chan, num, ints, language, options, audiofd, ctrlfd);
915  } else if (!strncasecmp(language, "se", 2)) { /* Swedish syntax */
916  return ast_say_number_full_se(chan, num, ints, language, options, audiofd, ctrlfd);
917  } else if (!strncasecmp(language, "th", 2)) { /* Thai syntax */
918  return ast_say_number_full_th(chan, num, ints, language, audiofd, ctrlfd);
919  } else if (!strncasecmp(language, "zh", 2)) { /* Taiwanese / Chinese syntax */
920  return ast_say_number_full_zh(chan, num, ints, language, audiofd, ctrlfd);
921  } else if (!strncasecmp(language, "ur", 2)) { /* Urdu syntax */
922  return ast_say_number_full_ur(chan, num, ints, language, options, audiofd, ctrlfd);
923  } else if (!strncasecmp(language, "vi", 2)) { /* Vietnamese syntax */
924  return ast_say_number_full_vi(chan, num, ints, language, audiofd, ctrlfd);
925  }
926 
927  /* Default to english */
928  return ast_say_number_full_en(chan, num, ints, language, audiofd, ctrlfd);
929 }
static int ast_say_number_full_se(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_number_full_se: Swedish syntax
Definition: say.c:2705
static int ast_say_number_full_hu(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
ast_say_number_full_hu: Hungarian syntax
Definition: say.c:1769
static int ast_say_number_full_ru(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_number_full_ru: Russian syntax
Definition: say.c:2984
static int ast_say_number_full_gr(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
Greek support A list of the files that you need to create -> digits/xilia = "xilia" -> digits/myrio =...
Definition: say.c:8228
static int ast_say_number_full_nl(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
ast_say_number_full_nl: dutch syntax New files: digits/nl-en
Definition: say.c:2124
static int ast_say_number_full_it(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
ast_say_number_full_it: Italian
Definition: say.c:1969
static int ast_say_number_full_is(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_number_full_is: Icelandic syntax
Definition: say.c:1849
static int ast_say_number_full_fr(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_number_full_fr: French syntax Extra sounds needed: 1F: feminin 'une' et: 'and' ...
Definition: say.c:1505
static int ast_say_number_full_no(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_number_full_no: Norwegian syntax New files: In addition to American English, the following sounds are required: "and", "1N"
Definition: say.c:2222
static int ast_say_number_full_cs(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_number_full_cs: Czech syntax
Definition: say.c:976
static int ast_say_number_full_de(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_number_full_de: German syntax
Definition: say.c:1188
static int ast_say_number_full_en_GB(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
ast_say_number_full_en_GB: British syntax New files:
Definition: say.c:1322
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:189
static int ast_say_number_full_es(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_number_full_es: Spanish syntax
Definition: say.c:1401
static int ast_say_number_full_da(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_number_full_da: Danish syntax New files:
Definition: say.c:1074
static int ast_say_number_full_vi(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
ast_say_number_full_vi: Vietnamese syntax
Definition: say.c:3133
static int ast_say_number_full_th(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
Thai syntax.
Definition: say.c:3063
static int ast_say_number_full_zh(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
ast_say_number_full_zh: Taiwanese / Chinese syntax
Definition: say.c:2785
static int ast_say_number_full_en(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
ast_say_number_full_en: English syntax
Definition: say.c:933
static int ast_say_number_full_ka(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_number_full_ka: Georgian syntax
Definition: say.c:9462