Добавляем звука в OpenWRT

Иногда по субботам мне хочется странного, а тут еще и день рождения подкрался. А какой же день рождения без музыки? И вот я внезапно решил превратить свой роутер в, как говорят у них, джукбокс. Но чтоб музыку играл, а монет не просил.

Вода

Что нужно, чтобы роутер начал воспроизводить музыку? Если бы мне задали такой вопрос десять лет назад, я б только спросил: «А что такое роутер?». Если бы пять лет назад — «Вы, должно быть, шутите, ведь роутер — это для сетей». Ну а сегодня я бы просто недоуменно пожал плечами и ответил: «Очевидно, внешняя карта с USB-выходом».

USB-выходом на роутере сегодня никого не удивить, а на некоторых моделях их ставят аж по два (жаль, в остальном отношении эти модели не удовлетворяют ожидания также вдвойне). Стоковые — они же официальные — прошивки позволяют подключать принтеры, внешние накопители: флешки, жесткие диски, кратно расширяя полезность и функциональность аппарата.

Железо

Итак, я раздобыл внешнюю аудиокарту с USB-выходом с замысловатым названием Creative Sound Blaster X-Fi Surround 5.1 Pro, а если проще — SB1095. Имеет разъемы под наушники, микрофон, линейный вход, два разъема под тюльпаны на 2.0-колонки, два мини-джека для сабвуфера и передних сателлитов, S/PDIF. В комплекте идет переходник с двух тюльпанов-пап на мини-джек-маму, а также маленький IR-пульт дистанционного управления.

Creative SB X-Fi Surround 5.1 Pro как она есть.
Приятные аксессуары.

А поскольку на моем роутере всего один USB-порт, я нашел и семипортовый USB-хаб за авторством D-Link: DUB-H7. К хабу прилагается внешний отдельный источник питания, однако можно обойтись и без него, если не подключать прожорливых устройств.

D-Link DUB-H7.

Оба аппарата — эталонный продукт потуг современного маркетолога. Глянцевые поверхности, всеми силами притягивающие пыль, отпечатки и царапины; сверхъяркие синие светодиоды-индикаторы, освещающие комнату в темноте не хуже ночника. Все то, что якобы должно манить взгляд потенциального покупателя. Об этом еще напишу чуть позже, а теперь надо проверять, как оно все работает.

Я подключил аудиокарту к своей основной машине, подхватилось без проблем. В pavucontrol (утилита PulseAudio) появился новый так называемый «sink» — приемник звука, на который можно в один клик перекинуть воспроизведение.

PulseAudio жжот.

Работает, и даже немного похоже на волшебство. Естественно, не обошлось и без накладок: ни IR-пульт, ни колесо громкости наверху корпуса не заработали. Впрочем, звук есть, и это уже хорошо.

Проверка на работоспособность пройдена.

Пора собирать всю конструкцию вокруг роутера.

Все в сборе — временный вариант.

…и устанавливать ПО. Напомню — на моем роутере стоит OpenWRT образца августа 2012 года.

Софт

Первым делом нужно установить базовую поддержку звуковых и USB-устройств. Можно просто следовать инструкциям в OpenWRT-вики: USB-устройства, аудиоустройства, и поставить через opkg модули ядра. Здесь проблем никаких не встречено.

ALSA

Нужно поставить два пакета: alsa-lib и alsa-utils. Во втором лежат всякие полезные утилиты для диагностики и управления. Должно получиться вот так:
root@dmserver:~# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Pro [SB X-Fi Surround 5.1 Pro], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: Pro [SB X-Fi Surround 5.1 Pro], device 1: USB Audio [USB Audio #1]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
root@dmserver:~# aplay -L
null
    Discard all samples (playback) or generate zero samples (capture)
front:CARD=Pro,DEV=0
    SB X-Fi Surround 5.1 Pro, USB Audio
    Front speakers
surround40:CARD=Pro,DEV=0
    SB X-Fi Surround 5.1 Pro, USB Audio
    4.0 Surround output to Front and Rear speakers
surround41:CARD=Pro,DEV=0
    SB X-Fi Surround 5.1 Pro, USB Audio
    4.1 Surround output to Front, Rear and Subwoofer speakers
surround50:CARD=Pro,DEV=0
    SB X-Fi Surround 5.1 Pro, USB Audio
    5.0 Surround output to Front, Center and Rear speakers
surround51:CARD=Pro,DEV=0
    SB X-Fi Surround 5.1 Pro, USB Audio
    5.1 Surround output to Front, Center, Rear and Subwoofer speakers
surround71:CARD=Pro,DEV=0
    SB X-Fi Surround 5.1 Pro, USB Audio
    7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
iec958:CARD=Pro,DEV=0
    SB X-Fi Surround 5.1 Pro, USB Audio
    IEC958 (S/PDIF) Digital Audio Output
Регулятора громкости на аудиокарте нет, поэтому можно воспользоваться широко известным костылем под названием «softvol». Нужно поместить в /etc/asound.conf такое:
root@dmserver:~# cat /etc/asound.conf
pcm.!default {
    type plug
    slave.pcm «softvol»
}
pcm.softvol {
    type softvol
    slave.pcm «plughw:0,0»
    control {
        name «Master»
        card 0
    }
}
Далее запустить, например, aplay, чтобы настройки подхватились, а затем alsamixer. Должен появиться регулятор громкости. В принципе, уже можно воспроизвести что-то через aplay, но у меня кроме треска из колонок ничего не вышло. Кстати, если в alsamixer выбрать «Power LED» и нажать клавишу M (стало быть, «Mute»), светодиод на аудиокарте начнет мигать.
Новый регулятор громкости.

PulseAudio

Сначала у меня была идея поставить PulseAudio, чтобы играть что угодно и откуда угодно. Было бы здорово иметь возможность вывести на подвесные колонки поток с основного компьютера, с планшета, с телефона. К сожалению, этим мечтам не суждено было сбыться. Модуль module-udev-detect (см. /etc/pulse/default.pa) наотрез отказался обнаруживать аудиокарту, а когда я явно указал цель через module-alsa-sink, написал в лог красным шрифтом, якобы что-то неладное произошло с памятью. Не удалось завести, в общем.

MPD

Не знаю, что курил автор MPD, когда придумал оформить плеер музыки в клиент-серверной архитектуре. Впрочем, идея получилась вполне рабочая. MPD aka «Music Player Daemon» — демон, запускаемый на машине, которая может воспроизводить звук. Рядом кладется медиа-библиотека с музыкой и обложками, их демон сможет индексировать. Далее, либо на этой же машине, либо на любой другой удаленной устанавливается клиент (консольный mpc, gmpc для GNOME, MPDroid для Android), который не будет играть музыку, но является просто интерфейсом с кнопками «Следующий/предыдущий трек», регулятором громкости и прочими полезными элементами. Таким образом, демоном можно управлять сразу из нескольких мест, и все клиенты будут синхронизированы.
Интерфейс gmpc.
Интерфейс MPDroid — чуть поаккуратнее.
Поставьте пакет mpd-full и пропишите в /etc/mpd.conf такой источник звука:
audio_output {
    type «alsa»
    name «ALSA»
    device «softvol»
    mixer_control «Master»
}
Теперь можно слушать музыку с регулируемой громкостью.
Кстати, MPD умеет играть и интернет-радио, достаточно просто добавить m3u-плейлист в список воспроизведения.

Эквалайзер

При первом же прослушивании выяснилось, что музыка звучит «плоско» и без деталей. Примерно как если подключить планшет, и отключить в нем эквалайзер. Стало быть, и в данном случае программный эквалайзер нужен.
Хорошие новости: все уже придумано, и существует стандарт LADSPA, который описывает, как должен выглядеть типичный плагин для аудиообработки. Кроме того, один умный человек написал ворох совместимых со стандартом плагинов практически на любой вкус (swh-plugins). В том числе и реализацию многополосного эквалайзера. Все эти чудеса можно прикрутить к ALSA с помощью alsaequal, который есть в разных репозиториях (например, Debian’а), и которого, к сожалению, нет в репозитории opkg. Не буду описывать, как я портировал и кросскомпилировал все это хозяйство; как, вооружившись strace, dbg и fprintf пару вечеров выяснял, почему при использовании оператора new в конструкторе so-библиотеки все падает к чертям собачьим в segmentation fault; как курочил make-сценарии, пытаясь передать в них правильные параметры для сборки под MIPS; в общем, материала хватило бы на отдельный пост. К чести создателей OpenWRT, система сборки оказалась гибкой, логичной и вполне простой, правда,оценил я ее не сразу.
А плохая новость всего одна — ничего не получилось. Вернее, эквалайзер работает, но съедает 100% ресурсов центрального процессора, в результате чего музыка играет жуткими рывками.
Эквалайзер mbeq из swh-plugins.
Я попробовал другой набор плагинов (caps), попробовал состыковать их напрямую с ALSA через «type ladspa», чтоб эквалайзер был хотя бы статическим — ничего не помогло. Попробовал взять эквалайзер попроще, на три полосы, и он заработал все с той же загрузкой в 100%, но уже без заиканий музыки. Автор плагинов пишет, что на PIII большой эквалайзер будет отъедать всего 20МГц, поэтому удивительно, как он может занять процессор частотой 600 МГц полностью. Либо это говорят различия в архитектуре, либо слишком много вычислений в один момент времени, либо нужны специальные параметры сборки, либо все разом. В любом случае, планирую еще немного покопаться в исходниках.

LIRC

Ну а это уже в качестве бонуса. У нас остались незадействованными пультик и колесо. Оказывается, их можно оживить с помощью демона LIRC. Он позволяет снимать сигналы с инфракрасного приемника на аудиокарте и запускать какие-нибудь команды. IR (они же «infrared», т.е. инфракрасные) приемники и передатчики нынче уже не так широко распространены, на их замену пришли другие беспроводные стандарты связи. А вот раньше IR-окошки можно было увидеть на многих сотовых телефонах, в беспроводных клавиатурах и мышах.
Итак, для начала нужно поставить пакеты lirc и lirctools. Демон lircd следует запускать так, с указанием конкретного драйвера:
root@dmserver:~# ps | grep lirc
16801 root      2232 S    lircd -H alsa_usb

Если вы поставили прекомпилированный пакет из репозитория, поддержки драйвера alsa_usb там не будет. Придется разворачивать дерево исходников, настраивать окружение для сборки (у вас ведь Linux, верно?). В package/feeds/packages/lirc/Makefile в переменную CONFIGURE_ARGS нужно будет добавить параметр —with-driver=»alsa_usb», а в секцию package/lirc/Default добавить зависимость DEPENDS:=alsa-lib. Теперь можно собирать ipk-пакет, копировать на роутер, устанавливать через opkg. В ходе этого квеста будет еще пара сложностей, если встретите — пишите, расскажу решение. Как видите, все просто (шутка).
Для пультика, а его модель написана прямо под нижним рядом кнопок (RM-820), нужно взять специфический файл конфигурации /etc/lircd.conf. Скачать можно тут. При активном демоне запустите утилиту irw и понажимайте что-нибудь на пультике. Если сигнал воспринимается, irw выдаст коды нажатых кнопок.
Еще понадобится привязка приложений к нажатию кнопок, лежит в /etc/lirc/lircrc. За привязку отвечает приложение irexec. Я разметил вот так. Финальным аккордом, если, конечно, вы не хотите запускать демон после каждой перезагрузки роутера, нужно создать скрипт для автозапуска в /etc/init.d/ (почему-то изначально его не оказалось). Мой вариант тут.
Теперь и колесо громкости, и пультик выполняют свою роль. Правда, кнопки REW и FWD работают неуверенно, через раз, но они не слишком-то и важны. Даже остались свободные кнопки, на которые также можно навесить нечто полезное. Подозреваю, что подобным образом можно приспособить любой пульт, хоть от телевизора.

Моддинг

Настала пора объединить части в единый комплекс. В интернете видел картинки, где юные и горячие умельцы прикручивали в подобной ситуации все к корпусу роутера болтами. Портить товарный вид нового роутера я пожалел, а на глаза как раз попалась подставка от старого D-Link DIR-300, которая почти по размеру идеально встала с торца роутера.
Подставка от DIR-300.
Все же без жертв не обошлось: в нижних частях корпусов аудиокарты и USB-хаба прокрутил по паре отверстий. Изначально идея была скрепить все болтами с гайками, но болты оказались длинноваты, а укоротить их или откусить не вышло. Поэтому в дело пошли нейлоновые стяжки «Ермак». Удивительное изобретение и невероятно полезное.
Притягиваем…

…и собираем.
Осталось подключить кабели и вуаля! «Building complete!», как говаривала Lt. Eva Lee в незабвенной Red Alert 2.
He’s alive!

Брюзжание

Как я уже говорил, в оба аппарата встроены синие сверх-ультра-супер-пупер-яркие светодиоды. Если смотреть прямо на них, натурально слепят.

Хочешь уснуть? Давай, пробуй!

К счастью, существует давно проверенный рабочий на 100% способ исправить подобный промах инженеров. Я испробовал его еще на своем последнем системнике, где индикатором питания вкручен точно такой же яркий синий светодиод. Итак, берем любой максимально плотный материал, у которого одна сторона намазана клеем, вырезаем заплатку и лепим беспощадно на назойливый индикатор. Я использую клейкую часть бумажных стикеров. В итоге испускаемый свет не только становится тусклее, но и, смешиваясь с окраской стикера, меняет свой цвет на зеленый! Вот такой спонтанный моддинг. Но если есть черные наклейки, лучше взять их, конечно.

Поверхности — мечта криминалиста, все заляпалось в два счета.

Позже, когда разбирал корпуса, переклеил бумажки на внутреннюю поверхность. Индикатор на аудиокарте стал снаружи почему-то внезапно красным.

Чтобы выглядело цивилизованнее.

А еще понравилось первое, что бросилось в глаза, когда я открыл коробку с аудиокартой.

Пугают почем зря.

Предупреждение, что, буквально, «По информации штата Калифорния взаимодействие с этим продуктом может вызывать рак либо нарушать детородные функции, мойте руки после использования». Феерично. Я поискал по форумам, где люди в недоумении спрашивали, мол, это что ль шутка такая? На что получали ответы вида «не ешьте камеры/плееры, и все будет отлично», «in California, walking across the street will cause cancer». На самом деле существует документ, который и предписывает ставить такую надпись, и компания Creative добросовестно лепит бумажку на многие другие свои продукты. Вот как страшно жить.

Добавляем звука в OpenWRT: 9 комментариев

  1. buzzkiller

    Здравствуйте. Спасибо за познавательную статью. Пробую собрать lirc с alsa_usb. Делаю все по вашей инструкции, но при компиляции выходит ошибка:
    make -r package/lirc/compile: build failed. Please re-run make with V=s to see what's going on
    make: *** [package/lirc/compile] Error 1

  2. buzzkiller

    Пробовал запусить с параметрами V=s, выдает такое:
    configure: error: *** you need to have the ALSA libraries and drivers
    from at least version 1.0.9 for this driver
    Ну да ладно. В mpd я использую вывод звука через oss, загрузка проца меньше и качество звука мне больше нравится, а вот будет ли lirc работоспособен в данном случае?

  3. mic Автор записи

    Насчет OSS не подскажу, поэкспериментировать не на чем. Предполагаю, что не получится.
    А вот как можно собрать с alsa_usb (проверил только что на чистых с нуля исходниках openwrt):
    1. Делаем make menuconfig, отмечаем звездочкой Libraries → alsa-lib и Utilities → lirc.
    2. Редактируем package/feeds/packages/lirc/Makefile:
    2.1. Опционально, если хочется самое свежее: меняем PKG_VERSION на 0.9.0 + ставим # перед PKG_MD5SUM. Это заставит сборщика скачать последнюю версию и не сверять содержимое архива.
    2.2. Добавляем в секцию "define Package/lirc" строку DEPENDS:=alsa-lib. Сборщик будет знать, что нужно подключить библиотеку libasound.so.
    2.3. Добавляем в переменную CONFIGURE_ARGS строку —with-driver="alsa_usb" (не забыть обратный слэш в конце).

  4. buzzkiller

    Наконец удалось скомпилировать lirс, irw принимает команды, светодиод мигает, но пакете lirctools почему то отсутствует irexec. При выполнении opkg info lirctools он там есть, но вот система не находит. Как быть?

  5. mic Автор записи

    Предположу, что про него забыли в package/feeds/packages/lirc/Makefile. Если после сборки поискать в директории openwrt, irexec там есть (find . -name irexec).
    Можно попробовать руками перекинуть его на роутер.
    Вообще, там два irexec: один исполняемый (лежит в .libs), а другой скрипт-обертка. Нужен, соответственно, первый.

  6. buzzkiller

    Поиск irexeс ничего не дал.
    Руками скачиваю пакет из репозитория http://downloads.openwrt.org/attitude_adjustment/12.09/ar71xx/generic/packages/lirctools_0.8.7-1_ar71xx.ipk
    Распаковываю архиватором, лежат 3 файла:
    irsend
    irw
    mode2
    Они же и лежат в директории usr/sbin, irexec там и нет.
    Обидно немного… Явно баг какой-то.

  7. buzzkiller

    Прошу прощения, не там искал, закинул irexec на роутер, при исполении выдает:
    irexec: can't load library 'liblirc_client.so.0'

  8. buzzkiller

    Закинул библиотеку в папку lib и чудо произошло — работает. Премного благодарен! Я уже руки опустил, потратил кучу нервов и времени, значит не зря все.

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

Ваш e-mail не будет опубликован.