Все об Arch Linux

Arch Linux будет тем, что вы из него сделаете!

WirePlumber: переключение профилей звука

Подключил HDMI-монитор, а звук остался в колонках — или наоборот, наушники есть, а в системе их нет. Почти всегда причина одна: у звуковой карты стоит не тот профиль, а менять его вручную неохота. PipeWire профили не выбирает, за него это делает WirePlumber, и весь разбор сводится к четырём понятиям — карта, профиль, узел и маршруты. Разложим их по полкам и разберём, что делать, когда переключение нужно довести до автоматического.

Чем карта отличается от профиля и узла?

Карта (device) — это ALSA-карта, то есть контейнер для путей. В wpctl status она видна как строка вроде 57. Renoir/Cezanne HDMI/DP Audio Controller [alsa]. Сама по себе карта звука не производит: у неё есть только список возможностей.

Профиль (profile) — набор этих возможностей: какие порты открыть и сколько sink/source из них получится. У типичной карты ноутбука в списке есть output:analog-stereo (только аналоговый выход), output:hdmi-stereo (только HDMI), объединённый output:analog-stereo + input:analog-stereo и универсальный pro-audio. Профиль решает, появится ли вообще sink для HDMI, поэтому смена профиля — главный ход при пропащем звуке.

Узел (node) — конкретный поток, созданный из профиля: sink для воспроизведения, source для записи. Имя узла заканчивается именем профиля, поэтому по нему видно, что сейчас стоит: alsa_output.pci-0000_30_00.6.analog-stereo — sink, alsa_input.pci-0000_30_00.6.analog-stereo — source (микрофон или линия). После смены профиля узлы пересоздаются и получают новые номера.

Маршруты (routes) — порты карты и правило, какой из них активен: analog-output-headphones, hdmi-output-0, analog-input-mic. Смена маршрута не трогает профиль и не меняет sink, но именно она решает, звук в разъёме или в HDMI.

Как посмотреть, что сейчас настроено?

Главная команда — wpctl status:

wpctl status
Audio
 ├─ Devices:
 │      57. Renoir/Cezanne HDMI/DP Audio Controller [alsa]
 │      58. Ryzen HD Audio Controller           [alsa]
 ├─ Sinks:
 │  *   34. Ryzen HD Audio Controller Аналоговый стерео [vol: 0.25]
 │      47. Renoir/Cezanne HDMI/DP Audio Controller Цифровой стерео (HDMI) [vol: 0.55]
 ├─ Sources:
 │      49. Ryzen HD Audio Controller Аналоговый стерео [vol: 1.00]
 └─ Streams:

Звёздочка отмечает узел по умолчанию. Флаги -k и -n меняют вид: -k показывает короткие имена (node.nick, например ALC897 Analog), -n — технические node.name.

Список профилей с полными флагами удобнее смотреть через PulseAudio-совместимый вывод:

pactl list cards

В секции Profiles: у каждого профиля есть количество sink’ов и source’ов, приоритет и доступность. Там же видно текущий выбор строкой Active Profile: и секция Ports: с типами разъёмов.

Низкоуровневый вид — через PipeWire напрямую:

pw-cli list-objects Node | grep -E 'node.name|node.nick|media.class'
pw-dump > /tmp/pw.json

Отдельного флага --verbose у команды wireplumber нет: бинарь понимает только -v/--version, -c/--config-file и -p/--profile. Зато подробности есть у wpctl inspect <ID> (все свойства объекта) и у лога в реальном времени.

Как переключить профиль карты вручную?

Порядок такой. Сначала находим номер карты в wpctl status (у нас это 58). Потом смотрим индексы профилей — они есть и в pactl list cards, и в параметре EnumProfile карты. Дальше одна команда:

wpctl set-profile 58 2

Индексы всегда одни и те же для одной карты: 0 — off, дальше output:analog-stereo, output:hdmi-stereo и так далее по списку. Ноль означает «профиль выключено»: у этой карты пропадают все sink’и и source’и, звука нет вообще. Проверяем результат:

wpctl status

Тот же переключатель через PulseAudio-совместимый синтаксис, где профиль задаётся именем, а карта — строкой device.name (её видно в выводе wpctl inspect):

pactl get-card-profile alsa_card.pci-0000_00_1f.3
pactl set-card-profile alsa_card.pci-0000_00_1f.3 output:hdmi-stereo

Помни про две мелочи. Первая: после смены профиля номера узлов меняются, поэтому дефолтный sink лучше задать заново — wpctl set-default 47. Вторая: выбор профиля хранится в состоянии WirePlumber и переживает перезапуск, но сбрасывается, если правило выбора не совпадает с тем, что ты сделал руками.

Как заставить WirePlumber всегда ставить нужный профиль?

Ручной выбор — это разовое действие. Для постоянства нужен конфиг: WirePlumber 0.5 читает файлы из /etc/wireplumber/wireplumber.conf.d/ и из ~/.config/wireplumber/wireplumber.conf.d/, в формате SPA-JSON, где комментарии начинаются с #. Создай /etc/wireplumber/wireplumber.conf.d/50-card-profile.conf:

# принудительный профиль для карты по короткому имени ALSA
monitor.alsa.rules = [
  {
    matches = [
      { alsa.card_name = "HD-Audio Generic" }
    ]
    actions = {
      update-props = {
        device.profile = "pro-audio"
      }
    }
  }
]

Как это работает: скрипт device/find-best-profile смотрит свойство device.profile у карты, и если профиль с таким именем доступен, он получает абсолютный приоритет над всеми остальными кандидатами. Отсюда и available в списке профилей: значение no отбрасывает профиль, unknown (как у pro-audio на большинстве карт) оставляет на волю правилу, yes — пригоден для автоматического выбора.

Имя для matches берётся из свойств карты, а не из догадок:

wpctl inspect 58 | grep -E 'card_name|device.name'
cat /proc/asound/card0/id

Кроме alsa.card_name можно матчить device.name (alsa_card.pci-0000_00_1f.3), node.name или node.nick. Более тонкий вариант — секция device.profile.priority.rules, где перечисляются имена профилей в порядке предпочтения: выигрывает первый доступный, и если его нет, берётся следующий.

Применяем и проверяем:

sudo mkdir -p /etc/wireplumber/wireplumber.conf.d
systemctl --user restart wireplumber
wpctl status

Если параллельно живёт PulseAudio, он умеет перехватывать карту и ставить профиль по-своему — про конфликт и его разбор я писал здесь. Правило не сработало — смотри лог: journalctl --user -u wireplumber -f, там видно, какой профиль выбрал менеджер и почему отказался.

Как устроено автопереключение в 0.5?

Логика выбора в WirePlumber 0.5 разложена по Lua-скриптам, объявленным как виртуальные возможности policy.*. За профили отвечает policy.device.profile (это device/select-profile.lua, device/find-best-profile.lua, device/apply-profile.lua и автопереключение Bluetooth-профиля), за узлы по умолчанию — policy.default-nodes (default-nodes/find-best-default-node.lua, state-default-nodes.lua, apply-default-node.lua), за маршруты — policy.device.routes, за соединение потоков — policy.linking.standard.

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

wireplumber.settings = {
  device.restore-profile = false
  node.restore-default-targets = false
}

Первый запрещает запоминать выбор и возвращать его при старте, второй — запоминать, какой узел был дефолтным, иначе WirePlumber продолжает цепляться за устройство, которого уже нет.

Источники живут по тем же правилам: source — это узел с классом Audio/Source, у наушников с микрофоном он появляется вместе с профилем гарнитуры, а переключение на него удобнее делать в pavucontrol, GNOME «Звук» или qpwgraph. Как выглядит перебор доступных вариантов в интерфейсе, я разбирал в статье про переключение на наушники. Отдельно в настройках есть bluetooth.autoswitch-to-headset-profile — он включён по умолчанию и заставляет Bluetooth-гарнитуру отдавать профиль с микрофоном во время записи.

Что такое routes и когда нужен профиль pro-audio?

Маршруты — это порты карты с указанием, доступны они сейчас или нет. В pactl list cards это секция Ports:, где у каждого порта есть тип (hdmi, headphone, mic), приоритет, группа доступности и пометка available или not available. У HDMI-карты порт hdmi-output-0 относится к группе Legacy 1, а hdmi-output-1 к Legacy 2 и числится недоступным, пока к нему ничего не подключено. Переключение маршрута не меняет профиль — проще всего сделать его мышкой в qpwgraph, из командной строки отдельной команды wpctl для портов нет, только Lua-скрипты. В настройках есть device.restore-routes — запоминать маршруты между сессиями, и device.routes.mute-on-alsa-playback-removed — заглушать звук при отключении кабеля.

pro-audio стоит выдельно. Он открывает все каналы напрямую, минуя микшер PulseAudio, и карта отдаёт их как есть. Нужен он для JACK, гитары, многоканального выхода, работы с внешним ЦАПом. Обычному пользователю не нужен: в списке профилей у него приоритет 1 и доступность unknown, поэтому автоматический выбор его пропускает, и включить его нужно руками или правилом из предыдущего раздела. Цена решения простая: приложения, ожидающие привычный стерео-микшер, получают один многоканальный sink, а громкость приходится крутить самой картой, потому что программного микшера над потоком нет.

Почему после смены профиля звук пропал?

Три причины закрывают почти все случаи. Первая: профиль в списке есть, но все его порты помечены available: no — путь через ALSA/UCM не открывается, и PipeWire не создаёт рабочий sink. Вторая: выставлен индекс 0, то есть профиль off, у которого ноль sink’ов и ноль source’ов, — карта включена, но играть нечем. Третья: дефолтный узел указывал на номер узла, которого после смены профиля уже не существует, поэтому звук идёт, но не туда.

Диагностика идёт снизу вверх:

wpctl inspect 57
pactl list sinks short
pw-dump | python3 -m json.tool | less
journalctl --user -u wireplumber -f

wpctl inspect карты покажет device.routes и доступность профилей, а wpctl inspect sink’а — device.profile.name и card.profile.device, то есть сразу станет ясно, какой профиль в силе. pactl list sinks short даёт состояние узла: RUNNING означает, что поток идёт, SUSPENDED — узел есть, но молчит. Если звук не появляется вообще ни в одном приложении, проверь сначала профиль и только потом микшер: разбор полностью молчащей системы начинается ровно с wpctl status.

Частые вопросы

Профиль сбросился после перезагрузки, что делать?

Убедись, что в /etc/wireplumber/wireplumber.conf.d/ нет файла с device.profile, который указывает на другое имя, и перезапусти systemctl --user restart wireplumber. Помогает очистка состояния: rm -r ~/.local/state/wireplumber при остановленном сервисе.

Можно ли переключить профиль, не перезапуская плеер?

Обычно да: WirePlumber переподключает активные потоки на новый узел, этому отвечает настройка linking.follow-default-target. С pro-audio так не выйдет — структура потока меняется, и аудиоплеер придётся перезапустить.

Почему wpctl set-profile не находит карту?

Номера карт не постоянны: между сессиями они меняются. Узнай номер заново через wpctl status или обойди нумерацию, взяв имя карты из pactl list cards и вызвав pactl set-card-profile.

Как отличить профиль от узла в выводе?

Профиль — строка со sinks:/sources: в секции Profiles:, возможности карты. Узел — строка в Sinks:/Sources: с номером и громкостью, конкретный поток, который уже можно выбрать через wpctl set-default.

Полезные ресурсы

  • ArchWiki: WirePlumber — правила в конфигах, приоритеты узлов, отключение лишних карт.
  • ArchWiki: PipeWire — виртуальные устройства, одновременный вывод, разбор профилей.

Заключение

Переключение профиля — это правка одной строки состояния: сначала смотришь wpctl status, потом узнаёшь индекс из pactl list cards и меняешь профиль через wpctl set-profile. Если менять приходится после каждого подключения монитора или наушников, переноси решение в конфиг с device.profile, и карта перестанет удивлять. А дальше остаётся смотреть wpctl inspect и лог — там видно всё, что надумал менеджер.



Не получилось? Поможем настроить

Задай вопрос в чате — отвечаем быстро, по делу и без воды.

Читайте также

Комментарии

Загрузка…

Откроется GitHub: создайте новый issue с вашим комментарием (кнопка «Submit new issue»). После отправки обновите эту страницу — комментарий появится ниже.

Telegram Max