Все об Arch Linux

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

Звук только в наушниках: почему молчат динамики

Если звук ушёл в гарнитуру, а встроенные динамики молчат, причина почти всегда одна: карта HDA Intel или Realtek сообщает PipeWire, что в разъём воткнута гарнитура, и профиль переключается на наушники. Помогают три уровня — принудительный профиль карты, конфиг WirePlumber и, когда кодек совсем неверно читает пины, hdajackretask. Разберём по порядку: сначала посмотрим, что система вообще видит, потом зафиксируем нужное поведение.

Почему звук идёт только в наушники, а динамики молчат?

У карты HDA один усилитель на колонки и наушники, и переключением между ними занимается кодек, когда приходит сигнал с jack-контакта разъёма. PipeWire на основе этих сигналов создаёт два устройства вывода: alsa_output.pci-0000_00_1f.3.analog-stereo — это колонки, и alsa_output.pci-0000_00_1f.3.analog-stereo.headphone — наушники. Пока гарнитура воткнута, активным становится второе устройство, а профиль карты меняется на output:analog-stereo+input:analog-stereo, чтобы появился микрофон гарнитуры.

Дальше начинается самое неприятное. Окислившийся контакт, неисправный кабель, гарнитура с нестандартной распиновкой или док-станция могут держать сигнал «jack inserted» постоянно. Тогда PipeWire честно считает, что гарнитура подключена, и молчит в колонки, даже когда её в системе нет. Обратная ситуация тоже знакома: гарнитуру вытащили, активный sink перешёл в состояние unavailable, и звук пропадает целиком, потому что никто не слушает выключенное устройство.

Как посмотреть, что именно происходит?

Первым делом открывай wpctl status — он показывает карты, профили, sink’и и источники с отметкой активного устройства звёздочкой:

wpctl status

Вывод интересует в такой части:

├─ Devices:
│  └─ Device #48: Built-in Audio Analog Stereo
│     ├─ Profile: output:analog-stereo+input:analog-stereo
│     ├─ Sinks:
│     │  └─ #49: Built-in Audio Analog Stereo (SPEAKERS)
│     └─ Sources:

Номер #48 здесь не совпадает с индексом ALSA card0 — это разные нумерации, не ищи в них соответствия. Pulse-совместимый список короче и привычнее:

pactl list short cards
pactl list short sinks
pactl get-default-sink

Профили удобнее смотреть в полном виде, там есть строки Profile и Available Profiles:

pactl list cards

А вот за состоянием разъёмов удобно наблюдать вживую — каждое втыкание и извлечение гарнитуры печатается отдельной строкой:

pactl subscribe

Активный sink помечен звёздочкой в конце строки, а пометка unavailable рядом с именем означает, что устройство есть, но слушать его некому. Громкость основного вывода проверяется одним вызовом с волшебным именем @DEFAULT_AUDIO_SINK@ — его не нужно подставлять вручную, он всегда указывает на текущий вывод:

wpctl get-volume @DEFAULT_AUDIO_SINK@

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

wpctl умеет менять профиль напрямую, указываешь id карты из wpctl status и имя профиля из Available Profiles:

wpctl set-profile 48 output:analog-stereo

У Pulse-совместимого варианта имена длиннее, карта задаётся именем:

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

Дальше выбери нужный sink основным и, если колонки и наушники — это один и тот же усилитель, укажи порт руками:

wpctl set-default alsa_output.pci-0000_00_1f.3.analog-stereo
pactl set-sink-port alsa_output.pci-0000_00_1f.3.analog-stereo analog-output-speaker

Ручное переключение живёт до первого же события: воткнул гарнитуру — профиль сменился обратно, перезапустил wireplumber — снова тот профиль, который выбрала политика. Поэтому это способ проверить гипотезу, а не решение. И ещё момент: профиль output:analog-stereo не содержит входа, и встроенный микрофон на ноутбуке пропадёт. Если микрофон нужен, бери output:analog-stereo+input:analog-stereo и правь не профиль, а устройство вывода.

Как переключить вывод для одного приложения?

Профиль у карты общий, но маршрут конкретного потока можно завернуть на другой sink, не трогая остальные:

pactl list short sink-inputs
pactl move-sink-input 512 alsa_output.pci-0000_00_1f.3.analog-stereo

Число 512 берётся из вывода pactl list sink-inputs, где видно и название процесса. Удобно, когда гарнитура нужна только для звонка, а колонки должны звучать постоянно.

Как закрепить профиль, чтобы он не слетал?

Политика WirePlumber выбирает профиль автоматически, и перебить её можно сниппетом в wireplumber.conf.d. Создай файл и пропиши в нём SELECTED_PROFILE для хука select-profile:

sudo mkdir -p /etc/wireplumber/wireplumber.conf.d
sudo nano /etc/wireplumber/wireplumber.conf.d/50-force-analog.conf
metadata = {
  rules = [
    {
      preserve = true,
      match.type = "hook",
      hook.name = "select-profile",
      action.env.SELECTED_PROFILE = "output:analog-stereo+input:analog-stereo",
    }
  ]
}

Такая же папка есть и в домашнем каталоге — ~/.config/wireplumber/wireplumber.conf.d/, если править систему не хочется. Перезапуск сервиса обязателен, иначе сниппет не подхватится:

systemctl --user restart wireplumber

Действующий профиль сразу видно в wpctl status, он больше не прыгает между гарнитурой и колонками. Если wireplumber в системе недавно появился и сначала не заводился, начни с подробного разбора установки и первых граблей — там же лежит проверка, что сервис вообще запущен.

Когда нужен hdajackretask?

Если профиль зафиксирован, а колонки всё равно молчат, значит кодек физически неверно определяет состояние пинов. Тут помогает hdajackretask — небольшая графическая утилита из семейства ALSA-инструментов, которая показывает пины карты и позволяет переназначить их вручную:

sudo pacman -S hdajackretask
hdajackretask

В окне есть тумблер Show un-pinned pins — включи его, чтобы видеть пины, которые кодек не использует. Дальше снимаешь галочку Retask у пина наушников или у внутреннего динамика, и PipeWire перестаёт считать разъём подключённым навсегда. Можно пойти дальше и задать пину свой Pin Default в выпадающем списке режимов, например Headphone или Internal Speaker.

Снимай галочку только с пина, который мешает: если расшарить пины микрофона или линейного входа, отвалится запись, причём без всяких сообщений. Перед правкой имеет смысл снять дамп состояния — самый простой способ это позволяет утилита, а сравнить потом вывод с исходным можно через cat /proc/sound/card0/codec#0.

Изменения применяются сразу, но до перезагрузки живут только в памяти. Чтобы закрепить их, параметры модуля snd_hda_intel прописывают в /etc/modprobe.d/ — ровно это утилита и предлагает сохранить:

sudo nano /etc/modprobe.d/hdajackretask.conf
options snd_hda_intel force_unpinned_hp=1 force_unpinned_sp=1

Точный набор опций зависит от кодека, поэтому сверяйся с тем, что показывает утилита, и проверяй результат в выводе ALSA:

cat /proc/sound/card0/codec#0

Для части ноутбуков с криво определённым кодеком вместо переназначения пинов помогает явный профиль в том же файле — options snd_hda_intel model=ideapad или похожий. Неудачный model симптомы только усиливает, поэтому менять его стоит, только когда в выводе кодека видно, что имя устройства не совпадает с ожидаемым.

Как проверить, что переключение заработало?

Проверяй в три приёма. Первый — wpctl status: у карты стоит нужный Profile, а активный sink отмечен звёздочкой. Второй — живая подписка: запусти pactl subscribe в одном окне и воткни-вытащи гарнитуру, события должны появиться сразу, без перезапуска сессии. Третий — журнал сессии, там видно, какое решение приняла политика:

journalctl --user -u wireplumber -f

Если переключение всё ещё не происходит, перезагрузи сервис и проверь ещё раз — иногда правки в wireplumber.conf.d подхватываются только с чистого старта.

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

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

Активным остался sink гарнитуры, который после unplug переходит в состояние unavailable — слушать его некому, поэтому тишина. Смотри wpctl status, найди устройство с пометкой unavailable и верни колонки основными: wpctl set-default alsa_output.pci-0000_00_1f.3.analog-stereo. Если состояние не меняется, помогает systemctl --user restart wireplumber.

В списке sink’ов только HDMI от видеокарты, динамиков нет

Тут проблема не в разъёме, а в том, что PipeWire выбрал карту расширения. Профиль output:hdmi-stereo на карте NVIDIA живёт отдельно от встроенной аналоговой карты, и лечится либо фиксацией нужной карты в конфиге, либо разбором HDMI-звука — как вернуть звук через видеокарту NVIDIA.

Почему правки /etc/asound.conf ничего не меняют?

Этот файл описывает устройства для нативного ALSA, а PipeWire работает поверх своего бэкенда alsa и конфигурации ALSA из этого файла не читает. Параметры драйвера и кодеков живут в /etc/modprobe.d/, а политика выбора устройств — в wireplumber.conf.d/. Правь эти два места.

Как вернуть микрофон, если профиль зафиксирован?

Бери профиль output:analog-stereo+input:analog-stereo в SELECTED_PROFILE, как в примере выше, либо оставь output:analog-stereo и пользуйся внешним USB-микрофоном. После смены профиля проверь pactl list short sources — источник должен появиться.

А если после всех правок стало только хуже?

Откатывай по порядку: убери свой сниппет из wireplumber.conf.d, затем файл из /etc/modprobe.d/ и пересобери модуль (mkinitcpio -P, затем перезагрузка). Иногда набор пакетов с аудио-стеком проще снести и поставить заново — разбор таких случаев с командами отката.

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

Заключение

Звук, который застрял в гарнитуре, лечится по нарастающей сложности: сначала принудительный профиль и проверка портов, затем закреплённый SELECTED_PROFILE в конфиге WirePlumber, и только в последнюю очередь hdajackretask с переназначением пинов. Начинай с wpctl status — он сразу показывает, где именно сломалось переключение.



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

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

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

Комментарии

Загрузка…

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

Telegram Max