]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
mod_say_ru now support say_string like mod_say_en. Now support channel variables...
authorBuklov Boris <buklov@mail.ru>
Fri, 1 Apr 2011 18:53:52 +0000 (22:53 +0400)
committerBuklov Boris <buklov@mail.ru>
Fri, 1 Apr 2011 18:53:52 +0000 (22:53 +0400)
src/mod/say/mod_say_ru/mod_say_ru.c
src/mod/say/mod_say_ru/mod_say_ru.h

index 9c8db5732e5385ccfac28e03bfe4c17d932bc869..b1bff612055b7ba2cd9c8ed69eac7b8aed10357a 100644 (file)
@@ -61,60 +61,50 @@ struct say_t matrix[7][8] = { {m_00, m_01, m_02, m_03, m_04, m_05, m_06, m_07},
 SWITCH_MODULE_LOAD_FUNCTION(mod_say_ru_load);
 SWITCH_MODULE_DEFINITION(mod_say_ru, mod_say_ru_load, NULL, NULL);
 
-#define say_file(...) {\
-               char tmp[80];\
-               switch_status_t tstatus;\
-               switch_snprintf(tmp, sizeof(tmp), __VA_ARGS__);\
-               if ((tstatus = switch_ivr_play_file(session, NULL, tmp, args)) != SWITCH_STATUS_SUCCESS){ \
-                       return tstatus;\
-               }\
-               if (!switch_channel_ready(switch_core_session_get_channel(session))) {\
-                       return SWITCH_STATUS_FALSE;\
-               }}
-
-static switch_status_t play_group(say_type_t say_type, casus_t casus, int a, int b, int c,
-                                                                 unit_t what, switch_core_session_t *session, switch_input_args_t *args)
+
+static switch_status_t play_group(say_gender_t gender, cases_t cases, int a, int b, int c, unit_t what,        switch_say_file_handle_t *sh)
 {
+//     switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "play_group ! %d%d%d  gender=%d  causes=%d\n",a,b,c,gender,cases);
        if (a) {
-               if (((b == 0) && (c == 0)) || (matrix[casus][say_type].all == 1)) {     //если b и с равны 0 то сказать шестьсот, сестисотый, шестисотая
+               if (((b == 0) && (c == 0)) || (matrix[cases][gender].all == 1)) {       //если b и с равны 0 то сказать шестьсот, сестисотый, шестисотая
                        if (what == million) {  //префикс           число          окончание
-                               say_file("digits/%s%d00%s.wav", matrix[casus][say_type].million[12], a, matrix[casus][say_type].million[13]);
-                               say_file("digits/%s.wav", matrix[casus][say_type].million[11]);
+                               switch_say_file(sh, "digits/%s%d00%s", matrix[cases][gender].million[12], a, matrix[cases][gender].million[13]);
+                               switch_say_file(sh, "digits/%s", matrix[cases][gender].million[11]);
                        } else if (what == thousand) {
-                               say_file("digits/%s%d00%s.wav", matrix[casus][say_type].thousand[12], a, matrix[casus][say_type].thousand[13]);
-                               say_file("digits/%s.wav", matrix[casus][say_type].thousand[11]);
+                               switch_say_file(sh, "digits/%s%d00%s", matrix[cases][gender].thousand[12], a, matrix[cases][gender].thousand[13]);
+                               switch_say_file(sh, "digits/%s", matrix[cases][gender].thousand[11]);
                        } else {
-                               say_file("digits/%s%d00%s.wav", matrix[casus][say_type].num[6], a, matrix[casus][say_type].num[7]);
+                               switch_say_file(sh, "digits/%s%d00%s", matrix[cases][gender].num[6], a, matrix[cases][gender].num[7]);
                        }
                } else {                                //если дальше есть цифры то тысячи и миллионы не прозносить пока
-                       say_file("digits/%d00.wav", a);
+                       switch_say_file(sh, "digits/%d00", a);
                }
        }
 
        if (b) {
                if (b > 1) {                    //если 20 и больше
-                       if ((c == 0) || (matrix[casus][say_type].all == 1)) {   //если с равны 0 то сказать 20, двадцати, двадцатая
+                       if ((c == 0) || (matrix[cases][gender].all == 1)) {     //если с равны 0 то сказать 20, двадцати, двадцатая
                                if (what == million) {  //префикс            число          окончание
-                                       say_file("digits/%s%d0%s.wav", matrix[casus][say_type].million[12], b, matrix[casus][say_type].million[13]);
-                                       say_file("digits/%s.wav", matrix[casus][say_type].million[11]);
+                                       switch_say_file(sh, "digits/%s%d0%s", matrix[cases][gender].million[12], b, matrix[cases][gender].million[13]);
+                                       switch_say_file(sh, "digits/%s", matrix[cases][gender].million[11]);
                                } else if (what == thousand) {
-                                       say_file("digits/%s%d0%s.wav", matrix[casus][say_type].thousand[12], b, matrix[casus][say_type].thousand[13]);
-                                       say_file("digits/%s.wav", matrix[casus][say_type].thousand[11]);
+                                       switch_say_file(sh, "digits/%s%d0%s", matrix[cases][gender].thousand[12], b, matrix[cases][gender].thousand[13]);
+                                       switch_say_file(sh, "digits/%s", matrix[cases][gender].thousand[11]);
                                } else {
-                                       say_file("digits/%s%d0%s.wav", matrix[casus][say_type].num[6], b, matrix[casus][say_type].num[7]);
+                                       switch_say_file(sh, "digits/%s%d0%s", matrix[cases][gender].num[6], b, matrix[cases][gender].num[7]);
                                }
                        } else {                        //если есть дальше цифры
-                               say_file("digits/%d0.wav", b);
+                               switch_say_file(sh, "digits/%d0", b);
                        }
                } else {                                //от 10 до 19
                        if (what == million) {
-                               say_file("digits/%s%d%d%s.wav", matrix[casus][say_type].million[12], b, c, matrix[casus][say_type].million[13]);
-                               say_file("digits/%s.wav", matrix[casus][say_type].million[11]);
+                               switch_say_file(sh, "digits/%s%d%d%s", matrix[cases][gender].million[12], b, c, matrix[cases][gender].million[13]);
+                               switch_say_file(sh, "digits/%s", matrix[cases][gender].million[11]);
                        } else if (what == thousand) {
-                               say_file("digits/%s%d%d%s.wav", matrix[casus][say_type].thousand[12], b, c, matrix[casus][say_type].thousand[13]);
-                               say_file("digits/%s.wav", matrix[casus][say_type].thousand[11]);
+                               switch_say_file(sh, "digits/%s%d%d%s", matrix[cases][gender].thousand[12], b, c, matrix[cases][gender].thousand[13]);
+                               switch_say_file(sh, "digits/%s", matrix[cases][gender].thousand[11]);
                        } else {                        //просто произнести цифры с префиксом и окончанием
-                               say_file("digits/%s%d%d%s.wav", matrix[casus][say_type].num[6], b, c, matrix[casus][say_type].num[7]);
+                               switch_say_file(sh, "digits/%s%d%d%s", matrix[cases][gender].num[6], b, c, matrix[cases][gender].num[7]);
                        }
                        c = 0;
                }
@@ -123,28 +113,28 @@ static switch_status_t play_group(say_type_t say_type, casus_t casus, int a, int
        if (c || what == zero) {
                if (c <= 5) {
                        if (what == million) {
-                               if ((strlen(matrix[casus][say_type].million[c * 2])) > 0) {     // не произносить если не заданно например 1 миллион а просто миллион
-                                       say_file("digits/%s.wav", matrix[casus][say_type].million[c * 2])
+                               if ((strlen(matrix[cases][gender].million[c * 2])) > 0) {       // не произносить если не заданно например 1 миллион а просто миллион
+                                       switch_say_file(sh, "digits/%s", matrix[cases][gender].million[c * 2]);
                                }
-                               say_file("digits/%s.wav", matrix[casus][say_type].million[c * 2 + 1]);
+                               switch_say_file(sh, "digits/%s", matrix[cases][gender].million[c * 2 + 1]);
                        } else if (what == thousand) {
-                               if ((strlen(matrix[casus][say_type].thousand[c * 2])) > 0) {    // не произносить если не заданно например одна тысячас  а просто тысяча
-                                       say_file("digits/%s.wav", matrix[casus][say_type].thousand[c * 2])
+                               if ((strlen(matrix[cases][gender].thousand[c * 2])) > 0) {      // не произносить если не заданно например одна тысячас  а просто тысяча
+                                       switch_say_file(sh, "digits/%s", matrix[cases][gender].thousand[c * 2]);
                                }
-                               say_file("digits/%s.wav", matrix[casus][say_type].thousand[c * 2 + 1]);
+                               switch_say_file(sh, "digits/%s", matrix[cases][gender].thousand[c * 2 + 1]);
                        } else {                        //просто произнести цифры с префиксом и окончанием
-                               say_file("digits/%s.wav", matrix[casus][say_type].num[c]);
+                               switch_say_file(sh, "digits/%s", matrix[cases][gender].num[c]);
                        }
                } else {                                /* больше 5 */
 
                        if (what == million) {
-                               say_file("digits/%s%d%s.wav", matrix[casus][say_type].million[12], c, matrix[casus][say_type].million[13]);
-                               say_file("digits/%s.wav", matrix[casus][say_type].million[11]);
+                               switch_say_file(sh, "digits/%s%d%s", matrix[cases][gender].million[12], c, matrix[cases][gender].million[13]);
+                               switch_say_file(sh, "digits/%s", matrix[cases][gender].million[11]);
                        } else if (what == thousand) {
-                               say_file("digits/%s%d%s.wav", matrix[casus][say_type].thousand[12], c, matrix[casus][say_type].thousand[13]);
-                               say_file("digits/%s.wav", matrix[casus][say_type].thousand[11]);
+                               switch_say_file(sh, "digits/%s%d%s", matrix[cases][gender].thousand[12], c, matrix[cases][gender].thousand[13]);
+                               switch_say_file(sh, "digits/%s", matrix[cases][gender].thousand[11]);
                        } else {                        //просто произнести цифры с префиксом и окончанием
-                               say_file("digits/%s%d%s.wav", matrix[casus][say_type].num[6], c, matrix[casus][say_type].num[7]);
+                               switch_say_file(sh, "digits/%s%d%s", matrix[cases][gender].num[6], c, matrix[cases][gender].num[7]);
                        }
                }
        }
@@ -152,20 +142,20 @@ static switch_status_t play_group(say_type_t say_type, casus_t casus, int a, int
 }
 
 
-static switch_status_t ru_say_count(switch_core_session_t *session, char *tosay, say_type_t say_type, casus_t casus, switch_input_args_t *args)
+static switch_status_t ru_say_count(switch_say_file_handle_t *sh, char *tosay, say_gender_t gender, cases_t cases)
 {
        int in;
        int x = 0;
        int places[9] = { 0 };
-       char sbuf[128] = "";
+       char sbuf[13] = "";
        int in_;
 
        switch_status_t status;
 
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ru_say_count %s!\n", tosay);
+       //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ru_say_count %s!   gender=%d  causes=%d\n", tosay,gender,cases);
 
        if (!(tosay = switch_strip_commas(tosay, sbuf, sizeof(sbuf)-1)) || strlen(tosay) > 9) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n");
+               //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n");
                return SWITCH_STATUS_GENERR;
        }
 
@@ -182,44 +172,40 @@ static switch_status_t ru_say_count(switch_core_session_t *session, char *tosay,
 
                //миллионы      
                if (places[8] || places[7] || places[6]) {
-                       if ((in_ % 1000000 > 0) && (matrix[casus][say_type].all != 1)) {        // если поле миллионов  есть цифры поизнести как числительое именительного падежа
-                               if ((status = play_group(male_c, nominativus, places[8], places[7], places[6], million, session, args)) != SWITCH_STATUS_SUCCESS) {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "play group %d %d %d million! status=%d\n", places[8], places[7], places[6],
-                                                                         status);
+                       if ((in_ % 1000000 > 0) && (matrix[cases][gender].all != 1)) {  // если поле миллионов  есть цифры поизнести как числительое именительного падежа
+                               if ((status = play_group(male, nominativus, places[8], places[7], places[6], million, sh)) != SWITCH_STATUS_SUCCESS) {
+                                       //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "play group %d %d %d million! status=%d\n", places[8], places[7], places[6], status);
                                        return status;
                                }
                        } else {                        // иначе произнести в нужном падеже
-                               if ((status = play_group(say_type, casus, places[8], places[7], places[6], million, session, args)) != SWITCH_STATUS_SUCCESS) {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "play group %d %d %d million! status=%d\n", places[8], places[7], places[6],
-                                                                         status);
+                               if ((status = play_group(gender, cases, places[8], places[7], places[6], million, sh)) != SWITCH_STATUS_SUCCESS) {
+                                       //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "play group %d %d %d million! status=%d\n", places[8], places[7], places[6],  status);
                                        return status;
                                }
                        }
                }
                //тысячи      
                if (places[5] || places[4] || places[3]) {
-                       if ((in_ % 1000 > 0) && (matrix[casus][say_type].all != 1)) {   // если поле миллионов  есть цифры поизнести как числительое именительного падежа
-                               if ((status = play_group(male_c, nominativus, places[5], places[4], places[3], thousand, session, args)) != SWITCH_STATUS_SUCCESS) {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "play group %d %d %d thousand! status=%d\n", places[5], places[4], places[3],
-                                                                         status);
+                       if ((in_ % 1000 > 0) && (matrix[cases][gender].all != 1)) {     // если поле миллионов  есть цифры поизнести как числительое именительного падежа
+                               if ((status = play_group(male, nominativus, places[5], places[4], places[3], thousand, sh)) != SWITCH_STATUS_SUCCESS) {
+                                       //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "play group %d %d %d thousand! status=%d\n", places[5], places[4], places[3],  status);
                                        return status;
                                }
                        } else {                        // иначе произнести в нужном падеже
-                               if ((status = play_group(say_type, casus, places[5], places[4], places[3], thousand, session, args)) != SWITCH_STATUS_SUCCESS) {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "play group %d %d %d thousand! status=%d\n", places[5], places[4], places[3],
-                                                                         status);
+                               if ((status = play_group(gender, cases, places[5], places[4], places[3], thousand, sh)) != SWITCH_STATUS_SUCCESS) {
+                                       //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "play group %d %d %d thousand! status=%d\n", places[5], places[4], places[3],  status);
                                        return status;
                                }
                        }
                }
                // сотни
-               if ((status = play_group(say_type, casus, places[2], places[1], places[0], empty, session, args)) != SWITCH_STATUS_SUCCESS) {
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "play group %d %d %d thousand! status=%d\n", places[5], places[4], places[3], status);
+               if ((status = play_group(gender, cases, places[2], places[1], places[0], empty, sh)) != SWITCH_STATUS_SUCCESS) {
+                       //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "play group %d %d %d thousand! status=%d\n", places[5], places[4], places[3], status);
                        return status;
                }
        } else {
-               if ((status = play_group(say_type, casus, places[2], places[1], places[0], zero, session, args)) != SWITCH_STATUS_SUCCESS) {
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "play group %d %d %d other!\n", places[2], places[1], places[0]);
+               if ((status = play_group(gender, cases, places[2], places[1], places[0], zero, sh)) != SWITCH_STATUS_SUCCESS) {
+                       //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "play group %d %d %d other!\n", places[2], places[1], places[0]);
                        return status;
                }
        }
@@ -228,28 +214,37 @@ static switch_status_t ru_say_count(switch_core_session_t *session, char *tosay,
 }
 
 //дописать
-static switch_status_t ru_say_general_count(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args)
+static switch_status_t ru_say_general_count(switch_say_file_handle_t *sh, char *tosay, switch_say_args_t *say_args,say_opt_t *say_opt)
 {
        switch_status_t status;
-       casus_t casus;                          //падеж
-       say_type_t say_type;            //тип произношения
+       cases_t cases;                          //падеж
+       say_gender_t gender;            //тип произношения
 
        switch (say_args->type) {
        case SST_MESSAGES:
-               say_type = it_c;
-               casus = nominativus;
+               gender = it;
+               cases = nominativus;
                break;
        default:
-               say_type = male_c;
-               casus = nominativus;
+               gender = male;
+               cases = nominativus;
+               if (say_opt->gender>0) {
+                   gender=say_opt->gender;
+//                 //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " opt_gender=%d type=%d   cases=%d\n", gender, cases,say_opt->gender);
+               }
+               if (say_opt->cases>0) {
+                   cases=say_opt->cases;
+//                 //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " opt_gender=%d type=%d   cases=%d\n", gender, cases,say_opt->gender);
+
+               }
                break;
        };
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " type=%d   casus=%d\n", say_type, casus);
-       status = ru_say_count(session, tosay, say_type, casus, args);
+       //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " opt_gender=%d type=%d   cases=%d\n", gender, cases,say_opt->gender);
+       status = ru_say_count(sh, tosay, (say_gender_t)gender, (cases_t)cases);
        return status;
 }
 
-static switch_status_t ru_say_money(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args)
+static switch_status_t ru_say_money(switch_say_file_handle_t *sh, char *tosay, switch_say_args_t *say_args,say_opt_t *say_opt)
 {
        char sbuf[16] = "";
        char *rubles = NULL;
@@ -259,10 +254,10 @@ static switch_status_t ru_say_money(switch_core_session_t *session, char *tosay,
        int ikopecks = 0;
        int ikopeck = 0;
 
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " ru_say_money %s\n", tosay);
+       //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " ru_say_money %s\n", tosay);
 
        if (strlen(tosay) > 15 || !(tosay = switch_strip_nonnumerics(tosay, sbuf, sizeof(sbuf)-1))) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n");
+               //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n");
                return SWITCH_STATUS_GENERR;
        }
 
@@ -279,11 +274,11 @@ static switch_status_t ru_say_money(switch_core_session_t *session, char *tosay,
        }
 
        if (sbuf[0] == '-') {
-               say_file("currency/minus.wav");
+               switch_say_file(sh, "currency/minus");
                rubles++;
        }
 
-       ru_say_count(session, rubles, male_c, nominativus, args);
+       ru_say_count(sh, rubles, male, nominativus);
 
        if (rubles) {
                irubles = atoi(rubles) % 100;
@@ -291,16 +286,16 @@ static switch_status_t ru_say_money(switch_core_session_t *session, char *tosay,
        }
 
        if (irubles == 1 || (irubles > 20 && iruble == 1)) {    /* рубль */
-               say_file("currency/ruble.wav");
+               switch_say_file(sh, "currency/ruble");
        } else if ((irubles > 1 && irubles < 5) || (irubles > 20 && iruble > 1 && iruble < 5)) {        /*рубля */
-               say_file("currency/ruble-a.wav");
+               switch_say_file(sh, "currency/ruble-a");
        } else {                                        /*рублей */
-               say_file("currency/rubles.wav");
+               switch_say_file(sh, "currency/rubles");
        }
 
        /* Say kopecks */
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " %s\n", kopecks);
-       ru_say_count(session, kopecks, female_c, nominativus, args);
+       //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " %s\n", kopecks);
+       ru_say_count(sh, kopecks, female, nominativus);
 
        if (kopecks) {
                ikopecks = atoi(kopecks) % 100;
@@ -309,28 +304,28 @@ static switch_status_t ru_say_money(switch_core_session_t *session, char *tosay,
 
        if (ikopecks == 1 || (ikopecks > 20 && ikopeck == 1)) {
                /* копейка */
-               say_file("currency/kopeck.wav");
+               switch_say_file(sh, "currency/kopeck");
        } else if ((ikopecks > 1 && ikopecks < 5) || (ikopecks > 20 && ikopeck > 1 && ikopeck < 5)) {
                /* копейки */
-               say_file("currency/kopeck-i.wav");
+               switch_say_file(sh, "currency/kopeck-i");
        } else {
                /* копеек */
-               say_file("currency/kopecks.wav");
+               switch_say_file(sh, "currency/kopecks");
        }
        return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t ru_say_time(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args)
+static switch_status_t ru_say_time(switch_say_file_handle_t *sh, char *tosay, switch_say_args_t *say_args,say_opt_t *say_opt)
 {
        int32_t t;
        char buf[80];
        switch_time_t target = 0, target_now = 0;
        switch_time_exp_t tm, tm_now;
        uint8_t say_date = 0, say_time = 0, say_year = 0, say_month = 0, say_dow = 0, say_day = 0, say_yesterday = 0, say_today = 0;
-       switch_channel_t *channel = switch_core_session_get_channel(session);
-       const char *tz = switch_channel_get_variable(channel, "timezone");
+       const char *tz = NULL;
+       tz = switch_say_file_handle_get_variable(sh, "timezone");    
 
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " ru_say_time %s  type=%d method=%d\n", tosay, say_args->type, say_args->method);
+       //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " ru_say_time %s  type=%d method=%d\n", tosay, say_args->type, say_args->method);
 
        if (say_args->type == SST_TIME_MEASUREMENT) {
                int64_t hours = 0;
@@ -339,7 +334,7 @@ static switch_status_t ru_say_time(switch_core_session_t *session, char *tosay,
                int64_t r = 0;
 
                if (strchr(tosay, ':')) {
-                       char *tme = switch_core_session_strdup(session, tosay);
+                       char *tme = strdup(tosay);
                        char *p;
 
                        if ((p = strrchr(tme, ':'))) {
@@ -355,6 +350,7 @@ static switch_status_t ru_say_time(switch_core_session_t *session, char *tosay,
                                        minutes = atoi(tme);
                                }
                        }
+                       free(tme);
                } else {
                        if ((seconds = atol(tosay)) <= 0) {
                                seconds = (int64_t) switch_epoch_time_now(NULL);
@@ -373,37 +369,37 @@ static switch_status_t ru_say_time(switch_core_session_t *session, char *tosay,
                }
 
                switch_snprintf(buf, sizeof(buf), "%u", (unsigned) hours);
-               ru_say_count(session, buf, male_c, nominativus, args);
+               ru_say_count(sh, buf, male, nominativus);
 
                if (((hours % 10) == 1) && (hours != 11)) {
                        /* час */
-                       say_file("time/hour.wav");
+                       switch_say_file(sh, "time/hour");
                } else if (((hours % 10 > 1) && (hours % 10 < 5)) && ((hours < 12) || (hours > 14))) {
-                       say_file("time/hours-a.wav");   /* часа */
+                       switch_say_file(sh, "time/hours-a");    /* часа */
                } else {
-                       say_file("time/hours.wav");     /* часов */
+                       switch_say_file(sh, "time/hours");      /* часов */
                }
 
                switch_snprintf(buf, sizeof(buf), "%u", (unsigned) minutes);    //перевести минуты в *char
-               ru_say_count(session, buf, female_c, nominativus, args);
+               ru_say_count(sh, buf, female, nominativus);
 
                if (((minutes % 10) == 1) && (minutes != 11)) {
-                       say_file("time/minute.wav");    //минута
+                       switch_say_file(sh, "time/minute");     //минута
                } else if (((minutes % 10 > 1) && (minutes % 10 < 5)) && ((minutes < 12) || (minutes > 14))) {
-                       say_file("time/minutes-i.wav"); // минуты
+                       switch_say_file(sh, "time/minutes-i");  // минуты
                } else {
-                       say_file("time/minutes.wav");   //минут
+                       switch_say_file(sh, "time/minutes");    //минут
                }
 
                if (seconds != 0) {
                        switch_snprintf(buf, sizeof(buf), "%u", (unsigned) seconds);
-                       ru_say_count(session, buf, female_c, nominativus, args);
+                       ru_say_count(sh, buf, female, nominativus);
                        if (((seconds % 10) == 1) && (seconds != 11)) {
-                               say_file("time/second.wav");    // секунда
+                               switch_say_file(sh, "time/second");     // секунда
                        } else if (((seconds % 10 > 1) && (seconds % 10 < 5)) && ((seconds < 12) || (seconds > 14))) {
-                               say_file("time/seconds-i.wav"); // секуны
+                               switch_say_file(sh, "time/seconds-i");  // секуны
                        } else {
-                               say_file("time/seconds.wav");   //секунд
+                               switch_say_file(sh, "time/seconds");    //секунд
                        }
                }
                return SWITCH_STATUS_SUCCESS;
@@ -419,6 +415,7 @@ static switch_status_t ru_say_time(switch_core_session_t *session, char *tosay,
 
        if (tz) {
                int check = atoi(tz);
+               //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Timezone is [%s]\n", tz);
                if (check) {
                        switch_time_exp_tz(&tm, target, check);
                        switch_time_exp_tz(&tm_now, target_now, check);
@@ -472,13 +469,13 @@ static switch_status_t ru_say_time(switch_core_session_t *session, char *tosay,
        }
 
        if (say_today) {
-               say_file("time/today.wav");
+               switch_say_file(sh, "time/today");
        }
        if (say_yesterday) {
-               say_file("time/yesterday.wav");
+               switch_say_file(sh, "time/yesterday");
        }
        if (say_dow) {
-               say_file("time/day-%d.wav", tm.tm_wday);
+               switch_say_file(sh, "time/day-%d", tm.tm_wday);
        }
        if (say_date) {
                say_year = say_month = say_day = say_dow = 1;
@@ -486,74 +483,103 @@ static switch_status_t ru_say_time(switch_core_session_t *session, char *tosay,
        }
        if (say_day) {
                switch_snprintf(buf, sizeof(buf), "%u", (unsigned) tm.tm_mday);
-               ru_say_count(session, buf, male_h, genitivus, args);
+               ru_say_count(sh, buf, male_h, genitivus);
        }
        if (say_month) {
-               say_file("time/mon-%d.wav", tm.tm_mon);
+               switch_say_file(sh, "time/mon-%d", tm.tm_mon);
        }
        if (say_year) {
                switch_snprintf(buf, sizeof(buf), "%u", (unsigned) (tm.tm_year + 1900));
-               ru_say_count(session, buf, male_h, genitivus, args);
-               say_file("time/h-year.wav");
+               ru_say_count(sh, buf, male_h, genitivus);
+               switch_say_file(sh, "time/h-year");
        }
        if (say_time) {
                if (say_month || say_year || say_date || say_dow) {
-                       say_file("time/at.wav");
+                       switch_say_file(sh, "time/at");
                }
                switch_snprintf(buf, sizeof(buf), "%d:%d:%d", tm.tm_hour, tm.tm_min, tm.tm_sec);
                say_args->type = SST_TIME_MEASUREMENT;
-               ru_say_time(session, buf, say_args, args);
+               ru_say_time(sh, buf, say_args,say_opt);
        }
        return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t ru_ip(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args)
+static switch_status_t ru_ip(switch_say_file_handle_t *sh, char *tosay, switch_say_args_t *say_args,say_opt_t *say_opt)
 {
        char *a, *b, *c, *d;
-       if (!(a = switch_core_session_strdup(session, tosay))) {
-               return SWITCH_STATUS_FALSE;
+       switch_status_t status = SWITCH_STATUS_FALSE;
+       if (!(a = strdup(tosay))) {
+               abort();
+//             return SWITCH_STATUS_FALSE;
        }
 
        if (!(b = strchr(a, '.'))) {
-               return SWITCH_STATUS_FALSE;
+               goto end;
        }
 
        *b++ = '\0';
 
        if (!(c = strchr(b, '.'))) {
-               return SWITCH_STATUS_FALSE;
+                goto end;
        }
 
        *c++ = '\0';
 
        if (!(d = strchr(c, '.'))) {
-               return SWITCH_STATUS_FALSE;
+                goto end;
        }
 
        *d++ = '\0';
 
-       ru_say_count(session, a, male_c, nominativus, args);
-       say_file("digits/dot.wav");
+       ru_say_count(sh, a, male, nominativus);
+       switch_say_file(sh, "digits/dot");
 
-       ru_say_count(session, b, male_c, nominativus, args);
-       say_file("digits/dot.wav");
+       ru_say_count(sh, b, male, nominativus);
+       switch_say_file(sh, "digits/dot");
 
-       ru_say_count(session, c, male_c, nominativus, args);
-       say_file("digits/dot.wav");
+       ru_say_count(sh, c, male, nominativus);
+       switch_say_file(sh, "digits/dot");
 
-       ru_say_count(session, d, male_c, nominativus, args);
-       return SWITCH_STATUS_SUCCESS;
+       ru_say_count(sh, d, male, nominativus);
+end:
+       free(a);
+       return status;
 }
 
-static switch_status_t ru_say(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args)
+
+static switch_status_t ru_say_spell(switch_say_file_handle_t *sh, char *tosay, switch_say_args_t *say_args,say_opt_t *say_opt)
 {
-       switch_say_callback_t say_cb = NULL;
+        char *p;
+
+        for (p = tosay; p && *p; p++) {
+                int a = tolower((int) *p);
+                if (a >= '0' && a <= '9') {
+                        switch_say_file(sh, "digits/%c", a);
+                } else {
+                        if (say_args->type == SST_NAME_SPELLED) {
+                                switch_say_file(sh, "ascii/%d", a);
+                        } else if (say_args->type == SST_NAME_PHONETIC) {
+                                switch_say_file(sh, "phonetic-ascii/%d", a);
+                        }
+                }
+        }
+
+        return SWITCH_STATUS_SUCCESS;
+}
+
+
+
 
+static switch_new_say_callback_ru_t choose_callback(switch_say_args_t *say_args)
+{
+
+       switch_new_say_callback_ru_t say_cb = NULL;
        switch (say_args->type) {
        case SST_NUMBER:
        case SST_ITEMS:
        case SST_PERSONS:
        case SST_MESSAGES:
+       
                say_cb = ru_say_general_count;
                break;
        case SST_TIME_MEASUREMENT:
@@ -576,23 +602,171 @@ static switch_status_t ru_say(switch_core_session_t *session, char *tosay, switc
                break;
        case SST_NAME_SPELLED:
        case SST_NAME_PHONETIC:
-               return switch_ivr_say_spell(session, tosay, say_args, args);
+               say_cb = ru_say_spell;
                break;
        case SST_CURRENCY:
                say_cb = ru_say_money;
                break;
        default:
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown Say type=[%d]\n", say_args->type);
+               //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown Say type=[%d]\n", say_args->type);
                break;
        }
 
-       if (say_cb) {
-               return say_cb(session, tosay, say_args, args);
+       return say_cb;
+}
+
+
+                                                                                                
+
+
+static switch_status_t run_callback(switch_new_say_callback_ru_t say_cb, char *tosay, switch_say_args_t *say_args, switch_core_session_t *session, char **rstr)
+{
+        switch_say_file_handle_t *sh;
+        switch_status_t status = SWITCH_STATUS_FALSE;
+        switch_event_t *var_event = NULL;
+        const char *cases=NULL;
+        const char *gender=NULL;
+        const char *currency=NULL;
+       say_opt_t say_opt;
+
+        if (session) {
+                switch_channel_t *channel = switch_core_session_get_channel(session);
+                switch_channel_get_variables(channel, &var_event);
+// проверяем не заданы ли канальные переменные род, падеж, валюта
+                gender = switch_channel_get_variable(channel, "gender");
+                cases = switch_channel_get_variable(channel, "cases");
+                currency = switch_channel_get_variable(channel, "currency");
+                //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ru_say!!!  %s  %s   %s !\n",gender, cases,currency);
+                if (cases) {
+                   //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ru_say!!!  %s!\n", cases);
+                
+                   if ((strcmp(cases,"nominativus")==0) || (strcmp(cases,"именительный")==0)) {
+                       say_opt.cases=(cases_t)0;
+                   }
+                   if ((strcmp(cases,"genitivus")==0) || (strcmp(cases,"родительный")==0)) {
+                       say_opt.cases=(cases_t)1;
+                   }
+                   if ((strcmp(cases,"dativus")==0) || (strcmp(cases,"дательный")==0)) {
+                       say_opt.cases=(cases_t)2;
+                   }
+                   if ((strcmp(cases,"accusativus_a")==0) || (strcmp(cases,"винительный_о")==0)) {
+                       say_opt.cases=(cases_t)3;
+                   }
+                   if ((strcmp(cases,"accusativus_i")==0) || (strcmp(cases,"винительный_н")==0)) {
+                       say_opt.cases=(cases_t)4;
+                   }
+                   if ((strcmp(cases,"instrumentalis")==0) || (strcmp(cases,"творительный")==0)) {
+                       say_opt.cases=(cases_t)5;
+                   }
+                   if ((strcmp(cases,"prepositive")==0) || (strcmp(cases,"предложный")==0)) {
+                       say_opt.cases=(cases_t)6;
+                   }
+               }
+                if (gender) {
+                   //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ru_say!!!  %s!\n", gender);
+                
+                   if ((strcmp(gender,"male")==0) || (strcmp(gender,"мужской")==0)) {
+                       say_opt.gender=(say_gender_t)0;
+                   }
+                   if ((strcmp(gender,"it")==0) || (strcmp(gender,"средний")==0)) {
+                       say_opt.gender=(say_gender_t)1;
+                   }
+                   if ((strcmp(gender,"female")==0) || (strcmp(gender,"женский")==0)) {
+                       say_opt.gender=(say_gender_t)2;
+                   }
+                   if ((strcmp(gender,"plural")==0) || (strcmp(gender,"множественное")==0)) {
+                       say_opt.gender=(say_gender_t)3;
+                   }
+                   if ((strcmp(gender,"male_h")==0) || (strcmp(gender,"мужской_порядковый")==0)) {
+                       say_opt.gender=(say_gender_t)4;
+                   }
+                   if ((strcmp(gender,"it_h")==0) || (strcmp(gender,"средний_порядковый")==0)) {
+                       say_opt.gender=(say_gender_t)5;
+                   }
+                   if ((strcmp(gender,"female_h")==0) || (strcmp(gender,"женский_порядковый")==0)) {
+                       say_opt.gender=(say_gender_t)6;
+                   }
+                   if ((strcmp(gender,"plural_h")==0) || (strcmp(gender,"множественное_порядковый")==0)) {
+                       say_opt.gender=(say_gender_t)7;
+                   }
+            
+               }
+                if (currency) {
+                   //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ru_say!!!  %s!\n", currency);
+                
+                   if (strcmp(currency,"rubl") || strcmp(currency,"рубль")) {
+                       say_opt.currency=(currency_t)0;
+                   }
+                   if (strcmp(gender,"dollar") || strcmp(gender,"доллар")) {
+                       say_opt.currency=(currency_t)1;
+                   }
+               }
+               //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ru_say!!!  %s!   say_opt.gender=%d   say_opt.cases=%d\n", tosay,say_opt.gender,say_opt.cases);
+                                                                                
        }
+        switch_say_file_handle_create(&sh, say_args->ext, &var_event);
+//запуск ru_ip,ru_say_money ...
+        status = say_cb(sh, tosay, say_args,&say_opt);
+
+        if ((*rstr = switch_say_file_handle_detach_path(sh))) {
+                status = SWITCH_STATUS_SUCCESS;
+        }
 
-       return SWITCH_STATUS_FALSE;
+        switch_say_file_handle_destroy(&sh);
+
+        return status;
+}
+
+
+
+static switch_status_t ru_say(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args)
+{
+
+        switch_new_say_callback_ru_t say_cb = NULL;
+        char *string = NULL;
+        switch_status_t status;
+        
+        status = SWITCH_STATUS_FALSE;
+        
+        say_cb = choose_callback(say_args);
+
+        if (say_cb) {
+                status = run_callback(say_cb, tosay, say_args, session, &string);
+                if (session && string) {
+                        status = switch_ivr_play_file(session, NULL, string, args);
+                }
+
+                switch_safe_free(string);
+        }
+
+        return status;
 }
 
+
+
+static switch_status_t ru_say_string(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, char **rstr)
+{
+
+        switch_new_say_callback_ru_t say_cb = NULL;
+        char *string = NULL;
+
+        switch_status_t status = SWITCH_STATUS_FALSE;
+
+        say_cb = choose_callback(say_args);
+
+        if (say_cb) {
+                status = run_callback(say_cb, tosay, say_args, session, &string);
+                if (string) {
+                        status = SWITCH_STATUS_SUCCESS;
+                        *rstr = string;
+                }
+        }
+
+        return status;
+}
+
+
+
 SWITCH_MODULE_LOAD_FUNCTION(mod_say_ru_load)
 {
        switch_say_interface_t *say_interface;
@@ -601,6 +775,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_say_ru_load)
        say_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_SAY_INTERFACE);
        say_interface->interface_name = "ru";
        say_interface->say_function = ru_say;
+       say_interface->say_string_function = ru_say_string;
 
        /* indicate that the module should continue to be loaded */
        return SWITCH_STATUS_SUCCESS;
index 3c460126d3d57ea3448d61b353d5344c70880714..d7769ad246194e188f3fbbd8bb99d9455f32ca74 100644 (file)
@@ -12,6 +12,8 @@
 //http://ru.wiktionary.org/wiki/%D0%BE%D0%B4%D0%B8%D0%BD
 //http://ru.wiktionary.org/wiki/%D0%BF%D0%B5%D1%80%D0%B2%D1%8B%D0%B9
 
+                                                                                                                                                                                                                    
+
 typedef enum {
        million,
        thousand,
@@ -22,28 +24,40 @@ typedef enum {
 //тип числа порядковое или количественное
 typedef enum {
        nominativus,                            // именительный Кто? Что?
-       genitivus,                                      // Родительный  Кого? Чего?
-       dativus,                                        // дательный    Кого? Что?
+       genitivus,                              // Родительный  Кого? Чего?
+       dativus,                                // дательный    Кого? Что?
        accusativus_a,                          // Винительный  Кого? animate - одушевлённый
        accusativus_i,                          // Винительный  Что?  inanimate - неодушевлённый
        instrumentalis,                         // Творительный Кем? Чем?
-       prepositive                                     // Предложный   О ком? О чём?
-} casus_t;
+       prepositive                             // Предложный   О ком? О чём?
+} cases_t;
 
 
 typedef enum {
        //количественный
-       male_c,                                         //мужского пола
-       it_c,                                           //среднего
-       female_c,                                       //женского
-       plural_c,                                       //множественное число
+       male,                                   //мужского пола
+       it,                                     //среднего
+       female,                                 //женского
+       plural,                                 //множественное число
        //порядковый
-       male_h,                                         //порядковое мужского пола
-       it_h,                                           //порядковое среднего
-       female_h,                                       //порядковое женского
-       plural_h                                        //порядковое множественное число
-} say_type_t;
+       male_h,                                 //порядковое мужского пола
+       it_h,                                   //порядковое среднего
+       female_h,                               //порядковое женского
+       plural_h                                //порядковое множественное число
+} say_gender_t;
+
+
+typedef enum {
+       ruble,
+       dollar
+} currency_t;
+
 
+typedef struct {
+       say_gender_t gender;
+       cases_t    cases;
+       currency_t currency;        
+} say_opt_t;
 
 
 struct say_t {
@@ -53,6 +67,7 @@ struct say_t {
        int all;
 };
 
+typedef switch_status_t (*switch_new_say_callback_ru_t) (switch_say_file_handle_t *sh, char *tosay, switch_say_args_t *say_args,say_opt_t *say_opt);
 
 //именительный 
 //именительный количественный/числительное
@@ -60,7 +75,7 @@ struct say_t {
 //мужской род родительный падеж
 
 //первая строка описывае как произносить цифры от 0 до 5 потом пристаставка и окончания для остальных
-// Ñ\82оже Ñ\81амое Ð´Ð»Ñ\8f Ñ\82Ñ\8bÑ\81Ñ\8fÑ\87 Ð¸ Ð¼Ð¸Ð»Ð»Ð¸Ð¾Ð½Ð¾Ð², Ñ\82олÑ\8cко ÐµÑ\89Ñ\91 Ñ\81 Ð¿Ñ\80оизноÑ\88ением Ñ\82Ñ\8bÑ\81Ñ\8fÑ\87 Ð¸ Ð¼Ð¸Ð»Ð»Ð¸Ð¾Ð½Ð¾Ð² Ð² Ð²онце так же окончание для цифр
+// Ñ\82оже Ñ\81амое Ð´Ð»Ñ\8f Ñ\82Ñ\8bÑ\81Ñ\8fÑ\87 Ð¸ Ð¼Ð¸Ð»Ð»Ð¸Ð¾Ð½Ð¾Ð², Ñ\82олÑ\8cко ÐµÑ\89Ñ\91 Ñ\81 Ð¿Ñ\80оизноÑ\88ением Ñ\82Ñ\8bÑ\81Ñ\8fÑ\87 Ð¸ Ð¼Ð¸Ð»Ð»Ð¸Ð¾Ð½Ð¾Ð² Ð² Ðºонце так же окончание для цифр
 // как произносить тысячи и миллионы берёт с цифры 5
 
 #define m_00 {\
@@ -96,23 +111,25 @@ struct say_t {
 //порядковый
 //мужской
 #define m_04 {\
-       {"","","","","","","",""},\
-       {"","","","","","","","","","","","","",""},\
-       {"","","","","","","","","","","","","",""},\
+       {"h-0m","h-1m","h-2m","h-3m","h-4m","h-5m","h-","m"},\
+       {"","","1f","thousand","2f","thousands-i","3","thousands-i","4","thousands-i","5","thousands","",""},\
+       {"","","","million","2","million-a","3","million-a","4","million-a","5","millions","",""},\
        0,\
 }\
                                                                //средний
+
 #define m_05 {\
-       {"","","","","","","",""},\
-       {"","","","","","","","","","","","","",""},\
-       {"","","","","","","","","","","","","",""},\
+       {"0","1n","2","3","4","5","",""},\
+       {"","","1f","thousand","2f","thousands-i","3","thousands-i","4","thousands-i","5","thousands","",""},\
+       {"","","","million","2","million-a","3","million-a","4","million-a","5","millions","",""},\
        0,\
 }\
+
                                                                //женский
 #define m_06 {\
-       {"","","","","","","",""},\
-       {"","","","","","","","","","","","","",""},\
-       {"","","","","","","","","","","","","",""},\
+       {"h-0f","h-1f","h-2f","h-3f","h-4f","h-5f","h-","f"},\
+       {"","","1f","thousand","2f","thousands-i","3","thousands-i","4","thousands-i","5","thousands","",""},\
+       {"","","1","million","2","million-a","3","million-a","4","million-a","5","millions","",""},\
        0,\
 }\