.. ARU (c) 2018 - 2025, Pavel Priluckiy, Vasiliy Stelmachenok and contributors

   ARU is licensed under a
   Creative Commons Attribution-ShareAlike 4.0 International License.

   You should have received a copy of the license along with this
   work. If not, see <https://creativecommons.org/licenses/by-sa/4.0/>.

.. _sound:

**********************
Низкие задержки звука
**********************

.. index:: installation, lowlatency, audio, pipewire
.. _pipewire:

========
PipeWire
========

`PipeWire <https://wiki.archlinux.org/title/PipeWire_(Русский)>`__ -
это новая альтернатива PulseAudio, которая призвана избавить от
проблем своего предшественника, уменьшить задержки звука, снизить
потребление памяти и улучшить безопасность. PipeWire поставляется по
умолчанию в Arch Linux в качестве звукового сервера, требуемого для
клиентов libpulse [#]_, так что никаких команд для его установки
прописывать не нужно. Однако несмотря на это рекомендуется установить
дополнительные компоненты и явно включить пользовательские службы для
уменьшения их задержки запуска через активацию путем сокетов, которая
используется по умолчанию для запуска PipeWire::

  sudo pacman -S pipewire-jack lib32-pipewire gst-plugin-pipewire
  systemctl --user enable --now pipewire pipewire-pulse wireplumber

.. note:: Пакет ``lib32-pipewire`` нужен для правильной работы звука в
   32-битных играх запускаемых через Wine или Proton, а также в нативных портах
   игр под Linux.

Для непосредственно уменьшения самих задержек установим дополнительный
пакет ``realtime-privileges`` и добавим пользователя в группу
``realtime``::

  sudo pacman -S realtime-privileges rtkit
  sudo usermod -aG realtime "$USER"

Дополнительно советуем установить реализацию Jack API. См. раздел
ниже.

.. [#] https://gitlab.archlinux.org/archlinux/packaging/packages/pipewire/-/commit/14614b08f6f8cf8e50b4cbb78a141e82066e7f80

.. index:: pipewire, lowlatency, audio, sound
.. _pipewire_setup:

--------------------
Настройка PipeWire
--------------------

Несмотря на то, что настройки по умолчанию могут работать достаточно
хорошо для большинства оборудования, имеет смысл выполнить
дополнительную настройку для улучшения качества звука (особенно если
вы являетесь обладателем ЦАП или полноценной звуковой карты).

Сначала создадим пути для хранения конфигурационных файлов в домашней
директории::

  mkdir -p ~/.config/pipewire/pipewire.conf.d

В появившейся директории создадим файл со следующим содержанием:

.. code-block:: shell
  :caption: ``nano ~/.config/pipewire/pipewire.conf.d/10-no-resampling.conf``

   context.properties = {
     default.clock.rate = 48000
     default.clock.allowed-rates = [ 44100 48000 96000 192000 ]
   }


Фактически здесь мы настраиваем две вещи: первое, это частота дискретизации,
используемая по умолчанию (``defalut.clock.rate``), в зависимости от которой
PipeWire так же считает оптимальные задержки для вывода звука, а именно так
называемые значения ``quantum``, о которых будет рассказано в следующем
разделе. Во-вторых, мы явно перечисляем все доступные частоты дискретизации
(``defalut.clock.allowed-rates``), поддерживаемые нашим устройством вывода
звука (ЦАП или встроенная аудиокарта). Это нужно для того, чтобы PipeWire не
делал ресемплирования, то есть изменения частоты дискретизации исходного
аудиопотока к частоте используемой по умолчанию, что может повлечь за собой
ухудшение качества итогового звучания, а также дополнительные накладные расходы
в виде нагрузки на CPU.

Важно отметить, что PipeWire выполняет переключение между указанными частотами
дискретизации только в состоянии покоя непосредственно перед началом вывода
нового аудиопотока, однако если вы начинаете проигрывать ещё один аудиопоток,
то PipeWire не поменяет частоту дискретизации с учетом второго аудиопотока, а
продолжит использовать ту же частоту дискретизации, что и у первого, и это
может опять же привести к ситуации ресемплинга второго аудиопотока до уровня
первого. В случае же если первоначальный аудиопоток не попадал в указанный
диапозон частот, то он также бы ресемплировался от целовой к самой "ближайшей"
частоте из перечисленных.

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

.. tab-set::

   .. tab-item:: Звуковой чип

      ::

         cat /proc/asound/card0/codec\#0 | grep -A 8 "Audio Output" -m 1 | grep rates

   .. tab-item:: ЦАП

      ::

         cat /proc/asound/card0/stream0 | grep Rates | uniq

Частоты, которые были получены таким образом, нужно прописать через пробел
взамен тех, что даны в примере выше. Если доступно несколько устройств, то при
помощи команды ``cat /proc/asound/cards`` узнайте номер звуковой карты, которая
используется непосредственно для вывода звука, и подставьте его в команду выше.

.. index:: pipewire, upmix, 5.1, sound
.. _upmixing-5.1:

^^^^^^^^^^^^^^^^^^^^^^^^^^^
Микширование стерео в 5.1
^^^^^^^^^^^^^^^^^^^^^^^^^^^

PipeWire так же как и PulseAuido позволяет микшировать звук в 5.1.
Эта возможность отключена по умолчанию, но для неё существует заранее
подготовленный конфигурационный файл, который нам нужно просто
перенести в домашнюю директорию::

  mkdir -p ~/.config/pipewire/pipewire-pulse.conf.d ~/.config/pipewire/client-rt.conf.d
  cp /usr/share/pipewire/client-rt.conf.avail/20-upmix.conf ~/.config/pipewire/pipewire-pulse.conf.d
  cp /usr/share/pipewire/client-rt.conf.avail/20-upmix.conf ~/.config/pipewire/client-rt.conf.d

.. index:: pipewire, choppy, high-load, cpu, sound
.. _choppy-audio:

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Исправление хрипов под нагрузкой
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Некоторые пользователи после перехода на PipeWire могут столкнуться с
появлением "хрипов" во время произведения звука, если система находится
под высокой нагрузкой (например, фоновой компиляцией или во время игры).
Это происходит потому, что PipeWire старается осуществлять вывод с
звука с наименьшими задержками, что сложно гарантировать когда
система нагружена даже с установленными ``realtime-privileges``.

Для их исправления отредактируем файл, который мы создали выше, и
изменим следующие значения для размера буфера по умолчанию:

.. code-block:: shell
  :caption: ``nano ~/.config/pipewire/pipewire.conf.d/10-sound.conf``

   context.properties = {
     default.clock.rate = 48000
     default.clock.allowed-rates = [ 44100 48000 88200 96000 ]
     default.clock.min-quantum = 512
     default.clock.quantum = 4096
     default.clock.max-quantum = 8192
   }

Здесь вы должны изменить только значение параметра ``quantum`` до
4096. Остальные значения как ``default.clock.rate`` и
``default.clock.allowed-rates`` вы должны указывать с учетом
вашего оборудования, как уже говорилось выше.

.. jack:

----
JACK
----

JACK - это ещё один альтернативный звуковой сервер с одноименной
библиотекой API, цель которого состоит выведение звука с минимальной
задержкой. Несмотря на неплохую поддержку JACK со стороны многих
приложений, автор рекомендует по прежнему использовать звуковой сервер
PipeWire, так как актуальная реализация JACK - `jack2
<https://github.com/jackaudio/jack2>`__, практически не получает
серьёзных улучшений и находится скорее в состоянии сопровождения.

Для правильной работы приложений использующих JACK в качестве
библиотеки API лучше всего установить пакет ``pipewire-jack``, который
предоставляет совместимость между такими приложениями со звуковым
сервером PipeWire, что позволяет всем изменениям проделенным выше для
его настройки распространяться и на приложения, использующие JACK.

.. vim:set textwidth=70:
