СОДЕРЖАНИЕ

Аудиосистема полупромышленного масштаба

14.01.2018

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

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

Последние варианты, которые мне довелось строить – очень просты и технологичны. За основу берётся linix-сервер, на базе RPi ($30). К нему, через хаб подключается какое-то количество USB-звуковых карт ($1/шт), а выходы звуковых карт заводятся на небольшие китайские усилители ($10). Очень удобно подобное решение совмещать в корпусе 1U, например, от старого свича или оптического кросса. Итоговая цена всего развлечения на 5 помещений - $100. Нужно ещё не забыть про БП. Но он зависит от конкретной конфигурации.

Отдельно хочу отвлечься на серьёзную проблему, с которой мне не удалось справиться. Все относительно простые звуковые карты, которые имеются в продаже, имеют один очень странный дефект – они почти все сделаны на одном чипе C-Media. Чип сам по себе неплохой, но его особенность в том, что в поле iSerial, которое должно содержать уникальный идентификатор данного чипа – записан 0. Поэтому если включить данные звуковые карты в один сервер, то не будет никакой возможности идентифицировать конкретную карту. Это очень неудобно. Исключением из данного правила, по моему опыту, оказался только оригинальный Creative SoundBlaster. У него всё нормально. Да и вообще это лучшая из попадавших ко мне в руки карт. У неё один косяк – она стоит где-то на порядок дороже своих убогих китайских собратьев.

Нет, есть конечно же способ отличить карты друг от друга после подключения. Это номер USB-порта, в который каждая из них включена. Это возможный вариант! Благо, что он не только возможный, но и единственный оставшийся. Но представьте – пришлось вам выключить карты из хаба для каких-то работ. Ну, например, для работ по переносу этого чудо-устройства с настроечного стола в место постоянной дислокации. И если вы перепутаете последовательность подключения карт в хаб, то играть будут колонки не в том помещении. Нет, это очень неудобно.

Вернёмся к linux-серверу. В общем, при некоторой доработке напильником, родная система alsa позволит вам работать с подключенными картами. Из косяков, что мне попались – нельзя объединить больше 4 устройств в одну группу проигрывания (а группа обязательно нужна, поскольку в её отсутствие вы получите жуткий эффект эхо).

Ну и ещё, при каком-то стечении обстоятельств (в котором ещё участвует сам USB-хаб), возникают артефакты при одновременном проигрывании на 5-6 устройствах (я не смог точно локализовать эту проблему, но она иногда всплывала. Помогала замена USB-хаба на более дорогой. Кстати, те что 3.0 – все работали безобразно).

Ну и конечно же тихий ад с адресаций карт, поскольку проигрыватель требовал номер alsa hw для проигрывания, а этот номер менялся после каждой перезагрузки и его нужно было заново вычислять на основании usb-path.

Некоторый дискомфорт, также, доставлял зоопарк USB-карт, которые были от разных производителей и в зависимости от этого менялись наименования системных микшеров. Приходилось уходить на софтовые. Да и сама методология настройки через asound.conf представляет из себя тихий ужас, если, например, делать на каждую карту несколько разных audio-потоков, которые должны играть одновременно (например, музыкальная часть и часть аудио-оповещения).

Но пока дело происходит на одном сервере – справиться с этим можно.

Беда начинает наступать при некотором масштабировании. Допустим появился второй дом. Или мастерская. Или баня. И вы хотите туда также вывести часть аудиосистемы.

Понятно, что тащить в таком случае туда медные провода от существующего сервера будет не лучшим решением. Хотя, если это возможно, то все проблемы снимаются. Но мне не удалось. Нужно было что-то более элегантное.

На помощь пришло решение PulseAudio. На сегодняшний день оно уже является стандартом для X11 GUI от Debian, но я не пользуюсь X11, поэтому для меня это было почти откровением. И мне кажется, что это не просто так, поскольку в самой популярной сейчас версии debian jessie – версия PulseAudio была 5.0. Хотя реально разработчики выпустили уже 11.1. В свежей stretch уже лучше. Там 10.0. Попытки передать звук с PulseAudio 5.0 на PulseAudio 10.0, кстати, оказались успешными. Ну как успешными… Оно заиграло! Правда с задержкой в 23000 ms, но всё-таки заиграло. Ладно, обновился и всё нормализовалось.

В целом – можно порекомендовать решение. В таком формате оно делится на две части. У вас появляется рабочая лошадка в виде RPi, на котором стоит PulseAudio. Настройки в данном случае сокращаются почти до нуля. Это "почти" - это тот самый модуль, которому придётся генерировать конфигурацию на для PulseAudio на основании usb-path, поскольку никакого другого чуда не случилось. При этом в моём случае – PulseAudio даже в 11.1 версии не смогло запуститься с модулем автоматического определения устройств. Оно в режиме отладки беспрерывно чего-то требовало от alsa, но данное желание было односторонним. И запуститься PulseAudio не могло. Так что всё ручками! Но это просто.

Кстати, не зацепитесь случайно за модуль module-alsa-card. Я потратил на него огромное количество времени и насобирал неимоверное число глюков. В том числе у меня при запуске PulseAudio с этими модулями начинали меняться alsa hw id по отношению к usb-path. Абсурд. Видимо я чего-то не понял. По любому - в нём нет ценности для нашего случая. Нам нужны чистые module-alsa-sink. Этот модуль не пытается ничего переделать в системе, а просто позволяет проиграть что-то на нужной нам карте издалека. При этом все остальные модули я отключил, поскольку нам никакой автоматики уже не нужно.

Ну и вторая часть системы – центральный аудио-сервер. Его уже можно строить не на RPi, а на чём-то внятном. Ну, например, в моём случае это был сервер в vSphere. Лишний Debian там ничего не изменил, с минимумом памяти и диском под mp3 коллекцию. Зато скорость запуска плеера на подобном сервере меняется уже на порядки.

На центральном сервере также устанавливается PulseAudio, но поскольку никакой связи с железом нет, то всё становится относительно прозрачно. Мы зацепляем все железные проигрыватели посредством модуля module-tunnel-sink, и получаем возможность играть любой поток на дочерние сервера. Не наступите только на module-tunnel-sink-new. Модуль "–new" имеет какую-то прекрасную ошибку, которая не даёт объединить набор модулей в combine.

Поскольку с автоматизацией опять оказалось не блестяще, то необходимо раз в какое-то время анализировать текущие sink на центральном сервере и по мере их исчезновения (какие-то сложности с рабочими серверами) восстанавливать удалившиеся потоки. А также не забывать править combine-потоки, если вы ими пользуетесь.

Из домашних наработок могу порекомендовать создавать раздельные потоки для проигрывания музыки и проигрывания аудио-оповещений. Это удобно из-за того, что на них задаются изначально разные настройки громкости и если вы хотите послушать музыку "громче", то это не изменит настройку громкости аудио-оповещения. Ну, например, ночью в спальне оно не сработает на 100% мощности. При этом, рекомендую, на момент проигрывания аудио-оповещения выставлять громкость музыки на некий минимум. Создаётся приятный эффект того, что музыкальное сопровождение на момент аудио-оповещения было не выключено, а слегка приглушено. А по окончании аудио-оповещения громкость музыкального канала восстанавливается до предыдущего уровня.

На центральном сервере, конечно же, имеет смысл поставить простейший обработчик очереди, который будет корректно отрабатывать внешние события последовательно. А также и будет отвечать за корректное выставление уровней громкости под каждое событие. Без него всё равно не обойтись, поскольку плеер нужно запускать из-под конкретного юзера (или рута), а если это делать из-под www-data, то проблем будет больше, чем сэкономленного времени.

В целом, если у вас есть какое-то количество свободного времени, то рекомендую попробовать.