Pull to refresh

Разговорное радио на коленке

Reading time 12 min
Views 36K
В определённый момент, страдая от лени обновлять новостной блог про OpenStreetMap, я решил сделать еженедельную передачу про проект. Вместо трёх часов вымучивания текста — часик пообсуждать со знакомыми участниками OSM новинки и актуальные вопросы. Отличная идея, порадовались и разошлись. Через полгода со словами «ну блин хватит бездельничать, давайте послезавтра звоните в скайп» я начал разбираться, как в этом вашем линуксе записать звук с микрофона и скайпа, одновременно передавая его в интернет. Эта история — про настройку PulseAudio, про скайп и мамбл, и про удивительный JACK. Оказалось, поднять собственное радио с гостями в эфире проще, чем нарисовать для него логотип.


Лабиринты PulseAudio


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

Как для пользователя выглядит «конструктор» PulseAudio? Для каждой звуковой карты есть устройство-вход (source, обычно — микрофон) и устройство-выход (sink, обычно — колонки). Приложения берут звук из source и выдают в sink. Но как тогда записать звук с колонок, т. е. подать приложению звук из sink? Для этого у всех sink есть monitor, который тоже является source. Получается такой направленный граф. А как направить звук из source в sink без приложения посередине? Модуль module-loopback — виртуальное приложение, которое просто копирует звук. Часто его подключают, чтобы слышать в наушниках микрофон (и горе вам, если запустите loopback из микрофона в колонки — я умудрился такую конфигурацию включить в автозапуск, и очень испугался). Втыкаем наушники в аудиовыход и набираем безо всяких sudo:

pactl load-module module-loopback

Этот модуль позволит сделать простейшую схему записи одновременно своего голоса и соведущих:



Чтобы настроить вход и выход у Skype, gstreamer (см. ниже) и loopback, нужно запустить соответствующие потребители звука (например, позвонить в «Sound Test Service» скайпа) и найти приложение в «регуляторе громкости» (pavucontrol). Во вкладке «Playback» выбираем sink (наушники в нашем случае), в «Recording» — source (микрофон). Чтобы увидеть в окне модуль loopback, внизу нужно выбрать «All Streams».



На картинке я выбираю source для скайпа. Две кнопки справа позволяют пустить на вход тишину и регулировать громкость левого и правого каналов отдельно (по умолчанию они связаны). Обязательно проверьте, чтобы уровень сигнала во всех вкладках был 100%, и уменьшайте только при необходимости.

Самым сложным в этой схеме было говорить. Да, банально произносить связные предложения. Потому что loopback происходит с задержкой от 0,2 секунды: как будто сам себя постоянно перебиваешь. Рефлекс — замолчать и дать тому, кто в наушниках, выговориться. Но тот тоже замолкает! Кое-как снизил этот эффект, заглушив один канал в наушниках.

Ретранслятор Icecast


Для живой трансляции в интернет нужен сервер типа shoutcast, самый популярный из открытых — icecast2. Он есть во всех популярных дистрибутивах Linux. После установки достаточно отредактировать /etc/icecast2/icecast.xml, прописав в разделе «authentication» свои пароли, да поправив чуть ниже «hostname». Ещё нужно проверить, чтобы в /etc/default/icecast2 параметр ENABLE был true. Дальше запускаем демона icecast2 и прописываем его в автозапуск. Возможно, понадобится открыть tcp-порты (по умолчанию — 8000 и 8001).

Состояние и статистику сервера можно посмотреть, зайдя на порт 8000 браузером. Мне не хватало распределения слушателей по странам и городам — для этого я написал простой php-скрипт, задействующий модуль PECL GeoIP.

Помедленнее, gstreamer записывает


Для отправки звука на сервер icecast странные люди в интернете ставят какие-то мутные программы вроде Darkice или LiquidSoap, но на деле достаточно обычного gstreamer. Им очень просто записать звук с любого source в файл mp3 (или ogg, по вкусу):

SOURCE=alsa_output.pci-0000_00_1b.0.analog-stereo.monitor
DATE=$(date +%y%m%d-%H%M)
gst-launch-0.10 pulsesrc device=$SOURCE ! audioconvert ! audio/x-raw-int,channels=1 ! lamemp3enc bitrate=64 cbr=true ! filesink location=radio-$DATE.mp3

Доступные источники для переменной SOURCE покажет команда

pactl list short sources

Хотя источник можно просто выбрать в регуляторе громкости. Другие инструкции из сети подскажут, как отправить звук на сервер:

gst-launch-0.10 pulsesrc device=$SOURCE ! audioconvert ! audio/x-raw-int,channels=1 ! lamemp3enc bitrate=64 cbr=true ! shout2send ip=$IP port=8000 password=$PASSWORD mount=radio 'streamname=Beta Radio'

Наконец, механизм потоков позволяет сделать и то и то одной командой:

gst-launch-0.10 pulsesrc device=$SOURCE ! audioconvert ! audio/x-raw-int,channels=1 ! lamemp3enc bitrate=64 cbr=true ! tee name=t ! queue ! shout2send ip=$IP port=8000 password=$PASSWORD mount=radio 'streamname=Beta Radio' t. ! queue ! filesink location=radio-$DATE.mp3

Вуаля! Замечу, что когда я забыл перевести поток в моно, компьютер не справлялся с кодированием и отправлял в интернет какие-то ошмётки. Так что обязательно проверяйте поток и записанный файл. Можно запустить несколько gstreamer-ов для записи в файлы разных устройств: например, отдельно микрофона и скайпа, чтобы потом отдельно их почистить и собрать подкаст в редакторе.

Это не архиватор, это Audacity


Передача прошла, нужно опубликовать подкаст в интернете. Можно сразу, но некомильфо: дорожка шумит, голоса тихие, паузы по десять секунд раздражают. Так что чёрной подкастерской работы не избежать: запускаем Audacity и открываем там запись. Сначала нужно удалить пустоту из начала и конца, затем — особо зияющие паузы и случайные нарушения NDA гостями. Я заметил, что правильная фоновая музыка не мешает такому кромсанию: скачки ритма почти незаметны. Так что отдельные записи каналов пока не пригодились.

Дальше удаляем клики (Effect→Click Removal), находим тихое место без музыки и без дыхания (для этого хорошо записать эфир после передачи, когда музыка кончилась) и получаем из этих 0,5-1 секунды профиль шума (Effect→Noise Removal→Get Noise Profile). И, сбросив выделение, там же удаляем шум. Я не профессионал, параметры по умолчанию не менял. Просто проверяю, что процедура не удалила полезных частот — не сделала голоса глуше или звонче — и довольствуюсь этим.

Самое сложное, судя по десяткам инструкций только на русском языке, — компрессия звука (Effect→Compressor). С архивированием ничего общего, это банальное сжатие волны по амплитуде. Как я понял, алгоритм берёт фрагменты волны с амплитудой больше «Threshold», и вот эти верхушки (не всю волну) сжимает в заданное в «Ratio» количество раз. Я нетерпелив, поэтому ставлю 8:1, но, говорят, лучше несколько подходов по 3-4. Вот некоторые из статей на тему:


При сохранении в MP3 (File→Export→MP3 Files) выберите режим «Preset / Standard» (это очень хорошее качество, поверьте), и потом обязательно введите значения тегов. Жанр я ставлю «Vocal», хотя, наверное, есть более подходящие варианты.

VLC, гроза диджея


Эта конфигурация позволила записать неуклюжий нулевой выпуск, но не подошла для первого: на «вечере оживших карт» неделей раньше я записал на диктофон несколько интервью, и хотел воспроизвести их в передаче. Также многие рекомендуют пустить под голосами ведущих тихую музыку, которая не только маскирует длинные паузы и делает передачу динамичнее, но и покажет, что связь не оборвана.

Музыка, разумеется, должна быть с открытой лицензией, т.н. podsafe. Многие сайты советуют musicalley, но он жуткий, поэтому я пошёл копаться в объедках на promodj. Требования просты: без вокала, без ударных, желательно в стиле старых приставок (впечатлился музыкой из видеодневников отаку.ру). Конечно, хороших треков по этим данным не нашёл, но пару приемлемых собрал. Один пускаю фоном, остальные включаю за полчаса до эфира, чтобы ранние слушатели не скучали.

Поскольку радио у меня на коленке, источником музыки и интервью определён плеер VLC. В нём прямо из меню можно указать, в какой sink отправлять звук. Но вот задача: интервью должны слышать и собеседники в скайпе, чтобы знать, что обсуждать.

Обратно к графу


Второй полезный модуль PulseAudio — module-null-sink, виртуальное устройство со входом и выходом. Его можно использовать как промежуточное: в моём примере туда складывают звук микрофон и VLC. Смикшированный результат получает скайп на вход, и соведущие всю программу слушают фоновую музыку, и интервью иногда. Напомню:

  • приложения (на схеме — зелёные) берут звук из source и/или выдают его в sink;
  • передать звук из одного приложения сразу в другое нельзя, нужен промежуточный module-null-sink;
  • передать звук из source напрямую в sink нельзя, нужен промежуточный module-loopback.

Получилась схема, которую я использовал для трансляции и записи нескольких выпусков:



Когда запускается интервью, звук из скайпа можно перенаправить в наушники, а устройство микрофона либо заглушить (кнопка в регуляторе громкости), либо направить прямо в скайп. Наконец, немного усложнив схему, можно одновременно передавать в интернет весь «бутерброд», а в файл писать только речь ведущих, которую после обработки наложить на музыкальные файлы. В восторге от роутинговых возможностей PulseAudio, я написал и отладил скрипт для подготовки к трансляции. Правда, в «продакшене» ни разу не использовал: сразу после написания нашёл в себе силы взять и настроить JACK.

Блог на коленке


Главный результат еженедельных эфиров — не пятнадцать удовлетворённых слушателей, а подкаст, который послушают сотни человек. Для его публикации и обсуждения нужен блог. Я по привычке выбрал бирмановский e2: простой и лёгкий, даже аудиофайлы поддерживает из коробки.

Комментарии так и не появились, а главной задачи, про которую я не догадывался, блог не решил. Несколько слушателей пожаловались, что RSS блога не принимает их приложение для подкастов. Оказывается, записи RSS должны содержать ссылки на аудиофайлы в enclosure и десяток их параметров в специальных тегах. Эгея такого не умеет, а ставить что-то тяжёлое не хотелось, поэтому я завёл копию подкаста на rpod.ru: через этот сайт нас слушают около 10% аудитории, но зато там легко подписаться. И есть регулятор громкости на плеере.

Правильно было бы не выпендриваться и пойти стопами немецкого подкаста про OSM, который на обычный WordPress накатил плагин Podlove. Результат несколько монструозен технически, но приятен на вид, и позволяет, например, быструю навигацию внутри подкаста по меткам. Другой вариант я нашёл на этой неделе: блог подкастов We Build сделан на GitHub Pages, т.е. на статических шаблонах Jekyll.

Публиковаться только на rpod чревато: так, пятую передачу я не смог туда загрузить из-за идиотской ошибки про превышение объёма, объяснения которой нет (файлы всего по 40 мегабайт), только пара разочарованных реплик столкнувшихся с нею же подкастеров.

Время JACK


Эксперты обработки звука в нашем чатике подначивали меня перейти на продвинутую аудиоподсистему JACK, и я, конечно, не удержался, толкаемый любопытством, желанием избавиться от 200 мс задержки loopback и надеждой на прелести IDJC (см. ниже). Оказалось, что 1) для работы с JACK уже не нужно удалять или отключать PulseAudio, и его можно включать-выключать по желанию — например, только для записи передачи. И 2) все нужные пакеты почему-то уже установлены в Fedora из коробки. Осталось только доустановить qjackctl и запустить его.

Конечно, эта панель сразу пожаловалась на кривую настройку. Говорит, давай-ка ты включишь в своём линуксе realtime scheduling. Опять же, оказалось, для этого не нужно менять ядро, достаточно отредактировать /etc/security/limits.conf. И опять же кто-то в федоре сделал это за меня: судя по /etc/security/limits.d/95-jack.conf, достаточно внести себя в группу jackuser. А для этого нужно перелогиниться. Никогда не выходил из системы в KDE, пришлось погуглить.

Снова запускаю QjackCtl. В настройках указал нужные микрофон и выход, и главное — в закладке «Misc» включить «Enable D-Bus interface», ну и следующую галочку, про выключение JACK при выходе. Кажется, это все настройки аудиоподсистемы, можно нажать Start — и запустить вожделенный Internet DJ Console.

И, наконец, IDJC


Эту консоль многие советуют для организации несложной радиостанции. Она заточена под трансляцию музыки и миксов, но умеет и правильно обращаться с голосом диджея. Как полагается продвинутой консоли, она пугает количеством кнопок и рычажков:



На деле всё, конечно, несложно. Две панели музыки, ниже — кроссфейдер для переключения между ними (кнопка «Pass» переключает плавно). Есть канал диджея и канал трансляции («Stream»), они раздельны: так, можно отключить музыку для DJ, или наоборот, проверять второй плейлист, пока на радио играет первый. Справа куча индикаторов, самый интересный — число под наушниками, количество слушателей. Кнопки внизу включают трансляцию голоса ведущего и потоков из других каналов (на картинке — окончательный вариант, после Mumble, про который дальше). Немного описаний и ссылка на учебник есть на сайте проекта.

Все настройки спрятаны под кнопкой слева внизу. В «Preferences» я включил раздельные регуляторы громкости для плейлистов: в первом лежит повторяемая по кругу тихая фоновая мелодия, во втором — предэфирные песни и интервью. Вкладка «Channels» может запутать: в ней настраиваются одновременно кнопки внизу плеера, открывающие каналы, и сами эти каналы. Там видно, что звук с микрофона прогоняется через кучу фильтров, включая High Pass, лимитер, нойзгейт и т.п. Если потратить время на настройку (не только для себя, но и для соведущих), постобработка может не понадобиться. Я не потратил. Для начала достаточно первого канала, который с микрофоном.

Трансляция настраивается в «Output». Их может быть до шести (в разном качестве и форматах). Внизу — кнопка записи в файл. У меня, почему-то, она работает только один раз за сеанс, приходится перезапускать. Что неочевидно в этом окне — для включения трансляции нужно раскрыть «Individual Controls» и нажать там кнопку с адресом сервера. Возможно, проще включить галочки выше и нажать «Connect», не знаю.



Вот эта вермишель — окно QjackCtl под кнопкой «Connect». Раздел system — микрофон и колонки, в PulseAudio вещает только скайп, поэтому я не стал для него делать отдельный sink. Весь этот роутинг JACK делает по умолчанию, я только добавил векторы из PulseAudio в voip_in раздела IDJC. Это делает работоспособными кнопки с телефонами: красная ни к чему, а вот зелёная микширует звук из скайпа в трансляцию. Когда нужно запустить интервью, протягиваю дополнительные связи из str_out в PulseAudio (банальным перетаскиванием). Чтобы удалить связь, нужно выбрать источник слева, приёмник справа, нажать на последнем правую кнопку и «Disconnect».

Проблему задержки loopback-а новая конфигурация, правда, не решила. Всё те же 0,2 секунды. Но зато проще поднимать, и как-то по-взрослому.

У вас продаётся Go Mic?


Не прошло и месяца, как петличный микрофон меня окончательно выбесил шумами и низкой громкостью, и я решил его заменить. Все руководства для новичков в подкастах рекомендовали взять USB-микрофон, и между двухсотдолларовым Rode и двухтысячерублёвым Samson Go Mic я выбрал последний. Найти его в магазинах несложно, труднее сохранять серьёзное выражение лица, диктуя название продавцу. Размерами он примерно с хорошую зажигалку.

И, конечно, в сравнении с моими прошлыми микрофонами — небо и земля. Чувствительность такая, что слышно мурлыкание кошки, спящей в соседней комнате, и слив воды тремя этажами ниже. Но зато не нужно кричать, не нужно держать микрофон у рта, и благодаря разъёму USB, дешёвая внешняя звуковуха ушла на полку (у моего ноутбука нет микрофонного входа). Поп-фильтр, кажется, не критичен для этого микрофона, а вот стойку нужно поискать.

Неожиданно Go Mic решил проблему с задержкой loopback-а в наушники: у него внутри своя звуковая карточка, которая микширует сигнал с компьютера с голосом в микрофоне. Поскольку сигнал не прокручивается в компьютере, задержка выходит нулевая. Наконец-то мне не мешает собственное эхо. Непросто было отключить loopback в IDJC: галочки «In The DJ's Mix» я нашёл, но если нажать кнопку VoIP, эхо возвращается, и что с ним делать — непонятно. Решил отказаться от кнопок с телефонами, привинтив скайп на четвёртый канал и сделав для него кнопку рядом с «DJ» — как для Mumble.

Mumble вместо Skype


Проблема голосовых конференций в скайпе — в непредсказуемости. Ведущий с трансляцией почти наверняка не окажется админом, и голоса соведущих будут идти долго и тяжело. Кто-то случайно отключится — и заберёт с собой всех собеседников. Наконец, линуксовый скайп иногда начисто вылетает просто так, немотивированно. Альтернатив несколько, я выбрал самую популярную и с открытым кодом: Mumble. Привлекло наличие клиентов не только подо все настольные операционки, но и для iOS и Android.

Сервер, Murmur, ставится вообще в два счёта: прописать в /etc/murmur/murmur.ini серверный пароль (настройки по умолчанию адекватны), запустить и прописать в автозапуск демона, открыть для tcp и udp порт 64738.

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

Звучит сложно, но из своего прошлого с ArchLinux я помню про AUR. Это удивительный репозиторий, лучшее, что я встречал в линуксах, и единственное, о чём я жалею, уйдя с арча. Записи базы AUR — это инструкции по подготовке установочного пакета из грязи и палок исходников и патчей, при этом для пользователя — не сложнее обычного pacman -S. Для Mumble там есть сборка из снапшота, сборка из гита, сборка из гита с применением патча JACK и сборка из исходников стабильной версии с этим патчем. Открываем pkgbuild последней, скачиваем патч и выполняем инструкции из prepare() и build(). Инструкция по сборке (без патча) есть и в mumble wiki. Главное — не забыть про пакет jack-...-devel. Собранное приложение не устанавливал в /usr, запускаю из каталога сборки. В настройках нужно будет включить JACK и отключить всю мишуру, типа эха и positional audio.

От скайпа не избавиться: я хочу оставить его для принятия звонков от слушателей и для гостей, у которых нет времени настраивать мамбл. Граф роутинга сигнала превратился в непонятную вермишель:



Попробую объяснить. Звук из микрофона идёт на 1 и 2 каналы IDJC (как обычно), в мамбл и в скайп. В наушники уходит только dj_out из IDJC. Выход мамбла прикручен к 3 каналу, скайпа — к 4 (стерео в моно), никакого шаманства с voip. Наконец, скайп и мамбл связаны в обе стороны, чтобы гость и ведущие слышали друг друга.

Что делать с записями интервью, которые должны слышать в скайпе и мамбле? Увы, руками протягивать ещё несколько связей, из str_out туда и туда. И отключать трансляцию всех четырёх каналов в IDJC, конечно. Несмотря на сложность полученной системы, откатываться на PulseAudio не хочу: связи в QjackCtl править быстрее и нагляднее, чем в «регуляторе громкости», и работать в одном IDJC проще, чем согласовывать VLC, gstreamer и «регулятор».

Радио без головы


Даже безотносительно технической части (уверен, меня раскритикуют профессионалы подкастинга), есть куда развивать систему. Сейчас мне не нравится зависимость трансляции от моего ноутбука. А что если я в дороге, или забыл ноутбук? Планирую для этого запихать на сервер murmur робота, который в час Ч включит запись всех собеседников в файл (как умеет настольный клиент Mumble), и кнопкой где-нибудь в вебе под паролем — запустит и потом остановит трансляцию на сервер icecast. Главное — выдержать еженедельный график онлайна, а подкаст собрать можно и потом. В такой конфигурации я смогу вести радиопередачу даже со смартфона.

Нужна штанга и поп-фильтр для микрофона, это да. Ещё лениво перетыкать разъёмы в JACK, нужно написать скрипт. Настроить фильтры микрофона, чтобы не приходилось каждый раз в Audacity чистить запись от шума. Починить, наконец, RSS в блоге подкаста. Всё это мелочи, главное — мы взяли и сделали, теперь у нашего сообщества есть предсказуемая, регулярная передача, в которой можно участвовать как через IRC-канал, так и голосом. Слышать голоса участников, всё-таки, совсем не то, что читать их на форуме: сообщество как будто получило новое измерение, за словами стали видны люди.
Tags:
Hubs:
+49
Comments 27
Comments Comments 27

Articles