На сегодняшний момент для n900 существует две свободные программы с голосовой навигацией: mapero и navit. В обоих случаях для голосовых объявлений используется синтез речи. И, если с синтезом английского языка дела обстоят неплохо, то синтез русского является куда более сложной задачей. Из доступных на n900 программ синтеза русским владеют espeak и festival (заводится с бубном и это отдельная тема для разговора). Однако качество синтеза espeak очень посредственное и требует много усилий, чтобы разобрать, что же оно такео говорит. Так что для голосовой навигации он не годится. festival с голосом, разработанным в МГУ, справляется на ура, все четко и вполне понятно, хотя за время тестов его "повернитэ" необнократно вызывало колкие замечания. Но есть одно но, festival кушает до 130 MB оперативной памяти во время генерации звука, а так как на n900 ее всего 256 MB, то команда генерируется секунд 30, что тоже никуда не годится.
В коммерческих навигаторах успешно применяется проигрывание заранее записанных звуковых фрагментов, благо не так много фраз знает навигатор. Но зато названия улиц, как это делает navit, они говорить не могут. И тогда появилась идея кэширующего прокси для синтезатора речи, получившего название cachetts (доступен в extras-devel). Это демон, слушающий DBus. Когда приходит сообщение, он выделяет в нем знакомые ему куски и воспроизводит заранее подготовленные для них звуковые файлы. Незнакомые фрагменты отправляются на синтез в festival, причем синтезируются они тоже в файлы. Если к моменту, когда фрагмент надо произнести festival еще не закончил (что бывает очень часто), фрагмент синтезируется через espeak (то есть плохо, зато здесь и сейчас). В следующий раз cachetts найдет сгенерированный festival файл и воспроизведет его. Возможно и другое поведение, все настраивается.
В виде дополнительного бонуса к входной строке применяется блок замен (описанных в replaces.csv), что позволяет исправлять некоторые ошибки во фразах строимых навгаторами. Так festival валится на воспроизведении строки "2.2", поэтому точка во всех десятичных дробях заменяется на союз "и".
Использование
Прежде всего программу нужно настроить. Настройки лежат в файле /home/user/.cachetts.py
[cachetts]
# Режим воспроизведения текста для festival
textmode=fundamental
# Каталог, куда будут складываться фразы, синтезированные festival
cachedir=/home/user/MyDocs/cachetts/cache/
# Каталог с голосом
prefix=/home/user/MyDocs/cachetts/voice/
# Команда, передаваемая festival, используйте для включения русского голоса
festival_init_cmd=(voice_msu_ru_nsh_clunits)
# Команда для запуска espeak
espeakcmd=espeak -vru
# Файл с описанием фраз, которые известны для данного голоса
templates=/home/user/MyDocs/cachetts/templates.csv
# Файл с описанием замен (используются регулярные выражения, файл фактически содержит два первых аргумента командв re.sub)
replaces=/home/user/MyDocs/cachetts/replaces.csv
# Основной генератор звука
generator=festival_cache
# Запасной генератор звука
backup_generator=espeak
В данный момент поддерживаются генераторы festival, festival_cache, espeak.
Теперь надо запустить программу. Сделать это можно либо набрав
cachetts.py от обычного пользователя в консоли (вы получите отладочную печать, однако программа будет завершена, если вы закроете консоль), либо
/etc/init.d/cachetts start от рута, что запустит программу в фоновом режиме. Остановить её можно будет командой
/etc/init.d/cachetts stop. Программа использует одно tty устройство для общеия с festival, если будет вываливаться с сообщением о нехватке tty устройств, придется закрыть одну из консолей.
Дальнейшее общение производится через DBus:
-
Произнести строку
dbus-send --system --type=signal /su/kibergus/cachetts su.kibergus.cachetts.say_string string:'Строка, которую надо сказать' boolean:false string:navit boolean:true
Параметры имеют следующее значение:
say_string(string, urgent, tag, kickoff)
Если установлен флаг urgent сообщение будет воспроизведено в первую очередь, не дожидаясь своей очереди. Если установлен флаг kickoff, то при поступлении сообщения из очереди будут удалены все сообщения с тем же тэгом и установленным флагом kickoff. Сделано на случай, если навигатор будет отдавать команды слишком часто.
-
Произнести строку через определенный генератор и с/без использования словаря (описанного в templates.csv)
dbus-send --system --type=signal /su/kibergus/cachetts su.kibergus.cachetts.say_string_custom string:'Строка, которую надо сказать' boolean:false string:navit boolean:true boolean:true string:espeak
say_string_custom(string, urgent, tag, kickoff, caching, generator)
-
Установить генератор по-умолчанию.
set_generator (type, generator)
где type может быть либо main, либо backup
-
Включает и отключает использование словаря.
Остается только объяснить навигатору, как этой программой пользоваться. Для navit соответсвующая строчка в nvit.xml будет выглядеть так:
<speech type="cmdline" data="dbus-send --system --type=signal /su/kibergus/cachetts su.kibergus.cachetts.say_string string:'%s' boolean:false string:navit boolean:true" cps="6"/>
Дальнейшие пути развития
В настоящий момент звуки хранятся в wav, воспроизводиться могут любые форматы, которые поддерживает gstreamer, так что можете сконвертировать их в ogg (насколько я знаю, использование mp3 приведет к увеличению пауз между словами), однако я не нашел способа переконвертировать звук прямо на n900 без установки дополнительных пакетов, поэтому решил не вставлят фазу сжатия wav после их генерации фестивалем.
Ну и конечно голоса. Когда я писал эту программу, я хотел, чтобы у моей девушки навигатор говорил моим голосом, но пока его не записал. Я надеюсь, что найдутся умельцы, которые запишут голоса более приятные, чем у синтезаторов.