In bluealsa-aplay the mixer device is not set by default same as the output device
Hi all, I finally moved from an old version of bluez-alsa to the latest from source, however I had quite an hard time setting up the hardware mixer in bluealsa-aplay
I have a Raspberry Pi 2 with an USB DAC, I thus have three audio output device.
With the older version I used the following startup command:
/usr/bin/bluealsa-aplay -S -D plughw:CARD=AUDIO,DEV=0 --mixer-name="SMSL USB AUDIO "
this worked just fine, however with latest code it failed to open the mixer:
/usr/bin/bluealsa-aplay -D plughw:CARD=AUDIO,DEV=0 --mixer-name='SMSL USB AUDIO '
bluealsa-aplay: [2717] D: ../../../utils/aplay/aplay.c:797: Creating IO worker 78:D8:40:82:76:6E
bluealsa-aplay: [2717] D: ../../../utils/aplay/aplay.c:1223: Starting main loop
bluealsa-aplay: [2718] D: ../../../utils/aplay/aplay.c:460: Opening BlueALSA source PCM: /org/bluealsa/hci0/dev_78_D8_40_82_76_6E/a2dpsnk/source
bluealsa-aplay: [2718] D: ../../../utils/aplay/aplay.c:484: Starting IO loop
bluealsa-aplay: [2718] D: ../../../utils/aplay/aplay.c:613: Opening ALSA playback PCM: name=plughw:CARD=AUDIO,DEV=0 channels=2 rate=96000
bluealsa-aplay: [2718] D: ../../../utils/aplay/aplay.c:634: Opening ALSA mixer: name=default elem=SMSL USB AUDIO index=0
bluealsa-aplay: [2718] W: ../../../utils/aplay/aplay.c:640: Couldn't open ALSA mixer: Mixer element not found
After some trial and error I found that this syntax works:
/usr/bin/bluealsa-aplay -D plughw:CARD=AUDIO,DEV=0 --mixer-name='SMSL USB AUDIO ' --mixer-device='default:CARD=AUDIO'
Basically bluealsa-aplay was selecting by default as mixer device the internal audio board rather than the same device used for the output.
While not technically an error I think is a wrong behavior. If it's not specified, is logical to suppose that the device for which we want to change the volume is the same where we output the sound.
While not technically an error I think is a wrong behavior. If it's not specified, is logical to suppose that the device for which we want to change the volume is the same where we output the sound.
I fully agree with you. However, I'm not sure whether there is any way to determine the name of the mixer device based on the given PCM....
It worked in the previous version. If needed I can restore the old image and provide you whatever log or data you need
It worked in the previous version.
Which version you've been using?
Cloned from git on may 3, 2024
I'm interested to know how you define the mixer device to be the "same" as the pcm device. Do you have an example application which does this so I can see how they define this?
With the older version I used the following startup command:
/usr/bin/bluealsa-aplay -S -D plughw:CARD=AUDIO,DEV=0 --mixer-name="SMSL USB AUDIO "
Hmm, are you sure that when using that older version then bluealsa-aplay was actually operating the hw control (by seeing it change in alsamixer, for example). I'm wondering whether it might have been using bluealsa's internal software volume control (note that bluealsa did not switch to pass-through volume control by default for A2DP until commit 61adf95 in September 2024).
I was pretty sure it worked with the HW volume because I remember the struggle with the stupid blank as trailing char in the mixer name, however I restored the previous image and retried it.
The mixer volume actually does not change, which surprised me, however I start bluealsa with:
/usr/bin/bluealsa --loglevel=debug -p a2dp-source -p a2dp-sink --a2dp-volume -c aptX -c aptX-HD
and bluealsa-aplay with:
/usr/bin/bluealsa-aplay -v -D plughw:CARD=AUDIO,DEV=0 --mixer-name="SMSL USB AUDIO " --loglevel=debug
and even if the volume actually does not change, the mixer is opened correctly:
bluealsa-aplay: [4398] I: aplay.c:1241: Selected configuration:
BlueALSA service: org.bluealsa
ALSA PCM device: plughw:CARD=AUDIO,DEV=0
ALSA PCM buffer time: 500000 us
ALSA PCM period time: 100000 us
Volume control type: auto
ALSA mixer device: default
ALSA mixer element: 'SMSL USB AUDIO ',0
Bluetooth device(s): ANY
Profile: A2DP
bluealsa-aplay: [4398] D: aplay.c:876: Creating IO worker 78:D8:40:82:76:6E
bluealsa-aplay: [4398] D: aplay.c:1287: Starting main loop
bluealsa-aplay: [4399] D: aplay.c:542: Opening BlueALSA source PCM: /org/bluealsa/hci0/dev_78_D8_40_82_76_6E/a2dpsnk/source
bluealsa-aplay: [4399] D: aplay.c:568: Starting IO loop
bluealsa-aplay: [4399] D: aplay.c:692: Opening ALSA playback PCM: name=plughw:CARD=AUDIO,DEV=0 channels=2 rate=48000
bluealsa-aplay: [4399] D: aplay.c:708: Opening ALSA mixer: name=default elem=SMSL USB AUDIO index=0
bluealsa-aplay: [4399] D: aplay.c:606: BT device marked as inactive: 78:D8:40:82:76:6E
bluealsa-aplay: [4399] D: aplay.c:692: Opening ALSA playback PCM: name=plughw:CARD=AUDIO,DEV=0 channels=2 rate=48000
bluealsa-aplay: [4399] D: aplay.c:708: Opening ALSA mixer: name=default elem=SMSL USB AUDIO index=0
bluealsa-aplay: [4399] D: aplay.c:606: BT device marked as inactive: 78:D8:40:82:76:6E
bluealsa-aplay: [4399] D: aplay.c:636: BlueALSA source PCM disconnected: /org/bluealsa/hci0/dev_78_D8_40_82_76_6E/a2dpsnk/source
bluealsa-aplay: [4399] D: aplay.c:501: Exiting IO worker 78:D8:40:82:76:6E
ok, sorry to everyone and forget about the "worked in the previous version" Seems someone (who could actually only have been myself) had configured asound.conf in /etc to redefine as default the AUDIO card, this obviously made previous version work without configuring the mixer device parameter
I'm not sure whether there is any way to determine the name of the mixer device based on the given PCM
Something like:
snd_pcm_info_t *info;
snd_pcm_t *pcm;
int card;
...
snd_pcm_info_alloca(&info);
snd_pcm_info(pcm, info);
card = snd_pcm_info_get_card(info);
Then construct a mixer device name on that card as "hw:<card>". If the pcm device is not on a card (e.g. the file plugin or some ioplug) then snd_pcm_info_get_card() returns -1 and we must use some other strategy.
we must use some other strategy.
maybe try, in order:
- open mixer with same name as pcm
- open mixer with same name as pcm (omitting ARGS)
- fail with message "unable to identify mixer device for PCM
"
"fail" could mean either terminate the application, or else operate as if "--volume=none" was given
I'm quite ignorant in alsa APIs but "amixer -c <cardN> scontrols" can list the mixer names for each card.
Isn't it possible to get the card number from the PCM device and then use a code similar to amixer to get the name of the available mixers for that card?
amixer -c 0 scontrols
Simple mixer control 'SMSL USB AUDIO ',0
Simple mixer control 'SMSL USB AUDIO ',1
Welcome to the wonderfully confusing world of ALSA terminology.
"mixer" is an API that enables access to a collection of controls. A "mixer device" is a binding of that API to a specific control collection. Exactly what that collection represents depends on the "type" of the mixer device. ALSA defines only one mixer device type internally, called "hw". The hw mixer device type contains all the controls of a single soundcard. To define a mixer device of that type it is necessary to bind it to a specific card. So, for example "hw:1" contains all the controls on card 1, "hw:AUDIO" contains all the controls on card AUDIO, etc. There are also other mixer device types defined outside of the ALSA core configuration; you will be familiar with the types "bluealsa", "pipewire", "pulse".
Your amixer example is listing all the "simple controls" on card 0. To get that list it opens the mixer device "hw:0" and then iterates over the collection of controls that device contains.
"control" is also a confusing term, and it is something that this feature request will have to address, but first I think we should decide on what to do when the mixer device is unspecified. Only after that should we start discussing what to do when the control name is unspecified. (The bluealsa-aplay command line uses the option "--mixer-name" to select the "simple control name" which only adds to the confusion I suppose).
My confused end-user expectation would be:
If no PCM device and no Mixer device option are specified, use "default" for both
If PCM device option is specified and no Mixer device option is specified, use for the Mixer device the same CARD as in the PCM device. If no mixer can be found print a warning message and use volume=none
If PCM device is not specified and Mixer device is specified, I'd assume the user is as confused as me, would print an error or warning message that PCM device is required and either exit or use defaults for both
If both PCM and Mixer devices are specified but are different, just use it, probably the user knows what he's doing
For the mixer name control then, if none is specified determine the available ones on the device decided in the previous step and use the first one returned
Hope it makes sense
If no PCM device and no Mixer device option are specified, use "default" for both
I agree. In fact that is what happens now.
If PCM device option is specified and no Mixer device option is specified, use for the Mixer device the same CARD as in the PCM device. If no mixer can be found print a warning message and use volume=none
Not all PCM devices have a card. As described previously, my preference for such devices is to at least try a mixer device with the same name as the pcm device, if one exists. When none can be found then my preference is the same as yours, to "carry on regardless" (with appropriate logging of course).
If PCM device is not specified and Mixer device is specified, I'd assume the user is as confused as me, would print an error or warning message that PCM device is required and either exit or use defaults for both.
Hmm, not sure about this one. My instinct would be to use "default" pcm and specified mixer device; but I could be persuaded otherwise.
If both PCM and Mixer devices are specified but are different, just use it, probably the user knows what he's doing
Agreed.
For the mixer name control then, if none is specified determine the available ones on the device decided in the previous step and use the first one returned
I'm afraid that will not work. Its fine for cards that have a "Master" or "Speaker" control (such as PCH or USB) as these names are given priority when sorting simple controls; but for other card types, the first item may not even be a volume control. For example the very commonly used IQaudio DAC has 'DSP Program' as its first item. Perhaps this heuristic could be refined to select the first control that has decibel scaling, since at least that is definitely a volume control.
Not all PCM devices have a card.
I definitely do not have the experience required to give good advice on ALSA
Hmm, not sure about this one. My instinct would be to use "default" pcm and specified mixer device; but I could be persuaded otherwise.
I trust your judgement, but still a "Warning, I do what you ask, if volume does not work maybe the problem is here" kind of message would make sense
Perhaps this heuristic could be refined to select the first control that has decibel scaling, since at least that is definitely a volume control.
Agreed 100%
The bluealsa-aplay command line uses the option "--mixer-name" to select the "simple control name" which only adds to the confusion I suppose
I'm OK to change that to some less confusing name (which will align better with ALSA nomenclature).
change that to some less confusing name
my suggestion is --mixer-control=
but I would not change it unless it is also decided to change the default mixer device selection logic. The current option names and default selections are exactly as documented in the manual page, so I think that anyone who has read that manual page should know exactly what to expect. (I have very little sympathy for people who do not read the manuals for the tools they are using).
select the first control that has decibel scaling, since at least that is definitely a volume control
... or maybe not. I've just noticed that on the IQaudio cards (which are the "official" HAT sound cards manufactured and sold by raspberrypi.com), the first decibel scaling control is "Analogue". This control has only two values: 0.0dB and -6.0dB. Clearly it is of no use for scaling the output volume. So I retract that suggestion, I think trying to guess the correct control for any arbitrary card will create more problems than it solves.