[asterisk-commits] mjordan: trunk r417591 - in /trunk: CHANGES apps/app_voicemail.c main/say.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sun Jun 29 23:00:24 CDT 2014


Author: mjordan
Date: Sun Jun 29 23:00:19 2014
New Revision: 417591

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=417591
Log:
app_voicemail, say: Add support for Japanese Language

This patch adds support for the Japanese language to both the say family of
applications, as well as for VoiceMail and VoiceMailMain. A new pack of
language sounds will be released at the same time as the next major version
of Asterisk to support the new language features.

The language features can be enabled using a language code of 'ja'.

Review: https://reviewboard.asterisk.org/r/3477

ASTERISK-23324 #close
Reported by: Kevin McCoy
patches:
  app_voicemail.c.20140226.jb.patch uploaded by Kevin McCoy (License 6586)
  say.c.20140226.jb.patch uploaded by Kevin McCoy (License 6586)


Modified:
    trunk/CHANGES
    trunk/apps/app_voicemail.c
    trunk/main/say.c

Modified: trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/trunk/CHANGES?view=diff&rev=417591&r1=417590&r2=417591
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Sun Jun 29 23:00:19 2014
@@ -52,6 +52,28 @@
 ------------------
  * The JACK_HOOK function now supports audio with a sample rate higher than
    8kHz.
+
+Say
+------------------
+ * The 'say' family of dialplan applications now support the Japanese
+   language. The 'language' parameter in say.conf now recognizes a setting of
+   'ja', which will enable Japanese language specific mechanisms for playing
+   back numbers, dates, and other items.
+
+VoiceMail
+------------------
+ * VoiceMail and VoiceMailMain now support the Japanese language. The
+   'language' parameter in voicemail.conf now recognizes a setting of 'ja',
+   which will enable prompts to be played back using a Japanese grammatical
+   structure. Additional prompts are necessary for this functionality,
+   including:
+   - jb-arimasu: there is
+   - jb-arimasen: there is not
+   - jb-oshitekudasai: please press
+   - jb-ni: article ni
+   - jb-ga: article ga
+   - jb-wa: article wa
+   - jb-wo: article wo
 
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 12.3.0 to Asterisk 12.4.0 ------------

Modified: trunk/apps/app_voicemail.c
URL: http://svnview.digium.com/svn/asterisk/trunk/apps/app_voicemail.c?view=diff&rev=417591&r1=417590&r2=417591
==============================================================================
--- trunk/apps/app_voicemail.c (original)
+++ trunk/apps/app_voicemail.c Sun Jun 29 23:00:19 2014
@@ -755,6 +755,15 @@
 \arg \b vm-vecchio	old
 \arg \b vm-vecchi	old plural
 
+Japanese requires the following additional soundfile:
+\arg \b jp-arimasu          there is
+\arg \b jp-arimasen         there is not
+\arg \b jp-oshitekudasai    please press
+\arg \b jp-ni               article ni
+\arg \b jp-ga               article ga
+\arg \b jp-wa               article wa
+\arg \b jp-wo               article wo
+
 Chinese (Taiwan) requires the following additional soundfile:
 \arg \b vm-tong		A class-word for call (tong1)
 \arg \b vm-ri		A class-word for day (ri4)
@@ -7579,6 +7588,34 @@
 	return d;
 }
 
+/* Japanese Syntax */
+static int get_folder_ja(struct ast_channel *chan, int start)
+{
+        int x;
+        int d;
+        char fn[256];
+        for (x = start; x< 5; x++) {    /* For all folders */
+                if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, ast_channel_language(chan), (char *) NULL))) {
+                        return d;
+		}
+		snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x));     /* Folder name */
+		d = vm_play_folder_name(chan, fn);
+		if (d) {
+                        return d;
+		}
+                d = ast_waitfordigit(chan, 500);
+                if (d) {
+                        return d;
+		}
+        }
+        d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */
+        if (d) {
+                return d;
+	}
+        d = ast_waitfordigit(chan, 4000);
+        return d;
+}
+
 /*!
  * \brief plays a prompt and waits for a keypress.
  * \param chan
@@ -7600,7 +7637,12 @@
 	while (((res < '0') || (res > '9')) &&
 			(res != '#') && (res >= 0) &&
 			loops < 4) {
-		res = get_folder(chan, 0);
+                /* res = get_folder(chan, 0); */
+                if (!strcasecmp(ast_channel_language(chan),"ja")) {   /* Japanese syntax */
+                      res = get_folder_ja(chan, 0);
+                } else { /* Default syntax */
+		      res = get_folder(chan, 0);
+		}
 		loops++;
 	}
 	if (loops == 4) { /* give up */
@@ -8326,6 +8368,8 @@
 		res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "'vm-received' q  H 'digits/kai' M ", NULL);
 	} else if (!strncasecmp(ast_channel_language(chan), "it", 2)) {     /* ITALIAN syntax */
 		res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "'vm-received' q 'digits/at' 'digits/hours' k 'digits/e' M 'digits/minutes'", NULL);
+	} else if (!strcasecmp(ast_channel_language(chan),"ja")) {     /* Japanese syntax */
+		res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "PHM q 'jp-ni' 'vm-received'", NULL);
 	} else if (!strncasecmp(ast_channel_language(chan), "nl", 2)) {     /* DUTCH syntax */
 		res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "'vm-received' q 'digits/nl-om' HM", NULL);
 	} else if (!strncasecmp(ast_channel_language(chan), "no", 2)) {     /* NORWEGIAN syntax */
@@ -8891,6 +8935,19 @@
 	}
 }
 
+static int vm_play_folder_name_ja(struct ast_channel *chan, char *box)
+{
+        int cmd;
+
+        if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) {
+                cmd = ast_play_and_wait(chan, box);
+                return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
+        } else {
+                cmd = ast_play_and_wait(chan, box);
+                return cmd;
+        }
+}
+
 static int vm_play_folder_name_pl(struct ast_channel *chan, char *box)
 {
 	int cmd;
@@ -8933,6 +8990,8 @@
 		return vm_play_folder_name_gr(chan, box);
 	} else if (!strncasecmp(ast_channel_language(chan), "he", 2)) {  /* Hebrew syntax */
 		return ast_play_and_wait(chan, box);
+        } else if (!strncasecmp(ast_channel_language(chan), "ja", 2)) {  /* Japanese syntax */
+                return vm_play_folder_name_ja(chan, box);
 	} else if (!strncasecmp(ast_channel_language(chan), "pl", 2)) {
 		return vm_play_folder_name_pl(chan, box);
 	} else if (!strncasecmp(ast_channel_language(chan), "ua", 2)) {  /* Ukrainian syntax */
@@ -9156,6 +9215,45 @@
 	}
 	return res;
 }
+
+/* Japanese syntax */
+static int vm_intro_ja(struct ast_channel *chan,struct vm_state *vms)
+{
+      /* Introduce messages they have */
+      int res;
+      if (vms->newmessages) {
+              res = ast_play_and_wait(chan, "vm-INBOX");
+              if (!res)
+                      res = ast_play_and_wait(chan, "vm-message");
+              if (!res)
+                      res = ast_play_and_wait(chan, "jp-ga");
+              if (!res)
+                      res = say_and_wait(chan, vms->newmessages, ast_channel_language(chan));
+              if (vms->oldmessages && !res)
+                      res = ast_play_and_wait(chan, "silence/1");
+
+      }
+      if (vms->oldmessages) {
+              res = ast_play_and_wait(chan, "vm-Old");
+              if (!res)
+                      res = ast_play_and_wait(chan, "vm-message");
+              if (!res)
+                      res = ast_play_and_wait(chan, "jp-ga");
+              if (!res)
+                      res = say_and_wait(chan, vms->oldmessages, ast_channel_language(chan));
+      }
+      if (!vms->oldmessages && !vms->newmessages) {
+              res = ast_play_and_wait(chan, "vm-messages");
+              if (!res)
+                      res = ast_play_and_wait(chan, "jp-wa");
+              if (!res)
+                      res = ast_play_and_wait(chan, "jp-arimasen");
+      }
+      else {
+              res = ast_play_and_wait(chan, "jp-arimasu");
+      }
+      return res;
+} /* Japanese */
 	
 /* Default English syntax */
 static int vm_intro_en(struct ast_channel *chan, struct vm_state *vms)
@@ -9880,6 +9978,8 @@
 		return vm_intro_he(chan, vms);
 	} else if (!strncasecmp(ast_channel_language(chan), "it", 2)) {  /* ITALIAN syntax */
 		return vm_intro_it(chan, vms);
+	} else if (!strncasecmp(ast_channel_language(chan), "ja", 2)) {  /* JAPANESE syntax */
+		return vm_intro_ja(chan, vms);
 	} else if (!strncasecmp(ast_channel_language(chan), "nl", 2)) {  /* DUTCH syntax */
 		return vm_intro_nl(chan, vms);
 	} else if (!strncasecmp(ast_channel_language(chan), "no", 2)) {  /* NORWEGIAN syntax */
@@ -9993,6 +10093,102 @@
 	return res;
 }
 
+static int vm_instructions_ja(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms,  int skipadvanced, int in_urgent)
+{
+        int res = 0;
+        /* Play instructions and wait for new command */
+        while (!res) {
+                if (vms->starting) {
+                        if (vms->lastmsg > -1) {
+                                res = vm_play_folder_name(chan, vms->vmbox);
+                                if (!res)
+                                        res = ast_play_and_wait(chan, "jp-wa");
+                                if (!res)
+                                        res = ast_play_and_wait(chan, "digits/1");
+                                if (!res)
+                                        res = ast_play_and_wait(chan, "jp-wo");
+                                if (!res)
+                                        res = ast_play_and_wait(chan, "silence/1");
+                        }
+                        if (!res)
+                                res = ast_play_and_wait(chan, "vm-opts");
+                } else {
+                        /* Added for additional help */
+                        if (skipadvanced) {
+                                res = vm_play_folder_name(chan, vms->vmbox);
+                                if (!res)
+                                        res = ast_play_and_wait(chan, "jp-wa");
+                                if (!res)
+                                        res = ast_play_and_wait(chan, "digits/1");
+                                if (!res)
+                                        res = ast_play_and_wait(chan, "jp-wo");
+                                if (!res)
+                                        res = ast_play_and_wait(chan, "silence/1");
+                                res = ast_play_and_wait(chan, "vm-opts-full");
+                        }
+                        /* Logic:
+                         * If the current message is not the first OR
+                         * if we're listening to the first new message and there are
+                         * also urgent messages, then prompt for navigation to the
+                         * previous message
+                         */
+                        if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) {
+                                res = ast_play_and_wait(chan, "vm-prev");
+                        }
+                        if (!res && !skipadvanced)
+                                res = ast_play_and_wait(chan, "vm-advopts");
+                        if (!res)
+                                res = ast_play_and_wait(chan, "vm-repeat");
+                        /* Logic:
+                         * If we're not listening to the last message OR
+                         * we're listening to the last urgent message and there are
+                         * also new non-urgent messages, then prompt for navigation
+                         * to the next message
+                         */
+                        if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) ||
+                                (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) {
+                                res = ast_play_and_wait(chan, "vm-next");
+                        }
+                        if (!res) {
+                                int curmsg_deleted;
+#ifdef IMAP_STORAGE
+                                ast_mutex_lock(&vms->lock);
+#endif
+                                curmsg_deleted = vms->deleted[vms->curmsg];
+#ifdef IMAP_STORAGE
+                                ast_mutex_unlock(&vms->lock);
+#endif
+                                if (!curmsg_deleted) {
+                                        res = ast_play_and_wait(chan, "vm-delete");
+                                } else {
+                                        res = ast_play_and_wait(chan, "vm-undelete");
+                                }
+                                if (!res) {
+                                        res = ast_play_and_wait(chan, "vm-toforward");
+                                }
+                                if (!res) {
+                                        res = ast_play_and_wait(chan, "vm-savemessage");
+                                }
+                        }
+                }
+
+		if (!res) {
+			res = ast_play_and_wait(chan, "vm-helpexit");
+		}
+		if (!res)
+			res = ast_waitfordigit(chan, 6000);
+		if (!res) {
+			vms->repeats++;
+			if (vms->repeats > 2) {
+				res = 't';
+			}
+		}
+
+	}
+
+        return res;
+}
+
 static int vm_instructions_zh(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms,  int skipadvanced, int in_urgent)
 {
 	int res = 0;
@@ -10019,7 +10215,9 @@
 
 static int vm_instructions(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)
 {
-	if (vms->starting && !strncasecmp(ast_channel_language(chan), "zh", 2)) { /* CHINESE (Taiwan) syntax */
+        if (!strncasecmp(ast_channel_language(chan), "ja", 2)) { /* Japanese syntax */
+                return vm_instructions_ja(chan, vmu, vms, skipadvanced, in_urgent);
+        } else if (vms->starting && !strncasecmp(ast_channel_language(chan), "zh", 2)) { /* CHINESE (Taiwan) syntax */
 		return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent);
 	} else {					/* Default to ENGLISH */
 		return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent);
@@ -10440,6 +10638,33 @@
 	return cmd;
 }
 
+/*!
+ * \brief Japanese syntax for 'You have N messages' greeting.
+ * \param chan
+ * \param vms
+ * \param vmu
+ *
+ * \return zero on success, -1 on error.
+ */
+static int vm_browse_messages_ja(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
+{
+        int cmd = 0;
+
+        if (vms->lastmsg > -1) {
+                cmd = play_message(chan, vmu, vms);
+        } else {
+                snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
+                cmd = ast_play_and_wait(chan, vms->fn);
+                if (!cmd)
+                        cmd = ast_play_and_wait(chan, "vm-messages");
+                if (!cmd)
+                        cmd = ast_play_and_wait(chan, "jp-wa");
+                if (!cmd)
+                        cmd = ast_play_and_wait(chan, "jp-arimasen");
+        }
+        return cmd;
+}
+
 /*! 
  * \brief Spanish syntax for 'You have N messages' greeting.
  * \param chan
@@ -10565,6 +10790,8 @@
 		return vm_browse_messages_he(chan, vms, vmu);
 	} else if (!strncasecmp(ast_channel_language(chan), "it", 2)) {  /* ITALIAN */
 		return vm_browse_messages_it(chan, vms, vmu);
+        } else if (!strncasecmp(ast_channel_language(chan), "ja", 2)) {  /* JAPANESE */
+                return vm_browse_messages_ja(chan, vms, vmu);
 	} else if (!strncasecmp(ast_channel_language(chan), "pt", 2)) {  /* PORTUGUESE */
 		return vm_browse_messages_pt(chan, vms, vmu);
 	} else if (!strncasecmp(ast_channel_language(chan), "vi", 2)) {  /* VIETNAMESE */
@@ -11510,6 +11737,22 @@
 			break;
 		case '*': /* Help */
 			if (!vms.starting) {
+                                if (!strncasecmp(ast_channel_language(chan), "ja", 2)) {
+                                        cmd = vm_play_folder_name(chan, vms.vmbox);
+                                        if (!cmd)
+                                                cmd = ast_play_and_wait(chan, "jp-wa");
+                                        if (!cmd)
+                                                cmd = ast_play_and_wait(chan, "digits/1");
+                                        if (!cmd)
+                                                cmd = ast_play_and_wait(chan, "jp-wo");
+                                        if (!cmd)
+                                                cmd = ast_play_and_wait(chan, "silence/1");
+                                        if (!cmd)
+                                                cmd = ast_play_and_wait(chan, "vm-opts");
+                                        if (!cmd)
+                                                cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent);
+                                        break;
+                                }
 				cmd = ast_play_and_wait(chan, "vm-onefor");
 				if (!strncasecmp(ast_channel_language(chan), "he", 2)) {
 					cmd = ast_play_and_wait(chan, "vm-for");
@@ -12092,9 +12335,7 @@
 		} else if (!strncasecmp(arg.attribute, "pager", 5)) {
 			ast_copy_string(buf, vmu->pager, len);
 		} else if (!strncasecmp(arg.attribute, "language", 8)) {
-			const char *lang = S_OR(vmu->language, chan ?
-				ast_channel_language(chan) : ast_defaultlanguage);
-			ast_copy_string(buf, lang, len);
+			ast_copy_string(buf, S_OR(vmu->language, ast_channel_language(chan)), len);
 		} else if (!strncasecmp(arg.attribute, "locale", 6)) {
 			ast_copy_string(buf, vmu->locale, len);
 		} else if (!strncasecmp(arg.attribute, "tz", 2)) {
@@ -13804,7 +14045,7 @@
 		break;
 	}
 
-	if (!(test_channel1 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, NULL,
+	if (!(test_channel1 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
         NULL, NULL, 0, 0, "TestChannel1"))) {
 		goto exit_vmsayname_test;
 	}

Modified: trunk/main/say.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/say.c?view=diff&rev=417591&r1=417590&r2=417591
==============================================================================
--- trunk/main/say.c (original)
+++ trunk/main/say.c Sun Jun 29 23:00:19 2014
@@ -381,6 +381,7 @@
 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 int ast_say_number_full_zh(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
 static int ast_say_number_full_gr(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
+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_ru(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_ka(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);
@@ -403,6 +404,7 @@
 static int ast_say_date_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_date_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_date_gr(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);
 static int ast_say_date_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_date_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
@@ -420,6 +422,7 @@
 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);
 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);
 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);
+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_th(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_vi(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone);
 
@@ -431,6 +434,7 @@
 static int ast_say_time_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_time_zh(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_time_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+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);
 static int ast_say_time_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_time_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
@@ -444,6 +448,7 @@
 static int ast_say_datetime_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_datetime_zh(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_datetime_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+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);
 static int ast_say_datetime_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
 static int ast_say_datetime_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
@@ -500,6 +505,8 @@
 		return ast_say_number_full_ka(chan, num, ints, language, options, audiofd, ctrlfd);
 	} else if (!strncasecmp(language, "gr", 2)) { /* Greek syntax */
 	   return ast_say_number_full_gr(chan, num, ints, language, audiofd, ctrlfd);
+	} else if (!strncasecmp(language, "ja", 2)) { /* Japanese syntax */
+	   return ast_say_number_full_ja(chan, num, ints, language, audiofd, ctrlfd);
 	} else if (!strncasecmp(language, "he", 2)) { /* Hebrew syntax */
 	   return ast_say_number_full_he(chan, num, ints, language, options, audiofd, ctrlfd);
 	} else if (!strncasecmp(language, "hu", 2)) { /* Hungarian syntax */
@@ -1929,31 +1936,31 @@
 	m100 = m1000 % 100;
 	i100 = m1000 / 100;
 
-	if (i100>0)
-		pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->setki[i100]);
-
-	if (m100 > 0 && m100 <= 9) {
-		if (m1000 > 0)
-			pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry2[m100]);
-		else
-			pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry[m100]);
-	} else if (m100 % 10 == 0 && m100 != 0) {
-		pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->dziesiatki[m100 / 10]);
-	} else if (m100 > 10 && m100 <= 19) {
-		pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->nastki[m100 % 10]);
-	} else if (m100 > 20) {
-		if (odm->separator_dziesiatek[0] == ' ') {
-			pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->dziesiatki[m100 / 10]);
-			pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry2[m100 % 10]);
-		} else {
-			char buf[10];
-			char *b = buf;
-			b = pl_append(b, odm->dziesiatki[m100 / 10]);
-			b = pl_append(b, odm->separator_dziesiatek);
-			pl_append(b, odm->cyfry2[m100 % 10]);
-			pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, buf);
-		}
-	}
+        if (i100>0)
+                pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->setki[i100]);
+
+        if (m100 > 0 && m100 <= 9) {
+                if (m1000 > 0)
+                        pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry2[m100]);
+                else
+                        pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry[m100]);
+        } else if (m100 % 10 == 0 && m100 != 0) {
+                pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->dziesiatki[m100 / 10]);
+        } else if (m100 > 10 && m100 <= 19) {
+                pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->nastki[m100 % 10]);
+        } else if (m100 > 20) {
+                if (odm->separator_dziesiatek[0] == ' ') {
+                        pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->dziesiatki[m100 / 10]);
+                        pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry2[m100 % 10]);
+                } else {
+                        char buf[10];
+                        char *b = buf;
+                        b = pl_append(b, odm->dziesiatki[m100 / 10]);
+                        b = pl_append(b, odm->separator_dziesiatek);
+                        pl_append(b, odm->cyfry2[m100 % 10]);
+                        pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, buf);
+                }
+        }
 
 	if (rzad > 0) {
 		pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, pl_rzad_na_tekst(odm, i, rzad));
@@ -3340,6 +3347,8 @@
 		return ast_say_date_ka(chan, t, ints, lang);
 	} else if (!strncasecmp(lang, "gr", 2)) { /* Greek syntax */
 		return ast_say_date_gr(chan, t, ints, lang);
+	} else if (!strncasecmp(lang, "ja", 2)) { /* Japanese syntax */
+		return ast_say_date_ja(chan, t, ints, lang);
 	} else if (!strncasecmp(lang, "he", 2)) { /* Hebrew syntax */
 		return ast_say_date_he(chan, t, ints, lang);
 	} else if (!strncasecmp(lang, "hu", 2)) { /* Hungarian syntax */
@@ -3689,6 +3698,8 @@
 		return ast_say_date_with_format_fr(chan, t, ints, lang, format, tzone);
 	} else if (!strncasecmp(lang, "gr", 2)) { /* Greek syntax */
 		return ast_say_date_with_format_gr(chan, t, ints, lang, format, tzone);
+	} else if (!strncasecmp(lang, "ja", 2)) { /* Japanese syntax */
+		return ast_say_date_with_format_ja(chan, t, ints, lang, format, tzone);
 	} else if (!strncasecmp(lang, "it", 2)) { /* Italian syntax */
 		return ast_say_date_with_format_it(chan, t, ints, lang, format, tzone);
 	} else if (!strncasecmp(lang, "mx", 2)) { /* deprecated Mexican syntax */
@@ -6321,6 +6332,8 @@
 		return ast_say_time_ka(chan, t, ints, lang);
 	} else if (!strncasecmp(lang, "gr", 2)) { /* Greek syntax */
 		return ast_say_time_gr(chan, t, ints, lang);
+	} else if (!strncasecmp(lang, "ja", 2)) { /* Japanese syntax */
+		return ast_say_time_ja(chan, t, ints, lang);
 	} else if (!strncasecmp(lang, "he", 2)) { /* Hebrew syntax */
 		return ast_say_time_he(chan, t, ints, lang);
 	} else if (!strncasecmp(lang, "hu", 2)) { /* Hungarian syntax */
@@ -6652,6 +6665,8 @@
 		return ast_say_datetime_ka(chan, t, ints, lang);
 	} else if (!strncasecmp(lang, "gr", 2)) { /* Greek syntax */
 		return ast_say_datetime_gr(chan, t, ints, lang);
+	} else if (!strncasecmp(lang, "ja", 2)) { /* Japanese syntax */
+		return ast_say_datetime_ja(chan, t, ints, lang);
 	} else if (!strncasecmp(lang, "he", 2)) { /* Hebrew syntax */
 		return ast_say_datetime_he(chan, t, ints, lang);
 	} else if (!strncasecmp(lang, "hu", 2)) { /* Hungarian syntax */
@@ -7394,6 +7409,71 @@
 	return res;
 }
 
+/* Japanese syntax */
+static int ast_say_number_full_ja(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
+{
+     int res = 0;
+     int playh = 0;
+     char fn[256] = "";
+     if (!num)
+             return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
+
+     while (!res && (num || playh)) {
+             if (num < 0) {
+                     ast_copy_string(fn, "digits/minus", sizeof(fn));
+                     if ( num > INT_MIN ) {
+                             num = -num;
+                     } else {
+                             num = 0;
+                     }
+             } else if (playh) {
+                     ast_copy_string(fn, "digits/hundred", sizeof(fn));
+                     playh = 0;
+             } else  if (num < 20) {
+                     snprintf(fn, sizeof(fn), "digits/%d", num);
+                     num = 0;
+             } else  if (num < 100) {
+                     snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
+                     num %= 10;
+             } else {
+                     if (num < 1000){
+                             snprintf(fn, sizeof(fn), "digits/%d", (num/100));
+                             playh++;
+                             num %= 100;
+                     } else {
+                             if (num < 1000000) { /* 1,000,000 */
+                                     res = ast_say_number_full_en(chan, num / 1000, ints, language, audiofd, ctrlfd);
+                                     if (res)
+                                             return res;
+                                     num %= 1000;
+                                     snprintf(fn, sizeof(fn), "digits/thousand");
+                             } else {
+                                     if (num < 1000000000) { /* 1,000,000,000 */
+                                             res = ast_say_number_full_en(chan, num / 1000000, ints, language, audiofd, ctrlfd);
+                                             if (res)
+                                                     return res;
+                                             num %= 1000000;
+                                             ast_copy_string(fn, "digits/million", sizeof(fn));
+                                     } else {
+                                             ast_debug(1, "Number '%d' is too big for me\n", num);
+                                             res = -1;
+                                     }
+                             }
+                     }
+             }
+             if (!res) {
+                     if (!ast_streamfile(chan, fn, language)) {
+                             if ((audiofd  > -1) && (ctrlfd > -1))
+                                     res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
+                             else
+                                     res = ast_waitstream(chan, ints);
+                     }
+                     ast_stopstream(chan);
+             }
+     }
+     return res;
+}
+
 
 /*! \brief Greek support
  *
@@ -7438,6 +7518,39 @@
 	return res;
 }
 
+
+/* Japanese syntax */
+int ast_say_date_ja(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
+{
+      struct ast_tm tm;
+      struct timeval tv = { t, 0 };
+      char fn[256];
+      int res = 0;
+      ast_localtime(&tv, &tm, NULL);
+      if (!res)
+              res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
+      if (!res)
+              res = ast_waitstream(chan, ints);
+      if (!res)
+              res = ast_streamfile(chan, "digits/nen", lang);
+      if (!res) {
+              snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
+              res = ast_streamfile(chan, fn, lang);
+              if (!res)
+                      res = ast_waitstream(chan, ints);
+      }
+      if (!res)
+              res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
+      if (!res)
+              res = ast_streamfile(chan, "digits/nichi", lang);
+      if (!res) {
+              snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
+              res = ast_streamfile(chan, fn, lang);
+              if (!res)
+                      res = ast_waitstream(chan, ints);
+      }
+      return res;
+}
 
 
 /*! \brief Greek support
@@ -7496,6 +7609,52 @@
 }
 
 
+/* Japanese */
+static int ast_say_time_ja(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
+{
+
+      struct timeval tv = { t, 0 };
+      struct ast_tm tm;
+      int res = 0;
+      int hour, pm=0;
+
+      ast_localtime(&tv, &tm, NULL);
+      hour = tm.tm_hour;
+
+      if (!hour)
+              hour = 12;
+      else if (hour == 12)
+              pm = 1;
+      else if (hour > 12) {
+              hour -= 12;
+              pm = 1;
+      }
+
+      if (pm) {
+              if (!res)
+                      res = ast_streamfile(chan, "digits/p-m", lang);
+      } else {
+              if (!res)
+                      res = ast_streamfile(chan, "digits/a-m", lang);
+      }
+      if (hour == 9 || hour == 21) {
+              if (!res)
+                      res = ast_streamfile(chan, "digits/9_2", lang);
+      } else {
+              if (!res)
+                      res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
+      }
+      if (!res)
+              res = ast_streamfile(chan, "digits/ji", lang);
+      if (!res)
+              res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
+      if (!res)
+              res = ast_streamfile(chan, "digits/fun", lang);
+      if (!res)
+              res = ast_waitstream(chan, ints);
+      return res;
+}
+
 
 /*! \brief Greek support
  */
@@ -7529,6 +7688,72 @@
 
 	res = ast_say_time_gr(chan, t, ints, lang);
 	return res;
+}
+
+/* Japanese syntax */
+int ast_say_datetime_ja(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
+{
+      struct timeval tv = { t, 0 };
+      struct ast_tm tm;
+      char fn[256];
+      int res = 0;
+      int hour, pm=0;
+
+      ast_localtime(&tv, &tm, NULL);
+
+      if (!res)
+              res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
+      if (!res)
+              res = ast_streamfile(chan, "digits/nen", lang);
+      if (!res) {
+              snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
+              res = ast_streamfile(chan, fn, lang);
+              if (!res)
+                      res = ast_waitstream(chan, ints);
+      }
+      if (!res)
+              res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
+      if (!res)
+              res = ast_streamfile(chan, "digits/nichi", lang);
+      if (!res) {
+              snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
+              res = ast_streamfile(chan, fn, lang);
+      if (!res)
+              res = ast_waitstream(chan, ints);
+      }
+
+      hour = tm.tm_hour;
+      if (!hour)
+              hour = 12;
+      else if (hour == 12)
+              pm = 1;
+      else if (hour > 12) {
+              hour -= 12;
+              pm = 1;
+      }
+      if (pm) {
+              if (!res)
+                      res = ast_streamfile(chan, "digits/p-m", lang);
+      } else {
+              if (!res)
+                      res = ast_streamfile(chan, "digits/a-m", lang);
+      }
+      if (hour == 9 || hour == 21) {
+              if (!res)
+                      res = ast_streamfile(chan, "digits/9_2", lang);
+      } else {
+              if (!res)
+                      res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
+      }
+      if (!res)
+              res = ast_streamfile(chan, "digits/ji", lang);
+      if (!res)
+              res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
+      if (!res)
+              res = ast_streamfile(chan, "digits/fun", lang);
+      if (!res)
+              res = ast_waitstream(chan, ints);
+      return res;
 }
 
 /*! \brief Greek support
@@ -7704,6 +7929,274 @@
 	return res;
 }
 
+/* Japanese syntax */
+int ast_say_date_with_format_ja(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone)
+{
+     struct timeval tv = { time, 0 };
+     struct ast_tm tm;
+     int res=0, offset, sndoffset;
+     char sndfile[256], nextmsg[256];
+
+     if (!format)
+           format = "YbdAPIMS";
+
+     ast_localtime(&tv, &tm, timezone);
+
+     for (offset=0 ; format[offset] != '\0' ; offset++) {
+             ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
+             switch (format[offset]) {
+                     /* NOTE:  if you add more options here, please try to be consistent with strftime(3) */
+                     case '\'':
+                             /* Literal name of a sound file */
+                             sndoffset=0;
+                             for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
+                                     sndfile[sndoffset] = format[offset];
+                             sndfile[sndoffset] = '\0';
+                             res = wait_file(chan,ints,sndfile,lang);
+                             break;
+                     case 'A':
+                     case 'a':
+                             /* Sunday - Saturday */
+                             snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
+                             res = wait_file(chan,ints,nextmsg,lang);
+                             break;
+                     case 'B':
+                     case 'b':
+                     case 'h':
+                             /* January - December */
+                             snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
+                             res = wait_file(chan,ints,nextmsg,lang);
+                             break;
+                     case 'd':
+                     case 'e':
+                             /* First - Thirtyfirst */
+                             if (tm.tm_mday < 21) {
+                                     snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d_2", tm.tm_mday);
+                                     res = wait_file(chan,ints,nextmsg,lang);
+                             } else if (tm.tm_mday < 30) {
+                                     /* Between 21 and 29 - two sounds */
+                                     res = wait_file(chan,ints, "digits/20",lang);
+                                     if (!res) {
+                                             snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_mday - 20);
+                                             res = wait_file(chan,ints,nextmsg,lang);
+                                     }
+                                     res = wait_file(chan,ints, "digits/nichi",lang);
+                             } else if (tm.tm_mday == 30) {
+                                     /* 30 */
+                                     res = wait_file(chan,ints, "digits/h-30_2",lang);
+                             } else {
+                                     /* 31 */
+                                     res = wait_file(chan,ints, "digits/30",lang);
+                                     res = wait_file(chan,ints, "digits/1",lang);
+                                     res = wait_file(chan,ints, "digits/nichi",lang);
+                             }
+                             break;
+                     case 'Y':
+                             /* Year */
+                             if (tm.tm_year > 99) {
+                                     res = wait_file(chan,ints, "digits/2",lang);
+                                     if (!res) {
+                                             res = wait_file(chan,ints, "digits/thousand",lang);
+                                     }
+                                     if (tm.tm_year > 100) {

[... 202 lines stripped ...]



More information about the asterisk-commits mailing list