|
|
[[_TOC_]]
|
|
|
|
|
|
# General
|
|
|
|
|
|
ALSA devices are created and managed by the session manager with the alsa-monitor module. For general configuration of the session manager see [here](Config-pipewire-media-session).
|
|
|
|
|
|
# Configuration File (`alsa-monitor.conf`)
|
|
|
|
|
|
The alsa-monitor module uses udev to detect devices. For each device, a new PipeWire device is created. Setting a profile on the device will then create the source and sink nodes used for capture and playback to the device.
|
|
|
|
|
|
The alsa-monitor module has a configuration file template located in `/usr/share/pipewire/media-session.d/alsa-monitor.conf`. You can copy and edit the file to `/etc/pipewire/` or `~/.config/pipewire/media-session.d/alsa-monitor.conf`.
|
|
|
|
|
|
## Properties
|
|
|
|
|
|
The configuration file has the following properties in the `properties = {}` section:
|
|
|
|
|
|
```
|
|
|
alsa.jack-device = false
|
|
|
```
|
|
|
`alsa.jack-device` defaults to false. Setting this to true will create a new JACK device. Setting the device profile to `On` (Using pactl, pavucontrol or [pw-cli](Migrate-PulseAudio#set-card-profile)) will create a JACK sink and source node that connects to the JACK server and allows data exchange with a JACK server.
|
|
|
|
|
|
```
|
|
|
alsa.reserve = true
|
|
|
```
|
|
|
Uses dbus to perform [device reservation](http://git.0pointer.net/reserve.git/tree/reserve.txt). You can manually disable this feature, for example, when dbus is not available.
|
|
|
|
|
|
## Matching Rules
|
|
|
|
|
|
The alsa-monitor module implements pipewire-media-session [matching rules](Config-pipewire-media-session#matching-rules). Check out the documentation for the matching rules for how to configure matching rules for devices and nodes (sinks and sources).
|
|
|
|
|
|
In the next sections we talk about the properties that can be configured on the object from the alsa-monitor module.
|
|
|
|
|
|
### Device Properties
|
|
|
|
|
|
PipeWire devices correspond to the ALSA cards. The following properties can be configured on devices created by alsa-monitor:
|
|
|
|
|
|
```
|
|
|
api.alsa.use-acp = true
|
|
|
```
|
|
|
Use the ACP (alsa card profile) code to manage 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.
|
|
|
|
|
|
ACP is also required when your device requires a UCM profile to operate.
|
|
|
|
|
|
```
|
|
|
api.alsa.use-ucm = true
|
|
|
```
|
|
|
By default, the UCM configuration is used when it is available for your device. With this option you can disable this and use the ACP profiles instead.
|
|
|
|
|
|
```
|
|
|
api.alsa.soft-mixer = false
|
|
|
```
|
|
|
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.
|
|
|
|
|
|
```
|
|
|
api.alsa.ignore-dB = false
|
|
|
```
|
|
|
Setting this option to `true` will ignore the decibel setting configured by the driver. Use this when the driver reports wrong settings.
|
|
|
|
|
|
```
|
|
|
device.profile-set = "profileset-name"
|
|
|
```
|
|
|
This option can be used to select a custom profileset name for the device. Usually this is configured in udev rules but it can also be specified here.
|
|
|
|
|
|
```
|
|
|
device.profile = "default profile name"
|
|
|
```
|
|
|
The default active profile name.
|
|
|
|
|
|
```
|
|
|
api.acp.auto-profile = false
|
|
|
```
|
|
|
Automatically select the best profile for the device. Normally this option is disabled because the session manager will manage the profile of the device. The session manager can save and load previously selected profiles. Enable this if your session manager does not handle this feature.
|
|
|
|
|
|
```
|
|
|
api.acp.auto-port = false
|
|
|
```
|
|
|
Automatically select the highest priority port that is available. This is by default disabled because the session manager handles the task of selecting and restoring ports. It can, for example, restore previously saved volumes. Enable this here when the session manager does not handle port restore.
|
|
|
|
|
|
Some of the other properties that might be configured on devices:
|
|
|
|
|
|
```
|
|
|
device.nick = "My Device"
|
|
|
device.description = "My Device"
|
|
|
```
|
|
|
|
|
|
`device.description` will show up in most apps when a device name is shown.
|
|
|
|
|
|
### Node Properties
|
|
|
|
|
|
Nodes are sinks or sources in the PipeWire graph. They correspond to the ALSA devices.
|
|
|
|
|
|
In addition to the generic [stream](Config-client#streams) node configuration options, there are some alsa specific options as well:
|
|
|
|
|
|
```
|
|
|
priority.driver = 2000
|
|
|
```
|
|
|
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.
|
|
|
|
|
|
```
|
|
|
priority.session = 100
|
|
|
```
|
|
|
This configures the priority of the device when selecting a default device. Higher priority devices will be more likely candidates as a default device.
|
|
|
|
|
|
```
|
|
|
node.pause-on-idle = false
|
|
|
```
|
|
|
Pause-on-idle will stop the node when nothing is linked to it anymore. This is by default false because some devices cause a pop when they are opened/closed. The node will, normally, pause and suspend after a timeout (see [module-suspend](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-pipewire-media-session#module-suspend)).
|
|
|
|
|
|
```
|
|
|
session.suspend-timeout-seconds = 5 # 0 disables suspend
|
|
|
```
|
|
|
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 manually be suspended with `pactl suspend-sink|source`.
|
|
|
|
|
|
The following properties can be used to configure the format used by the ALSA device:
|
|
|
|
|
|
```
|
|
|
audio.format = "S16LE"
|
|
|
```
|
|
|
By default, PipeWire will use a 32 bits sample format but a different format can be set here.
|
|
|
|
|
|
The Audio rate of a device can be set here:
|
|
|
```
|
|
|
audio.rate = 44100
|
|
|
```
|
|
|
By default, the ALSA device will be configured with the same samplerate as the global graph. If this is not supported, or a custom values is set here, resampling will be used to match the graph rate.
|
|
|
|
|
|
```
|
|
|
audio.channels = 2
|
|
|
audio.position = "FL,FR"
|
|
|
```
|
|
|
By default the 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.
|
|
|
|
|
|
```
|
|
|
api.alsa.use-chmap = false
|
|
|
```
|
|
|
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.
|
|
|
|
|
|
```
|
|
|
api.alsa.disable-mmap = true
|
|
|
```
|
|
|
PipeWire will by default 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.
|
|
|
|
|
|
````
|
|
|
channelmix.normalize
|
|
|
````
|
|
|
Makes sure that during such mixing & resampling original 0 dB level is preserved, so nothing sounds wildly quieter/louder.
|
|
|
|
|
|
````
|
|
|
channelmix.mix-lfe
|
|
|
````
|
|
|
Creates "center" channel for X.0 recordings from front stereo on X.1 setups and pushes some low-frequency/bass from "center" from X.1 recordings into front stereo on X.0 setups.
|
|
|
|
|
|
|
|
|
```
|
|
|
monitor.channel-volumes = false
|
|
|
```
|
|
|
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.
|
|
|
|
|
|
|
|
|
### ALSA Buffer Properties
|
|
|
|
|
|
PipeWire uses a timer to consume and produce samples to/from ALSA devices. After every timeout, it queries the device hardware pointers of the device and uses this information to set a new timeout. See also [this](https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/master/spa/plugins/alsa/test-timer.c) example program.
|
|
|
|
|
|
By default, PipeWire handles ALSA batch devices differently from non-batch devices. Batch devices only get their hardware pointers updated after each hardware interrupt. Non-batch devices get 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.
|
|
|
|
|
|
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:
|
|
|
|
|
|
```
|
|
|
api.alsa.period-size = 1024
|
|
|
```
|
|
|
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.
|
|
|
|
|
|
```
|
|
|
api.alsa.headroom = 0
|
|
|
```
|
|
|
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.
|
|
|
|
|
|
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
|
|
|
|
|
|
It is possible to disable the batch device tweaks with:
|
|
|
|
|
|
```
|
|
|
api.alsa.disable-batch = true
|
|
|
```
|
|
|
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.
|
|
|
|
|
|
### 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:
|
|
|
|
|
|
```
|
|
|
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:
|
|
|
```
|
|
|
# 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:
|
|
|
```
|
|
|
# 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
|
|
|
|
|
|
Some devices need some time before they can report accurate hardware pointer positions. In those cases, an extra start delay can be added that is used to compensate for this startup delay:
|
|
|
|
|
|
```
|
|
|
api.alsa.start-delay = 0
|
|
|
```
|
|
|
It is unsure when this tunable should be used.
|
|
|
|
|
|
### IEC958 (S/PDIF) passthrough
|
|
|
|
|
|
S/PDIF passthrough will only be enabled when the accepted codecs are configured on the ALSA device.
|
|
|
|
|
|
This can be done in 3 different ways:
|
|
|
|
|
|
1. Use pavucontrol and toggle the codecs in the output advanced section
|
|
|
|
|
|
2. Modify the `iec958.codecs = [ PCM DTS AC3 MPEG MPEG2-AAC EAC3 TrueHD DTS-HD ]` node property to something.
|
|
|
|
|
|
3. use `pw-cli s <node-id> Props '{ iec958Codecs : [ PCM ] }'` to modify the codecs at runtime.
|
|
|
|
|
|
|
|
|
## Changing Other Node Parameters
|
|
|
|
|
|
In all cases a match rule needs to be created for the nodes and then the properties need to be updated with the desired values.
|
|
|
|
|
|
### Changing the Node sample rate
|
|
|
|
|
|
Make a match rule for you node like this:
|
|
|
|
|
|
```
|
|
|
rules = [
|
|
|
{
|
|
|
matches = [
|
|
|
node.name = "alsa_output.pci-0000_02_02.0.analog-stereo"
|
|
|
]
|
|
|
actions = {
|
|
|
update-props = {
|
|
|
...
|
|
|
audio.rate = 16000
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
....
|
|
|
```
|
|
|
Change the `node.name` property to the name of the sink/source you want to change. Use `pw-cli ls Node` to find the `node.name property`.
|
|
|
|
|
|
Change the `audio.rate` property to the required value. You can also change `audio.channels` or `audio.position`
|
|
|
|
|
|
### Renaming Nodes
|
|
|
|
|
|
Long sound card descriptions cause problems for certain GUI applications such as pavucontrol where you need to make the window very wide in order to accommodate the strings. With PulseAudio you can rename them directly in pavucontrol by right-clicking the port dropdown as long as you have the module-device-manager PulseAudio module loaded.
|
|
|
|
|
|
To do the same in PipeWire add the following to your `/etc/pipewire/media-session.d/alsa-monitor.conf/` file:
|
|
|
````
|
|
|
rules = [
|
|
|
...
|
|
|
{
|
|
|
matches = [
|
|
|
{
|
|
|
node.name = "alsa_output.pci-0000_02_02.0.analog-stereo"
|
|
|
}
|
|
|
{
|
|
|
node.name = "alsa_output.pci-0000_02_02.0.pro-output-0"
|
|
|
}
|
|
|
]
|
|
|
actions = {
|
|
|
update-props = {
|
|
|
node.nick = "Onboard audio"
|
|
|
node.description = "Onboard audio output"
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
....
|
|
|
````
|
|
|
|
|
|
### Changing the Node Priority
|
|
|
|
|
|
Make a match rule for you node and add:
|
|
|
|
|
|
```
|
|
|
rules = [
|
|
|
...
|
|
|
{
|
|
|
matches = [
|
|
|
....
|
|
|
]
|
|
|
actions = {
|
|
|
update-props = {
|
|
|
...
|
|
|
priority.session = 3000
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
....
|
|
|
```
|
|
|
Device priorities are usually from 0 to 2000.
|
|
|
|
|
|
# Udev Rules
|
|
|
|
|
|
# ALSA `PipeWire:` Plugin
|
|
|
|
|
|
# Latency |