Calculate Forum

Pipewire и virtual surround (быстро и грязно)

В моей системе издавна был настроен и успешно работал вывод многоканального звука в обыкновенные (двухканальные) стереонаушники средствами pulseaudio с использованием module-virtual-surround-sink (AKA HRTF, virtual surround). Недавно gentoo и calculate вместе с ней тихо и незаметно переползла на pipewire, где этот модуль конечно же отсутствует. В результате я потерял часть не особо мне нужного, но всё же иногда используемого функционала.

Если вы не знаете что это и зачем нужно - вот вам статья в Википедии. Вкратце это способ получить объёмный звук в двухканальных наушниках (и ТОЛЬКО наушниках, не пытайтесь повторить это с двухканальными колонками, это не имеет смысла) с использованием специальных математических алгоритмов обработки и сведения звуковых каналов.

В целом обычному пользователю это не особенно нужно, так как многие игры делают такую обработку своими средствами, если в их настройках звука выбраны наушники (так поступает GTA V в частности), в использующих библиотеку OpenAL играх (например в Minecraft) это включается в пользовательском конфиге OpenAL. Видеопроигрыватель mpv так же имеет встроенный HRTF фильтр (ЕМНИП и его не выбросили из кода, mplayer точно умел). Однако использованный мною подход имел одно преимущество - работал глобально для всего что в принципе было способно выдавать многоканальный звук.

Так что обнаружив отвал этого функционала после перехода на pipewire я задался вопросом, как его вернуть? И способ был найден. Описанный ниже метод быстрый и грязный, так как меня в первую очередь волновала принципиальная практическая работоспособность, навести красоту с рюшечками я вам предлагаю самостоятельно.

Я опирался на статью из Pipewire wiki, так что первоисточник там.

Итак. Сначала потребуется ряд библиотек, которые будет использовать наш фильтр (который нам предстоит собрать вручную, ebuild я нигде не нашёл, самому его писать мне лень, но так как он элементарен оставляю эту задачу вам). Делаем раз:

emerge zita-convolver libclthreads libclxclient jack-audio-connection-kit

Теперь нам нужно добавить себя в группу “realtime”, ОТ ПОЛЬЗОВАТЕЛЯ ROOT (или с помощью sudo, если у вас оно настроено) выполняем:

usermod -aG realtime <ваш_юзернейм>

После этого ОБЯЗАТЕЛЬНО нужно перезайти в графическую сессию или перезагрузиться.

Далее нам нужно скомпилировать фильтр. Поскольку готовый ebuild отсутствует, сделаем это руками. Правильно конечно написать ebuild и положить его в локальный оверлей, но вот прямо сейчас мне лень, возможно когда нибудь я этим озадачусь (нет). Качаем JConvolver и распаковываем его куда нибудь в ~/src, переходим в ~/src/jconvolver-1.1.0/source и выполняем там команду make. В результате у нас соберутся три бинарника, нам из них нужен только один, собственно jconvolver.

Теперь подготовим директорию где у нас будет лежать конфиг и необходимые файлы:
mkdir ~/virtual-surround/
В этой директории создаём конфиг gsx-jconvolver.config следующего содержания:

# Virtual Surround fro Headphones using JCONVOLVER
# (https://kokkinizita.linuxaudio.org/linuxaudio/)
#
# This JCONVOLVER config downmixes 7 channel audio into 2 headphone
# channels while preserving audio positions as much as possible.
#
# For best results it is recommended to equalize your headphones
# and make them phase-neutral before applying the virtualization
#
# Impulse responses are taken from the HESUVI project.
# https://sourceforge.net/projects/hesuvi/

# -------------------------------------------------------------------------
#
/cd ~/virtual-surround
#
#
#                in  out   partition      maxsize       density
# -------------------------------------------------------------------------
/convolver/new    7    2        1024      800000        1.0
#
#
#              num    port name     connect to 
# -------------------------------------------------------------------------
/input/name     1     Input.FL 		"hrir-headphones:monitor_FL"
/input/name     2     Input.BL 		"hrir-headphones:monitor_BLC"   #5.1
/input/name     3     Input.SL 		"hrir-headphones:monitor_SL"    #7.1

/input/name     4     Input.FC 		"hrir-headphones:monitor_FC"	# 3.1

/input/name     5     Input.FR 		"hrir-headphones:monitor_FR"
/input/name     6     Input.BR 		"hrir-headphones:monitor_BRC"	#5.1
/input/name     7     Input.SR 		"hrir-headphones:monitor_SR"    #7.1


#
/output/name    1     Output.FL 	"HDA Intel PCH:playback_FL"
/output/name    2     Output.FR 	"HDA Intel PCH:playback_FR"
#
#
#               in out  gain  delay   offset  length  chan     file  
# -------------------------------------------------------------------------
#Front-Left
/impulse/read    1   1   1    0       0       0       1        gsx.wav
/impulse/read    1   2   1    0       0       0       2        gsx.wav

#Back-Left
/impulse/read    2   1   1    0       0       0       5        gsx.wav
/impulse/read    2   2   1    0       0       0       6        gsx.wav

#Side-Left
/impulse/read    3   1   1    0       0       0       3        gsx.wav
/impulse/read    3   2   1    0       0       0       4        gsx.wav

#CENTER
/impulse/read    4   1   1    0       0       0       7        gsx.wav
/impulse/read    4   2   1    0       0       0       14       gsx.wav

#Front-Right
/impulse/read    5   1   1    0       0       0       9        gsx.wav
/impulse/read    5   2   1    0       0       0       8        gsx.wav

#Back-Right
/impulse/read    6   1   1    0       0       0       13       gsx.wav
/impulse/read    6   2   1    0       0       0       12       gsx.wav

#Side-Right
/impulse/read    7   1   1    0       0       0       11       gsx.wav
/impulse/read    7   2   1    0       0       0       10       gsx.wav

Теперь нам нужно раздобыть gsx.wav. (Это не звуковой файл, несмотря на расширение, не нужно его пытаться играть плейером). Идём по адресу https://sourceforge.net/projects/hesuvi/ и скачиваем оттуда последнюю версию HeSuVi exe. Файл представляет собой самораспаковывающийся 7z архив, так что запускать его через wine не нужно, смените ему расширение на .7z, достаньте из него искомый gsx.wav и положите в ~/virtual-surround. Туда же скопируйте собранный перед этим jconvolver из ~/src/jconvolver-1.1.0/source.

Осталось совсем чуть чуть, наваять два скрипта, один из которых будет поднимать виртуальный surround, а второй его опускать. Я держу их в ~/bin, вместе со всяким прочим рукоблудием.

Первый скрипт vsurround-start.sh

#!/bin/sh
export PIPEWIRE_LATENCY=1024/48000
pw-cli create-node adapter '{ factory.name=support.null-audio-sink node.name=hrir-headphones media.class=Audio/Sink object.linger=1 audio.position=[FL,BL,SL,FC,FR,BR,SR] }'
pw-jack ~/virtual-surround/jconvolver -s pipewire-0 ~/virtual-surround/gsx-jconvolver.config &

Второй, vsurround-stop.sh

#!/bin/sh
pw-cli destroy `pw-cli dump short Node|grep hrir-headphones|awk -F: '{print $1}'`

Не забудьте сделать скрипты исполняемыми.

Теперь как всем этим богачеством пользоваться. Первый скрипт создаёт виртуальное устройство воспроизведения hrir-headphones. Второй соответственно его удаляет. Теперь запускаем выдающую многоканальный звук игру, или smplayer c имеющим многоканальную звуковую дорожку фильмом (не забудьте в настройках smplayer указать что у вас 7.1 звуковая система) и в kmix щелчком правой клавишей мыши по ползунку громкости нужного приложения выбираем “Использовать устройство” “hrir-headphones”. Если у вас не KDE, то же самое можно проделать в pavucontrol.

© 2007-2020 Calculate Ltd.
Mastodon Mastodon