Иногда у меня, как у звукача аниме/гик фестивалей/конвентов, появляется задача обеспечить звуком небольшой ивент, на площадке которого нет вообще ничего из оборудования. Такие патички довольно лайтовы и располагают к экспериментам. Так, для нашего осеннего опенэйра я выбрал следующий (весьма непривычный) опенсорсный сетап, который в итоге отлично сработал:
- Колонка 50 Вт
- Два микрофона
- Аудиоинтерфейс из серии BEHRINGER U-PHORIA
- Ноутбук на линуксе
- Ardour в качестве микшера и хоста плагинов
- Calf Studio Gear для обработки звука
- JACK в качестве звукового сервера
- VLC в качестве основного плеера
Идея делать микшер из простейшего аудиоинтерфейса на опенсорсном софте мне настолько понравилась, что я решил поделиться.
Why?
- Это интересно и познавательно! Вы можете сделать свой собственный FOSS-микшер не хуже серьёзных девайсов.
- Можно использовать почти любые плагины.
- Не надо арендовывать и таскать дополнительную бандуру (аппаратный микшер).
- Меньше проводов => меньше шумов.
- Полностью всё управление шоу в одном месте. Простор для автоматизации a-la QLab.
Однако, это же и минус: если посреди шоу выходит из сторя ноут, то наступает полный блэкаут. Даже микрофоны перестают работать. Решения нет: надо эксплуатировать аккуратно, много тестить до ивента и подготовить резервный ноут...
RealTime Linux Kernel
Обработка живого звука на бытовом железе обычно связана с одним неприятным эффектом: задержкой вывода. Чем больше задержка, тем сложнее человеку говорить в микрофон, так что, для комфортной работы ведущих, необходимо её минимизировать. Задержка вызвана буферизацией, а уменьшение буфера приводит к его периодическому опустошению или переполнению (xrun), что звучит как 100-1000мс громкого треска, то есть, неприемлемо.
С обычным ядром Linux, xrun'ы у меня возникают примерно раз в пару минут даже при очень большом буфере. Не знаю с чем это связано, но так точно не пойдёт. Можно было бы докопаться до сути и собрать своё ядро без лишнего мусора, однако, наиболее простым plug-and-play решением является Real-Time ядро Linux. На сайте JACK пишут, что RT-режим звукового сервера работает даже на обычном ядре, но точно не из коробки. Первое, что мы сделаем для подготовки системы к обработке живого звука — установим RT-ядро и перезагрузимся в него:
TL;DR
# Debian
sudo apt update && sudo apt install linux-image-rt
sudo reboot # select the 'rt' kernel in GRUB
# Ubuntu
sudo apt update && sudo apt install linux-lowlatency
sudo reboot # select the 'rt' kernel in GRUB
# CentOS
sudo dnf install centos-release-stream
sudo sed -i 's/enabled=0/enabled=1/' /etc/yum.repos.d/CentOS-Stream-RealTime.repo
sudo dnf install kernel-rt
sudo reboot # select the 'rt' kernel in GRUB
# Ubuntu Studio, AVLinux
sudo reboot # select the 'rt' kernel in GRUB
Longread
- В Debian пакет называется
linux-image-rt
. - В RHEL-семействе (Fedora, CentOS, etc.) пакет называется
kernel-rt
- Придётся подключить дополнительный репозиторий: CentOS Stream 8 — RealTime или Planet CCRMA Core (для Fedora).
- В Ubuntu от полноценного RealTime отказались по соображениям DoS-безопасности, но там есть квази-realtime ядро: пакет называется
linux-lowlatency
.
- В Ubuntu Studio и AVLinux, lowlatency kernel установлен по умолчанию.
После установки соответствующего пакета, в Вашем GRUB появится новый пункт с RT-ядром. Для повседневной работы RT-ядро не рекомендуется. На это есть как минимум две причины:
- Есть опасность, что какое-то приложение специально (или по ошибке) повесит всю систему, нагрузив её на 100% с максимальным приоритетом. Хотя камон, как будто десктопный линукс никогда не фризится на обычном ядре… Но, типа, вероятность меньше. Не думаю, что это прям серьёзный аргумент, однако, именно из-за этого в убунте вообще нет RT-ядра.
- Некоторые модули ядра могут не поддерживаться. Например, у меня на CentOS 8 в rt-ядре нет Wi-Fi. Иногда это даже удобно: можно с первого взгляза на верхнюю панельку GNOME определить что за ядро сейчас загружено. Однако, в CentOS 8 само ядро очень недавно добавили, так что может чуть позже завезут и модулей.
Если у Вас пока нет на ноуте никакого линукса, но Вы хотите его поставить ради микшера, лучше выбрать какой-нибудь мультимедиа-ориентированный дистрибутив, где всё уже из коробки оптимизировано под low latency: AVLinux или Ubuntu Studio.
Sound Server
Окей, вы добились работоспособности Real-Time ядра в Вашем дистрибутиве Linux, что дальше?
Далее нам потребуется звуковой сервер: это та программа, которая связывает звуковоспроизводящие (и звукослушающие) программы с "железным" аудиоинтерфейсом. Именно звуковой сервер отвечает за буферизацию (которая приводит к задержке вывода) и коммутацию входов/выходов.
TL;DR
# Debian, Ubuntu
sudo apt update
sudo apt install jackd pulseaudio-module-jack
# CentOS, Fedora
sudo dnf install jack-audio-connection-kit jack-audio-connection-kit-example-clients
# Ubuntu Studio, AVLinux
: # Preinstalled
For CentOS: Disable memory limits
Longread
Звуковых серверов много. В десктопном линуксе по умолчанию обычно работает связка ALSA+PulseAudio. ALSA ближе к железу, PulseAudio ближе к прикладному ПО. Для простых задач коммутации динамиков и микрофонов в браузеры и дискорды это работает сносно, но, как писал @merlin-vrn в комментариях к своей замечательной статье Интернет-радио с множеством ведущих из разных городов и звонками в прямом эфире (которая в далёком 2014м побудила меня заниматься звуком на линуксах),
I pronouce pulseaudio as pshhrrhrhshrhhhh…
И это отчасти правда даже в 2020-м: во время тестов пару раз у меня возникала ситуация, когда демон PulseAudio вешал всю аудио-подсистему и сильно грузил процессор, хотя никто его вообще не трогал. Если когда-нибудь PulseAudio умрёт, мне кажется, мир станет чуточку лучше (надежда есть). Я допускаю, что мы просто не умеем его готовить, но чистота архитектуры, производительность, гибкость и удобство JACK Audio Connection Kit сделало именно его стандартом отрасли проф. аудио на линуксе.
Устанавливаем пакет jackd
(для debian и ubuntu; также может называться jack-audio-connection-kit или просто jack). В системе должна появиться команда jackd
(jack daemon). В AVLinux и Ubuntu Studio он уже установлен, ничего делать не надо.
Если в Вашем дистрибутиве есть QjackCtl, можете тоже поставить. Эта программа предоставляет GUI к JACK, что помогает его настраивать и коммутировать каналы. Однако мы будем работать без неё, поскольку в CentOS её нет, компилировать лень, и без неё можно обойтись.
Инсталлятор JACK по максимуму подготавливает систему к работе в RealTime, но есть одна вещь, которую он упускает (по крайней мере на CentOS). Если при старте jackd
или Ardour появляется ворнинг Cannot allocate memory
, значит не применился лимит на максимальный объем выделенной оперативки. Проверить можно командой ulimit -l
: если всё ок, она выводит семизначное число не первых миллионов или unlimited
. По идее, лимиты должны настраиваться файлом /etc/security/limits.d/95-jack.conf
, который JACK успешно создаёт, но на CentOS при работе в GNOME, лимиты из SystemD почему-то перекрывают лимиты из /etc/security/limits.conf
, так что нужно их отдельно настроить в /etc/systemd/
:
# cat << EOF > /etc/systemd/user.conf.d/limits.conf
[Manager]
DefaultLimitMEMLOCK=4294967296
EOF
# cat << EOF > /etc/systemd/system.conf.d/limits.conf
[Manager]
DefaultLimitMEMLOCK=4294967296
EOF
# reboot
Ardour: Our DAW
В качестве микшера будем использовать Ardour. Из альтернатив имеется Non Mixer, но это какая-то совсем отдельная вселенная: я туда не заныривал и слышал, что там пока сыровато. Ardour — наш бро. Это бесплатная опенсорсная программа для профессиональной работы со звуком. По возможностям, удобству и дизайну интерфейса она не уступает коммерческим альтернативам под Windows и MacOS, так как у команды разработчиков Ardour есть финансирование. Схема монетизации Ardour весьма хороша: установщик не-триального Ardour можно скачать только за деньги, а исходный код с минимальными инструкциями по компиляции — бесплатно. Таким образом те, кто не может или не хочет хакать исходники могут заплатить сколько могут и максимально быстро получить готовую к работе DAW, а те, кто готов поменять деньги на время (и не считают необходимым поддерживать разработчиков) могут самостоятельно скомпилировать программу и пользоваться ей бесплатно. Вот она — настоящая свобода!
Установка из установщика тривиальная, а с запуском сейчас будем разбираться. Ура, наконец-то будут картинки! Запускаем Ardour и создаём новую сессию "Live" из Empty Template (либо Advanced Session, если хочется глубоко вникнуть в роутинг):
Выбираем JACK с какими-нибудь такими настройками:
- Почему 44100?
- На моей системе
alsa_in
(про него в конце) писал, что ресемплирует, и заставить его работать в 48 kHz не получалось. А если сделать весь пайплайн в 44.1 kHz, удаётся сократить количество бесполезных преобразований. Если можете, используйте 48 kHz: некоторым плагинам это больше нравится, да и задержка меньше. Впрочем, Ваши слушатели гарантированно не почувствуют разницы.
- На моей системе
- Почему буфер на 64 сэмпла?
- Технический минимум — 32 сэмпла. И это даже работает. Однако, с таким маленьким буфером есть немалый шанс словить xrun. При 64 сэмплах, задержка вывода должна составить 1.5 мс. За такое время звук успевает распространиться всего на полметра, так что такая задержка точно не будет заметна. Достаточно подойти на полметра ближе к монитору, чтобы её компенсировать. Если у Вас при тестировании будут возникать xrun'ы, можно безопасно увеличить буфер до 128 сэмплов (что соответствуют 1 метру и на слух неразличимо). Вот 2 метра уже можно заметить на слух, так что с учётом дополнительной задержки от физического распространения звука, лучше не подниматься выше 128 без крайней необходимости.
- Почему 3 периода?
- Лично я разницы между 2 и 3 не замечал, но в man jackd пишут что:
For USB audio devices it is recommended to use -n 3
- Лично я разницы между 2 и 3 не замечал, но в man jackd пишут что:
Такая конфигурация запишет в файл cat ~/.jackdrc
примерно следующую команду запуска звукового сервера (отрефакторено для наглядности):
/usr/bin/jackd --timeout 200 --port-max 2048 --realtime --temporary --driver alsa --nperiods 3 --rate 44100 --period 64 --device hw:CODEC,0
Файл ~/.jackdrc
используется для того, чтобы любое приложение могло при необходимости запустить звуковой сервер и его параметры были в порядке. Если Ardour обнаружит уже запущенный JACKd на момент открытия, то он попытается его использовать и уведомит при расхождении настроек проекта с параметрами работающего сервера. Флаг --temporary
означает, что звуковой сервер остановится когда от него отключится последний клиент. Возможно Вам будет удобнее держать сервер постоянно запущенным, но это актуально только если Вы полностью отказались от PulseAudio.
Вас встретит пустая DAW. Нужно переключиться в Mixer, скрыть всё лишнее и добавить первый канал:
Почему добавляем Bus, а не Track?
Чтобы Track мониторился в мастере, нужно на нём нажимать кнопку In (Monitor input) и следить, чтобы она не слетела. Тем временем, Bus всегда выводится и это невозможно изменить. То, что надо для работы в режиме микшера. Подключать к физическим инпутам можно как Track, так и Bus. Если у Вас нет и не планируется ни одного Track, можно вообще скрыть из интерфейса панельку Record & Monitor (у Bus в ней синяя кнопка Show Sends, бесполезная в нашем сценарии).
Теперь необходимо подключить добавленный канал к какому-нибудь источнику звука. В меню сразу перечисляются аппаратные входы аудиоинтерфейса, так что подключим его к первому (MIC/LINE 1). Если нужно подключить что-то более глубокое из недр JACK, открываем Routing Grid или QjackCtl.
ВНИМАНИЕ! Опасность петли! Если Ваш аудиоинтерфейс подключен к громкой колонке, которая находится рядом с микрофоном, после коммутации будет больно. Лучше уберите громкость в ноль перед коммутацией и плавно поднимайте после неё.
Профит! Звук с микрофона проходит через Ardour, выходит в MASTER и мониторится на выходе звучки.
Аналогичным образом можно добавить остальные каналы Вашего аудиоинтерфейса и накинуть плагинов в соответствующей секции канала.
Говоря о плагинах, также стоит упомянуть отличный хост плагинов Carla. Его можно использовать для построения сложных цепочек обработки и контроля графа соединений JACK (вместо QjackCtl). Если маленькое окошко в панели канала не удовлетворяет Ваши потребности в удобстве коммутации плагинов, попробуйте Carla.
Также, в связи с плагинами, появляется одна мега-важная вещь, о которой почти нереально узнать чисто из практического опыта. Спасибо, @merlin-vrn, за посвящение в глубокие внутренности цифровой обработки звука. Суть в следующем: при работе с вещественными числами (а JACK работает с вещественными числами), процессору время от времени приходится обрабатывать очень маленькие (по модулю) числа. Для работы с такими числами процессоры используют некий приём под названием Денормализованные числа, и во многих процессорах этот приём дико лагает. Его используют потому что он позволяет избежать проблем с точностью (а это, в общем случае, куда важнее). То есть, если число становится меньше определённого порога, арифметические операции с ним могут (при определённых условиях) стать чуть ли не в 100 раз медленнее. При обработке звука, чаще всего маленькое число означает тихий звук, который даже и не слышно, так что критически важно принять меры для защиты от denormals. В Ardour достаточно просто подкрутить настроки:
Возможно, DC bias — это оверкилл, процессоры чаще всего поддерживают режимы работы округления denormals. Но, зато, безопасно.
У меня для ивента была вот такая раскладка:
- Два микрофона.
- Оба через лимитер.
- В беспроводной иногда пели, поэтому там реверб в боевой готовности.
- VLC для основных треков.
- К каналу VLC умеет подключаться сам, далее описано как это настроить.
alsa_in
для системного звука из браузера.
- Об этом тоже есть отдельный абзац.
- Подключать его надо вручную через Routing Grid (на скриншоте он ни к чему не подключен).
Всё, классический микшер уже готов. Есть инпуты, у каждого свой фэйдер и кнопка MUTE, есть обработка, есть MASTER OUT и физический разъём к нему (у моей BEHRINGER UM2 даже два: тюльпаны для колонок и джек для мониторинга). Однако, для полного счастья, стоит добавить возможность включать треки с того же компа. Этим и займёмся.
Media Player
Для меня VLC — это плеер по умолчанию для любого медиаконтента. Однако, если Вас не пугают диджейские пульты, можно использовать Mixxx. В принципе, тогда Ardour и не нужен, в Mixxx есть 4 AUX и 4 MIC входа. Но лично мне комфортнее с классическим микшером и я расскажу про VLC. Ещё есть IDJC, но он уже довольно стар (даже его форк IDJC-X уже много лет не обновляется) и больше адаптирован под интернет-радио (тёплый ламповый Icecast), но может быть Вам будет удобен.
VLC умеет работать напрямую через JACK, в нём это реализовано максимально удобно.
То есть, VLC будет автоматически подключать свой аутпут к сорсам, имя которых совпадает с регуляркой VLC
. Можно просто указать подходящую строку в качестве имени канала в Ardour, и VLC сам подключатся к этому каналу при попытке что-то воспроизвести. Максимально удобно и надёжно.
Главное потом не забыть вернуть на PulseAudio или ALSA, когда через недельку захотите посмотреть видос, а звук работать не будет.
System Sound
Нафига вообще вводить звук из браузера?
- Когда толпа требует какой-то конкретный малоизвестный трек, можно стать хорошим диджеем и сделать их счастливыми, если этот трек соискать на стриминговых сервисах и поставить.
- Ещё иногда на ивентах бывают всякого рода видеомосты, а всякого рода дискорды не умеют в JACK.
- Разумеется, это имеет смысл только если у Вас на "микшере" есть Интернет.
- Или, например, моя программа FestEngine на момент выхода статьи не поддерживает JACK, так что его даже в оффлайне придётся заводить через PulseAudio.
Нам понадобится утилита alsa_in
. Она позволит ввести в JACK звук из приложений, которые сами не умеют выводить звук в JACK (например, браузер). Скорее всего alsa_in
установилась вместе с JACK, но в RHEL-мире это отдельный пакет jack-audio-connection-kit-example-clients.
Также нам потребуется PulseAudio Volume Control (пакет pavucontrol
), без него сложновато понимать что происходит внутри PulseAudio и влиять на это.
Важный момент: во многих дистрибутивах есть отличный пакет pulseaudio-module-jack
, который позволяет соединять PulseAudio с JACK напрямую, минуя ALSA. Если у Вас он есть, используйте module-jack-sink
вместо alsa_in
. Это будет намного чище, чем описанный далее способ. Я не пробовал, но хотел бы. Может как-нибудь соберу из исходников.
Утилиту alsa_in
можно запускать (в screen
, чтобы она работала в фоне, но была доступна) вот таким скриптом:
#!/bin/sh
cat << EOF > ~/.jackdrc
/usr/bin/jackd -T -P 70 -d alsa -d hw:CODEC,0 -r 44100 -n 3 -p 128
EOF
sudo modprobe snd-aloop id=JACK pcm_substreams=1
screen -dm alsa_in -j alsa_in -d hw:JACK,1 -p 1024
echo 'Use `screen -r` to connect to 'alsa_in' console, and [Ctrl+a,d] to disconnect.'
- Модуль ядра
snd-aloop
позволяет добавлять в ALSA виртуальные звучки, у которых выход соединён со входом. Здесь мы добавляем один input и один output по имени JACK. Внутри они соединены: то есть, всё, что мы выводим в output на ALSA-устройство JACK (как будто на динамики), попадает ему же в input (как будто из микрофона).
- PulseAudio автоматически не начнёт отправлять звук в новое виртуальное аудиоустройство JACK, его нужно установить в качестве fallback-девайса в PulseAudio Volume Control, а программы, которые уже куда-то что-то выводили переключить на JACK.
- Прога
alsa_in
переправляет input в звуковой сервер JACK.
- Он ни к чему автоматически не подключится, так что его нужно будет вручную подключить к нужному каналу Ardour. Это можно сделать через Routing Grid интересующего канала или через QjackCtl.
- Если на момент запуска
alsa_in
в системе нет активного JACK-сервера, он запускается с настройками из~/.jackdrc
- Куда предварительно сохраняются требуемые настройки.
- Этот вариант удобен тем, что можно читать вывод jackd.
Extra
- Без физических фэйдеров ощущения не те? Вставляем USB-MIDI-контроллер. Управление сценическим светом можно (в теории) на него же завести. Самые простые варианты:
- Хочется ходить с планшетиком по залу? Есть 2 варианта:
- x11vnc + что-нибудь типа VNC Viewer.
- OSC + что-нибудь типа TouchOSC.
Conclusion
Спасибо за интерес к свободному ПО. Если что-то не понятно или не получается, пишите комменты, попробуем разбираться :)
astenix
Отлично, спасибо!