- PVSM.RU - https://www.pvsm.ru -

Создаём сетевую звуковую карту с преферансом и поэтессами

Вдохновленный топиками раз [1] и два [2], решил соорудить нечто похожее.

В наличии:
— Один усилитель с колонками
— Один стационарный компьютер
— Один ноутбук
— Желание слушать интернет радио независимо от двух предыдущих пунктов и перетыканию проводов

В результате родился план собрать «audio card over ethernet». Исследовав вопрос совместимости оборудования, выбор пал на роутер TP-link MR3020 и USB аудио-карточку Creative SB Play.

Что из этого получилось:
Создаём сетевую звуковую карту с преферансом и поэтессами

О том, как это получить, добро пожаловать под кат.

Начну сразу с цены. Роутер можно найти за 700 рублей, звуковую карту за 800 рублей, USB hub за 200 рублей. В сумме 1700 рублей или $35. И почему еще никто это на поток не поставил?

Все недостатки прошивки OpenWRT (USB и сборка пакетов) касались лишь предыдущей версии 10.03. Последняя стабильная 12.09 практически идеальна.

Переносим раздел /overlay на USB flash

Свободного места на роутере около 800 kb. Чтобы это нас не стесняло, подключим к роутеру USB flash. Раздел на flash карте предварительно форматируем в ext4. Инструкция уже есть [3], вкратце:

opkg update
opkg install block-mount block-hotplug block-extroot kmod-usb-core kmod-usb2 kmod-usb-ohci kmod-usb-storage kmod-fs-ext4
mkdir /mnt/sda1
mount /dev/sda1 /mnt/sda1
tar -C /overlay -cvf — . | tar -C /mnt/sda1 -xf —

В /etc/config/fstab прописываем

config mount
option target /overlay
option device /dev/sda1
option fstype ext4
option options rw,sync
option enabled 1
option enabled_fsck 0

Перезагружаем роутер и проверяем:

mount | grep sda
/dev/sda1 on /overlay type ext4 (rw,sync,relatime,user_xattr,barrier=1,data=ordered)

Подключаем USB аудиокарточку

Устанавливаем необходимые модули

opkg install kmod-usb-audio kmod-sound-core

К USB hub'у подключаем звуковую карту флэшку, проверяем:

dmesg | grep -i audio
[ 41.080000] usbcore: registered new interface driver snd-usb-audio

Настраиваем pulseaudio

opkg install pulseaudio-daemon

Правим /etc/pulse/system.pa:

load-module module-native-protocol-unix auth-anonymous=1 # для ПО, запускаемого с самого роутера
load-module module-alsa-sink device=hw:0,0 tsched=0 # tsched=0 — грязный хак для устранения тресков и хрипов
load-module module-simple-protocol-tcp port=4712 rate=44100 format=s16le channels=2 # для проигрывания звука с windows
load-module module-rtp-recv # для проигрывания звука с linux устройств по wifi
load-module module-native-protocol-tcp auth-anonymous=1 # для воспроизведения звука с linux устройств по ethernet

Pulseaudio запускается от пользователя pulse, поэтому правим init скрипт для предоставления прав на запись для audio устройств /etc/init.d/pulseaudio:

--- pulseaudio_old 2013-06-19 12:30:18.425539419 +0400
+++ pulseaudio 2013-06-19 12:30:04.077704388 +0400
@@ -19,6 +19,9 @@
                 chmod 0750 /var/lib/pulse
                 chown pulse:pulse /var/lib/pulse
         }
+        [ -d /dev/snd ] &service_start /usr/bin/pulseaudio --daemonize --system --disallow-exit --disallow-module-loading --disable-shm --exit-idle-time=-1
 }

Добавляем pulseaudio в автозагрузку и запускаем:

/etc/init.d/pulseaudio enable
/etc/init.d/pulseaudio start

Добавляем на источнике звука свежеиспеченный audio сервер:

pacmd load-module module-tunnel-sink server=%serverIP%
pacmd set-default-sink 1 # номер может отличаться в зависимости от вывода pacmd list-sink

Пробуем воспроизвести звук.

Учим MPD работать с pulseaudio

Внимание, хардкор! Cкомпилировать MPD можно проще, но я пошел другим путем. Скачиваем исходники OpenWRT:

svn co svn://svn.openwrt.org/openwrt/tags/attitude_adjustment_12.09/

Собираем SDK (в make menuconfig не забываем указать свой роутер и платформу):

cd attitude_adjustment_12.09
make tools/install
make toolchain/install

Получаем feed'ы с приложениями и «устанавливаем» их в свою песочницу:

./scripts/feeds update
./scripts/feeds install pulseaudio
./scripts/feeds install mpd

Dev пакет pulseaudio устанавливает не все библиотеки, поэтому правим package/feeds/packages/pulseaudio/Makefile:

--- Makefile_old        2013-06-19 12:12:00.458287669 +0400
+++ Makefile  2013-06-19 12:07:43.225298052 +0400
@@ -139,7 +139,8 @@
        $(INSTALL_DIR) 
                $(1)/usr/lib/pkgconfig 
                $(1)/usr/include/pulse 
-               $(1)/usr/lib
+               $(1)/usr/lib 
+               $(1)/usr/lib/pulseaudio
        $(CP) 
                $(PKG_INSTALL_DIR)/usr/include/pulse/* 
                $(1)/usr/include/pulse
@@ -149,6 +150,9 @@
        $(CP) 
                $(PKG_INSTALL_DIR)/usr/lib/*.so* 
                $(1)/usr/lib/
+       $(CP) 
+               $(PKG_INSTALL_DIR)/usr/lib/pulseaudio/*.so* 
+               $(1)/usr/lib/pulseaudio/
 endef
 
 define Package/pulseaudio-daemon/install

Правим Makefile для mpd (package/feeds/packages/mpd/Makefile):

--- Makefile_old        2013-06-18 17:47:56.277865458 +0400
+++ Makefile   2013-06-18 17:37:35.037187159 +0400
@@ -49,7 +49,7 @@
   DEPENDS+= 
        +AUDIO_SUPPORT:alsa-lib 
        +libaudiofile +BUILD_PATENTED:libfaad2 +libffmpeg +libid3tag 
-       +libmms +libogg +libshout +libsndfile +libvorbis
+       +libmms +libogg +libshout +libsndfile +libvorbis +pulseaudio-daemon
   PROVIDES:=mpd
   VARIANT:=full
 endef
@@ -137,7 +137,7 @@
        $(if $(CONFIG_BUILD_PATENTED),MAD_LIBS="$(TARGET_LDFLAGS) -lmad") 
 
 TARGET_CFLAGS += -std=gnu99
-TARGET_LDFLAGS += -Wl,-rpath-link=$(STAGING_DIR)/usr/lib
+TARGET_LDFLAGS += -Wl,-rpath-link=$(STAGING_DIR)/usr/lib,-rpath-link=$(STAGING_DIR)/usr/lib/pulseaudio
 
 # use gcc instead of g++ to avoid unnecessary linking against libstdc++
 TARGET_CXX:=$(TARGET_CC)
@@ -160,6 +160,7 @@
        --enable-sndfile 
        --enable-vorbis 
        --enable-vorbis-encoder 
+       --enable-pulse 
        --with-faad="$(STAGING_DIR)/usr" 
        --with-tremor=no 

Запускаем make menuconfig, выбираем Sound/pulseaudio-daemon, Libraries/libffmpeg-mini, а затем Sound/mpd-full

Финальный этап:

make package/mpd/compile
make package/mpd/install

Если всё прошло без ошибок, то мы должны получить готовый пакет bin/ar71xx/packages/mpd-full_0.16.5-2_ar71xx.ipk. Если компилятор на что-то ругается, то запускаем make package/mpd/compile V=99 и смотрим что именно пошло не так.

Копируем пакет на роутер scp bin/ar71xx/packages/mpd-full_0.16.5-2_ar71xx.ipk tplink_ip:/tmp и устанавливаем пакет mpd:

opkg update
opkg install curl
rm /tmp/opkg-lists/attitude_adjustment
opkg install /tmp/mpd-full_0.16.5-2_ar71xx.ipk

Конфирурируем MPD /etc/mpd.conf:

input {
plugin «curl»
}
audio_output {
type «pulse»
name «My Device»
}

Включаем в автозагрузку и запускаем:

/etc/init.d/mpd enable
/etc/init.d/mpd start

Проверяем у себя на linux:

mpc add pub4.di.fm [4]:80/di_latinhouse
mpc play

Или в Windows, установив QMPDClient [5] (имхо лучший мультиплатформенный mpd клиент).

Проблема AAC

Стандартная библиотека libfaad2 проигрывает aac со 100% нагрузкой на процессор, т.к. на роутерах процессоры плохо справляются с вычислением с плавающей точкой. Для таких случаев разработчики библиотеки предусмотрели опцию FIXED_POINT, но разработчики OpenWRT не успели ею воспользоваться перед релизом attitude_adjustment_12.09. В последней версии Makefile для faad2 добавили возможность компиляции с FIXED_POINT. Просто скачиваем последний Makefile:

wget dev.openwrt.org/export/34527/packages/libs/faad2/Makefile [6]

Выбираем в make menuconfig Advanced configuration options -> Target options -> Use software floating point by default и перекомпилируем пакет:

make package/faad2/compile
make package/faad2install

Получаем пакет bin/ar71xx/packages/libfaad2_2.7-2_ar71xx.ipk, устанавливаем его таким же образом, что и mpd (только в данном случае командой opkg upgrade).
Наслаждаемся теплым ламповым звучанием aac.

Подключаем в качестве источника звука Windows

Единственное работоспособное решение транслировать звук на pulseaudio из Windows я нашел здесь [7]. Но к сожалению для этого потребуется купить ПО Virtual Audio Cable.
Запускается это у меня bat'ником:

linco.exe -B 16 -C 2 -R 44100 | nc.exe tplink_IP 4712

Да, есть задержки звука, особенно по WiFi, но при просмотре видео это легко лечится настройками плеера.

Вместо bat файлов можно попробовать запускать linco через srvany. У кого получится — просьба отписаться в комментариях.

Моддинг

Те, кто дружит с паяльником и руками (если уж читаете это, то с руками то наверняка дружите?), могут поместить всё в один корпус. Я решил разобрать китайский USB-hub, отпаять от него лишние USB разъемы, и металлические корпуса оставшихся двух USB разъемов. Таким образом получилось развернуть сами разъемы на 90 градусов.

На самом роутере я отпаял контакты USB разъема от платы, от самой платы протянул провода к USB хабу, а уже от самого USB хаба провел провода на внешний USB разъем. В корпусе роутера я просверлил два отверстия под Jack'и и мне удалось уместить всё достаточно компактно. К сожалению крышку роутера плотно закрыть уже не удается, но для этих нужд умные люди придумали синюю изоленту.

Как это выглядит:
Создаём сетевую звуковую карту с преферансом и поэтессами

Рабочее место в 2 часа ночи:
Создаём сетевую звуковую карту с преферансом и поэтессами

Штука в хозяйстве незаменимая. В планах сделать еще одну такую на кухню, а также подключить OLED дисплей через I2C [8], и IR-receiver через UART.

P.S. Замечания и сообщения об ошибках принимаю в личке.

P.P.S. Кто не хочет компилировать, вот собранные пакеты mpd и libfaad2
rghost.ru/46934574 [9]
rghost.ru/46934558 [10]

Автор: kay

Источник [11]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/linux/37234

Ссылки в тексте:

[1] раз: https://www.pvsm.ru/post/158127/

[2] два: https://www.pvsm.ru/post/181728/

[3] есть: http://wiki.openwrt.org/doc/howto/extroot

[4] pub4.di.fm: http://pub4.di.fm

[5] QMPDClient: http://bitcheese.net/wiki/QMPDClient/

[6] dev.openwrt.org/export/34527/packages/libs/faad2/Makefile: https://dev.openwrt.org/export/34527/packages/libs/faad2/Makefile

[7] здесь: http://gleamynode.net/articles/2228/

[8] I2C: http://wiki.openwrt.org/ru/toh/tp-link/tl-mr3020#adding.i2c.bus

[9] rghost.ru/46934574: http://rghost.ru/46934574

[10] rghost.ru/46934558: http://rghost.ru/46934558

[11] Источник: http://habrahabr.ru/post/184110/