ALSA DMIX and Pulse/Pipewire, Pulse insists on using a bad device
SlackwareThis Forum is for the discussion of Slackware Linux.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Could you share the output of "aplay -L" from Slackware 14.2 and Slackware 15.0? I know between the two versions there, which have two versions of ALSA, that the enumeration of devices by ALSA, including even the presence of a "default" and similarly named devices has changed. This behavior is also hardware dependent.
I have gotten PulseAudio to output to a virtual device that I created "pulse_default", by adding an entry to /usr/share/pulseaudio/alsa-mixer/profile-sets/default.conf.
I have defined the pulse_default virtual device /etc/asound.conf, routing it to dmix and card0.
PulseAudio and Audacious(ALSA) and xmms and aplay have simultaneously output sounds through dmix.
PulseAudio still takes over the controls, mixer, and mutes of the sound card.
It has a nasty habit of muting the headphones output when it is disconnected.
I have to use alsamixer to un-mute it again and set the volumes again for the other programs outputting directly to ALSA.
I have been working on determining a set of patches that are known to work, and what is legal syntax that users can rely upon when doing this themselves.
Towards this I have been studying every guide and documentation that I can access. Most of them are repeats of the same basic card redirection, and mostly useless for this task.
Have not found a comprehensive documentation of asound.conf configuration.
I have modified the PulseAudio code in several places to support pulse dedicated devices, but have not been able to get them to work (syntax and bad arguments) with ALSA.
One problem is that PulseAudio wants to search each card independendly, but I can only declare a virtual device in ALSA as a name without a card designation.
There are some indications that there must be some way to allow and make use of a card designation.
This may require altering the syntax that PulseAudio uses to probe the audio devices.
I am still investigating that.
How much patches of the PulseAudio code will be used, is still to be determined.
Another problem is that routing "default" output through dmix, disables the "default" microphone.
You can select a specific microphone directly, which is what most programs do.
Those that try to use the "default" microphone will get nothing, because dmix does not handle capture devices.
This can be fixed by declaring default using the asym plugin, which combines the output and capture devices into a virtual card.
========
My slackware 14.2 output from aplay -L.
Code:
null
Discard all samples (playback) or generate zero samples (capture)
pulse
PulseAudio Sound Server
default:CARD=SB
HDA ATI SB, ALC892 Analog
Default Audio Device
sysdefault:CARD=SB
HDA ATI SB, ALC892 Analog
Default Audio Device
front:CARD=SB,DEV=0
HDA ATI SB, ALC892 Analog
Front speakers
surround21:CARD=SB,DEV=0
HDA ATI SB, ALC892 Analog
2.1 Surround output to Front and Subwoofer speakers
surround40:CARD=SB,DEV=0
HDA ATI SB, ALC892 Analog
4.0 Surround output to Front and Rear speakers
surround41:CARD=SB,DEV=0
HDA ATI SB, ALC892 Analog
4.1 Surround output to Front, Rear and Subwoofer speakers
surround50:CARD=SB,DEV=0
HDA ATI SB, ALC892 Analog
5.0 Surround output to Front, Center and Rear speakers
surround51:CARD=SB,DEV=0
HDA ATI SB, ALC892 Analog
5.1 Surround output to Front, Center, Rear and Subwoofer speakers
surround71:CARD=SB,DEV=0
HDA ATI SB, ALC892 Analog
7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
iec958:CARD=SB,DEV=0
HDA ATI SB, ALC892 Digital
IEC958 (S/PDIF) Digital Audio Output
hdmi:CARD=HDMI,DEV=0
HDA ATI HDMI, HDMI 0
HDMI Audio Output
===========
Note: that most of the devices listed by aplay -L are virtual devices that are declared by default by ALSA.
They are all conversions that use the plug channel mixer to blend stereo channels into some set of output channels.
You can define one yourself with your own blend of channels, or redefine one of those.
These route directly to the slave device and thus will "busy" that device while they are open.
ALSA plug devices that use dmix do not "busy" the dmix device.
My experiments so far show that the dmix device opens the dest device and will "busy" that.
This is why PulseAudio access to all these devices all block the use of dmix, and the use of dmix blocks PulseAudio from using those devices.
The solution that I have gotten is to get PulseAudio to list and use a dmix virtual device.
I do not think that I am the first person to do this. I remember seeing reports from other people having modified the pulse definitions, but their descriptions lacked adequate detail.
===========
The problem has been that PulseAudio will not use the default device.
I know it is there in slackware 15 too, as Audacious and xmms and aplay all use it. I have routed it to dmix in asound.conf.
PulseAudio does know about default.
I will use it ONLY when it does not have a card specified. That is in the code, but when it is invoked is unknown yet.
When using the PulseAudio tools where the output device is selected, you do not get it as an option. That is the problem.
This effort is to get a usable output device entry in that list, so that most everybody who has had trouble with PulseAudio blocking programs using ALSA, can have a simple menu choice that does not do that.
============
Note that most of this work will later carry over into doing this with Pipewire. Assuming that Pipewire does not have its own solution.
I have looked into the Pipewire code and have not found any comparible code, that tests for which ALSA devices are present.
There are several possibilities.
1. Pipewire does the ALSA probe in some entirely different way, not using snd_pcm_open. This is hard to conceive of what it could be.
2. Some part of the Pipewire code is not in the source code tar file I have gotten from Slackware. Maybe there is more than one.
3. Pipewire is reading /etc/asound.conf directly, and interpreting it itself.
4. Pipewire is using PulseAudio libraries, and just calls them for this functionality.
Note that Pipewire does make use of some PulseAudio tools, like the pavucontrol.
Last edited by selfprogrammed; 09-25-2023 at 03:43 PM.
Per that request of "aplay -L" on Slackware 15. (I am running Slack 15 today).
This is with the additional "pulse_default" and a bunch of other test definitions added to /etc/asound.conf.
Code:
null
Discard all samples (playback) or generate zero samples (capture)
lavrate
Rate Converter Plugin Using Libav/FFmpeg Library
samplerate
Rate Converter Plugin Using Samplerate Library
speexrate
Rate Converter Plugin Using Speex Resampler
oss
Open Sound System
pulse
PulseAudio Sound Server
speex
Plugin using Speex DSP (resample, agc, denoise, echo, dereverb)
upmix
Plugin for channel upmix (4,6,8)
vdownmix
Plugin for channel downmix (stereo) with a simple spacialization
sysdefault:CARD=SB
HDA ATI SB, ALC892 Analog
Default Audio Device
front:CARD=SB,DEV=0
HDA ATI SB, ALC892 Analog
Front output / input
surround21:CARD=SB,DEV=0
HDA ATI SB, ALC892 Analog
2.1 Surround output to Front and Subwoofer speakers
surround40:CARD=SB,DEV=0
HDA ATI SB, ALC892 Analog
4.0 Surround output to Front and Rear speakers
surround41:CARD=SB,DEV=0
HDA ATI SB, ALC892 Analog
4.1 Surround output to Front, Rear and Subwoofer speakers
surround50:CARD=SB,DEV=0
HDA ATI SB, ALC892 Analog
5.0 Surround output to Front, Center and Rear speakers
surround51:CARD=SB,DEV=0
HDA ATI SB, ALC892 Analog
5.1 Surround output to Front, Center, Rear and Subwoofer speakers
surround71:CARD=SB,DEV=0
HDA ATI SB, ALC892 Analog
7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
iec958:CARD=SB,DEV=0
HDA ATI SB, ALC892 Digital
IEC958 (S/PDIF) Digital Audio Output
usbstream:CARD=SB
HDA ATI SB
USB Stream Output
hdmi:CARD=HDMI,DEV=0
HDA ATI HDMI, HDMI 0
HDMI Audio Output
usbstream:CARD=HDMI
HDA ATI HDMI
USB Stream Output
This is a patch to the PulseAudio default conf that makes it check for device "pulse_default".
This is NOT a finished product, but it is working for me.
Apply this patch to "/usr/share/pulseaudio/alsa-mixer/profile-sets/default.conf"
This is the /etc/asound.conf definitions that route the "pulse_default" to a dmix device.
This is what I am currently using that is working.
Code:
# set dmix as default, used by most audio programs
pcm.!default {
type plug
slave.pcm "dmix"
}
# create a virtual device for PulseAudio
# This routes pulse_default to the dmix device, which does NOT become "busy"
pcm.pulse_default {
type plug
slave.pcm "dmix"
}
This is another way to configure pulse_default that might be needed for more complicated situations.
Code:
pcm.pulse_default {
type dmix
ipc_key 76221 # unique buffer id (make up something)
slave {
pcm "hw:0,0"
channels 2
}
}
This is documentation on configure of ALSA asound.conf, with some PulseAudio specific hints.
File: "ALSA_asound_config.conf"
This is NOT finished yet, so it is preliminary version.
Code:
# Notes about asound.conf regarding PulseAudio.
# PRELIMINARY 2023/09/25
# This is from multiple sources, and personal testing.
# Some sources, which may have moved:
# "asoundrc" at "https://alsa-project.org"
# "A close look at ALSA", by Volker Schatz.
# The ALSA config file is re-read every time a device is opened.
# The default device.
# pcm.default { ... }
# ctl.default { ... }
# Default is equal to plug plugin with hw plugin as slave.
# The default device is the target of most audio programs.
# To override the usual default virtual device.
# For example, to make the HDMI card the default.
pcm.!default { # PCM redirect
type hw
card "HDMI"
}
ctl.!default { # mixer and volume control redirect
type hw
card "HDMI"
}
# Defaults can be overwritten in system and local configuration files.
# There are many defaults in: /usr/share/alsa/alsa.conf.
# These are mostly default settings for parameters, and default devices.
# The defaults when a card is not specified,
# such as if the default virtual device has not been defined.
# Set the card 'SB' as the default for pcm and ctl.
defaults.pcm.!card "SB"
defaults.ctl.!card "SB"
##### Sound Cards
# Your card info is available in /proc/asound/cards.
# Each card has a directory in /proc/asound.
# Each card has an index number.
# Card name examples: SB, HDMI, card0, card1
##### Devices and plugins
# A target device can be an audio card, a plugin, or a virtual device.
# Device specification: <name>:<param1>,<param2>,<param3>
# Parameters depend upon the plugin.
# While the hw plugin (and associated plugin) will accept a card index (hw:0),
# virtual devices will treat that as a syntax error.
# A list of plugins, and their ALSA definitions, can be seen at
# /usr/share/alsa/pcm
# Note: the string parameters are different than the slave parameters.
# They are listed separately in the conf files.
# The hw plugin.
# Hardware device interface: hw:<card>,<dev>,<subdev>
# A defined name can be used for card, dev, subdev.
# -1 means any
# Examples of hw routing strings:
# hw
# hw:0
# hw:0,0
# hw:supersonic,1
# hw:DEV=1,CARD=soundwave,SUBDEV=2
# Type hw syntax
# Has some additional specification over a hw string.
pcm.hw_example {
type hw
# card is required
card 2 # by name, or index
# optional
device 0 # by index, default 0
subdevice 0 # by index, default -1 (any)
mmap_emulation 0 # bool, enable emulation for ro and wo devices, default 0
}
# The plug plugin.
# Acts like a plug-board, connecting streams.
# plug:<slave>
# Examples:
# plug:hw
# plug:'hw:0,0'
# plug:SLAVE=hw
# Type plug syntax
pcm.plug_example {
type plug
# slave contains the parameters of the plug slave device
slave {
# pcm is required
pcm "name" # the name of the pcm stream, by name
# optional
format "S16_LE" # default nearest, or "unchanged"
channels 2 # mono, stereo, or more, or "unchanged"
rate 44100 # default nearest, or "unchanged"
}
# options
route_policy "default"
# default:
# average: average of input channels
# copy: only first channels are copied to dest
# duplicate: duplicate first set of channels
# Transfer table, swap channels, blending channels.
# Each channel in ttable is blend of the specified channels,
# mixed using the specified volumes.
# Reasonable volumes are in the range (-2.0 to 2.0).
ttable {
0 { 0 0.75, 2 0.3 }
1 ( 1 0.75, 2 0.3 }
}
}
# The plughw plugin, uses the plug plugin, and hw plugin as slave.
# plughw:<card>,<dev>,<subdev>
# Same syntax and parameters as hw.
# Examples:
# plughw:soundwave,1,2
# The dmix device, mixes multiple streams into one.
# The slave device of dmix cannot be an asym device (unknown reason), such as "front:0,0".
# See /usr/share/alsa/pcm/dmix.conf.
# The default sample rate is 48000.
# dmix:<card>,<dev>,<subdev>,<format>,<rate>,<channels>
# Examples:
# dmix
# dmix:RATE=44100,FORMAT="S16_BE",CHANNELS=2
# dmix:CARD=1
# dmix:SLAVE='hw:0,0'
pcm.dmix_example {
type dmix
ipc_key 1231
slave {
pcm "hw:1,0"
format "S32_LE"
channels 2
period_size 1024
period_time -1
periods 16
}
}
# The dsnoop device, splits one input into multiple outputs.
# see /usr/share/alsa/pcm/dsnoop.conf
pcm.dsnoop_example {
type dsnoop
ipc_key 992952 # must be unique
ipc_key_add_uid yes
slave {
pcm "hw:0,0"
channels 2
period_size 1024
buffer_size 4096
rate 48000
periods 0
period_time 0
}
bindings {
0 0
0 1
}
}
# The dpl plugin, converts 2 channel to 5 channel sound.
# see /usr/share/alsa/pcm/dpl.conf
# The shm plugin, shared memory device for server communication.
# shm:<socket>,<pcm_device>
# Examples:
# shm:/tmp/alsa.sock,default
# The tee device, stores to a file, and transfers to a slave.
# tee:<slave_device>,<filename>,<file_format>
# Examples:
# tee:hw,'/tmp/alsa_out.raw',raw
# The file device, stores to a file, with null device as a slave.
# file:<filename>,<file_format>
# Examples:
# tee:'/tmp/alsa_out.raw',raw
# The null device, null plugin, does nothing with the data.
# null
# The dshare plugin, gives exclusive access to channels.
# The route plugin,
# The asym plugin, combines a playback stream and a capture input stream into one device, so that ALSA can treat it like a card interface.
# The rate plugin, coverts to other rates. Most plugins also convert rates.
# The jack plugin, to connect to JACK.
pcm.jack_plug {
type plug
slave.pcm "jack"
}
pcm.jack_example {
playback_ports {
0 alsa_pcm:playback_1
1 alsa_pcm:playback_2
}
capture_ports {
0 alsa_pcm:capture_1
1 alsa_pcm:capture_2
}
}
##### Set parameters of plugins.
# For pcm (PCM audio) and for ctl (control) devices, plugins, and virtual devices.
# syntax:
# pcm.<name> {
# <settings>
# }
# The ! sign: override the default set by ALSA.
# pcm.!default ...
# Values can be assigned by:
# value string : "hw:1,0"
# container : hw { card=1 device=0 }
# reference : my_audigy_card # where this is defined in another line (see pcm_slave)
# Examples:
# This will route the default PCM device, to plugin dmix.
# Any audio tool outputing to default, will route to dmix.
# The default device is also used for capture, and the dmix plugin does NOT handle capture,
# so with this the default microphone will no longer work (see asym plugin).
pcm.!default {
type plug
slave.pcm "dmix"
}
# This will route the default control device, to card 1.
# Alsamixer will then default to opening card 1 control.
ctl.!default {
type hw
card 1
}
# Same effect as: >> alsamixer -D hw:1
##### DEFINITIONS
# Define a new pcm virtual device.
# pcm.<new_name> {
# type <plugin_type>
# <settings>
# }
# <plugin_type> : hw, plug, plughw
# <settings> : dependent upon the <plugin_type>
# Examples:
# Alias "george" to be your card 1.
pcm.george {
type hw
card 1
}
# Virtual slave device.
pcm.henry2 {
type plug
pcm "some_plug_device"
slave {
rate 48000
}
}
# This can be used as a plug slave, like it was a macro definition.
# slave slave_example_3
pcm_slave.slave_def_example_3 {
# a pcm stream with stream parameters
pcm "plughw:1,1"
channels 5
format S16_LE
rate 48000
}
pcm.henry3 {
type plug
slave slave_def_example_3
}
##### PulseAudio RECOMMENDED SETTINGS
# Choose which ones are appropriate for your system.
# DO NOT use them all, as they have different ways to define the same device,
# and they conflict.
# This pulse_default device will connect directly to hardware.
# It will NOT stop it from making it "busy" when in use.
pcm.pulse_default {
type hw
card 0
}
# This pulse_default device will redirect to dmix.
# It routes to dmix, which will NOT be "busy" when in use.
pcm.pulse_default {
type plug
slave.pcm "dmix"
}
# This pulse_default device will redirect to dmix_0,
# which is another virtual device.
pcm.pulse_default {
type plug
slave.pcm "dmix_0"
}
# This will setup a virtual device, that is dmix to a specific hardware device.
# It will NOT be "busy" when in use.
pcm.dmix_0 {
type dmix
ipc_key 77329 # a unique identifier key (make it unique)
slave {
pcm "front:0,0" # slave target designation
# parameters for the slave device
channels 2
period_time 0
period_size 1024
buffer_size 8192
rate 44100
}
bindings {
# swap channels, combine channels, or blend them
0 0
1 1
}
}
# This pulse_default will use dmix, with a specific SB card.
# The pulse controls are also routed to the same card.
pcm.pulse_default {
type plug
slave {
pcm "dmix:SB,0"
}
}
ctl.pulse_default {
type hw
card SB
}
##### FOUND RECOMMENDED SETTINGS
# These were gathered from various sources, and I do not claim to understand them,
# Define device pcm.dsp to route to dmix.
pcm.dsp {
type plug
slave.pcm "dmix"
}
# Set the default, overriding the default set by ALSA.
# This default routes its pcm output to dmix.
pcm.!default {
type plug
slave.pcm "dmix"
}
# Declare a custom device, with control.
# This redirects the PCM stream.
pcm.pulse_3 {
type plug
slave {
pcm "dmix:1,0"
}
}
# This redirects the mixer and volume controls.
ctl.pulse_3 {
type hw
card "card1"
}
#### Syntax notes
# Space is considered an adequate separator of values.
# Put values that contain a space in quotes.
# Comma, semicolon, and equal sign are optional.
# These are equivalent:
# hw 1
# hw=1
# hw 1,
# hw 1;
# These are equivalent:
# pcm { b=1 ... }
# pcm { b 1, ... }
# pcm.b=1, ...
Last edited by selfprogrammed; 09-26-2023 at 05:29 PM.
Reason: typo
This fix to the pulseaudio and the ALSA configuration, as shown above, has been working mostly flawlessly.
I have been playing XMMS for music, started a game using SDL->pulseaudio, had a zoom conversation, with the above setup.
There is that pulseaudio has a tendency to sometimes mute the audio card. It does not do it often enough that I remember that is the problem, so it is always the last thing I check. Somehow it muted audio while switching rooms in a zoom meeting, and I did not figure out why I lost audio until later that day (they had to call me on the phone).
I thought it was something that zoom was doing.
PulseAudio can also play havoc with the master and headphone level settings, as it considers that if it is is going off, EVERYONE is going off.
I have included this fix in my Linux sound setup tool.
I have had to take care of other pressing business, so this investigation has slowed for the time being. I have a release date coming up soon and have to tend to that.
This issue is still a hot item on my TODO list.
Still do not know how to apply this to pipewire, and have not found out yet if the newer pipewire are any different.
Last edited by selfprogrammed; 10-24-2023 at 05:31 PM.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.