Содержание #
1 Цели, задачи и обсуждение возможных реализаций
2 А можно ли без вообще без внешнего усилителя?
3 Что такое MPD и чем он хорош
6 Загрузка и первоначальная настройка JeOS
Дополнение 1: Настройка файервола
Дополнение 2: Настройки для "побитной точности"
Дополнение 3: Настройка cетевого звука
Цели, задачи и обсуждение возможных реализаций #
Имеем цифровую музыкальную библиотеку, выложенную на домашнем NAS. Существует потребность организовать проигрывание этой коллекции через Hi-Fi-аудио. Вывод звука будем выводить на внешний усилитель/ЦАП, к которому подключены стереоколонки. Какие варианты для этого есть?
Самый простой -- взять усилитель с возможностью непосредственного проигрывания с NAS. Идя по этому пути, мы существенно ограничиваем себя в выборе усилителя. Кроме того, управление будет осуществляться только через одно-единственное официальное мобильное приложение, которое существует только под Android/iOS. В лучшем случае будет предоставлен веб-интерфейс. А как быть, если мы хотим управлять системой с домашнего ПК на Линуксе или из альтернативной мобильной ОС?.. Очевидно, что самый простой вариант –- это не значит самый лучший. Нам нужно более гибкое решение, которое не будет настолько ограничивать как в выборе усилителя, так и в выборе способов управления проигрыванием.
Следующим вариантом будет использование уже имеющегося ПК или ноутбука. Поключаемся к NAS по сети, подключаем к нему усилитель и запускаем любимый проигрыватель на нем. Поскольку в усилитель встроен качественный ЦАП, довольно глупо подключать его к ПК по стандартному аналоговому выходу. Нам необходимо подключить его к ПК по цифровому интерфейсу. То есть как наш ПК, так и усилитель должны иметь поддержку одинакового цифрового интерфейса. Вполне рабочий вариант, но есть нюанс: для того, чтобы послушать музыку, нужно включать ПК. Или же держать его всегда включенным.
Очевидным следующим шагом является возложение данной задачи не на большой ПК, а на одноплатник. Действительно, на нем вполне можно запустить плеер –- обычно музыкальные плееры не слишком требовательны к ресурсам. Кроме того, одноплатники с их низким энергопотреблением, бесшумностью и доступностью по цене выглядят идеальными для постоянно работающей системы. Главным их недостатком для наших целей является низкокачественный аналоговый звук. Но нас эта проблема не волнует: мы уже решили, что нам требуется цифровой интерфейс. Поскольку специализированных звуковых выходов на одноплатниках нет, требуется либо использовать звуковые шапки, либо использовать стандартный интерфейс USB-A. Очевидным выбором является второй вариант: во-первых, не требуется дополнительного устройства и, во-вторых, поддержка snd_usb_audio уже давно содержится в "ванильной" ветке ядра Линукс в отличие от драйверов под "музыкальные" шапки, драйвера для которых часто доступны только для Raspberry Pi. Что получаем из ограничений? Усилитель должен поддерживать передачу звука по USB. Не просто иметь USB-порт (для чтения файлов с флешки), а именно поддерживать передачу звука! Вполне разумное ограничение: в современных усилителях поддержка USB-аудио весьма распространена, есть модели в любом ценовом диапазоне. Итак, имея навыки работы с Линуксом в общем и с Репкой в частности, попробуем приспособить ее для нашей задачи.
А можно ли без вообще без внешнего усилителя? #
Да, для получения Hi-Fi-звука возможно использование одноплатников без внешних усилителей. Сушествуют специальные "шапки", которые предназначены именно для этого. Самые популярные и самые доступные по цене -- HiFiBerry и ее клоны. Есть и более дорогие варианты. Но все равно цена даже этих более дорогих шапок не сопоставима с ценами на внешние усилители. Вполне рабочий вариант. Я этим вариантом несколько лет пользовался без необходимости покупать внешний усилитель. Но, как сказано выше, этот вариант подходит только для Raspberry Pi. Дело в том, что драйвера на эти устройства не содержатся в общей ветке ядра, а только в ветке для этих одноплатников. Соответственно, как на Репках, так и на китайских одноплатниках эти шапки просто не заведутся.
Что такое MPD и чем он хорош #
Итак, мы определились что будем использовать Репку в качестве одноплантого компьютера. Теперь нужно определится с музыкальным проигрывателем. Для подобнах задач идеально подойдет MPD. MPD -- это аббревиатура от Music Player Daemon. По своей сути он является музыкальным проигрывателем, который работает как демон ("демон" -- примерно то же самое, что "служба" в Windows). MPD не имеет ни графической оболочки, ни интерактивной командной строки. Задачи MPD сводятся к сканированию библиотеки, управлением очередью треков и управлением и передачей аудиопотока на устройство. При этом весь процесс управления проходит по сети через собственный протокол, работающий поверх TCP. За взаимодействие с пользователями (визуализация, обложки, листы и очереди проигрывания) отвечают внешние клиенты MPD, которые существуют под самые различные платформы на любой вкус -- консольные, консольные с псевдографическим интерфейсом, веб и, конечно же, разнообразные графические. Это делает MPD невероятно гибким, так как им можно одновременно управлять по сети с домашнего ПК, ноутбука, телефона и даже с часов. Причем, под управлением в случае MPD понимается не только стандартные действия -- стоп, пауза, предыдущая/следующая композиция, но и управление очередью проигрывания, листами проигрывания и коллекцией. Кроме того, указанные особенности делают MPD легковесным и нетребовательным к железу. Он написан на С++, потребляет минимум оперативной памяти и почти не нагружает процессор. Подробности об MPD можно узнать на официальном сайте плеера.
К СВЕДЕНИЮ
Стоит отметить, что MPD -- это именно музыкальный проигрыватель, а не платформа для стриминга музыкальных файлов как, например, Navidrome. Хотя MPD имеет возможность проигрывать файлы в поток, он не является многопользовательским в том смысле, что один запущенный экземпляр работает только с одним списком воспроизведения. Хотя технически существует возможность запустить несколько экзепляров MPD с разными настройками, ожидающими на разных портах, но использующих одну и ту же коллекцию.
Выбор дистрибутива #
Определившись с проигрывателем, нужно определиться с ОС, на которой данный проигрыватель мы будем запускать. Сразу стоит оговориться, что вообще существуют специальные аудиофильские дистрибутивы как, например, Volumio и Daphile. Причем, первый также основан на MPD. Но тогда наш выбор железа опять становится ограничен x86 и Raspberry Pi. И потом гораздо интереснее построить систему самому. Так что смотрим, что доступно для Репки. Официальная Репка ОС основана на Ubuntu c графической оболочкой. Благодаря выбору MPD в качестве проигрывателя графическая оболочка нам не нужна. Конечно, можно и из графической Убунты удалить все лишнее и получить систему без графики, но не будем с этим упражняться, посмотрим, что есть из альтернативных ОС. Есть прекрасный Armbian на Репке 3 и даже полновесный Debian на Репка 4. Отличный выбор, но хотелось бы посмотреть в сторону отечественных производителей. Из доступных мы имеем РедОС на Репке 4 и несколько вариантов ОС семейства Альт. Причем, на официальном сайте репки заявлена поддержка только Simply Linux и только для Репки 3. В вики Альта же говорится о поддержке Simply Linux и для Репки 3, и для Репки 4. Но Simply Linux -- это сборка ОС Альт с графическим интерфейсом, нам она не подходит. Для наших целей нужна минимальная ОС и идеальной для таких целей является JeOS, которая входит в стартовые наборы ОС семейства Альт и которая имеет сборки для нужной нам aarch64. Как бы то ни было, несмотря на наш выбор JeOS, абсолютно такой же результат можно получить на любом поддерживаемом дистрибутиве (даже большинство действий будут такими же).
Установка JeOS на Репку 3 #
Скачиваем образ по ссылке.
СОВЕТ
При этом мы используем сборку из стабильной ветки P11, а не из экспериментальной ветки Сизиф. При скачивании обратите на это внимание, чтобы не иметь потом проблем! Далее мы считаем, что скачанный образ находится в следующем каталоге: "/home/user/Downloads/"
Устанавливать ОС мы будем на Репку 3. Просто потому, что у меня есть свободная Репка 3 версии, и ее производительности достаточно. Но процесс установки будет принципиально одинаковым и на Репке 4. С Репкой 4 будет даже чуть проще, так как DTB-файл на Репку 4 уже содержится в образе JeOS, в отличие от Репки 3.
Также нам понадобится официальный загрузчик для Репки 3, который скачиваем отсюда и распаковываем архив. Естественно, нужно брать последнюю доступную по ссылке версию U-boot. DTB-файлы для Репки 3 лежат в том же архиве. Далее мы считаем, что распакованный архив находится в следующем каталоге: "/home/user/Downloads/Uboot."
Все операции мы будем проводить из ОС Линукс. В ОС Альт есть пакет alt-rootfs-installer, который содержит скрипты, автоматизирующие установки стартовых наборов и других дистрибутивов Альт на карту памяти, но чтобы не ограничивать выбор системы, из которой проходит установка, мы будем все делать вручную.
К СВЕДЕНИЮ
Здесь и далее “$” перед командой означает, что эту команду нужно вводить от обычного пользователя. Этот символ вводить не нужно. Скорее всего, вы его уже увидите в своем виртуальном терминале. Символ “#“ означает, что данную команду нужно вводить от рута. Соответственно, этот символ также не нужно вводить вручную.
Вставляем карту памяти, на которую будет устанавливать JeOS, в карт-ридер и поключаем к ПК. Узнаем путь к файлу карты памяти (помним, что в Unix-подобных системах все является файлом, в том числе и файлы всех устройств)
# fdisk -l
Карта памяти будет отображена подобным образом:
Диск /dev/sdd: 59,48 GiB, 63864569856 байт, 124735488 секторов
Disk model: Storage Device
Единицы: секторов по 1 * 512 = 512 байт
Записываем образ на карту памяти с помощью команды dd. Запись нужно делать на все устройство целиком (sdX), а не на раздел (sdX1):
# dd if=/home/user/Downloads/alt-p11-jeos-systemd-20260612-aarch64.img of=/dev/sdX bs=1024 status=progress
ВАЖНО
Важно указать правильный путь к диску, при указании неверного пути будут перезаписаны другие файлы, в том числе можно потерять данные на других дисках!
После того, как запись успешно завершится, на карте памяти будут 2 раздела, первый раздел с файловой системой fat32 (загрузочный раздел) и ext4 (раздел с ОС Альт). Теперь команда fdisk нам выведет:
Устр-во Загрузочный начало Конец Секторы Размер Идентификатор Тип
/dev/sdd1 32768 526335 493568 241M c W95 FAT32 (LBA)
/dev/sdd2 * 526336 8941567 8415232 4G 83 Linux
Дополнительно на карту памяти нужно установить загрузчик U-boot в самое начало диска (MBR):
# dd if=/home/user/Downloads/Uboot/Файл\ загрузчика/u-boot-sunxi-with-spl.bin of=/dev/sdX bs=1024 seek=8
ВАЖНО
Опять же в данной команде нужно внимательно проверить путь к устройству. Также обратите внимание, что запись идет на все устройство sdX, а не на раздел (например, sdX1).
Затем нам нужно записать на устройство DTB-файл для Репки 3. Записать его нужно на раздел с ОС Альт (а не на загрузочный раздел). Для этого создаем пустой каталог, куда будем подключать раздел:
# mkdir /mnt/jeos
Теперь подключаем раздел:
# mount /dev/sdX2 /mnt/jeos
Копируем DTB-файл:
# cp /home/user/Downloads/Uboot/DTB/sun50i-h5-repka-pi3-i2s-v1.6p.dtb /mnt/jeos/boot/dtb/allwinner/sun50i-h5-repka-pi3.dtb
ВАЖНО
Обратите внимание, что мы изменяем название файла после копирования: он должен называться sun50i-h5-repka-pi3.dtb. Также нужно не ошибиться с корректным файлом для версии Репки 3. У меня версия 1.6, поэтому я взял DTB-файл для нее.
Следующее, что нужно сделать -- это задать корректные параметры для загрузки ядра в файле extlinux.conf. Открываем его:
# nano /mnt/jeos/boot/extlinux/extlinux.conf
Находим в файле блок следующего содержания:
label linux
kernel ../vmlinuz
initrd ../initrd.img
fdtdir ../dtb
append root=UUID=cf2e6f26-a238-419c-b603-7d7eb1cc4867 ro
И превращаем его в такой вид:
label linux
kernel ../vmlinuz
initrd ../initrd.img
fdtdir ../dtb
#append root=UUID=cf2e6f26-a238-419c-b603-7d7eb1cc4867 ro
append root=/dev/mmcblk0p2 ro rootfstype=ext4 console=tty1 earlycon
Дополнительно можно вместо timeout 50 выставить timeout 5 (или меньше). Это уменьшит время ожидания выбора нужного пункта меню пользователем при загрузке.
Следующим шагом разрешим суперпользователю входить по ssh (потом мы это разрешение уберем):
# nano /mnt/jeos/etc/openssh/sshd_config
В открывшемся файле находим закомментированную строку "#PermitRootLogin without-password". Ниже нее вводим следующий текст:
PermitRootLogin yes
На этом мы готовы приступить к загрузке системы и окончательной настройке и доустановке ПО. Отключаем карту памяти и ждем, пока все данные на нее запишутся:
# umount /mnt/jeos
Опционально удаляем созданный каталог, он нам больше не понадобится:
# rmdir /mnt/jeos
К СВЕДЕНИЮ
Это последнее действие от суперпользователя на ПК, с которого мы проводим настройку. Все дальнейшие действия на этом ПК мы будем проводить от обычного пользователя. Поэтому нужно либо открыть новый сеанс терминала, либо в текущем сеансе ввести команду exit.
Загрузка и первоначальная настройка JeOS #
Вставляем карту памяти в Репку, вставляем в нее сетевой кабель (Ethernet) и включаем ее. ОС Альт настроена на автоматическое использование DHCP. Поэтому после включения проверяем, что диоды сетевой карты моргают, и заходим на страницу домашнего маршрутизатора, чтобы узнать, какой IP-адрес он выдал Репке. В нашем случае будем считать, что адрес 192.168.1.3, в дальнейшем будем использовать его.
Проверяем, что Репка запустилась и доступна по сети. Для этого заходим по ssh на Репку (команду ssh мы запускаем от обычного пользователя, но подключаемся мы к пользователю root на Репке):
$ ssh root@192.168.1.3
Получаем предупреждение, что сертификат данного компьютера не знаком нашему компьютеру:
The authenticity of host \'192.168.1.3\' can\'t be established.
ED25519 key fingerprint is ...
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
Принимаем сертификат (вбиваем "yes" и жмем enter). Далее вводим пароль суперпользователя (в JeOS он по умолчинию "altlinux" без кавычек) и входим на удаленный ПК. Убедившись, что мы можем подключиться к Репке удаленно, выходим из нее и копируем на ssh-сервер открытый ключ своего пользователя для доступа без пароля:
$ ssh-copy-id root@192.168.1.3
Для этой операции опять попросит ввести пароль пользователя root. Когда данная операция завершится успешно, мы сможем входить с данного ПК от данного пользователя не вбивая пароля. Повторяем операцию для других желаемых пользователей/ПК или вручную вводим соответствующие открытые ключи в ~/.ssh/authorized_keys на Репке.
После этого заходим на устройство по ssh и обновляем JeOS:
# apt-get update
# apt-get dist-upgrade
Вводим 'Y' и дожидаемся окончания обновления системы.
Далее нам будет нужно править конфигурационные файлы, для чего понадобится консольный редактор. Пожалуй, самый простой -- nano, но он не установлен по умолчанию. Сейчас мы это сделаем. Если вам комфортно работать в Vi/Vim, то ничего ставить не нужно: он идет из коробки.
# apt-get install nano
Проверим настройки времени:
# timedatectl status
Пример вывода:
Local time: Вс 2026-08-09 18:05:18 UTC
Universal time: Вс 2026-08-09 18:05:18 UTC
RTC time: Вс 2026-08-09 18:05:19
Time zone: UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
Время синхронизируется по сети, служба синхронизация времени работает. С этим проблем нет, но тут нас не устраивает часовой пояс. Поэтому выставляем свой (доступные часовые пояса можно узнать, просматривая их в каталоге /usr/share/zoneinfo):
# ln -sf /usr/share/zoneinfo/Europe/Moscow /etc/localtime
Теперь зададим свое имя хоста (в моем случае "snd"):
# hostnamectl set-hostname snd
При необходимости, можно задать доменное имя в файле /etc/hosts, но скорее всего вам это не нужно.
Теперь подкорректируем опции подключения дисков в файле /etc/fstab. Это нужно для более щадящего режима работы карты памяти:
# nano /etc/fstab
В открывшемся файле добавляем ",noatime" (через запятую, это не опечатка) в строчки подключения корневого раздела ("/") и загрузочного раздела ("/boot/efi"). После правки сроки должны выглядеть так (UUID может быть другими, их менять не нужно):
UUID=cf2e6f26-a238-419c-b603-7d7eb1cc4867 / ext4 defaults,noatime 1 1
UUID=F632-C19B /boot/efi vfat umask=0,quiet,showexec,iocharset=utf8,codepage=866,noatime 1 2
Теперь настроим journald, чтобы его конфиги не занимали слишком много места:
# tee /etc/systemd/journald.conf > /dev/null <<EOF
[Journal]
Storage=persistent
SystemMaxUse=256M
SystemKeepFree=256M
RuntimeMaxUse=64M
Compress=yes
EOF
# systemctl restart systemd-journald
Подключение к NAS будет происходить по NFSv4. Подключать мы их будем с помощью systemd-mount в режиме автопоключения. Каталог будет автоматически подключаться при обращении к нему и автоматически отключаться, если обращений не происходит. Считаем, что NFS-сервер находится по адресу 192.168.1.1, а путь на сервере до сетевого диска с музыкой -- /srv/nfs/music. Соответственно, подключаем сетевой диск к каталогу /mnt/nfs/music.
# mkdir -p /mnt/nfs/music
# tee /etc/systemd/system/mnt-nfs-music.mount > /dev/null <<EOF
[Unit]
Description=Music NFS folder
After=network.target network-online.target nss-lookup.target
Requires=network.target network-online.target nss-lookup.target
[Mount]
Where=/mnt/nfs/music
What=192.168.1.1:/srv/nfs/music
Type=nfs4
TimeoutSec=5
ForceUnmount=true
[Install]
WantedBy=multi-user.target
EOF
# tee /etc/systemd/system/mnt-nfs-music.automount > /dev/null <<EOF
[Unit]
Description=Automount Music NFS folder
[Automount]
Where=/mnt/nfs/music
TimeoutIdleSec=300
[Install]
WantedBy=multi-user.target
EOF
# systemctl daemon-reload
# systemctl enable --now mnt-nfs-music.automount
Теперь проверяем, что поключение проходит нормально. Мы должны увидеть содержимое нашего сетевого диска:
# ls /mnt/nfs/music
Если этого не происходит, нужно смотреть ошибки в systemctl/journalctl и проверить настройки сервера.
К СВЕДЕНИЮ
Подключение через SAMBA можно осуществить подобным же способом, только в юните mount нужно указать "Type=cifs", а также дополнительно нужно указать строку
"Options=username=пользователь,password=пароль,ro". И есть отличия в указании сетевого пути: если в случае NFS мы использовали доветочие:
"What=192.168.1.1:/srv/nfs/music", то для SAMBA двоеточие указывать не нужно, а сам путь в Windows-стиле начинается с двух косых черт:
"What=//192.168.1.1/Users/username/share".
Меняем ядро на версию, созданную специально для Репки 3:
# update-kernel -t repka
Выбираем Y, несмотря на предупреждения, дожидаемся установки нового ядра и после этого перезагружаем Репку:
# reboot
Сеанс отваливается. Дожидаемся перезагрузки и заходим по ssh снова. Проверяем, что мы загрузились на новом ядре:
# uname -a
Вывод будет содержать "repka-alt3".
Запретим удаленный вход для суперпользователя на Репку без пароля. Для этого в /etc/openssh/sshd_config удаляем созданную нами ранее строку "PermitRootLogin yes" И возвращаем (или раскомментируем) первоначальную строку "PermitRootLogin without-password". Далее перезапускаем демон ssh для того, чтобы изменения были приняты:
# systemctl restart sshd
К СВЕДЕНИЮ
Чтобы проверить, что доступ на Репку теперь возможен только по ключу тем пользователям/компьютерам, которые внесены в authorized_keys, нужно попробовать войти от другого пользователя или с другого ПК. Даже после введения правильного пароля мы должны увидеть "Permission denied, please try again".
Наконец, нам нужно сменить пароль суперпользователя.В сеансе ssh на Репке вводим команду passwd и далее вводим новый пароль (никакие вводимые символы отображаться не будут). Нажимаем Enter. Затем команда просит повторно ввести данный пароль, что мы и делаем.
Установка и настройка ALSA #
Для того, чтобы можно было работать со звуком, нам нужна ALSA. Поскольку звук будет у нас выводить одно-единственное приложение, MPD, то нам не требуются сложные системы типа PulseAudio или PipeWire, которые к тому же микшируют звук (чего мы хотим по-максимуму избежать).
# apt-get install alsa-utils alsa-plugins aplay
Соглашаемся с установкой зависимостей, дожидаемся окончания установки. Переходим к настройке звука. На данный мамент alsa и все утилиты к ней мы уже установили.
Теперь перезодим непосредственно к усилителю. Как уже обсуждалось выше, для наших целей усилитель должен поддерживать протокол USB Audio. В качестве примера дальше будет рассмотрен усилитель Premiera A3S. Подключаем усилитель по USB и проверяем, что он обнаружен. Команда lsusb должна показать что-то вроде:
Bus 001 Device 002: ID 20b1:30be XMOS Ltd A3S
Если мы видим усилитель, проверяем, как он отображается в alsa:
# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Codec [H3 Audio Codec], device 0: CDC PCM Codec-0 [CDC PCM Codec-0]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: A3S [A3S], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 2: sun9ihdmi [sun9i-hdmi], device 0: SUN9I-HDMI PCM i2s-hifi-0 [SUN9I-HDMI PCM i2s-hifi-0]
Subdevices: 1/1
Subdevice #0: subdevice #0
То есть наше устройство -- card 1, subdevice 0. Порядок устройств может меняться при переподключении и(или) перезагрузке. Чтобы не было сюрпризов впоследствии, зафиксируем первый номер за усилителем. Для этого нужно выставить номер для модуля ядра snd-usb-audio (усилитель подключется именно как стандартная USB-звуковая карта) в файле /etc/modprobe.d/alsa-modindex.conf:
# nano /etc/modprobe.d/alsa-modindex.conf
В файле находим и раскомментируем следующую строку, а также изменяем значение переменной index на 1 (если этой строки в какой-то версии JeOS не оказалось, нужно ее внести):
options snd-usb-audio index=1
ВАЖНО
Ни в коем случае не выставляйте значение 0 в этой строке! Это приведет к тому, что усилитель просто пропадет из списка устройств alsa, так как нулевой номер в Репке зарезервирован под встроенный кодек H3
Поскольку усилитель и так определился под номером 1, перезагружаться не нужно. Если бы номер был другой, то следовало бы перезагрузать Репку командой reboot, переподключиться к Репке по ssh и проверить, что усилитель имеет нужный номер в выводе aplay -l.
Запомним этот номер, мы его пропишем в настройках mpd в строке "device "hw:1,0""
К СВЕДЕНИЮ
Здесь мы не пользуемся утилитой alsamixer, так так устройство не имеет настроек, о чем нам alsamixer и говорит: "This sound device does not have any controls."
Установка и настройка MPD #
Теперь приступим к конечной цели: установке и настройке mpd. Устанавливаем сам проигрыватель MPD:
# apt-get install mpd
Настраиваем конфигурационный файл mpd:
# nano /etc/mpd.conf
В нем нужно прописать следующие переменные (строки, где эти переменные уже установлены по умолчанию, либо удаляем, либо закомментирываем):
music_directory "/mnt/nfs/music"
bind_to_address "any"
port "6600"
user "_mpd"
auto_update "yes"
audio_output {
type "alsa"
name "External DAC"
device "hw:1,0"
mixer_type "software"
auto_resample "no"
auto_format "no"
}
#mixer_type "alsa"
Тут мы установили путь к каталогу с музыкой, указали mpd ожидать комманд по всем интерфейсам, запускать mpd от пользователя _mpd (пользователь уже есть) и указали mpd обновлять коллекцию как только он обнаружит изменения в каталоге с музыкой (к сожалению, для сетевых каталогов данная функция не работает). Еще мы прописали конкретное устройство вывода alsa и отключили строку "mixer_type "alsa"". Тип микширующего устройства мы прописали в настройках аудио выхода. В настройках MPD в JeOS по умолчанию MPD выводит звук
через подсистему alsa. Это нам и нужно, так как мы не планируем использовать только один интерфейс только с одним источником звука. По этой причине настройку pulseaudio или pipewire мы рассматривать не будем: они нам просто не нужны.
К СВЕДЕНИЮ
Данная настройка не дает "побитную точность" обычно требуемую аудиофилами, но является разумным компромисом между качеством и удобством. Подробнее о "побитной точности" см. в.#_2
Теперь все готово. Можем запускать (и выставлять автозакуск при старте компьютера) демон mpd и проверять его работу:
# systemctl enable --now mpd
# systemctl status mpd
Теперь настриваем любимый клиент mpd и проверяем его работу. Все должно работать.
Что дальше? #
На этом, в принципе, можно и остановиться. Но можно сделать еще несколько необходимых настроек:
Настройка файервола #
Так как мы имеем дело с серверной машиной, имеет смысл настроить файервол. Запускать будем следующим образом: создадим скрипт для правил в домашнем каталоге пользователя root и затем будем запускать скрипт из службы systemd, которую также создадим. На JeOS iptables уже установлен из коробки, нам нужно только прописать правила и службу для запуска этих правил. Создаем скрипт:
# tee /root/iptables.rules > /dev/null <<'EOF'
#!/bin/sh
# Здесь нужно ввести данные своей сети
export LAN=192.168.1.0/24
# Порт который мы открываем, должен совпадать с тем, который мы задали в настройках MPD (по умолчанию 6600)
export MPD_PORT=6600
# Скорее всего, DHCP сервером будет маршрутизатор, поэтому нужно выставить адрес маршрутизатора
export DHCP_SERVER=192.168.1.1
iptables -F
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m state --state INVALID -j DROP
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
# MPD
iptables -A INPUT -s $LAN -p tcp --dport $MPD_PORT -j ACCEPT
# NFSv4
iptables -A OUTPUT -d $LAN -p tcp --dport 2049 -j ACCEPT
# SSH
iptables -A INPUT -s $LAN -p tcp --dport 22 -j ACCEPT
# Ping
iptables -A INPUT -s $LAN -p icmp -j ACCEPT
iptables -A OUTPUT -p icmp -j ACCEPT
# NTP
iptables -A OUTPUT -p udp --dport 123 -j ACCEPT
iptables -A INPUT -p udp --sport 123 -j ACCEPT
# enable UDP traceroute rejections to get sent out
#iptables -A INPUT -p udp --dport 33434:33523 -j REJECT
# Allow UDP traceroute
#iptables -A OUTPUT -p udp --dport 33434:33523 -j ACCEPT
#iptables -A INPUT -p udp --dport 33434:33523 -j ACCEPT
# DNS
iptables -A OUTPUT -p tcp --dport 43 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
# dhcp
iptables -A OUTPUT -d $DHCP_SERVER -p udp --dport 67:68 -j ACCEPT
# http for apt-get
iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
EOF
Далее создаем службу systemd для запуска скрипта:
# tee /etc/systemd/system/iptables.service > /dev/null <<EOF
[Service]
Type=oneshot
After=libvirtd.service,virtnetworkd.service,network.service
RemainAfterExit=yes
ExecStart=/root/iptables.rules
[Install]
WantedBy=multi-user.target
EOF
Теперь меняем права на скрипт и запускаем службу:
# chmod 700 ~/iptables.rules
# systemctl daemon-reload
# systemctl enable --now iptables.service
Настройки для "побитной точности"
Как правило для передачи на Hi-Fi-усилитель стараются добиться "побитной точности" (Bit Perfect) передачи звука. Под этим термином скрывается, что мы стараемся передать звук на усилитель как можно точнее, дальше всю работу будет делать он. Для этого мы должны исключить любое вмешательство в передаваемый звуковой поток программных средств на нашей Репке. По факту это означает следующее:
-
выставление всех настроек alsamixer в "нулевое" положение (0 dB -- чаще всего это означает 100 %, но бывают и исключения) или в положении "Off"/"Disabled" (как уже сказано ранее, усилитель Premiera A3S не имеет настроек, но если ваш усилитель или другое звуковое устройство их имеет, то это нужно сделать);
-
настройка MPD:
В файле mpd.conf в настройках аудио выхода нужно указать следующие параметры:
mixer_type "null"
auto_resample "no"
auto_format "no"
# format "44100:16:2" # (следует закомментировать или удалить данную строку)
К СВЕДЕНИЮ
Можно поэкспериментировать с опцией "mixer_type "hardware"". Она позволяет MPD отдавать команды изменения громкостью самому усилителю. Но для того, чтобы этот режим работал, нужно чтобы усилитель поддерживал управление громкостью через протокол USB Audio, чего на усилителе Premiera A3S нет.
ВАЖНО
Указание значение "null" для mixer_type обязательно! Эта опция позволяет MPD и, соответственно, его клиентам корректно отображать и изменять громкость звука, но при этом это число ни на что в самом MPD не влияет. Если, например, выставить значение "disabled", то это приведет к тому, что MPD будет всегда передавать значение громкости "-1", что не всегда корректно отображается клиентами и не оставляет клиентам возможности ваставлять значение громкости.
Дополнительно в любом случае нужно выключить опции "replaingain" и "volume_normalization" в главном разделе файла mpd.conf (так как эти опции по определению вносят искажения в громкость звука):
replaygain "off"
volume_normalization "no"
Обратной стороной получения "побитной точности" является то, что регулировать громкость с помощью MPD мы не сможем: вся регулировка громкости будет проходить через усилитель. В настройках ниже мы отключаем управление громкостью с помощью проигрывателя MPD. При этом громкость на клиенте MPD будет отображаться, и ее можно будет изменить, но изменение громкости на клиенте ни к чему не приведет. Однако данное ограничение можно обойти. Дело в том, что усилитель Premiera A3S имеет чип Wiim/Linkplay, который работает по протоколу UPnP/AV. То есть мы можем оправлять команды усилителю изменять громкость прямо с Репки по сети. А поскольку мы не просто отключили управление громкостью на MPD, а одновременно с этим оставили возможность клиентам управлять громкостью (просто это управление не будет иметь на MPD никакого эффекта), нам нужно написать утилиту, которая будет подключаться к MPD в качестве клиента, считывать текущее значение громкости и передавать его на усилитель по сети. Утилиту, написанную на go для Premiera A3S (бинарную сборку под aarch64 и ее исходный код) можно скачать здесь. Но прежде, поскольку мы уже настроили правила iptables и применили их, нам нужно разрешить несколько соединений:
- исходящие tcp на порт 443 -- для скачивания rpm-пакета (после скачивания пакета эту строку можно удалить или закомментировать).
- исходящие udp на широковещательный адрес 239.255.255.250 и порт 1900 -- для сканирования устройств в сети.
- входящие udp для всей сети (в нашем примере 192.168.1.0/24) -- для получения ответов при сканировании устройств (вообще-то стандарт требует отвечать на фиксированный порт 1900, но многие устройства так не делают и вместо этого отвечают на тот же порт, с которого пришел широковещательный запрос. А поскольку порт эфемерный (выбирается динамически), то и открывать мы должны всю подсеть. После сканирования это правило следует удалить или закомментировать!)
- исходящие tcp для всей сети (192.168.1.0/24) -- поскольку мы не знаем заранее, какие порты определены для различных служб UPnP на устройствах в сети, а при сканировании устройств нам требуется с этих портов загрузить файл описания, открываем все. После сканирования также нужно удалить или закомментировать это правило!)
- входящие tcp на порт, заданный в /etc/upnpvol.conf в переменной upnp_port (по умолчанию 8080) -- для прослушивания событий от усилителя (также можно прописать правило только для фиксированного IP-адреса усилителя).
- исходящие tcp на IP-адрес усилителя -- для UPnP-сообщений (SOAP), устанавливающих громкость на устройстве и считывающих гломкость с устройства (можно дополнительно прописать порт с устройства, его можно узнать из результатов сканирования устройств в утилите).
- Для соединения MPD ничего открывать не нужно, так как он установлен на том же устройстве.
К СВЕДЕНИЮ
Естественно, что для управления по сети через протокол UPnP усилитель Premiera A3S должен быть подключен к домашней сети по Wi-Fi или Ethernet. Также ему на маршрутизаторе следует выдать статический IP-адрес. Далее считаем, что его адрес 192.168.1.4.
Действуем поэтапно. Сначала откроем порты для сканирования и скачивания пакета. Добавляем следующие строки в конец файла /root/iptables.rules:
# https
iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT
# upnpvol
iptables -A OUTPUT -p udp -d 239.255.255.250 --dport 1900 -j ACCEPT
iptables -I INPUT -s 192.168.1.0/24 -p udp -j ACCEPT
iptables -I OUTPUT -d 192.168.1.0/24 -p tcp -j ACCEPT
Загружаем исправления правил iptables, затем скачиваем и устанавливаем программу:
# ~/iptables.rules
# wget --content-disposition -L https://gitflic.ru/project/redfox1914/upnpvol/release/9b818066-f3a5-46c6-8e94-9cdd8777c499/86f950c4-a777-4711-aa20-49687ba6fa01/download
# apt-get install ./upnpvol-1.0.0-alt1.aarch64.rpm
Запускаем сканирование устройств. Программа выводит список найденных устройств, пометив '*' те устройства, в которых есть служба управления звуком. Выбираем устройство (в данном списке 2). Программа предлагает проверить его на возможность управления звуком. Соглашаемся, после успешного завершения проверки устройство сохраняется для дальнейшего использования:
# upnpvol --scan
The scanning has completed. Found 3 devices.
─┬─ Devices list
├─ (0) XXXXXXXXXXXX (192.168.1.XX) at http://192.168.1.XX:5200
├─ (1) XXXXXXXXXXXX at http://192.168.1.X:1900
└─ (2) * A3S FE92 at http://192.168.1.4:49152
* - device has a volume adjustment service
Select a device index
Enter 'show <index>' to see a device datails
Enter 'list' to show the device list again
Enter 'scan' to scan for devices again
Enter 'test <index>' to test a device
Enter 'quit' or 'exit' to quit:
2
Do you want to test the device prior to selection (Y, n)?
Y
Testing device A3S FE92 at http://192.168.1.4:49152...
Getting the current volume... ( 28) success.
Getting the mute state... (false) success.
Setting the volume to 5... success.
Muting the device... success.
Returning the original mute state... success.
Returning the original volume state...success.
All tests have passed successfully.
Device 2 (A3S FE92 at http://192.168.1.4:49152) is selected. Now you can use it.
Run this application in scanning mode again to change the device if needed.
В данном выводе нужно обратить внимание на номер порта для службы: 49152. Именно его мы будем открывать далее для взаимодействия с усилителем. Опять правим /root/iptables.rules, не забыв закомментировать правила, которые нам нужны были для сканирования (для последующих сканирований, если нужно, их можно опять расскомментировать):
# https
#iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT
# upnpvol
#iptables -A OUTPUT -p udp -d 239.255.255.250 --dport 1900 -j ACCEPT
#iptables -I INPUT -s 192.168.1.0/24 -p udp -j ACCEPT
#iptables -I OUTPUT -d 192.168.1.0/24 -p tcp -j ACCEPT
iptables -A INPUT -s 192.168.1.4 -p tcp --dport 8080 -j ACCEPT
iptables -A OUTPUT -d 192.168.1.4 -p tcp --dport 49152 -j ACCEPT
Наконец, опять загружаем исправления правил iptables и запускаем программу в режиме демона (демон будет автоматически загружаться при загрузке Репки). После этого звук в MPD на усилителе должен автоматически синхронизироваться, и любое изменение громкости на любой строне должно приводить к соответствующему изменению громкости на другой стороне.
# ~/iptables.rules
# systemctl enable --now upnpvol.service
Настройка cетевого звука #
Как PulseAudio, так и его замена PipeWire поддерживают передачу звука по сети. Поэтому возможно сделать так, чтобы Репка выводила звук не только от MPD, но также и с других устройств (например, ПК под управлением Линукса) в сети. Для этого потребуется установить и настроить PulseAudio и(или) PipeWire для работы в режиме демона от рута. Однако, оба звуковых сервера по своей сути вносят изменения в звуковой поток. При этом для улучшения качества стоит настроить одновременное использование звуковой карты из-под alsa для MPD и из-под звукового сервера.