486 lines
17 KiB
ReStructuredText
486 lines
17 KiB
ReStructuredText
.. _config_alsa:
|
|
|
|
ALSA configuration
|
|
==================
|
|
|
|
One of the components of WirePlumber is the ALSA monitor. This monitor is
|
|
responsible for creating PipeWire devices and nodes for all the ALSA cards that
|
|
are available on the system. It also manages the configuration of these devices.
|
|
|
|
The ALSA monitor is enabled by default and can be disabled using the
|
|
``monitor.alsa`` :ref:`feature <config_features>` in the configuration file.
|
|
|
|
The monitor, as with all device monitors, is implemented as a SPA plugin and is
|
|
part of PipeWire. WirePlumber merely loads the plugin and lets it do its work.
|
|
The plugin then monitors UDev and creates device and node objects for all the
|
|
ALSA cards that are available on the system.
|
|
|
|
.. note::
|
|
|
|
One thing worth remembering here is that in ALSA, a "card" represents a
|
|
physical sound controller device, and a "device" is a logical access point
|
|
that represents a set of inputs and/or outputs that are part of the card. In
|
|
PipeWire, a "device" is the direct equivalent of an ALSA "card" and a "node"
|
|
is almost equivalent (close, but not quite) of an ALSA "device".
|
|
|
|
Properties
|
|
----------
|
|
|
|
The ALSA monitor SPA plugin (``api.alsa.enum.udev``) supports properties that
|
|
can be used to configure it when it is loaded. These properties can be set in
|
|
the ``monitor.alsa.properties`` section of the WirePlumber configuration file.
|
|
|
|
Example:
|
|
|
|
.. code-block::
|
|
|
|
monitor.alsa.properties = {
|
|
alsa.use-acp = true
|
|
}
|
|
|
|
.. describe:: alsa.use-acp
|
|
|
|
A boolean that controls whether the ACP (alsa card profile) code is to be
|
|
the default manager of the device. This will probe the device and configure
|
|
the available profiles, ports and mixer settings. The code to do this is
|
|
taken directly from PulseAudio and provides devices that look and feel
|
|
exactly like the PulseAudio devices.
|
|
|
|
Rules
|
|
-----
|
|
|
|
When device and node objects are created by the ALSA monitor, they can be
|
|
configured using rules. These rules allow matching the existing properties of
|
|
these objects and updating them with new values. This is the main way of
|
|
configuring ALSA device settings.
|
|
|
|
These rules can be set in the ``monitor.alsa.rules`` section of the WirePlumber
|
|
configuration file.
|
|
|
|
Example:
|
|
|
|
.. code-block::
|
|
|
|
monitor.alsa.rules = [
|
|
{
|
|
matches = [
|
|
{
|
|
# This matches the value of the 'device.name' property of the device.
|
|
device.name = "~alsa_card.*"
|
|
}
|
|
]
|
|
actions = {
|
|
update-props = {
|
|
# Apply all the desired device settings here.
|
|
api.alsa.use-acp = true
|
|
}
|
|
}
|
|
}
|
|
{
|
|
matches = [
|
|
# This matches the value of the 'node.name' property of the node.
|
|
{
|
|
node.name = "~alsa_output.*"
|
|
}
|
|
]
|
|
actions = {
|
|
# Apply all the desired node specific settings here.
|
|
update-props = {
|
|
node.nick = "My Node"
|
|
priority.driver = 100
|
|
session.suspend-timeout-seconds = 5
|
|
}
|
|
}
|
|
}
|
|
]
|
|
|
|
Device properties
|
|
^^^^^^^^^^^^^^^^^
|
|
|
|
The following properties can be configured on devices created by the monitor:
|
|
|
|
.. describe:: api.alsa.use-acp
|
|
|
|
Use the ACP (alsa card profile) code to manage this device. This will probe
|
|
the device and configure the available profiles, ports and mixer settings.
|
|
The code to do this is taken directly from PulseAudio and provides devices
|
|
that look and feel exactly like the PulseAudio devices.
|
|
|
|
:Default value: ``true``
|
|
:Type: boolean
|
|
|
|
.. describe:: api.alsa.use-ucm
|
|
|
|
When ACP is enabled and a UCM configuration is available for a device, by
|
|
default it is used instead of the ACP profiles. This option allows you to
|
|
disable this and use the ACP profiles instead.
|
|
|
|
This option does nothing if ``api.alsa.use-acp`` is set to ``false``.
|
|
|
|
:Default value: ``true``
|
|
:Type: boolean
|
|
|
|
.. describe:: api.alsa.soft-mixer
|
|
|
|
Setting this option to ``true`` will disable the hardware mixer for volume
|
|
control and mute. All volume handling will then use software volume and mute,
|
|
leaving the hardware mixer untouched. The hardware mixer will still be used
|
|
to mute unused audio paths in the device.
|
|
|
|
:Type: boolean
|
|
|
|
.. describe:: api.alsa.ignore-dB
|
|
|
|
Setting this option to ``true`` will ignore the decibel setting configured by
|
|
the driver. Use this when the driver reports wrong settings.
|
|
|
|
:Type: boolean
|
|
|
|
.. describe:: device.profile-set
|
|
|
|
This option can be used to select a custom ACP profile-set name for the
|
|
device. This can be configured in UDev rules, but it can also be specified
|
|
here. The default is to use "default.conf".
|
|
|
|
:Type: string
|
|
|
|
.. describe:: device.profile
|
|
|
|
The initial active profile name. The default is to start from the "Off"
|
|
profile and then let WirePlumber select the best profile based on its
|
|
policy.
|
|
|
|
:Type: string
|
|
|
|
.. describe:: api.acp.auto-profile
|
|
|
|
Automatically select the best profile for the device. Normally this option is
|
|
disabled because WirePlumber will manage the profile of the device.
|
|
WirePlumber can save and load previously selected profiles. Enable this in
|
|
custom configurations where the relevant WirePlumber components are disabled.
|
|
|
|
:Type: boolean
|
|
|
|
.. describe:: api.acp.auto-port
|
|
|
|
Automatically select the highest priority port that is available ("port" is a
|
|
PulseAudio/ACP term, the equivalent of a "Route" in PipeWire). This is by
|
|
default disabled because WirePlumber handles the task of selecting and
|
|
restoring Routes. Enable this in custom configurations where the relevant
|
|
WirePlumber components are disabled.
|
|
|
|
:Type: boolean
|
|
|
|
.. describe:: api.acp.probe-rate
|
|
|
|
Sets the samplerate used for probing the ALSA devices and collecting the
|
|
profiles and ports.
|
|
|
|
:Type: integer
|
|
|
|
.. describe:: api.acp.pro-channels
|
|
|
|
Sets the number of channels to use when probing the "Pro Audio" profile.
|
|
Normally, the maximum amount of channels will be used but with this setting
|
|
this can be reduced, which can make it possible to use other samplerates on
|
|
some devices.
|
|
|
|
:Type: integer
|
|
|
|
Some of the other properties that can be configured on devices:
|
|
|
|
.. describe:: device.nick
|
|
|
|
A short name for the device.
|
|
|
|
.. describe:: device.description
|
|
|
|
A longer, user-friendly name of the device. This will show up in most
|
|
user interfaces as the device's name.
|
|
|
|
.. describe:: device.disabled
|
|
|
|
Disables the device. PipeWire will remove it from the list of cards or
|
|
devices.
|
|
|
|
:Type: boolean
|
|
|
|
Node properties
|
|
^^^^^^^^^^^^^^^
|
|
|
|
The following properties can be configured on nodes created by the monitor:
|
|
|
|
.. describe:: priority.driver
|
|
|
|
This configures the node driver priority. Nodes with higher priority will be
|
|
used as a driver in the graph. Other nodes with lower priority will have to
|
|
resample to the driver node when they are joined in the same graph. The
|
|
default value is set based on some heuristics.
|
|
|
|
:Type: integer
|
|
|
|
.. describe:: priority.session
|
|
|
|
This configures the priority of the node when selecting a default node
|
|
(default sink/source as a link target for streams). Higher priority nodes
|
|
will be more likely candidates for becoming the default node.
|
|
|
|
:Type: integer
|
|
|
|
.. note::
|
|
|
|
By default, sources have a ``priority.session`` value around 1600-2000 and
|
|
sinks have a value around 600-1000. If you are increasing the priority of
|
|
a sink, it is **not advised** to use a value higher than 1500, as it may
|
|
cause a sink's monitor to be selected as the default source.
|
|
|
|
.. describe:: node.pause-on-idle
|
|
|
|
Pause the node when nothing is linked to it anymore. This is by default false
|
|
because some devices make a "pop" sound when they are opened/closed.
|
|
The node will normally pause and suspend after a timeout (see below).
|
|
|
|
:Type: boolean
|
|
|
|
.. describe:: session.suspend-timeout-seconds
|
|
|
|
This option configures a different suspend timeout on the node. By default
|
|
this is ``5`` seconds. For some devices (HiFi amplifiers, for example) it
|
|
might make sense to set a higher timeout because they might require some time
|
|
to restart after being idle.
|
|
|
|
A value of ``0`` disables suspend for a node and will leave the ALSA device
|
|
busy. The device can then be manually suspended with
|
|
``pactl suspend-sink|source``.
|
|
|
|
:Type: integer
|
|
|
|
.. describe:: audio.format
|
|
|
|
The sample format of the device. By default, PipeWire will use a 32 bits
|
|
sample format but a different format can be set here.
|
|
|
|
:Type: string (``"S16LE"``, ``"S32LE"``, ``"F32LE"``, ...)
|
|
|
|
.. describe:: audio.rate
|
|
|
|
The sample rate of the device. By default, the ALSA device will be configured
|
|
with the same samplerate as the global graph. If this is not supported, or a
|
|
custom value is set here, resampling will be used to match the graph rate.
|
|
|
|
:Type: integer
|
|
|
|
.. describe:: audio.channels
|
|
|
|
The number of channels of the device. By default the channels and their
|
|
position are determined by the selected device profile. You can override
|
|
this setting here.
|
|
|
|
:Type: integer
|
|
|
|
.. describe:: audio.position
|
|
|
|
The position of the channels. By default the number of channels and their
|
|
position are determined by the selected device profile. You can override
|
|
this setting here and optionally swap or reconfigure the channel positions.
|
|
|
|
:Type: array of strings (example: ``["FL", "FR", "LFE", "FC", "RL", "RR"]``)
|
|
|
|
.. describe:: api.alsa.use-chmap
|
|
|
|
Use the channel map as reported by the driver. This is disabled by default
|
|
because it is often wrong and the ACP code handles this better.
|
|
|
|
:Type: boolean
|
|
|
|
.. describe:: api.alsa.disable-mmap
|
|
|
|
Disable the use of mmap for the ALSA device. By default, PipeWire will access
|
|
the memory of the device using mmap. This can be disabled and force the usage
|
|
of the slower read and write access modes, in case the mmap support of the
|
|
device is not working properly.
|
|
|
|
:Type: boolean
|
|
|
|
.. describe:: channelmix.normalize
|
|
|
|
Normalize the channel volumes when mixing & resampling, making sure that the
|
|
original 0 dB level is preserved so that nothing sounds wildly
|
|
quieter/louder. This is disabled by default.
|
|
|
|
:Type: boolean
|
|
|
|
.. describe:: channelmix.mix-lfe
|
|
|
|
Creates a "center" channel for X.0 recordings from the front stereo on X.1
|
|
setups and pushes some low-frequency/bass from the "center" of X.1 recordings
|
|
into the front stereo on X.0 setups. This is disabled by default.
|
|
|
|
:Type: boolean
|
|
|
|
.. describe:: monitor.channel-volumes
|
|
|
|
By default, the volume of the sink/source does not influence the volume on
|
|
the monitor ports. Set this option to true to change this. PulseAudio has
|
|
inconsistent behaviour regarding this option, it applies channel-volumes only
|
|
when the sink/source is using software volumes.
|
|
|
|
:Type: boolean
|
|
|
|
.. describe:: node.disabled
|
|
|
|
Disables the node. Pipewire will remove it from the list of the nodes.
|
|
|
|
:Type: boolean
|
|
|
|
ALSA buffer properties
|
|
......................
|
|
|
|
PipeWire by default uses a timer to consume and produce samples to/from ALSA
|
|
devices. After every timeout, it queries the hardware pointers of the device and
|
|
uses this information to set a new timeout. This works well for most devices,
|
|
but there is a class of devices, so called "batch" devices, that need extra
|
|
buffering and timing tweaks to work properly. This is because batch devices only
|
|
get their hardware pointers updated after each hardware interrupt. When the
|
|
hardware interrupt frequency and the timer frequency are aligned, it is possible
|
|
for the hardware pointers to be updated just after the timer has expired,
|
|
resulting in sometimes wrong timing information being returned by the query. In
|
|
contrast, non-batch devices get pointer updates independent of the interrupt.
|
|
|
|
This means that for batch devices we need to set the interrupt at a sufficiently
|
|
high frequency, at the cost of CPU usage, while for non-batch devices we want to
|
|
set the interrupt frequency as low as possible to save CPU. For batch devices
|
|
we also need to take the extra buffering into account caused by the delayed
|
|
updates of the hardware pointers.
|
|
|
|
.. note::
|
|
|
|
Most USB devices are batch devices and will be handled as such by PipeWire by
|
|
default.
|
|
|
|
There are 2 tunable parameters to control the buffering and timeouts in a
|
|
device:
|
|
|
|
.. describe:: api.alsa.period-size
|
|
|
|
This sets the device interrupt to every period-size samples for non-batch
|
|
devices and to half of this for batch devices. For batch devices, the other
|
|
half of the period-size is used as extra buffering to compensate for the
|
|
delayed update. So, for batch devices, there is an additional period-size/2
|
|
delay. It makes sense to lower the period-size for batch devices to reduce
|
|
this delay.
|
|
|
|
:Type: integer (samples)
|
|
|
|
.. describe:: api.alsa.headroom
|
|
|
|
This adds extra delay between the hardware pointers and software pointers.
|
|
In most cases this can be set to 0. For very bad devices or emulated devices
|
|
(like in a VM) it might be necessary to increase the headroom value.
|
|
|
|
:Type: integer (samples)
|
|
|
|
.. describe:: api.alsa.period-num
|
|
|
|
This configures the number of periods in the hardware buffer, which controls
|
|
its size. Note that this is multiplied by the period of the device to
|
|
determine the size, so for batch devices, the total buffer size is
|
|
effectively period-num * period-size/2.
|
|
|
|
:Type: integer
|
|
|
|
In summary, this is the overview of buffering and timings:
|
|
|
|
============== ============================================ ==========================================
|
|
Property Batch Non-Batch
|
|
============== ============================================ ==========================================
|
|
IRQ Frequency api.alsa.period-size/2 api.alsa.period-size
|
|
Extra Delay api.alsa.headroom + api.alsa.period-size/2 api.alsa.headroom
|
|
Buffer Size api.alsa.period-num * api.alsa.period-size/2 api.alsa.period-num * api.alsa.period-size
|
|
============== ============================================ ==========================================
|
|
|
|
Finally, it is possible to disable the batch device tweaks with:
|
|
|
|
.. describe:: api.alsa.disable-batch
|
|
|
|
This disables the batch device tweaks. It removes the extra delay added of
|
|
period-size/2 if the device can support this. For batch devices it is also a
|
|
good idea to lower the period-size (and increase the IRQ frequency) to get
|
|
smaller batch updates and lower latency.
|
|
|
|
:Type: boolean
|
|
|
|
ALSA extra latency properties
|
|
.............................
|
|
|
|
Extra internal delay in the DAC and ADC converters of the device itself can be
|
|
set with the ``latency.internal.*`` properties:
|
|
|
|
.. code-block::
|
|
|
|
latency.internal.rate = 256
|
|
latency.internal.ns = 0
|
|
|
|
You can configure a latency in samples (relative to rate with
|
|
``latency.internal.rate``) or in nanoseconds (``latency.internal.ns``).
|
|
This value will be added to the total reported latency by the node of the device.
|
|
|
|
You can use a tool like ``jack_iodelay`` to get the number of samples of
|
|
internal latency of your device.
|
|
|
|
This property is also adjustable at runtime with the ``ProcessLatency`` param.
|
|
You will need to find the id of the Node you want to change. For example:
|
|
Query the current internal latency of an ALSA node with id 58:
|
|
|
|
.. code-block:: console
|
|
|
|
$ pw-cli e 58 ProcessLatency
|
|
Object: size 80, type Spa:Pod:Object:Param:ProcessLatency (262156), id Spa:Enum:ParamId:ProcessLatency (16)
|
|
Prop: key Spa:Pod:Object:Param:ProcessLatency:quantum (1), flags 00000000
|
|
Float 0.000000
|
|
Prop: key Spa:Pod:Object:Param:ProcessLatency:rate (2), flags 00000000
|
|
Int 0
|
|
Prop: key Spa:Pod:Object:Param:ProcessLatency:ns (3), flags 00000000
|
|
Long 0
|
|
|
|
Set the internal latency to 256 samples:
|
|
|
|
.. code-block:: console
|
|
|
|
$ pw-cli s 58 ProcessLatency '{ rate = 256 }'
|
|
Object: size 32, type Spa:Pod:Object:Param:ProcessLatency (262156), id Spa:Enum:ParamId:ProcessLatency (16)
|
|
Prop: key Spa:Pod:Object:Param:ProcessLatency:rate (2), flags 00000000
|
|
Int 256
|
|
remote 0 node 58 changed
|
|
remote 0 port 70 changed
|
|
remote 0 port 72 changed
|
|
remote 0 port 74 changed
|
|
remote 0 port 76 changed
|
|
|
|
Startup tweaks
|
|
..............
|
|
|
|
.. describe:: api.alsa.start-delay
|
|
|
|
Some devices need some time before they can report accurate hardware pointer
|
|
positions. In those cases, an extra start delay can be added to compensate
|
|
for this startup delay. This sets the startup delay in samples. The default
|
|
is 0.
|
|
|
|
:Type: integer (samples)
|
|
|
|
IEC958 (S/PDIF) passthrough
|
|
...........................
|
|
|
|
.. describe:: iec958.codecs
|
|
|
|
S/PDIF passthrough will only be enabled when the accepted codecs are configured
|
|
on the ALSA device. This can be done by setting the list of supported codecs
|
|
on this property.
|
|
|
|
Note that it is possible to also configure this property at runtime, either
|
|
with tools like pavucontrol or with the ``pw-cli`` tool, like this:
|
|
``pw-cli s <node-id> Props '{ iec958Codecs : [ PCM ] }'``
|
|
|
|
:Type: array of strings (example: ``[ "PCM", "DTS", "AC3", "EAC3", "TrueHD", "DTS-HD" ]``)
|