Александр Бутов
25.10.2019
1214

Text To Speech. Синтез речи посредством софтфона. Отвечаем в канал звонящему набирая текст.

В статье рассмотрим такую возможность, как синтез речи из текста для Linux на примере CentOS 7. Область применения можешь быть разной, всё будет зависеть от фантазии или реального ТЗ. Самое простое что можно получить, это звучание заготовленного текста в IVR. Но я решил поэкспериментировать и организовать ситуацию когда звонящий будет говорить, а отвечающий будет молча […]

В статье рассмотрим такую возможность, как синтез речи из текста для Linux на примере CentOS 7. Область применения можешь быть разной, всё будет зависеть от фантазии или реального ТЗ.

Самое простое что можно получить, это звучание заготовленного текста в IVR. Но я решил поэкспериментировать и организовать ситуацию когда звонящий будет говорить, а отвечающий будет молча набирать текст в софтфоне, который соответственно и будет озвучиваться звонящему.

По ходу решения такой задачи возникало несколько проблем для ее реализации, но об этом несколько позже.

Для начала нам понадобится установить пакет festival и все его зависимости, которые как раз и потребуются для самой генерации текста в голос.

В процессе нужна будет библиотека управления вводом-выводом на терминал. Установить  ее можно с помощью команды:

yum install ncurses-devel

Далее надо скачать требуемые пакеты festival в /usr/src:

cd /usr/src
wget http://www.cstr.ed.ac.uk/downloads/festival/2.4/festlex_CMU.tar.gz
wget http://www.cstr.ed.ac.uk/downloads/festival/2.4/festlex_OALD.tar.gz
wget http://www.cstr.ed.ac.uk/downloads/festival/2.4/festlex_POSLEX.tar.gz
wget http://www.cstr.ed.ac.uk/downloads/festival/2.4/festival-2.4-release.tar.gz
wget http://www.cstr.ed.ac.uk/downloads/festival/2.4/speech_tools-2.4-with-wrappers.tar.gz

Далее разархивируйте их следующими командами:

tar xvzf festival-2.4-release.tar.gz
tar xvzf festlex_CMU.tar.gz
tar xvzf festlex_POSLEX.tar.gz
tar xvzf festlex_OALD.tar.gz

Перейдите в директорию утилит и выполним компиляцию пакетов:

cd speech_tools
./configure
make

Вернемся в /usr/src:

cd ..

Пропатчим последнюю версию и выполним компиляцию:

cd festival
patch -p1 </usr/src/asterisk-14.4.1/contrib/festival-1.95.diff
./configure
make

Создайте переменную PATH, которая описывает путь до исполняемых файлов в директории festival/bin/:

export PATH=$PATH:/usr/src/festival/bin/

Изначально в программе festival не содержится русской речи, но тем не менее в интернете нашлись нужные библиотеки для исправления этого недостатка

Перейдем к установке русской речи.

cd ..
mkdir /usr/src/festival/lib/voices/
mkdir /usr/src/festival/lib/voices/russian/

Скачайте следующий набор:

wget http://sourceforge.net/projects/festlang.berlios/files/msu_ru_nsh_clunits-0.5.tar.bz2

Распакуйте в созданную директорию:

tar xjf msu_ru_nsh_clunits-0.5.tar.bz2 -C /festival/lib/voices/russian

Измените конфигурационный файл языка, для использования русского:

nano /usr/src/festival/lib/languages.scm

В начало вставьте:

(define (language_russian)
"(language_russian)
Set up language parameters for Russian."
(set! male1 voice_msu_ru_nsh_clunits)
(male1)
(Parameter.set 'Language 'russian)
)

Далее найдите:

(language_british_english))
((equal? language 'americanenglish)

И  добавьте:

((equal? language 'russian)
(language_russian))

В файле:        

nano /usr/src/festival/lib/siteinit.scm

В самый конец:

(set! voice_default 'voice_msu_ru_nsh_clunits)

Создайте директорию для кэша временных аудиофайлов:

mkdir /var/lib/asterisk/festivalcache/ && chown asterisk:asterisk /var/lib/asterisk/festivalcache/

Далее потребуется интегрировать его с asterisk.

Создайте требуемый файл конфигурации со следующим наполнением:

touch /etc/asterisk/festival.conf
chown asterisk:asterisk /etc/asterisk/festival.conf && chmod 664 /etc/asterisk/festival.conf
nano /etc/asterisk/festival.conf

И вставьте туда:

[general]
host=localhost
port=1314
usecache=yes
cachedir=/var/lib/asterisk/festivalcache/
festivalcommand=(tts_textasterisk "%s" 'file)(quit)\n

После того, как установили все требуемые пакеты, у asterisk’a появился нужный модуль. Но его еще надо активировать в CLI

Делается это следующим образом:

module load app_festival.so

В моем случае он был уже загружен, поэтому выдало соответствующую ошибку.

После чего в диалплане можно будет использовать новый application — Festival()

Синтаксис у такого приложения следующий:

Festival("text",intkeys)

Где text — это сам текст который будет воспроизводиться

intkeys — это не обязательный параметр и отвечает за клавишу по которой будет останавливаться и производиться воспроизведение. Для выбора любой используйте any.

Что бы реализовать возможность отправки сообщений, потребуется внеснить несколько параметров в конфигурацию asterisk или FreePBX.

Для астериска потребуется в файл /etc/asterisk/sip.conf в секции [general] следующие параметры:

textsupport = yes ;

поддержка текста

accept_outofcall_message = yes ;

прием сообщений

outofcall_message_context = festival ;

контекст в котором будет производиться отправка сообщений, да и в принципе их работа

auth_message_requests = no ;

настройка безопасности, но в положении yes могут возникнуть проблемы совместимости.

Не забудьте выполнить в CLI:

sip reload

Аналогично эти же параметры можно указать на FreePBX в разделе Settings -> Asterisk SIP Settings, вкладка Chan SIP Settings:

В самом низу поля Other SIP Settings:

Для организации возможности набора текста и его воспроизведения потребуется написать соответствующий диалплан:

В  nano /etc/asterisk/extensions_custom.conf

Требуется вставить:

[first]
exten = s,1,NoOp(START)
same = n,Set(MESSAGE(to)=sip:102)
same = n,Set(MESSAGE(from)=sip:${CALLERID(num)})
same = n,Set(MESSAGE(body)=Звонит ${CALLERID(num)})
same = n,MessageSend(sip:102,sip:${CALLERID(num)})
same = n,NoOp(Message BODY: ${MESSAGE(body)})
same = n,NoOp(Message TO: ${MESSAGE(to)})
same = n,NoOp(Message FROM: ${MESSAGE(from)})
same = n,Set(DB(MSGS/body)=)
same = n,Goto(festival,s,1)

[festival]
exten = s,1,Answer
same = n,Set(DB(MSGS/body)=${MESSAGE(body)})
same = n,NoOp(${MESSAGE(body)})
same = n,Festival("Здравствуйте! Сейчас вы будете общаться со мной с помощью синтеза речи")
same = n,Goto(festival,s,set)
same = n(send),NoOp(${MSGTMP})
same = n,ExecIf($["${MSGTMP}" = "${DB(MSGS/body)}"])?Goto(festival,s,skip)
same = n(set),Set(MSGTMP=${DB(MSGS/body)})
same = n,NoOp(${MSGTMP})
same = n,ExecIf($["${MSGTMP}" = "Звонит ${CALLERID(num)}"])?Goto(festival,s,skip)
same = n,Festival("${MSGTMP}")
same = n,Wait(3)
same = n(noreplay),Goto(festival,s,send)
same = n(skip),Set(DB(MSGS/body)=)
same = n,Wait(3)
same = n,Goto(festival,s,send)

В CLI не забудьте выполнить dialplan reload после внесенных изменений.

На FreePBX потребуется создать направление на кастомный диалплан. Сделать это можно следующим образом:

Admin -> Custom Destenation

И указываем

first,s,1

Что бы описать происходящее надо представлять как будет приходить сам вызов.

В данном случае будем в реальном времени отвечать по средством сообщений через софтфон Microsip версии 3.19.10. На других не тестировалось.

Суть следующая:

Клиент звонит на внешний номер, ему воспроизводится сообщение о том что сейчас он будет общаться с сотрудником отвечающим с помощью искусственной речи.

При этом самому сотруднику в софтфон придет сообщение о новом поступившем вызове и тем самым активируется чат. Далее он уже может отвечать. Новый набранные сообщения будут заноситься в БД астериска в одну и ту же ячейку MSGS/body с перезаписью. Оттуда с небольшой задержкой будет выполняться приложение Festival и получать нужный текст для воспроизведения. БД использовалась, т.к. сразу набранный текст я не мог заносить в переменную, т.к. они происходят в разных каналах. Возможно вы найдете для себя более удобный выход.

И всё бы ничего. Но в логике обработки вызова сразу возникает проблема — как слышать сотруднику то, что будет ему говорить клиент? Ведь вызов ему на прямую не поступал, а отвечаем мы с помощью тестового чата из софтфона.

При этом просто использовать Dial мы не можем, т.к. на нём выполнение диалплана и приостановиться на время всего разговора. Как вариант реализации, можно было бы, и более правильно, использовать Originate по средством AMI, который бы уже вызывал нашего сотрудника.

Но тем не менее есть еще более простой вариант — будем использовать ChanSpy =) То самое приложение asterisk, что отвечает за подслушивание.

Т.е. получается когда сотруднику 102 на софтфон придет сообщение с входящим от нового клиента — звоним 555 (стандартный сервисный код для вызова ChanSpy на FreePBX) и подключаемся к имеющемуся каналу.

Более подробно о реализации ChanSpy можно почитать в этой статье.

А теперь потребуется запустить сам server Festival командой:

/usr/src/festival/bin/festival --server

В консоли будет что то вроде этого:

Сообщения ниже команды – это сами вывод в процессе задействования приложения Festival() во время выполнения диалплана.

Ну и сам процесс звонка:

Подписаться
Уведомление о
guest
0 Комментарий
Inline Feedbacks
View all comments

Остались вопросы?

Я - Виталий Шелест, менеджер компании Voxlink. Хотите уточнить детали или готовы оставить заявку? Укажите номер телефона, я перезвоню в течение 3-х секунд.

VoIP оборудование

ближайшие курсы

ближайшие Вебинары

ONLINE

10 доводов в пользу Asterisk

Распространяется бесплатно.

Asterisk – программное обеспечение с открытым исходным кодом, распространяется по лицензии GPL. Следовательно, установив один раз Asterisk вам не придется дополнительно платить за новых абонентов, подключение новых транков, расширение функционала и прочие лицензии. Это приближает стоимость владения станцией к нулю.

Безопасен в использовании.

Любое программное обеспечение может стать объектом интереса злоумышленников, в том числе телефонная станция. Однако, сам Asterisk, а также операционная система, на которой он работает, дают множество инструментов защиты от любых атак. При грамотной настройке безопасности у злоумышленников нет никаких шансов попасть на станцию.

Надежен в эксплуатации.

Время работы серверов некоторых наших клиентов исчисляется годами. Это значит, что Asterisk работает несколько лет, ему не требуются никакие перезагрузки или принудительные отключения. А еще это говорит о том, что в районе отличная ситуация с электроэнергией, но это уже не заслуга Asterisk.

Гибкий в настройке.

Зачастую возможности Asterisk ограничивает только фантазия пользователя. Ни один конструктор шаблонов не сравнится с Asterisk по гибкости настройки. Это позволяет решать с помощью Asterisk любые бизнес задачи, даже те, в которых выбор в его пользу не кажется изначально очевидным.

Имеет огромный функционал.

Во многом именно Asterisk показал какой должна быть современная телефонная станция. За многие годы развития функциональность Asterisk расширилась, а все основные возможности по-прежнему доступны бесплатно сразу после установки.

Интегрируется с любыми системами.

То, что Asterisk не умеет сам, он позволяет реализовать за счет интеграции. Это могут быть интеграции с коммерческими телефонными станциями, CRM, ERP системами, биллингом, сервисами колл-трекинга, колл-бэка и модулями статистики и аналитики.

Позволяет телефонизировать офис за считанные часы.

В нашей практике были проекты, реализованные за один рабочий день. Это значит, что утром к нам обращался клиент, а уже через несколько часов он пользовался новой IP-АТС. Безусловно, такая скорость редкость, ведь АТС – инструмент зарабатывания денег для многих компаний и спешка во внедрении не уместна. Но в случае острой необходимости Asterisk готов к быстрому старту.

Отличная масштабируемость.

Очень утомительно постоянно возвращаться к одному и тому же вопросу. Такое часто бывает в случае некачественного исполнения работ или выбора заведомо неподходящего бизнес-решения. С Asterisk точно не будет такой проблемы! Телефонная станция, построенная на Asterisk может быть масштабируема до немыслимых размеров. Главное – правильно подобрать оборудование.

Повышает управляемость бизнеса.

Asterisk дает не просто набор полезных функций, он повышает управляемость организации, качества и комфортности управления, а также увеличивает прозрачность бизнеса для руководства. Достичь этого можно, например, за счет автоматизации отчетов, подключения бота в Telegram, санкционированного доступа к станции из любой точки мира.

Снижает расходы на связь.

Связь между внутренними абонентами IP-АТС бесплатна всегда, независимо от их географического расположения. Также к Asterisk можно подключить любых операторов телефонии, в том числе GSM сим-карты и настроить маршрутизацию вызовов по наиболее выгодному тарифу. Всё это позволяет экономить с первых минут пользования станцией.