Опубликовано Оставить комментарий

Обучим леди русскому языку

Пакет русских звуков

Для Asterisk 1.4, если добавить languageprefix=yes в asterisk.conf, структура звуковых каталогов будет как в более новых версиях по умолчанию.
Стандартный каталог: /var/lib/asterisk/ в котором подпапки, зависящие от двух «xx» букв ISO кода страны (ru, nl, fr, de, it, pt, es …)

        sounds/xx
        sounds/xx/digits
        sounds/xx/letters
        sounds/xx/phonetic

Создадим каталог, если его нет

 #mkdir /var/lib/asterisk/sounds/ru/

Загружаем русские звуки:

 #wget -O asterisk-sounds-additional-master.zip https://github.com/pbxware/asterisk-sounds-additional/archive/master.zip
 #wget -O asterisk-sounds-master.zip https://github.com/pbxware/asterisk-sounds/archive/master.zip

Распаковываем:

 #unzip asterisk-sounds-additional-master.zip
 #unzip asterisk-sounds-master.zip

Копируем на свое место:

 #cp -R ./asterisk-sounds-additional-master/* /var/lib/asterisk/sounds/ru/
 #cp -R ./asterisk-sounds-master/* /var/lib/asterisk/sounds/ru/

Посмотреть, какие фразы записаны можно в следующих файлах:

 #less ./asterisk-sounds-additional-master/additional-sounds-ru.txt
 #less ./asterisk-sounds-master/core-sounds-ru.txt

 

sip.conf

Укажем asterisk`у, использовать русский язык для SIP, добавив language=ru в [general]:

#cat /etc/asterisk/sip.conf
[general]
language=ru

Применяем настройки:
#asterisk -rx "sip reload"

say.conf

 

#cat /etc/asterisk/say.conf

[ru-base](!)
    _[n]um:0X		=> num:${SAY:1}

    _[n]um:X 		=> digits/${SAY}
    _[n]um:[1-2]f	=> digits/${SAY:0:1}f
    _[n]um:[3-9]f	=> digits/${SAY:0:1}

    ; Tens
    _[n]um:1X		=> digits/${SAY:0:2}
    _[n]um:1Xf		=> digits/${SAY:0:2}

    _[n]um:[2-9]0       => digits/${SAY:0:2}
    _[n]um:[2-9]0f      => digits/${SAY:0:2}

    _[n]um:[2-9][1-2]   => digits/${SAY:0:1}0, num:${SAY:1}
    _[n]um:[2-9][1-2]f  => digits/${SAY:0:1}0, num:${SAY:1}

    _[n]um:[2-9][3-9]   => digits/${SAY:0:1}0, num:${SAY:1}
    _[n]um:[2-9][3-9]f  => digits/${SAY:0:1}0, num:${SAY:1}


    ; Hundreds
    _[n]um:0XX		=>	num:${SAY:1}
    _[n]um:0XXf		=>	num:${SAY:1}

    _[n]um:[1-9]00	=>	digits/${SAY:0:1}00
    _[n]um:[1-9]00f	=>	digits/${SAY:0:1}00

    _[n]um:XXX		=>	num:${SAY:0:1}00, num:${SAY:1}
    _[n]um:XXXf		=>	num:${SAY:0:1}00, num:${SAY:1}


    ; enumeration
    _e[n]um:X			=>	digits/h-${SAY}
    _e[n]um:X[n]		=>	digits/h-${SAY}
    _e[n]um:0X			=>	enum:${SAY:1}
    _e[n]um:0X[n]		=>	enum:${SAY:1}
    _e[n]um:1X			=>	digits/h-${SAY}
    _e[n]um:1X[n]		=>	digits/h-${SAY}
    _e[n]um:[2-9]0		=>	digits/h-${SAY}
    _e[n]um:[2-9]0[n]		=>	digits/h-${SAY}
    _e[n]um:[2-9][1-9]		=>	num:${SAY:0:1}0, digits/h-${SAY:1}
    _e[n]um:[2-9][1-9][n]	=>	num:${SAY:0:1}0, digits/h-${SAY:1}
    _e[n]um:[1-9]00		=>	digits/h-${SAY}
    _e[n]um:[1-9]00[n]		=>	digits/h-${SAY}
    _e[n]um:[1-9]XX		=>	num:${SAY:0:1}00, enum:${SAY:1}
    _e[n]um:[1-9]XX[n]		=>	num:${SAY:0:1}00, enum:${SAY:1}



[ru](ru-base)

    _chas:0		=>	num:${SAY}, digits/hours
    _chas:1		=>	digits/${SAY}, digits/hour
    _chas:[2-4]		=>	num:${SAY}, digits/hours-a
    _chas:[5-9]		=>	num:${SAY}, digits/hours
    _chas:0X		=>	chas:${SAY:1}
    _chas:1X		=>	num:${SAY}, digits/hours
    _chas:20		=>	num:${SAY}, digits/hours
    _chas:2[1-4]	=>	num:${SAY:0:1}0, chas:${SAY:1}

    _mi[n]uta:0		=>	num:${SAY}, digits/minutes
    _mi[n]uta:1		=>	digits/1f, digits/minute
    _mi[n]uta:2		=>	digits/2f, digits/minutes-i
    _mi[n]uta:[3-4]	=>	num:${SAY}, digits/minutes-i
    _mi[n]uta:[5-9]	=>	num:${SAY}, digits/minutes
    _mi[n]uta:0X	=>	minuta:${SAY:1}
    _mi[n]uta:1X	=>	num:${SAY}, digits/minutes
    _mi[n]uta:[2-5]0	=>	num:${SAY}, digits/minutes
    _mi[n]uta:[2-5][1-9]	=>	num:${SAY:0:1}0, minuta:${SAY:1}

    _seku[n]da:0	=>	num:${SAY}, seconds
    _seku[n]da:[5-9]	=>	num:${SAY}, seconds
    _seku[n]da:0X	=>	sekunda:${SAY:1}
    _seku[n]da:1X	=>	num:${SAY}, seconds
    _seku[n]da:[2-5]0	=>	num:${SAY}, seconds

    _dayofweek:[0-6]	=>	digits/day-${SAY} 

    _dayofmo[n]th:X	=>	enum:${SAY}n
    _dayofmo[n]th:XX	=>	enum:${SAY}n

    _mo[n]th:X		=>	digits/mon-$[${SAY} - 1]
    _mo[n]th:XX		=>	digits/mon-$[${SAY} - 1]

Применяем настройки:
#asterisk -rx "module reload app_playback.so"

Контекст [ru-base] в say.conf имеет завершающий (!) восклицательный знак в скобках означает, что это шаблон, который мы в дальнейшем включаем в [ru]

Попробуем разобрать одно правило. Первое, на что стоит обратить внимание, это символы X Z N. Они интерпретируются asterisk`ом как специальные и если эти литеры фигурируют в названии правила чтения, их следует взять в квадратные скобки, например mo[n]th.

_mo[n]th:XX		=>	digits/mon-$[${SAY} - 1]

Синтаксис достаточно прост и правило совпадает, если входные данные XX — две любые цифры. Проигрываем файл digits/mon-(XX-1), где (XX-1) это арифметическая операция. При X=02 (да, «переваривает» даже такие цифры, что нам очень поможет), 02-1=1, digits/mon-1: «Февраля».

Отдельно стоит упомянуть секунды. Во-первых, в записанных фразах есть только единственная запись: «секунд». Это значит, что на вход этой функции должны приходить округленные данные, например 0, 10, 20, и так далее. А во-вторых, по мнению автора, это облегчит восприятие полученной информации.

extensions.conf

 

#cat /etc/asterisk/extensions.conf

[my_regular_context]  ; Там где живет ваш SIP абонент/телефон.
exten => 100,1,Goto(informer_100,s,1)

[informer_100]
exten => s,1,Set(FreezeEPOCH=$[${EPOCH} + 15]) ; Добавляем 15 секунд к unixtime.
 same => n,Set(TimeNow=${STRFTIME(${FreezeEPOCH},,%Y%m%d%H%M.%S-%w-%j)})
 same => n,Playback(silence/1&at-tone-time-exactly) ;Тишина 1 секунда + Текущее время
 same => n,Playback(chas:${TimeNow:8:2},say) ; десять + часов
 same => n,Playback(minuta:${TimeNow:10:2},say) ; сорок + одна + минута
 same => n,Playback(sekunda:${TimeNow:13:1}0,say) ; двадцать + секунд
 same => n,Playback(silence/1&digits/today) ; тишина 1 секунда + сегодня
 same => n,Playback(dayofweek:${TimeNow:16:1},say) ; четверг
 same => n,Playback(dayofmonth:${TimeNow:6:2},say) ; шестнадцатое
 same => n,Playback(month:${TimeNow:4:2},say) ; октября
 same => n,Playback(silence/1&beep) ; тишина 1 секунда + короткий гудок
 same => n,Hangup()

Применяем настройки:
#asterisk -rx "dialplan reload"

 

same => n,Set(FreezeEPOCH=$[${EPOCH} + 15])

В контексте [informer_100] стоит объяснить строчку, где мы в переменной FreezeEPOCH добавляем 15 секунд к unixtime. Сделано это для компенсации времени, потраченного на проигрывание файлов, предшествующих секундам.

Далее мы формируем необходимый нам формат даты в переменной TimeNow. Она содержит данные в виде: 201410160043.34-4-289. При чтении мы выдергиваем из «массива» необходимые числа. Они всегда на своих местах и извлечение не составит труда. Более подробно о форматах можно посмотреть в #man strftime.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *