Коммутирование звука в Linux

2012.02.25

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


  • Список пакетов для Debian: jackd2 jack-tools pulseaudio-module-jack.
  • Для автоматической настройки JACK, PulseAudio и маршрутизации и восстановления исходной конфигурации в конце сеанса можно использовать скрипт jack_pulse_bridge, который автоматизирует все описанные в статье процессы.

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

Схема распространения звука при использовании PulseAudio выглядит так:

figure 1

Более подробная схема есть в Википедии.  Главная проблема в том, что при вещании нужно отправлять джинглы и музыку не только в наушники, но ещё и собеседнику в Skype.  PulseAudio этого пока не умеет, зато это умеет JACK — сервер звука, который работает только с одной звуковой картой, зато он умеет перенаправлять потоки из одного приложения в другое, в любых комбинациях и количествах.  С помощью JACK можно создать такую схему маршрутизации звука:

figure 2

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

figure 3

Реализуется такая схема в три приёма: настраивается JACK, настраивается PulseAudio и настраивается маршрутизация.

JACK работает просто: это процесс, который запускается при начале проигрывания звука (никакой не системный демон), а закрывается, когда он никому не нужен.  Есть библиотека, через которую программы его используют, и эта библиотека умеет сама запускать сервер, если он ещё не запущен вручную, используя параметры, описанные в файле ~/.jackdrc.  У меня этот файл выглядит так:

/usr/bin/jackd -dalsa -dhw:Intel -r44100 -p1024 -n2 -s -H -M

Значения для параметра -dhw обычно "Intel", "USB", "PCH" или "default" (их можно узнать из вывода команды aplay -l).  Можно изменить частоту дискретизации, если звуковая карта предпочитает 48000Гц, больше ничего менять обычно не надо.

Настройки PulseAudio хранятся в файле ~/.pulse/default.pa.  Чтобы отправить звук в JACK, файл может выглядеть примерно так:

load-module module-jack-source
load-module module-jack-sink
load-module module-native-protocol-unix
load-module module-default-device-restore
load-module module-rescue-streams
load-module module-always-sink
load-module module-intended-roles
load-module module-suspend-on-idle
load-module module-console-kit

Первые две строки включают драйвер jack, остальные включают внутренние протоколы PulseAudio, не относящиеся ко звуковым устройствам.  После этого можно перезапустить PulseAudio командой pulseaudio -k (все запущенные приложения, использующие звук, зависнут).  Сервер перезапустится и сам запустит jackd, в чём можно убедиться командой:

$ ps auxc|grep -E 'pulse|jack'

Чтобы убедиться, что всё работает, можно проиграть тестовый звук (или совершить тестовый вызов) в Skype.  Звук должен успешно поступать с микрофона и выходить в колонки или наушники.  Музыкальный проигрыватель, который будет запускать музыку и джинглы (я рекомендую mplayer или moc), тоже должен работать, но звук в Skype идти пока не должен — пойдёт после настройки маршрутизации.

Для того, чтобы снова вернуть PulseAudio полный контроль над звуком, достаточно удалить (или переименовать) файл ~/.pulse/default.pa и перезапустить сервер командой pulseaudio -k.

Маршрутизацией звука занимается утилита jack.plumbing, которая читает настройки из файла ~/.jack.plumbing.  Каждая строка этого файла описывает связку источника и получателя одного канала звука.  Утилита занимается отслеживанием клиентов и коммутирует их в момент обнаружения.  Например, чтобы отправить mplayer в Skype, нужны такие правила:

(connect "MPlayer \[[0-9]+\]:out_0" "PulseAudio JACK Source:front-left")
(connect "MPlayer \[[0-9]+\]:out_1" "PulseAudio JACK Source:front-right")

Количество правил обычно больше, можно посмотреть в мои настройки, связывающие PulseAudio, mplayer, moc, darkice и IDJC.  Список активных на данный момент каналов можно посмотреть командой jack_lsp, а маршрутизатор (jack.plumbing) нужно запускать вручную.

Настройка стороннего ПО

Чтобы mplayer использовал драйвер jack, можно в командной строке использовать ключ -ao jack, а можно в файл ~/.mplayer/config добавить список предпочтений:

ao=jack,pulse,alsa

Настройки для moc хранятся в файле ~/.moc/config и выглядят так:

SoundDriver = jack

После выполнения всех этих действий можно совершить тестовый звонок через Skype (в echo123), поговорить в микрофон и проиграть музыку.  Всё это должно вернуться.  Если что-то не работает — пишите.

Дополнительный материал

Следить за развитием событий можно через RSS ленту или почтовую рассылку.